diff --git a/.clang-format b/.clang-format new file mode 100644 index 000000000000..5bead5f39dd3 --- /dev/null +++ b/.clang-format @@ -0,0 +1,2 @@ +BasedOnStyle: LLVM + diff --git a/.gitignore b/.gitignore index bde2fe708b8a..28853c5930f0 100644 --- a/.gitignore +++ b/.gitignore @@ -162,4 +162,8 @@ Desktop.ini # Mac OS X Finder .DS_Store +# Ctags index files +.tags +.tags_sorted_by_file + Code/Mantid/Vates/VatesSimpleGui/ViewWidgets/inc/MantidVatesSimpleGuiViewWidgets/LibHelper.h diff --git a/Code/Mantid/Build/CMake/DarwinSetup.cmake b/Code/Mantid/Build/CMake/DarwinSetup.cmake index c6a54e402f8c..6a6a88f3af7a 100644 --- a/Code/Mantid/Build/CMake/DarwinSetup.cmake +++ b/Code/Mantid/Build/CMake/DarwinSetup.cmake @@ -81,6 +81,14 @@ endif () ########################################################################### set ( CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -m64" ) set ( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -m64 -std=c++0x" ) +set ( CMAKE_XCODE_ATTRIBUTE_CLANG_CXX_LANGUAGE_STANDARD "c++0x" ) + +if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang") + set ( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -stdlib=libc++" ) + set ( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-deprecated-register" ) + set ( CMAKE_XCODE_ATTRIBUTE_OTHER_CPLUSPLUSFLAGS "-Wno-deprecated-register") + set ( CMAKE_XCODE_ATTRIBUTE_CLANG_CXX_LIBRARY "libc++" ) +endif() if( ${CMAKE_C_COMPILER} MATCHES "icc.*$" ) set ( CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -no-intel-extensions" ) @@ -113,8 +121,14 @@ if (OSX_VERSION VERSION_LESS 10.9) set ( SITEPACKAGES /Library/Python/${PY_VER}/site-packages ) else() # Assume we are using homebrew for now + # set Deployment target to 10.8 + set ( CMAKE_OSX_SYSROOT /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.9.sdk ) + set ( CMAKE_OSX_ARCHITECTURES x86_64 ) + set ( CMAKE_OSX_DEPLOYMENT_TARGET 10.8 ) set ( PYQT4_PYTHONPATH /usr/local/lib/python${PY_VER}/site-packages/PyQt4 ) set ( SITEPACKAGES /usr/local/lib/python${PY_VER}/site-packages ) + # use homebrew OpenSSL package + set ( OPENSSL_ROOT_DIR /usr/local/opt/openssl ) endif() # Python packages @@ -145,6 +159,8 @@ file ( GLOB THIRDPARTY_PYTHON_PACKAGES ${CMAKE_LIBRARY_PATH}/Python/* ) foreach ( PYPACKAGE ${THIRDPARTY_PYTHON_PACKAGES} ) if ( IS_DIRECTORY ${PYPACKAGE} ) install ( DIRECTORY ${PYPACKAGE} DESTINATION ${BIN_DIR} ) + else() + install ( FILES ${PYPACKAGE} DESTINATION ${BIN_DIR} ) endif() file ( COPY ${PYPACKAGE} DESTINATION ${PROJECT_BINARY_DIR}/bin ) endforeach( PYPACKAGE ) diff --git a/Code/Mantid/Build/CMake/FindPyQt.py b/Code/Mantid/Build/CMake/FindPyQt.py index 3c24b73afb84..fa5618d045c7 100644 --- a/Code/Mantid/Build/CMake/FindPyQt.py +++ b/Code/Mantid/Build/CMake/FindPyQt.py @@ -1,25 +1,48 @@ # Copyright (c) 2007, Simon Edwards +# Copyright (c) 2014, Raphael Kubo da Costa # Redistribution and use is allowed according to the terms of the BSD license. # For details see the accompanying COPYING-CMAKE-SCRIPTS file. -import PyQt4.pyqtconfig +import PyQt4.QtCore +import os +import sys -pyqtcfg = PyQt4.pyqtconfig.Configuration() -print("pyqt_version:%06.0x" % pyqtcfg.pyqt_version) -print("pyqt_version_str:%s" % pyqtcfg.pyqt_version_str) - -pyqt_version_tag = "" -in_t = False -for item in pyqtcfg.pyqt_sip_flags.split(' '): - if item=="-t": - in_t = True - elif in_t: - if item.startswith("Qt_4"): - pyqt_version_tag = item +def get_default_sip_dir(): + # This is based on QScintilla's configure.py, and only works for the + # default case where installation paths have not been changed in PyQt's + # configuration process. + if sys.platform == 'win32': + pyqt_sip_dir = os.path.join(sys.platform, 'sip', 'PyQt4') else: - in_t = False -print("pyqt_version_tag:%s" % pyqt_version_tag) + pyqt_sip_dir = os.path.join(sys.platform, 'share', 'sip', 'PyQt4') + return pyqt_sip_dir + +def get_qt4_tag(sip_flags): + in_t = False + for item in sip_flags.split(' '): + if item == '-t': + in_t = True + elif in_t: + if item.startswith('Qt_4'): + return item + else: + in_t = False + raise ValueError('Cannot find Qt\'s tag in PyQt4\'s SIP flags.') -print("pyqt_sip_dir:%s" % pyqtcfg.pyqt_sip_dir) -print("pyqt_sip_flags:%s" % pyqtcfg.pyqt_sip_flags) +if __name__ == '__main__': + try: + import PyQt4.pyqtconfig + pyqtcfg = PyQt4.pyqtconfig.Configuration() + sip_dir = pyqtcfg.pyqt_sip_dir + sip_flags = pyqtcfg.pyqt_sip_flags + except ImportError: + # PyQt4 >= 4.10.0 was built with configure-ng.py instead of + # configure.py, so pyqtconfig.py is not installed. + sip_dir = get_default_sip_dir() + sip_flags = PyQt4.QtCore.PYQT_CONFIGURATION['sip_flags'] + print('pyqt_version:%06.x' % PyQt4.QtCore.PYQT_VERSION) + print('pyqt_version_str:%s' % PyQt4.QtCore.PYQT_VERSION_STR) + print('pyqt_version_tag:%s' % get_qt4_tag(sip_flags)) + print('pyqt_sip_dir:%s' % sip_dir) + print('pyqt_sip_flags:%s' % sip_flags) diff --git a/Code/Mantid/Build/CMake/FindPyQt4.cmake b/Code/Mantid/Build/CMake/FindPyQt4.cmake index 9b45d5169b3c..b3fe28c7e63b 100644 --- a/Code/Mantid/Build/CMake/FindPyQt4.cmake +++ b/Code/Mantid/Build/CMake/FindPyQt4.cmake @@ -9,16 +9,20 @@ # Find the installed version of PyQt4. FindPyQt4 should only be called after # Python has been found. # -# This file defines the following variables: +# This file defines the following variables, which can also be overriden by +# users: # # PYQT4_VERSION - The version of PyQt4 found expressed as a 6 digit hex number -# suitable for comparision as a string +# suitable for comparison as a string # # PYQT4_VERSION_STR - The version of PyQt4 as a human readable string. # -# PYQT4_VERSION_TAG - The PyQt version tag using by PyQt's sip files. +# PYQT4_VERSION_TAG - The Qt4 version tag used by PyQt's sip files. # -# PYQT4_SIP_DIR - The directory holding the PyQt4 .sip files. +# PYQT4_SIP_DIR - The directory holding the PyQt4 .sip files. This can be unset +# if PyQt4 was built using its new build system and pyqtconfig.py is not +# present on the system, as in this case its value cannot be determined +# automatically. # # PYQT4_SIP_FLAGS - The SIP flags used to build PyQt. @@ -30,19 +34,38 @@ ELSE(EXISTS PYQT4_VERSION) FIND_FILE(_find_pyqt_py FindPyQt.py PATHS ${CMAKE_MODULE_PATH}) EXECUTE_PROCESS(COMMAND ${PYTHON_EXECUTABLE} ${_find_pyqt_py} OUTPUT_VARIABLE pyqt_config) - IF( NOT ${pyqt_config} MATCHES "Traceback" ) - STRING(REGEX REPLACE "^pyqt_version:([^\n]+).*$" "\\1" PYQT4_VERSION ${pyqt_config}) - STRING(REGEX REPLACE ".*\npyqt_version_str:([^\n]+).*$" "\\1" PYQT4_VERSION_STR ${pyqt_config}) - STRING(REGEX REPLACE ".*\npyqt_version_tag:([^\n]+).*$" "\\1" PYQT4_VERSION_TAG ${pyqt_config}) - STRING(REGEX REPLACE ".*\npyqt_sip_dir:([^\n]+).*$" "\\1" PYQT4_SIP_DIR ${pyqt_config}) - STRING(REGEX REPLACE ".*\npyqt_sip_flags:([^\n]+).*$" "\\1" PYQT4_SIP_FLAGS ${pyqt_config}) + IF(pyqt_config) + STRING(REGEX MATCH "^pyqt_version:([^\n]+).*$" _dummy ${pyqt_config}) + SET(PYQT4_VERSION "${CMAKE_MATCH_1}" CACHE STRING "PyQt4's version as a 6-digit hexadecimal number") - SET(PYQT4_FOUND TRUE) - ENDIF() + STRING(REGEX MATCH ".*\npyqt_version_str:([^\n]+).*$" _dummy ${pyqt_config}) + SET(PYQT4_VERSION_STR "${CMAKE_MATCH_1}" CACHE STRING "PyQt4's version as a human-readable string") - include ( FindPackageHandleStandardArgs ) - find_package_handle_standard_args ( PyQt4 DEFAULT_MSG PYQT4_VERSION ) + STRING(REGEX MATCH ".*\npyqt_version_tag:([^\n]+).*$" _dummy ${pyqt_config}) + SET(PYQT4_VERSION_TAG "${CMAKE_MATCH_1}" CACHE STRING "The Qt4 version tag used by PyQt4's .sip files") - mark_as_advanced ( _find_pyqt_py ) + STRING(REGEX MATCH ".*\npyqt_sip_dir:([^\n]+).*$" _dummy ${pyqt_config}) + SET(PYQT4_SIP_DIR "${CMAKE_MATCH_1}" CACHE FILEPATH "The base directory where PyQt4's .sip files are installed") + + STRING(REGEX MATCH ".*\npyqt_sip_flags:([^\n]+).*$" _dummy ${pyqt_config}) + SET(PYQT4_SIP_FLAGS "${CMAKE_MATCH_1}" CACHE STRING "The SIP flags used to build PyQt4") + + IF(NOT IS_DIRECTORY "${PYQT4_SIP_DIR}") + MESSAGE(WARNING "The base directory where PyQt4's SIP files are installed could not be determined. This usually means PyQt4 was built with its new build system and pyqtconfig.py is not present.\n" + "Please set the PYQT4_SIP_DIR variable manually.") + ELSE(NOT IS_DIRECTORY "${PYQT4_SIP_DIR}") + SET(PYQT4_FOUND TRUE) + ENDIF(NOT IS_DIRECTORY "${PYQT4_SIP_DIR}") + ENDIF(pyqt_config) + + IF(PYQT4_FOUND) + IF(NOT PYQT4_FIND_QUIETLY) + MESSAGE(STATUS "Found PyQt4 version: ${PYQT4_VERSION_STR}") + ENDIF(NOT PYQT4_FIND_QUIETLY) + ELSE(PYQT4_FOUND) + IF(PYQT4_FIND_REQUIRED) + MESSAGE(FATAL_ERROR "Could not find Python") + ENDIF(PYQT4_FIND_REQUIRED) + ENDIF(PYQT4_FOUND) ENDIF(EXISTS PYQT4_VERSION) diff --git a/Code/Mantid/Build/CMake/FindTcmalloc.cmake b/Code/Mantid/Build/CMake/FindTcmalloc.cmake index 592887aac4c6..ea16a9012830 100644 --- a/Code/Mantid/Build/CMake/FindTcmalloc.cmake +++ b/Code/Mantid/Build/CMake/FindTcmalloc.cmake @@ -7,7 +7,7 @@ # TCMALLOC_FOUND If false, do not try to use TCMALLOC find_path ( TCMALLOC_INCLUDE_DIR tcmalloc.h - PATHS /usr/include/google + PATHS /usr/include/gperftools ) find_library ( TCMALLOC_LIB NAMES tcmalloc tcmalloc_minimal ) diff --git a/Code/Mantid/Build/CMake/GNUSetup.cmake b/Code/Mantid/Build/CMake/GNUSetup.cmake index f9e14c004d0e..8209f3750482 100644 --- a/Code/Mantid/Build/CMake/GNUSetup.cmake +++ b/Code/Mantid/Build/CMake/GNUSetup.cmake @@ -6,16 +6,12 @@ # project settings should be included in the relevant CMakeLists.txt file # for that project. -# Get the GCC version -EXEC_PROGRAM(${CMAKE_CXX_COMPILER} ARGS --version | cut -d \" \" -f 3 OUTPUT_VARIABLE _compiler_output) -STRING(REGEX REPLACE ".*([0-9]\\.[0-9]\\.[0-9]).*" "\\1" GCC_COMPILER_VERSION ${_compiler_output}) -MESSAGE(STATUS "gcc version: ${GCC_COMPILER_VERSION}") - -# Export the GCC compiler version globally -set(GCC_COMPILER_VERSION ${GCC_COMPILER_VERSION} CACHE INTERNAL "") +# Set our own compiler version flag from the cmake one and export it globally +set( GCC_COMPILER_VERSION ${CMAKE_CXX_COMPILER_VERSION} CACHE INTERNAL "") +message( STATUS "gcc version: ${GCC_COMPILER_VERSION}" ) # Global warning flags. -set( GNUFLAGS "-Wall -Wextra -Wconversion -Winit-self -Wpointer-arith -Wcast-qual -Wcast-align -fno-common" ) +set( GNUFLAGS "-Wall -Wextra -Wconversion -Winit-self -Wpointer-arith -Wcast-qual -Wcast-align -fno-common" ) # Disable some warnings about deprecated headers and type conversions that # we can't do anything about # -Wno-deprecated: Do not warn about use of deprecated headers. @@ -38,4 +34,3 @@ set( CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${GNUFLAGS}" ) set( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${GNUFLAGS} -Woverloaded-virtual -fno-operator-names -std=c++0x" ) # Cleanup set ( GNUFLAGS ) - diff --git a/Code/Mantid/Build/CMake/LinuxSetup.cmake b/Code/Mantid/Build/CMake/LinuxSetup.cmake index 64a9f69d2742..e3c7d66865e4 100644 --- a/Code/Mantid/Build/CMake/LinuxSetup.cmake +++ b/Code/Mantid/Build/CMake/LinuxSetup.cmake @@ -97,9 +97,15 @@ if ( "${UNIX_DIST}" MATCHES "RedHatEnterprise" ) " ln -s $RPM_INSTALL_PREFIX0/${BIN_DIR}/launch_mantidplot.sh $RPM_INSTALL_PREFIX0/${BIN_DIR}/MantidPlot\n" "fi\n" ) - file ( WRITE ${CMAKE_CURRENT_BINARY_DIR}/launch_mantidplot.sh "#!/bin/sh\n" - "scl enable mantidlibs \"${CMAKE_INSTALL_PREFIX}/${BIN_DIR}/MantidPlot_exe $*\" \n" + if ( "${UNIX_CODENAME}" MATCHES "Santiago" ) # el6 + file ( WRITE ${CMAKE_CURRENT_BINARY_DIR}/launch_mantidplot.sh "#!/bin/sh\n" + "scl enable mantidlibs \"${CMAKE_INSTALL_PREFIX}/${BIN_DIR}/MantidPlot_exe $*\" \n" ) + else () + file ( WRITE ${CMAKE_CURRENT_BINARY_DIR}/launch_mantidplot.sh "#!/bin/sh\n" + "LD_LIBRARY_PATH=/usr/lib64/paraview:${LD_LIBRARY_PATH} ${CMAKE_INSTALL_PREFIX}/${BIN_DIR}/MantidPlot_exe $* \n" + ) + endif() install ( FILES ${CMAKE_CURRENT_BINARY_DIR}/launch_mantidplot.sh DESTINATION ${BIN_DIR} diff --git a/Code/Mantid/Build/CMake/UseSystemQt4.cmake b/Code/Mantid/Build/CMake/UseSystemQt4.cmake index db8dd519ee7d..f2744cafee87 100644 --- a/Code/Mantid/Build/CMake/UseSystemQt4.cmake +++ b/Code/Mantid/Build/CMake/UseSystemQt4.cmake @@ -23,8 +23,13 @@ # License text for the above reference.) ADD_DEFINITIONS(${QT_DEFINITIONS}) -SET_PROPERTY(DIRECTORY APPEND PROPERTY COMPILE_DEFINITIONS_DEBUG QT_DEBUG) -SET_PROPERTY(DIRECTORY APPEND PROPERTY COMPILE_DEFINITIONS_RELEASE QT_NO_DEBUG) +IF("${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION}.${CMAKE_PATCH_VERSION}" VERSION_GREATER 2.8.9) + SET_PROPERTY(DIRECTORY APPEND PROPERTY COMPILE_DEFINITIONS $<$:QT_DEBUG>) + SET_PROPERTY(DIRECTORY APPEND PROPERTY COMPILE_DEFINITIONS $<$>:QT_NO_DEBUG>) +ELSE() + SET_PROPERTY(DIRECTORY APPEND PROPERTY COMPILE_DEFINITIONS_DEBUG QT_DEBUG) + SET_PROPERTY(DIRECTORY APPEND PROPERTY COMPILE_DEFINITIONS_RELEASE QT_NO_DEBUG) +ENDIF() SET_PROPERTY(DIRECTORY APPEND PROPERTY COMPILE_DEFINITIONS_RELWITHDEBINFO QT_NO_DEBUG) SET_PROPERTY(DIRECTORY APPEND PROPERTY COMPILE_DEFINITIONS_MINSIZEREL QT_NO_DEBUG) diff --git a/Code/Mantid/Build/Jenkins/buildscript b/Code/Mantid/Build/Jenkins/buildscript index a2e28bc5e568..9e5d6139d1a4 100755 --- a/Code/Mantid/Build/Jenkins/buildscript +++ b/Code/Mantid/Build/Jenkins/buildscript @@ -13,6 +13,7 @@ # Print out the versions of things we are using ############################################################################### cmake --version +echo "SHA1=${sha1}" ############################################################################### # OS X setup steps diff --git a/Code/Mantid/Build/Jenkins/buildscript.bat b/Code/Mantid/Build/Jenkins/buildscript.bat index e63a5a20289f..3103588dea1c 100755 --- a/Code/Mantid/Build/Jenkins/buildscript.bat +++ b/Code/Mantid/Build/Jenkins/buildscript.bat @@ -8,6 +8,7 @@ ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: "C:\Program Files (x86)\CMake 2.8\bin\cmake.exe" --version +echo %sha1% ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: :: Check the required build configuration diff --git a/Code/Mantid/Build/class_maker.py b/Code/Mantid/Build/class_maker.py index a129c029385f..4e30ae21084f 100755 --- a/Code/Mantid/Build/class_maker.py +++ b/Code/Mantid/Build/class_maker.py @@ -129,6 +129,8 @@ def write_source(subproject, classname, filename, args): algorithm_source = """ //---------------------------------------------------------------------------------------------- + /// Algorithms name for identification. @see Algorithm::name + const std::string %s::name() const { return "%s"; } /// Algorithm's version for identification. @see Algorithm::version int %s::version() const { return 1;}; @@ -156,7 +158,7 @@ def write_source(subproject, classname, filename, args): // TODO Auto-generated execute stub } -""" % (classname, classname, classname, classname, classname) +""" % (classname, classname, classname, classname, classname, classname, classname) if not args.alg: algorithm_top = "" diff --git a/Code/Mantid/Build/dev-packages/rpm/mantid-developer/mantid-developer-el6.spec b/Code/Mantid/Build/dev-packages/rpm/mantid-developer/mantid-developer-el6.spec deleted file mode 100644 index ad41e6ea1667..000000000000 --- a/Code/Mantid/Build/dev-packages/rpm/mantid-developer/mantid-developer-el6.spec +++ /dev/null @@ -1,100 +0,0 @@ -Name: mantid-developer -Version: 1.1 -Release: 5%{?dist} -Summary: Meta Package to install dependencies for Mantid Development - -Group: Development/Tools -License: GPL - -BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n) - - -Requires: cmake-gui >= 2.8.5 -Requires: boost-devel -Requires: epel-release -Requires: gperftools-devel -Requires: gperftools-libs -Requires: gcc-c++ -Requires: gsl-devel -Requires: hdf-devel -Requires: hdf5-devel -Requires: python-ipython >= 1.1 -Requires: muParser-devel -Requires: mxml-devel -Requires: nexus >= 4.2 -Requires: nexus-devel >= 4.2 -Requires: numpy -Requires: OpenCASCADE-devel -Requires: poco-devel -Requires: PyQt4-devel -Requires: python-devel -Requires: qscintilla-devel -Requires: qt-devel >= 4.6 -Requires: qwt-devel -Requires: qwtplot3d-qt4-devel -Requires: redhat-lsb -Requires: rpmdevtools -Requires: scipy -Requires: sip-devel -Requires: git -Requires: openssl-devel -Requires: texlive-latex -Requires: dvipng -Requires: mantidlibs-qt-devel -Requires: scl-utils - -BuildArch: noarch - -%description -A virtual package which requires all the dependencies and tools that are -required for Mantid development. - -%prep - -%build - -%install - -%clean - -%post -# Remove myself once I have installed all the required packages. -#rpm -e %{name} - -%files - -%changelog -* Tue Feb 04 2014 Stuart Campbell -- Added scipy and ipython >= 1.1 dependency - -* Tue May 07 2013 Stuart Campbell -- Added dvipng and latex for qt-assistant stuff -- Added software collection dependencies - -* Thu Jun 7 2012 Russell Taylor -- Remove gmock & gtest now that we include them in our repo -- Remove subversion dependency now that we use git - -* Mon Mar 19 2012 Stuart Campbell -- Updated for google-perftools -> gperftools package rename. - -* Wed Feb 22 2012 Stuart Campbell -- Added nexus as it is not required by it's devel package. - -* Wed Feb 22 2012 Stuart Campbell -- Added git as a dependency -- Added openssl-devel dependency - -* Mon Feb 20 2012 Stuart Campbell -- Added dependency on NeXus development after nexus rpm split. -- Updated CMake dependency to 2.8.5 following 'the virus'! -- Added Google Mock and GTest. - -* Fri Jun 3 2011 Stuart Campbell -- Added rpmdevtools and lsb dependencies - -* Fri Jun 3 2011 Stuart Campbell -- Added versions for some packages - -* Fri Jun 3 2011 Stuart Campbell -- Initial release diff --git a/Code/Mantid/Build/dev-packages/rpm/mantid-developer/mantid-developer-f19.spec b/Code/Mantid/Build/dev-packages/rpm/mantid-developer/mantid-developer-f19.spec deleted file mode 100644 index 4c56f3acab44..000000000000 --- a/Code/Mantid/Build/dev-packages/rpm/mantid-developer/mantid-developer-f19.spec +++ /dev/null @@ -1,102 +0,0 @@ -Name: mantid-developer -Version: 1.2 -Release: 5%{?dist} -Summary: Meta Package to install dependencies for Mantid Development - -Group: Development/Tools -License: GPL - -BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n) - - -Requires: cmake-gui >= 2.8.5 -Requires: boost-devel -Requires: gperftools-devel -Requires: gperftools-libs -Requires: gcc-c++ -Requires: git-all -Requires: gsl-devel -Requires: hdf-devel -Requires: hdf5-devel -Requires: muParser-devel -Requires: mxml-devel -Requires: nexus >= 4.2 -Requires: nexus-devel >= 4.2 -Requires: numpy -Requires: OpenCASCADE-devel -Requires: poco-devel -Requires: PyQt4-devel -Requires: python-devel -Requires: python-ipython -Requires: qscintilla-devel -Requires: qt-devel >= 4.6 -Requires: qwt5-qt4-devel -Requires: qwtplot3d-qt4-devel -Requires: redhat-lsb -Requires: rpmdevtools -Requires: scipy -Requires: sip-devel -Requires: git -Requires: openssl-devel -Requires: texlive-latex -Requires: dvipng -Requires: qt-devel - -BuildArch: noarch - -%description -A virtual package which requires all the dependencies and tools that are -required for Mantid development. - -%prep - -%build - -%install - -%clean - -%post -# Remove myself once I have installed all the required packages. -#rpm -e %{name} - -%files - -%changelog -* Tue Feb 04 2014 Stuart Campbell -- Added scipy and ipython >= 1.1 dependency - -* Tue Aug 20 2013 Peter Peterson -- Removed things not necessary for fedora 19. - -* Tue May 07 2013 Stuart Campbell -- Added dvipng and latex for qt-assistant stuff -- Added software collection dependencies - -* Thu Jun 7 2012 Russell Taylor -- Remove gmock & gtest now that we include them in our repo -- Remove subversion dependency now that we use git - -* Mon Mar 19 2012 Stuart Campbell -- Updated for google-perftools -> gperftools package rename. - -* Wed Feb 22 2012 Stuart Campbell -- Added nexus as it is not required by it's devel package. - -* Wed Feb 22 2012 Stuart Campbell -- Added git as a dependency -- Added openssl-devel dependency - -* Mon Feb 20 2012 Stuart Campbell -- Added dependency on NeXus development after nexus rpm split. -- Updated CMake dependency to 2.8.5 following 'the virus'! -- Added Google Mock and GTest. - -* Fri Jun 3 2011 Stuart Campbell -- Added rpmdevtools and lsb dependencies - -* Fri Jun 3 2011 Stuart Campbell -- Added versions for some packages - -* Fri Jun 3 2011 Stuart Campbell -- Initial release diff --git a/Code/Mantid/Build/dev-packages/rpm/mantid-developer/mantid-developer-f20.spec b/Code/Mantid/Build/dev-packages/rpm/mantid-developer/mantid-developer.spec similarity index 87% rename from Code/Mantid/Build/dev-packages/rpm/mantid-developer/mantid-developer-f20.spec rename to Code/Mantid/Build/dev-packages/rpm/mantid-developer/mantid-developer.spec index 5dfcc58f859b..d5970a46aa71 100644 --- a/Code/Mantid/Build/dev-packages/rpm/mantid-developer/mantid-developer-f20.spec +++ b/Code/Mantid/Build/dev-packages/rpm/mantid-developer/mantid-developer.spec @@ -1,6 +1,6 @@ Name: mantid-developer -Version: 1.3 -Release: 8%{?dist} +Version: 1.4 +Release: 1%{?dist} Summary: Meta Package to install dependencies for Mantid Development Group: Development/Tools @@ -8,9 +8,10 @@ License: GPL BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n) -Requires: rpmfusion-nonfree-release +%{?fc20:Requires: rpmfusion-nonfree-release} Requires: cmake-gui >= 2.8.5 Requires: boost-devel +%{?el6:Requires: epel-release} Requires: gperftools-devel Requires: gperftools-libs Requires: gcc-c++ @@ -27,11 +28,16 @@ Requires: OCE-devel Requires: poco-devel Requires: PyQt4-devel Requires: python-devel -Requires: python-ipython +Requires: python-ipython >= 1.1 +Conflicts: python-ipython >= 2.0 Requires: python-sphinx Requires: qscintilla-devel Requires: qt-devel >= 4.6 +%if 0%{?el6} +Requires: qwt-devel +%else Requires: qwt5-qt4-devel +%endif Requires: qwtplot3d-qt4-devel Requires: redhat-lsb Requires: rpmdevtools @@ -44,8 +50,14 @@ Requires: texlive-latex-bin Requires: texlive-was Requires: tex-preview Requires: dvipng +%if 0%{?el6} +Requires: mantidlibs-qt-devel +Requires: mantidlibs-qtwebkit-devel +Requires: scl-utils +%else Requires: qt-devel Requires: qtwebkit-devel +%endif BuildArch: noarch @@ -68,6 +80,9 @@ required for Mantid development. %files %changelog +* Wed Aug 13 2014 Peter Peterson +- Merged all three distribution spec files into one + * Fri Apr 25 2014 Michael Reuter - Added texlive-latex-bin, texlive-was, tex-preview diff --git a/Code/Mantid/CMakeLists.txt b/Code/Mantid/CMakeLists.txt index 0f107a2f3478..2a19d9eb65ee 100644 --- a/Code/Mantid/CMakeLists.txt +++ b/Code/Mantid/CMakeLists.txt @@ -121,6 +121,7 @@ set ( CORE_MANTIDLIBS Kernel Geometry API ) # Add a target for all GUI tests add_custom_target ( GUITests ) +add_dependencies ( GUITests MantidWidgetsTest) add_dependencies ( check GUITests ) # Collect all tests together add_custom_target ( AllTests ) @@ -184,13 +185,20 @@ if ( ENABLE_CPACK ) message ( STATUS " CPACK_PACKAGE_FILE_NAME = ${CPACK_PACKAGE_FILE_NAME}" ) # rhel requirements - set ( CPACK_RPM_PACKAGE_REQUIRES "boost >= 1.34.1,qt4 >= 4.2,nexus,nexus-python,qwt,gsl,glibc,qwtplot3d-qt4,muParser,numpy" ) - # OpenCASCADE changed names when packaged for Fedora 20 - if( "${UNIX_CODENAME}" MATCHES "Heisenbug" ) + set ( CPACK_RPM_PACKAGE_REQUIRES "boost >= 1.34.1,qt4 >= 4.2,nexus,nexus-python,gsl,glibc,qwtplot3d-qt4,muParser,numpy" ) + # OpenCASCADE changed names when packaged for Fedora 20 and RHEL7 + if( "${UNIX_CODENAME}" MATCHES "Heisenbug" OR "${UNIX_CODENAME}" MATCHES "Maipo" ) set( CPACK_RPM_PACKAGE_REQUIRES "${CPACK_RPM_PACKAGE_REQUIRES},OCE-devel" ) else() set( CPACK_RPM_PACKAGE_REQUIRES "${CPACK_RPM_PACKAGE_REQUIRES},OpenCASCADE-libs-modelling >= 6.3.0,OpenCASCADE-libs-foundation >= 6.3.0,OpenCASCADE-libs-visualization >= 6.3.0,OpenCASCADE-libs-ocaf >= 6.3.0,OpenCASCADE-libs-ocaf-lite >= 6.3.0" ) endif() + # Qwt is qwt5-qt4 in RHEL7 + if( "${UNIX_CODENAME}" MATCHES "Maipo" ) + set( CPACK_RPM_PACKAGE_REQUIRES "${CPACK_RPM_PACKAGE_REQUIRES},qwt5-qt4" ) + else() + set( CPACK_RPM_PACKAGE_REQUIRES "${CPACK_RPM_PACKAGE_REQUIRES},qwt" ) + endif() + set ( CPACK_RPM_PACKAGE_REQUIRES "${CPACK_RPM_PACKAGE_REQUIRES},poco-crypto,poco-data,poco-mysql,poco-sqlite,poco-odbc,poco-util,poco-xml,poco-zip,poco-net,poco-netssl,poco-foundation,PyQt4,sip" ) set ( CPACK_RPM_PACKAGE_REQUIRES "${CPACK_RPM_PACKAGE_REQUIRES},python-ipython >= 1.1.0" ) # scipy & matplotlib diff --git a/Code/Mantid/Framework/API/CMakeLists.txt b/Code/Mantid/Framework/API/CMakeLists.txt index 4957f3a3eb42..63b186613846 100644 --- a/Code/Mantid/Framework/API/CMakeLists.txt +++ b/Code/Mantid/Framework/API/CMakeLists.txt @@ -105,6 +105,7 @@ set ( SRC_FILES src/Run.cpp src/Sample.cpp src/SampleEnvironment.cpp + src/SampleShapeValidator.cpp src/ScopedWorkspace.cpp src/ScriptBuilder.cpp src/ScriptRepository.cpp @@ -264,6 +265,7 @@ set ( INC_FILES inc/MantidAPI/Run.h inc/MantidAPI/Sample.h inc/MantidAPI/SampleEnvironment.h + inc/MantidAPI/SampleShapeValidator.h inc/MantidAPI/ScopedWorkspace.h inc/MantidAPI/ScriptBuilder.h inc/MantidAPI/ScriptRepository.h @@ -355,6 +357,7 @@ set ( TEST_FILES PropertyNexusTest.h RunTest.h SampleEnvironmentTest.h + SampleShapeValidatorTest.h SampleTest.h ScopedWorkspaceTest.h ScriptBuilderTest.h diff --git a/Code/Mantid/Framework/API/inc/MantidAPI/Algorithm.h b/Code/Mantid/Framework/API/inc/MantidAPI/Algorithm.h index 12e6ea4b6352..5166e98be7ec 100644 --- a/Code/Mantid/Framework/API/inc/MantidAPI/Algorithm.h +++ b/Code/Mantid/Framework/API/inc/MantidAPI/Algorithm.h @@ -338,6 +338,11 @@ class MANTID_API_DLL Algorithm : public IAlgorithm, public Kernel::PropertyManag /// Pointer to the parent history object (if set) boost::shared_ptr m_parentHistory; + /// One vector of workspaces for each input workspace property + std::vector m_groups; + /// Size of the group(s) being processed + size_t m_groupSize; + private: /// Private Copy constructor: NO COPY ALLOWED Algorithm(const Algorithm&); @@ -354,6 +359,9 @@ class MANTID_API_DLL Algorithm : public IAlgorithm, public Kernel::PropertyManag bool executeAsyncImpl(const Poco::Void & i); + // Report that the algorithm has completed. + void reportCompleted(const double& duration, const bool groupProcessing = false); + // --------------------- Private Members ----------------------------------- /// Poco::ActiveMethod used to implement asynchronous execution. Poco::ActiveMethod> *m_executeAsync; @@ -387,14 +395,10 @@ class MANTID_API_DLL Algorithm : public IAlgorithm, public Kernel::PropertyManag /// All the WorkspaceProperties that are Output (not inOut). Set in execute() std::vector m_pureOutputWorkspaceProps; - /// One vector of workspaces for each input workspace property - std::vector m_groups; /// Pointer to the WorkspaceGroup (if any) for each input workspace property std::vector > m_groupWorkspaces; /// If only one input is a group, this is its index. -1 if they are all groups int m_singleGroup; - /// Size of the group(s) being processed - size_t m_groupSize; /// All the groups have similar names (group_1, group_2 etc.) bool m_groupsHaveSimilarNames; /// A non-recursive mutex for thread-safety diff --git a/Code/Mantid/Framework/API/inc/MantidAPI/Column.h b/Code/Mantid/Framework/API/inc/MantidAPI/Column.h index 33ea5f2cf67a..e7b8fd3abe5b 100644 --- a/Code/Mantid/Framework/API/inc/MantidAPI/Column.h +++ b/Code/Mantid/Framework/API/inc/MantidAPI/Column.h @@ -9,9 +9,10 @@ #ifndef Q_MOC_RUN # include #endif +#include #include -#include #include +#include #include namespace Mantid @@ -114,7 +115,7 @@ class MANTID_API_DLL Column { return *static_cast(void_pointer(index)); } - + /// Templated method for returning a value (const version). No type checks are done. template @@ -127,17 +128,17 @@ class MANTID_API_DLL Column template bool isType()const { - return get_type_info() == typeid(T); + return !std::strcmp(get_type_info().name(), typeid(T).name()); } - /// get plot type - /// @return See description of setPlotType() for the interpretation of the returned int + /// get plot type + /// @return See description of setPlotType() for the interpretation of the returned int int getPlotType() const { return m_plotType; } - /// Set plot type where + /// Set plot type where void setPlotType(int t); /** @@ -169,7 +170,7 @@ class MANTID_API_DLL Column std::string m_name;///< name std::string m_type;///< type - /// plot type where + /// plot type where /// None = 0 (means it has specifically been set to 'no plot type') /// NotSet = -1000 (this is the default and means plot style has not been set) /// X = 1, Y = 2, Z = 3, xErr = 4, yErr = 5, Label = 6 @@ -184,7 +185,7 @@ class MANTID_API_DLL Column }; /** @class Boolean - As TableColumn stores its data in a std::vector bool type cannot be used + As TableColumn stores its data in a std::vector bool type cannot be used in the same way as the other types. Class Boolean is used instead. */ struct MANTID_API_DLL Boolean @@ -197,7 +198,7 @@ struct MANTID_API_DLL Boolean operator bool(){return value;} /// equal to operator bool operator==(const Boolean& b)const - {return(this->value==b.value); + {return(this->value==b.value); } // operator double(void)const{return double(this->value);} diff --git a/Code/Mantid/Framework/API/inc/MantidAPI/ExperimentInfo.h b/Code/Mantid/Framework/API/inc/MantidAPI/ExperimentInfo.h index ddf8051b4304..e4d2316c4fde 100644 --- a/Code/Mantid/Framework/API/inc/MantidAPI/ExperimentInfo.h +++ b/Code/Mantid/Framework/API/inc/MantidAPI/ExperimentInfo.h @@ -155,7 +155,7 @@ namespace API private: /// Fill with given instrument parameter void populateWithParameter(Geometry::ParameterMap & paramMap, - const std::string & name, const Geometry::XMLlogfile & paramInfo, + const std::string & name, const Geometry::XMLInstrumentParameter & paramInfo, const Run & runData); /// Detector grouping information diff --git a/Code/Mantid/Framework/API/inc/MantidAPI/HistoryView.h b/Code/Mantid/Framework/API/inc/MantidAPI/HistoryView.h index 7eaf0947a50e..2873c1856c4c 100644 --- a/Code/Mantid/Framework/API/inc/MantidAPI/HistoryView.h +++ b/Code/Mantid/Framework/API/inc/MantidAPI/HistoryView.h @@ -7,6 +7,7 @@ #include "MantidAPI/DllConfig.h" #include "MantidAPI/HistoryItem.h" #include "MantidAPI/WorkspaceHistory.h" +#include "MantidKernel/DateAndTime.h" #include #include @@ -55,13 +56,14 @@ class MANTID_API_DLL HistoryView void unrollAll(); void roll(size_t index); void rollAll(); + void filterBetweenExecDate(Mantid::Kernel::DateAndTime start, Mantid::Kernel::DateAndTime end = Mantid::Kernel::DateAndTime::getCurrentTime()); const std::vector getAlgorithmsList() const; size_t size() const { return m_historyItems.size(); } private: void unroll(std::list::iterator it); void roll(std::list::iterator it); - + const WorkspaceHistory m_wsHist; std::list m_historyItems; }; diff --git a/Code/Mantid/Framework/API/inc/MantidAPI/IFileLoader.h b/Code/Mantid/Framework/API/inc/MantidAPI/IFileLoader.h index f7a2ae647015..538d6748c970 100644 --- a/Code/Mantid/Framework/API/inc/MantidAPI/IFileLoader.h +++ b/Code/Mantid/Framework/API/inc/MantidAPI/IFileLoader.h @@ -42,6 +42,8 @@ namespace Mantid virtual ~IFileLoader() {} /// Returns a confidence value that this algorithm can load a file virtual int confidence(DescriptorType & descriptor) const = 0; + /// Returns a value indicating whether or not loader wants to load multiple files into a single workspace + virtual bool loadMutipleAsOne() { return false; } }; } // namespace API diff --git a/Code/Mantid/Framework/API/inc/MantidAPI/ILiveListener.h b/Code/Mantid/Framework/API/inc/MantidAPI/ILiveListener.h index 5497a5cf8c3d..6bf6546d106d 100644 --- a/Code/Mantid/Framework/API/inc/MantidAPI/ILiveListener.h +++ b/Code/Mantid/Framework/API/inc/MantidAPI/ILiveListener.h @@ -7,6 +7,7 @@ #include #include #include "MantidKernel/DateAndTime.h" +#include "MantidKernel/PropertyManager.h" #include "MantidGeometry/IDTypes.h" #include "MantidAPI/DllConfig.h" @@ -39,7 +40,7 @@ namespace Mantid You should have received a copy of the GNU General Public License along with this program. If not, see . */ - class MANTID_API_DLL ILiveListener + class MANTID_API_DLL ILiveListener: public Kernel::PropertyManager { public: //---------------------------------------------------------------------- diff --git a/Code/Mantid/Framework/API/inc/MantidAPI/IMDNode.h b/Code/Mantid/Framework/API/inc/MantidAPI/IMDNode.h index 5cea41bcf918..9205f66d1869 100644 --- a/Code/Mantid/Framework/API/inc/MantidAPI/IMDNode.h +++ b/Code/Mantid/Framework/API/inc/MantidAPI/IMDNode.h @@ -71,6 +71,7 @@ class IMDNode *@param loadFileData -- if true, the data on HDD and not yet in memory are loaded into memory before deleting fileBacked information, if false, all on HDD contents are discarded, which can break the data integrity (used by destructor) */ virtual void clearFileBacked(bool loadFileData)=0; + virtual void reserveMemoryForLoad(uint64_t)=0; /**Save the box at specific disk position using the class, respoinsible for the file IO. */ virtual void saveAt(API::IBoxControllerIO *const /*saver */, uint64_t /*position*/)const=0; diff --git a/Code/Mantid/Framework/API/inc/MantidAPI/LiveListenerFactory.h b/Code/Mantid/Framework/API/inc/MantidAPI/LiveListenerFactory.h index a5c453a3f575..75b05dcad19c 100644 --- a/Code/Mantid/Framework/API/inc/MantidAPI/LiveListenerFactory.h +++ b/Code/Mantid/Framework/API/inc/MantidAPI/LiveListenerFactory.h @@ -50,7 +50,7 @@ namespace Mantid class MANTID_API_DLL LiveListenerFactoryImpl : public Kernel::DynamicFactory { public: - boost::shared_ptr create(const std::string& instrumentName, bool connect) const; + boost::shared_ptr create(const std::string& instrumentName, bool connect, const Kernel::IPropertyManager* props = NULL) const; bool checkConnection(const std::string& instrumentName) const; private: diff --git a/Code/Mantid/Framework/API/inc/MantidAPI/MatrixWorkspace.h b/Code/Mantid/Framework/API/inc/MantidAPI/MatrixWorkspace.h index fa7473cd1df5..7ec8edb85097 100644 --- a/Code/Mantid/Framework/API/inc/MantidAPI/MatrixWorkspace.h +++ b/Code/Mantid/Framework/API/inc/MantidAPI/MatrixWorkspace.h @@ -16,6 +16,7 @@ #include "MantidAPI/Run.h" #include "MantidAPI/Sample.h" #include "MantidAPI/SpectraDetectorTypes.h" +#include "MantidKernel/EmptyValues.h" namespace Mantid @@ -33,6 +34,13 @@ namespace Mantid { class SpectrumDetectorMapping; + /// typedef for the image type + typedef std::vector> MantidImage; + /// shared pointer to MantidImage + typedef boost::shared_ptr MantidImage_sptr; + /// shared pointer to const MantidImage + typedef boost::shared_ptr MantidImage_const_sptr; + //---------------------------------------------------------------------- /** Base MatrixWorkspace Abstract Class. @@ -167,7 +175,7 @@ namespace Mantid const MantidVec& readDx(size_t const index) const { return getSpectrum(index)->dataDx(); } /// Returns the x data - virtual MantidVec& dataX(const std::size_t index) { return getSpectrum(index)->dataX(); } + virtual MantidVec& dataX(const std::size_t index) { invalidateCommonBinsFlag(); return getSpectrum(index)->dataX(); } /// Returns the y data virtual MantidVec& dataY(const std::size_t index) { return getSpectrum(index)->dataY(); } /// Returns the error data @@ -192,13 +200,13 @@ namespace Mantid virtual Kernel::cow_ptr refX(const std::size_t index) const { return getSpectrum(index)->ptrX(); } /// Set the specified X array to point to the given existing array - virtual void setX(const std::size_t index, const MantidVec& X) { getSpectrum(index)->setX(X); } + virtual void setX(const std::size_t index, const MantidVec& X) { getSpectrum(index)->setX(X); invalidateCommonBinsFlag(); } /// Set the specified X array to point to the given existing array - virtual void setX(const std::size_t index, const MantidVecPtr& X) { getSpectrum(index)->setX(X); } + virtual void setX(const std::size_t index, const MantidVecPtr& X) { getSpectrum(index)->setX(X); invalidateCommonBinsFlag(); } /// Set the specified X array to point to the given existing array - virtual void setX(const std::size_t index, const MantidVecPtr::ptr_type& X) { getSpectrum(index)->setX(X); } + virtual void setX(const std::size_t index, const MantidVecPtr::ptr_type& X) { getSpectrum(index)->setX(X); invalidateCommonBinsFlag(); } /** Sets the data in the workspace @param index :: the workspace index to set. @@ -227,15 +235,21 @@ namespace Mantid /// Return a vector with the integrated counts for all spectra withing the given range virtual void getIntegratedSpectra(std::vector & out, const double minX, const double maxX, const bool entireRange) const; + /// Return an index in the X vector for an x-value close to a given value + std::pair getXIndex(size_t i, double x, bool isLeft = true, size_t start = 0) const; + //---------------------------------------------------------------------- int axes() const; Axis* getAxis(const std::size_t& axisIndex) const; void replaceAxis(const std::size_t& axisIndex, Axis* const newAxis); - + /// Returns true if the workspace contains data in histogram form (as opposed to point-like) virtual bool isHistogramData() const; + /// Returns true if the workspace contains has common X bins + virtual bool isCommonBins() const; + std::string YUnit() const; void setYUnit(const std::string& newUnit); std::string YUnitLabel() const; @@ -308,12 +322,34 @@ namespace Mantid // End IMDWorkspace methods //===================================================================================== + //===================================================================================== + // Image methods + //===================================================================================== + + /// Get start and end x indices for images + std::pair getImageStartEndXIndices( size_t i, double startX, double endX ) const; + /// Create an image of Ys. + MantidImage_sptr getImageY (size_t start = 0, size_t stop = 0, size_t width = 0, double startX = EMPTY_DBL(), double endX = EMPTY_DBL() ) const; + /// Create an image of Es. + MantidImage_sptr getImageE (size_t start = 0, size_t stop = 0, size_t width = 0, double startX = EMPTY_DBL(), double endX = EMPTY_DBL() ) const; + /// Copy the data (Y's) from an image to this workspace. + void setImageY( const MantidImage &image, size_t start = 0 ); + /// Copy the data from an image to this workspace's errors. + void setImageE( const MantidImage &image, size_t start = 0 ); + + //===================================================================================== + // End image methods + //===================================================================================== + protected: MatrixWorkspace(Mantid::Geometry::INearestNeighboursFactory* factory = NULL); /// Initialises the workspace. Sets the size and lengths of the arrays. Must be overloaded. virtual void init(const std::size_t &NVectors, const std::size_t &XLength, const std::size_t &YLength) = 0; + /// Invalidates the commons bins flag. This is generally called when a method could allow the X values to be changed. + void invalidateCommonBinsFlag() { m_isCommonBinsFlagSet = false; } + /// A vector of pointers to the axes for this workspace std::vector m_axes; @@ -322,6 +358,10 @@ namespace Mantid MatrixWorkspace(const MatrixWorkspace&); /// Private copy assignment operator. NO ASSIGNMENT ALLOWED MatrixWorkspace& operator=(const MatrixWorkspace&); + /// Create an MantidImage instance. + MantidImage_sptr getImage(const MantidVec& (MatrixWorkspace::*read)(std::size_t const) const, size_t start, size_t stop, size_t width, size_t indexStart, size_t indexEnd) const; + /// Copy data from an image. + void setImage( MantidVec& (MatrixWorkspace::*dataVec)(const std::size_t), const MantidImage &image, size_t start ); /// Has this workspace been initialised? bool m_isInitialized; @@ -332,6 +372,12 @@ namespace Mantid std::string m_YUnitLabel; /// Flag indicating whether the Y-values are dimensioned. False by default bool m_isDistribution; + + /// Flag indicating whether the m_isCommonBinsFlag has been set. False by default + mutable bool m_isCommonBinsFlagSet; + /// Flag indicating whether the data has common bins. False by default + mutable bool m_isCommonBinsFlag; + /// The set of masked bins in a map keyed on spectrum index std::map< int64_t, MaskList > m_masks; diff --git a/Code/Mantid/Framework/API/inc/MantidAPI/ParamFunction.h b/Code/Mantid/Framework/API/inc/MantidAPI/ParamFunction.h index 8af5aec6a9ca..60abcbfa5ce5 100644 --- a/Code/Mantid/Framework/API/inc/MantidAPI/ParamFunction.h +++ b/Code/Mantid/Framework/API/inc/MantidAPI/ParamFunction.h @@ -10,12 +10,6 @@ #include #include -#ifndef HAS_UNORDERED_MAP_H -#include -#else -#include -#endif - namespace Mantid { namespace API diff --git a/Code/Mantid/Framework/API/inc/MantidAPI/Sample.h b/Code/Mantid/Framework/API/inc/MantidAPI/Sample.h index 2c70be07ab90..e518afa05c0a 100644 --- a/Code/Mantid/Framework/API/inc/MantidAPI/Sample.h +++ b/Code/Mantid/Framework/API/inc/MantidAPI/Sample.h @@ -5,9 +5,8 @@ // Includes //------------------------------------------------------------------------------ #include "MantidAPI/DllConfig.h" -#include "MantidKernel/V3D.h" -#include "MantidKernel/Material.h" #include "MantidGeometry/Objects/Object.h" +#include "MantidKernel/V3D.h" #include @@ -28,28 +27,28 @@ namespace Mantid //------------------------------------------------------------------------------ class SampleEnvironment; - /** - This class stores information about the sample used in particular + /** + This class stores information about the sample used in particular run. It is a type of ObjComponent meaning it has a shape, a position and a material. Copyright © 2007-2012 ISIS Rutherford Appleton Laboratory & NScD Oak Ridge National Laboratory - + This file is part of Mantid. - + Mantid is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. - + Mantid is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. - + You should have received a copy of the GNU General Public License along with this program. If not, see . - + File change history is stored at: . Code Documentation is available at: */ @@ -82,10 +81,8 @@ namespace Mantid /** @name Material properties.*/ //@{ - /// Return the material + /// Return the material (convenience method) const Kernel::Material & getMaterial() const; - /// Set the type of material that this sample is composed from - void setMaterial(const Kernel::Material& material); //@} /** @name Access the environment information */ @@ -102,7 +99,7 @@ namespace Mantid const Geometry::OrientedLattice & getOrientedLattice() const; /// Get a reference to the sample's OrientedLattice Geometry::OrientedLattice & getOrientedLattice(); - /** Set the pointer to OrientedLattice defining the sample's lattice and orientation. + /** Set the pointer to OrientedLattice defining the sample's lattice and orientation. No copying is done in the class, but the class deletes pointer on destruction so the application, providing the pointer should not do it*/ void setOrientedLattice(Geometry::OrientedLattice * latt); bool hasOrientedLattice() const; @@ -129,18 +126,16 @@ namespace Mantid /// Sets the width void setWidth(double width); /// Returns the width - double getWidth() const; + double getWidth() const; //@} /// Delete the oriented lattice void clearOrientedLattice(); - private: + private: /// The sample name std::string m_name; /// The sample shape object Geometry::Object m_shape; - /// The sample composition - Kernel::Material m_material; /// An owned pointer to the SampleEnvironment object boost::shared_ptr m_environment; /// Pointer to the OrientedLattice of the sample, NULL if not set. diff --git a/Code/Mantid/Framework/API/inc/MantidAPI/SampleEnvironment.h b/Code/Mantid/Framework/API/inc/MantidAPI/SampleEnvironment.h index 91164bd4edfa..8f3a71500201 100644 --- a/Code/Mantid/Framework/API/inc/MantidAPI/SampleEnvironment.h +++ b/Code/Mantid/Framework/API/inc/MantidAPI/SampleEnvironment.h @@ -5,67 +5,69 @@ // Includes //------------------------------------------------------------------------------ #include "MantidAPI/DllConfig.h" -#include "MantidGeometry/Instrument/CompAssembly.h" +#include "MantidGeometry/Objects/Object.h" +#include "MantidKernel/ClassMacros.h" namespace Mantid { + namespace Geometry + { + class Track; + } namespace API { - /** + /** This class stores details regarding the sample environment that was used during - a specific run. It is implemented as a type of CompAssembly so that enviroment kits - consisting of objects made from different materials can be constructed easily. - - @author Martyn Gigg, Tessella plc - @date 23/11/2010 - + a specific run. It is implemented as a collection of pairs of Object elements + Copyright © 2007-2010 ISIS Rutherford Appleton Laboratory & NScD Oak Ridge National Laboratory - + This file is part of Mantid. - + Mantid is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. - + Mantid is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. - + You should have received a copy of the GNU General Public License along with this program. If not, see . - + File change history is stored at: . Code Documentation is available at: */ - class MANTID_API_DLL SampleEnvironment : public Geometry::CompAssembly + class MANTID_API_DLL SampleEnvironment { public: /// Constructor defining the name of the environment SampleEnvironment(const std::string & name); - /// Copy constructor - SampleEnvironment(const SampleEnvironment& original); - /// Clone the assembly - virtual Geometry::IComponent* clone() const; - /// Type of object - virtual std::string type() const {return "SampleEnvironment"; } - /// Override the default add member to only add components with a defined - /// shape - int add(IComponent* comp); + /// @return The name of kit + inline const std::string name() const { return m_name; } + /// @return The number of elements the environment is composed of + inline size_t nelements() const { return m_elements.size(); } + /// Return the bounding box of all of the elements + Geometry::BoundingBox boundingBox() const; + + /// Add an element + void add(const Geometry::Object & element); + /// Is the point given a valid point within the environment bool isValid(const Kernel::V3D & point) const; /// Update the given track with intersections within the environment void interceptSurfaces(Geometry::Track & track) const; private: - /// Default constructor - SampleEnvironment(); - /// Assignment operator - SampleEnvironment& operator=(const SampleEnvironment&); - + DISABLE_DEFAULT_CONSTRUCT(SampleEnvironment) + // Name of the kit + std::string m_name; + // The elements + std::vector m_elements; }; } } diff --git a/Code/Mantid/Framework/API/inc/MantidAPI/SampleShapeValidator.h b/Code/Mantid/Framework/API/inc/MantidAPI/SampleShapeValidator.h new file mode 100644 index 000000000000..57270adc5444 --- /dev/null +++ b/Code/Mantid/Framework/API/inc/MantidAPI/SampleShapeValidator.h @@ -0,0 +1,52 @@ +#ifndef MANTID_API_SAMPLESHAPEVALIDATOR_H_ +#define MANTID_API_SAMPLESHAPEVALIDATOR_H_ + +#include "MantidAPI/DllConfig.h" +#include "MantidAPI/ExperimentInfo.h" + +#include "MantidKernel/TypedValidator.h" + +namespace Mantid +{ + namespace API + { + + /** + Verify that a workspace has valid sample shape. + + Copyright © 2014 ISIS Rutherford Appleton Laboratory + & NScD Oak Ridge National Laboratory + + This file is part of Mantid. + + Mantid is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + Mantid is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + + File change history is stored at: + Code Documentation is available at: + */ + class MANTID_API_DLL SampleShapeValidator : + public Kernel::TypedValidator > + { + public: + std::string getType() const; + Kernel::IValidator_sptr clone() const; + + private: + std::string checkValidity(const boost::shared_ptr& value) const; + }; + + } // namespace API +} // namespace Mantid + +#endif /* MANTID_API_SAMPLESHAPEVALIDATOR_H_ */ diff --git a/Code/Mantid/Framework/API/inc/MantidAPI/WorkspaceValidators.h b/Code/Mantid/Framework/API/inc/MantidAPI/WorkspaceValidators.h index d09d2b1e3f70..fbc3c24c4aec 100644 --- a/Code/Mantid/Framework/API/inc/MantidAPI/WorkspaceValidators.h +++ b/Code/Mantid/Framework/API/inc/MantidAPI/WorkspaceValidators.h @@ -222,20 +222,8 @@ class DLLExport CommonBinsValidator : public MatrixWorkspaceValidator std::string checkValidity( const MatrixWorkspace_sptr& value ) const { if ( !value ) return "Enter an existing workspace"; - //there being only one or zero histograms is accepted as not being an error - if ( !value->blocksize() || value->getNumberHistograms() < 2) return ""; - //otherwise will compare some of the data, to save time just check two the first and the last - const size_t lastSpec = value->getNumberHistograms() - 1; - // Quickest check is to see if they are actually the same vector - if ( &(value->readX(0)[0]) == &(value->readX(lastSpec)[0]) ) return ""; - // Now check numerically - const double first = std::accumulate(value->readX(0).begin(),value->readX(0).end(),0.); - const double last = std::accumulate(value->readX(lastSpec).begin(),value->readX(lastSpec).end(),0.); - if ( std::abs(first-last)/std::abs(first+last) > 1.0E-9 ) - { - return "The workspace must have common bin boundaries for all histograms"; - } - return ""; + if ( value->isCommonBins() ) return ""; + else return "The workspace must have common bin boundaries for all histograms"; } }; @@ -381,6 +369,44 @@ class DLLExport IncreasingAxisValidator : public MatrixWorkspaceValidator } }; +//=============================================================================================== +/** + * A validator which checks whether data in each spectrum of the input workspace are monotonically increasing. + */ +class DLLExport IncreasingDataValidator : public MatrixWorkspaceValidator +{ +public: + ///Gets the type of the validator + std::string getType() const { return "increasingdata"; } + /// Clone the current state + Kernel::IValidator_sptr clone() const { return boost::make_shared(*this); } + +private: + /** Validate a workspace. + * @param value :: The workspace to test + * @return A message for users with negative results, otherwise "" + */ + std::string checkValidity( const MatrixWorkspace_sptr& value ) const + { + if ( value->blocksize() < 2 ) + { + return "Spectra must have two or more data points (bins)."; + } + for(size_t spec = 0; spec < value->getNumberHistograms(); ++spec) + { + auto &Y = value->readY( spec ); + double y = Y.front(); + for(auto it = Y.begin() + 1; it != Y.end(); ++it) + { + if ( y > *it ) return "Data in the workspace must monotonically increase."; + y = *it; + } + } + return ""; + } + +}; + } // namespace API } // namespace Mantid diff --git a/Code/Mantid/Framework/API/src/Algorithm.cpp b/Code/Mantid/Framework/API/src/Algorithm.cpp index 195941bfa7c7..f7cec91dc0fe 100644 --- a/Code/Mantid/Framework/API/src/Algorithm.cpp +++ b/Code/Mantid/Framework/API/src/Algorithm.cpp @@ -78,13 +78,13 @@ namespace Mantid Algorithm::Algorithm() : PropertyManagerOwner(), m_cancel(false),m_parallelException(false), m_log("Algorithm"), g_log(m_log), + m_groupSize(0), m_executeAsync(NULL), m_notificationCenter(NULL), m_progressObserver(NULL), m_isInitialized(false), m_isExecuted(false),m_isChildAlgorithm(false), m_recordHistoryForChild(false), m_alwaysStoreInADS(false),m_runningAsync(false), - m_running(false),m_rethrow(false),m_algorithmID(this), - m_singleGroup(-1), m_groupSize(0), m_groupsHaveSimilarNames(false) + m_running(false), m_rethrow(false), m_algorithmID(this), m_singleGroup(-1), m_groupsHaveSimilarNames(false) { } @@ -523,33 +523,6 @@ namespace Mantid } } - // ----- Perform validation of the whole set of properties ------------- - std::map errors = this->validateInputs(); - if (!errors.empty()) - { - size_t numErrors = errors.size(); - // Log each issue - auto & errorLog = getLogger().error(); - auto & warnLog = getLogger().warning(); - for (auto it = errors.begin(); it != errors.end(); it++) - { - if (this->existsProperty(it->first)) - errorLog << "Invalid value for " << it->first << ": " << it->second << "\n"; - else - { - numErrors -= 1; // don't count it as an error - warnLog << "validateInputs() references non-existant property \"" - << it->first << "\"\n"; - } - } - // Throw because something was invalid - if (numErrors > 0) - { - notificationCenter().postNotification(new ErrorNotification(this,"Some invalid Properties found")); - throw std::runtime_error("Some invalid Properties found"); - } - } - // ----- Check for processing groups ------------- // default true so that it has the right value at the check below the catch block should checkGroups throw bool callProcessGroups = true; @@ -557,16 +530,11 @@ namespace Mantid { // Checking the input is a group. Throws if the sizes are wrong callProcessGroups = this->checkGroups(); - if (callProcessGroups) - { - // This calls this->execute() again on each member of the group. - return processGroups(); - } } catch(std::exception& ex) { - getLogger().error() << "Error in execution of algorithm "<< this->name() << std::endl - << ex.what()<name() << "\n" + << ex.what() << "\n"; notificationCenter().postNotification(new ErrorNotification(this,ex.what())); m_running = false; if (m_isChildAlgorithm || m_runningAsync || m_rethrow) @@ -574,11 +542,74 @@ namespace Mantid m_runningAsync = false; throw; } + return false; + } + + // ----- Perform validation of the whole set of properties ------------- + if (!callProcessGroups) // for groups this is called on each workspace separately + { + std::map errors = this->validateInputs(); + if (!errors.empty()) + { + size_t numErrors = errors.size(); + // Log each issue + auto & errorLog = getLogger().error(); + auto & warnLog = getLogger().warning(); + for (auto it = errors.begin(); it != errors.end(); it++) + { + if (this->existsProperty(it->first)) + errorLog << "Invalid value for " << it->first << ": " << it->second << "\n"; + else + { + numErrors -= 1; // don't count it as an error + warnLog << "validateInputs() references non-existant property \"" + << it->first << "\"\n"; + } + } + // Throw because something was invalid + if (numErrors > 0) + { + notificationCenter().postNotification(new ErrorNotification(this,"Some invalid Properties found")); + throw std::runtime_error("Some invalid Properties found"); + } + } + } + + if(trackingHistory()) + { + // count used for defining the algorithm execution order + // If history is being recorded we need to count this as a separate algorithm + // as the history compares histories by their execution number + ++Algorithm::g_execCount; + + //populate history record before execution so we can record child algorithms in it + AlgorithmHistory algHist; + m_history = boost::make_shared(algHist); } + + // ----- Process groups ------------- // If checkGroups() threw an exception but there ARE group workspaces // (means that the group sizes were incompatible) if (callProcessGroups) - return false; + { + // This calls this->execute() again on each member of the group. + start_time = Mantid::Kernel::DateAndTime::getCurrentTime(); + // Start a timer + Timer timer; + // Call the concrete algorithm's exec method + const bool completed = processGroups(); + // Check for a cancellation request in case the concrete algorithm doesn't + interruption_point(); + // Get how long this algorithm took to run + const float duration = timer.elapsed(); + + if(completed) + { + // Log that execution has completed. + reportCompleted(duration, true/*indicat that this is for group processing*/); + } + return completed; + } // Read or write locks every input/output workspace this->lockWorkspaces(); @@ -593,19 +624,6 @@ namespace Mantid Poco::FastMutex::ScopedLock _lock(m_mutex); m_running = true; } - - - if(trackingHistory()) - { - // count used for defining the algorithm execution order - // If history is being recorded we need to count this as a separate algorithm - // as the history compares histories by their execution number - ++Algorithm::g_execCount; - - //populate history record before execution so we can record child algorithms in it - AlgorithmHistory algHist; - m_history = boost::make_shared(algHist); - } start_time = Mantid::Kernel::DateAndTime::getCurrentTime(); // Start a timer @@ -631,14 +649,9 @@ namespace Mantid // RJT, 19/3/08: Moved this up from below the catch blocks setExecuted(true); - if (!m_isChildAlgorithm || m_alwaysStoreInADS) - { - getLogger().notice() << name() << " successful, Duration " - << std::fixed << std::setprecision(2) << duration << " seconds" << std::endl; - } - else - getLogger().debug() << name() << " finished with isChild = " << isChild() << std::endl; - m_running = false; + + // Log that execution has completed. + reportCompleted(duration); } catch(std::runtime_error& ex) { @@ -1614,6 +1627,32 @@ namespace Mantid if (m_cancel) throw CancelException(); } + /** + Report that the algorithm has completed. + @param duration : Algorithm duration + @param groupProcessing : We have been processing via processGroups if true. + */ + void Algorithm::reportCompleted(const double& duration, const bool groupProcessing) + { + std::string optionalMessage; + if(groupProcessing) + { + optionalMessage = ". Processed as a workspace group"; + } + + if (!m_isChildAlgorithm || m_alwaysStoreInADS) + { + getLogger().notice() << name() << " successful, Duration " + << std::fixed << std::setprecision(2) << duration << " seconds" << optionalMessage << std::endl; + } + + else + { + getLogger().debug() << name() << " finished with isChild = " << isChild() << std::endl; + } + m_running = false; + } + } // namespace API diff --git a/Code/Mantid/Framework/API/src/ExperimentInfo.cpp b/Code/Mantid/Framework/API/src/ExperimentInfo.cpp index ed6160a6db53..3a4b3eec95e6 100644 --- a/Code/Mantid/Framework/API/src/ExperimentInfo.cpp +++ b/Code/Mantid/Framework/API/src/ExperimentInfo.cpp @@ -8,7 +8,7 @@ #include "MantidGeometry/Crystal/OrientedLattice.h" #include "MantidGeometry/Instrument/ParameterMap.h" #include "MantidGeometry/Instrument/ParComponentFactory.h" -#include "MantidGeometry/Instrument/XMLlogfile.h" +#include "MantidGeometry/Instrument/XMLInstrumentParameter.h" #include "MantidKernel/ConfigService.h" #include "MantidKernel/DateAndTime.h" @@ -213,7 +213,7 @@ namespace API struct ParameterValue { - ParameterValue(const Geometry::XMLlogfile & paramInfo, + ParameterValue(const Geometry::XMLInstrumentParameter & paramInfo, const API::Run & run) : info(paramInfo), runData(run) {} @@ -234,7 +234,7 @@ namespace API else if(boost::iequals(info.m_value, "yes")) return true; else return false; } - const Geometry::XMLlogfile & info; + const Geometry::XMLInstrumentParameter & info; const Run & runData; }; ///@endcond @@ -817,7 +817,7 @@ namespace API std::string instrument(Kernel::ConfigService::Instance().getInstrument(instrumentName).name()); // Get the search directory for XML instrument definition files (IDFs) - std::string directoryName = Kernel::ConfigService::Instance().getInstrumentDirectory(); + const std::vector& directoryNames = Kernel::ConfigService::Instance().getInstrumentDirectories(); boost::regex regex(instrument+"_Definition.*\\.xml", boost::regex_constants::icase); Poco::DirectoryIterator end_iter; @@ -826,39 +826,44 @@ namespace API std::string mostRecentIDF; // store most recently starting matching IDF if found, else most recently starting IDF. DateAndTime refDate("1900-01-31 23:59:00"); // used to help determine the most recently starting IDF, if none match DateAndTime refDateGoodFile("1900-01-31 23:59:00"); // used to help determine the most recently starting matching IDF - for ( Poco::DirectoryIterator dir_itr(directoryName); dir_itr != end_iter; ++dir_itr ) + for ( auto instDirs_itr = directoryNames.begin(); instDirs_itr != directoryNames.end(); ++instDirs_itr) { - if ( !Poco::File(dir_itr->path() ).isFile() ) continue; - - std::string l_filenamePart = Poco::Path(dir_itr->path()).getFileName(); - if ( regex_match(l_filenamePart, regex) ) + //This will iterate around the directories from user ->etc ->install, and find the first beat file + std::string directoryName = *instDirs_itr; + for ( Poco::DirectoryIterator dir_itr(directoryName); dir_itr != end_iter; ++dir_itr ) { - g_log.debug() << "Found file: '" << dir_itr->path() << "'\n"; - std::string validFrom, validTo; - getValidFromTo(dir_itr->path(), validFrom, validTo); - g_log.debug() << "File '" << dir_itr->path() << " valid dates: from '" << validFrom << "' to '" << validTo << "'\n"; - DateAndTime from(validFrom); - // Use a default valid-to date if none was found. - DateAndTime to; - if (validTo.length() > 0) - to.setFromISO8601(validTo); - else - to.setFromISO8601("2100-01-01T00:00:00"); + if ( !Poco::File(dir_itr->path() ).isFile() ) continue; - if ( from <= d && d <= to ) + std::string l_filenamePart = Poco::Path(dir_itr->path()).getFileName(); + if ( regex_match(l_filenamePart, regex) ) { - if( from > refDateGoodFile ) - { // We'd found a matching file more recently starting than any other matching file found - foundGoodFile = true; - refDateGoodFile = from; + g_log.debug() << "Found file: '" << dir_itr->path() << "'\n"; + std::string validFrom, validTo; + getValidFromTo(dir_itr->path(), validFrom, validTo); + g_log.debug() << "File '" << dir_itr->path() << " valid dates: from '" << validFrom << "' to '" << validTo << "'\n"; + DateAndTime from(validFrom); + // Use a default valid-to date if none was found. + DateAndTime to; + if (validTo.length() > 0) + to.setFromISO8601(validTo); + else + to.setFromISO8601("2100-01-01T00:00:00"); + + if ( from <= d && d <= to ) + { + if( from > refDateGoodFile ) + { // We'd found a matching file more recently starting than any other matching file found + foundGoodFile = true; + refDateGoodFile = from; + mostRecentIDF = dir_itr->path(); + } + } + if ( !foundGoodFile && ( from > refDate ) ) + { // Use most recently starting file, in case we don't find a matching file. + refDate = from; mostRecentIDF = dir_itr->path(); } } - if ( !foundGoodFile && ( from > refDate ) ) - { // Use most recently starting file, in case we don't find a matching file. - refDate = from; - mostRecentIDF = dir_itr->path(); - } } } g_log.debug() << "IDF selected is " << mostRecentIDF << std::endl; @@ -1099,7 +1104,7 @@ namespace API * @param runData A reference to the run object, which stores log value entries */ void ExperimentInfo::populateWithParameter(Geometry::ParameterMap & paramMap, - const std::string & name, const Geometry::XMLlogfile & paramInfo, + const std::string & name, const Geometry::XMLInstrumentParameter & paramInfo, const Run & runData) { const std::string & category = paramInfo.m_type; diff --git a/Code/Mantid/Framework/API/src/HistoryView.cpp b/Code/Mantid/Framework/API/src/HistoryView.cpp index 1d8e8d09bfe1..13356e963bd8 100644 --- a/Code/Mantid/Framework/API/src/HistoryView.cpp +++ b/Code/Mantid/Framework/API/src/HistoryView.cpp @@ -24,7 +24,7 @@ HistoryView::HistoryView(const WorkspaceHistory& wsHist) /** * Unroll an algorithm history to export its child algorithms. * - * This places each of the child algorithm histories into the + * This places each of the child algorithm histories into the * HistoryView object. The parent is retained as a marker so we can * "roll" the history back up if we want. This method does nothing if * the history object has no children @@ -43,13 +43,13 @@ void HistoryView::unroll(size_t index) auto it = m_historyItems.begin(); std::advance (it,index); - unroll(it); + unroll(it); } /** * Unroll an algorithm history to export its child algorithms. * - * This places each of the child algorithm histories into the + * This places each of the child algorithm histories into the * HistoryView object. The parent is retained as a marker so we can * "roll" the history back up if we want. This method does nothing if * the history object has no children @@ -62,15 +62,15 @@ void HistoryView::unroll(std::list::iterator it) const auto childHistories = history->getChildHistories(); if (!it->isUnrolled() && childHistories.size() > 0) - { + { //mark this record as being ignored by the script builder it->unrolled(true); - + ++it; //move iterator forward to insertion position //insert each of the records, in order, at this position for (auto childIter = childHistories.begin(); childIter != childHistories.end(); ++childIter) { - HistoryItem item(*childIter); + HistoryItem item(*childIter); m_historyItems.insert(it, item); } } @@ -125,8 +125,8 @@ void HistoryView::roll(size_t index) //advance to the item at the index auto it = m_historyItems.begin(); std::advance (it,index); - - roll(it); + + roll(it); } /** @@ -145,7 +145,7 @@ void HistoryView::roll(std::list::iterator it) // the number of records after this position const size_t numChildren = it->numberOfChildren(); if (it->isUnrolled() && numChildren > 0) - { + { //mark this record as not being ignored by the script builder it->unrolled(false); ++it; //move to first child @@ -153,7 +153,7 @@ void HistoryView::roll(std::list::iterator it) //remove each of the children from the list for (size_t i = 0; i < numChildren; ++i) { - //check if our children are unrolled and + //check if our children are unrolled and //roll them back up if so. if(it->isUnrolled()) { @@ -165,6 +165,31 @@ void HistoryView::roll(std::list::iterator it) } } +/** + * Filter the list of history items to remove any anlgorithms whos start + * time is outside of the given range. + * + * @param start Start of time range + * @param end End of time range + */ +void HistoryView::filterBetweenExecDate(Mantid::Kernel::DateAndTime start, Mantid::Kernel::DateAndTime end) +{ + for(auto it = m_historyItems.begin(); it != m_historyItems.end();) + { + Mantid::Kernel::DateAndTime algExecutionDate = it->getAlgorithmHistory()->executionDate(); + + // If the algorithm is outside of the time range, remove it and keep iterating + if(algExecutionDate < start || algExecutionDate > end) + { + it = m_historyItems.erase(it); + } + else + { + ++it; + } + } +} + /** * Get the list of History Items for this view. * diff --git a/Code/Mantid/Framework/API/src/LiveListenerFactory.cpp b/Code/Mantid/Framework/API/src/LiveListenerFactory.cpp index 130ab94aa9ca..2989b8aa1f50 100644 --- a/Code/Mantid/Framework/API/src/LiveListenerFactory.cpp +++ b/Code/Mantid/Framework/API/src/LiveListenerFactory.cpp @@ -29,17 +29,23 @@ namespace API * @param instrumentName The name of the instrument to 'listen to' (Note that the argument has * different semantics to the base class create method). * @param connect Whether to connect the listener to the data stream for the given instrument. + * @param properties Property manager to copy property values to the listener if it has any. * @returns A shared pointer to the created ILiveListener implementation * @throws Exception::NotFoundError If the requested listener is not registered * @throws std::runtime_error If unable to connect to the listener at the configured address */ - boost::shared_ptr LiveListenerFactoryImpl::create(const std::string& instrumentName, bool connect) const + boost::shared_ptr LiveListenerFactoryImpl::create(const std::string& instrumentName, bool connect, const Kernel::IPropertyManager* properties) const { ILiveListener_sptr listener; // See if we know about the instrument with the given name try { Kernel::InstrumentInfo inst = Kernel::ConfigService::Instance().getInstrument(instrumentName); listener = Kernel::DynamicFactory::create(inst.liveListener()); + // set the properties + if ( properties ) + { + listener->updatePropertyValues( *properties ); + } if ( connect && !listener->connect(Poco::Net::SocketAddress(inst.liveDataAddress())) ) { // If we can't connect, log and throw an exception diff --git a/Code/Mantid/Framework/API/src/MatrixWorkspace.cpp b/Code/Mantid/Framework/API/src/MatrixWorkspace.cpp index 83e91c844712..e0adfb391d6a 100644 --- a/Code/Mantid/Framework/API/src/MatrixWorkspace.cpp +++ b/Code/Mantid/Framework/API/src/MatrixWorkspace.cpp @@ -40,6 +40,7 @@ namespace Mantid IMDWorkspace(), ExperimentInfo(), m_axes(), m_isInitialized(false), m_YUnit(), m_YUnitLabel(), m_isDistribution(false), + m_isCommonBinsFlagSet(false),m_isCommonBinsFlag(false), m_masks(), m_indexCalculator(), m_nearestNeighboursFactory((nnFactory == NULL) ? new NearestNeighboursFactory : nnFactory), m_nearestNeighbours() @@ -61,9 +62,9 @@ namespace Mantid { std::ostringstream os; os << id() << "\n" - << "Title: " << getTitle() << "\n" - << "Histograms: " << getNumberHistograms() << "\n" - << "Bins: " << blocksize() << "\n"; + << "Title: " << getTitle() << "\n" + << "Histograms: " << getNumberHistograms() << "\n" + << "Bins: " << blocksize() << "\n"; if ( isHistogramData() ) os << "Histogram\n"; else os << "Data points\n"; @@ -73,7 +74,7 @@ namespace Mantid { Axis *ax = getAxis(0); if ( ax && ax->unit() ) os << ax->unit()->caption() - << " / " << ax->unit()->label().ascii(); + << " / " << ax->unit()->label().ascii(); else os << "Not set"; } else @@ -81,7 +82,7 @@ namespace Mantid os << "N/A"; } os << "\n" - << "Y axis: " << YUnitLabel() << "\n"; + << "Y axis: " << YUnitLabel() << "\n"; os << ExperimentInfo::toString(); return os.str(); @@ -122,13 +123,13 @@ namespace Mantid //--------------------------------------------------------------------------------------- /** Set the title of the workspace - * - * @param t :: The title - */ + * + * @param t :: The title + */ void MatrixWorkspace::setTitle(const std::string& t) { Workspace::setTitle(t); - + // A MatrixWorkspace contains uniquely one Run object, hence for this workspace // keep the Run object run_title property the same as the workspace title Run& run = mutableRun(); @@ -138,9 +139,9 @@ namespace Mantid //--------------------------------------------------------------------------------------- /** Get the workspace title - * - * @return The title - */ + * + * @return The title + */ const std::string MatrixWorkspace::getTitle() const { if ( run().hasProperty("run_title") ) @@ -170,12 +171,12 @@ namespace Mantid //--------------------------------------------------------------------------------------- /** - * Rebuild the default spectra mapping for a workspace. If a non-empty - * instrument is set then the default maps each detector to a spectra with - * the same ID. If an empty instrument is set then a 1:1 map from 1->NHistograms - * is created. - * @param includeMonitors :: If false the monitors are not included - */ + * Rebuild the default spectra mapping for a workspace. If a non-empty + * instrument is set then the default maps each detector to a spectra with + * the same ID. If an empty instrument is set then a 1:1 map from 1->NHistograms + * is created. + * @param includeMonitors :: If false the monitors are not included + */ void MatrixWorkspace::rebuildSpectraMapping(const bool includeMonitors) { if( sptr_instrument->nelements() == 0 ) @@ -190,7 +191,7 @@ namespace Mantid size_t index = 0; std::vector::const_iterator iend = pixelIDs.end(); for( std::vector::const_iterator it = pixelIDs.begin(); - it != iend; ++it ) + it != iend; ++it ) { // The detector ID const detid_t detId = *it; @@ -219,10 +220,10 @@ namespace Mantid //--------------------------------------------------------------------------------------- /** - * Handles the building of the NearestNeighbours object, if it has not already been - * populated for this parameter map. - * @param ignoreMaskedDetectors :: flag indicating that masked detectors should be ignored. True to ignore detectors. - */ + * Handles the building of the NearestNeighbours object, if it has not already been + * populated for this parameter map. + * @param ignoreMaskedDetectors :: flag indicating that masked detectors should be ignored. True to ignore detectors. + */ void MatrixWorkspace::buildNearestNeighbours(const bool ignoreMaskedDetectors) const { if ( !m_nearestNeighbours ) @@ -253,13 +254,13 @@ namespace Mantid //--------------------------------------------------------------------------------------- /** Queries the NearestNeighbours object for the selected detector. - * NOTE! getNeighbours(spectrumNumber, radius) is MUCH faster. - * - * @param comp :: pointer to the querying detector - * @param radius :: distance from detector on which to filter results - * @param ignoreMaskedDetectors :: flag indicating that masked detectors should be ignored. True to ignore detectors. - * @return map of DetectorID to distance for the nearest neighbours - */ + * NOTE! getNeighbours(spectrumNumber, radius) is MUCH faster. + * + * @param comp :: pointer to the querying detector + * @param radius :: distance from detector on which to filter results + * @param ignoreMaskedDetectors :: flag indicating that masked detectors should be ignored. True to ignore detectors. + * @return map of DetectorID to distance for the nearest neighbours + */ std::map MatrixWorkspace::getNeighbours(const Geometry::IDetector *comp, const double radius, const bool ignoreMaskedDetectors) const { if ( !m_nearestNeighbours ) @@ -280,12 +281,12 @@ namespace Mantid //--------------------------------------------------------------------------------------- /** Queries the NearestNeighbours object for the selected spectrum number. - * - * @param spec :: spectrum number of the detector you are looking at - * @param radius :: distance from detector on which to filter results - * @param ignoreMaskedDetectors :: flag indicating that masked detectors should be ignored. True to ignore detectors. - * @return map of DetectorID to distance for the nearest neighbours - */ + * + * @param spec :: spectrum number of the detector you are looking at + * @param radius :: distance from detector on which to filter results + * @param ignoreMaskedDetectors :: flag indicating that masked detectors should be ignored. True to ignore detectors. + * @return map of DetectorID to distance for the nearest neighbours + */ std::map MatrixWorkspace::getNeighbours(specid_t spec, const double radius, bool ignoreMaskedDetectors) const { if ( !m_nearestNeighbours ) @@ -296,14 +297,14 @@ namespace Mantid return neighbours; } - //--------------------------------------------------------------------------------------- + //--------------------------------------------------------------------------------------- /** Queries the NearestNeighbours object for the selected spectrum number. - * - * @param spec :: spectrum number of the detector you are looking at - * @param nNeighbours :: unsigned int, number of neighbours to include. - * @param ignoreMaskedDetectors :: flag indicating that masked detectors should be ignored. True to ignore detectors. - * @return map of DetectorID to distance for the nearest neighbours - */ + * + * @param spec :: spectrum number of the detector you are looking at + * @param nNeighbours :: unsigned int, number of neighbours to include. + * @param ignoreMaskedDetectors :: flag indicating that masked detectors should be ignored. True to ignore detectors. + * @return map of DetectorID to distance for the nearest neighbours + */ std::map MatrixWorkspace::getNeighboursExact(specid_t spec, const int nNeighbours, bool ignoreMaskedDetectors) const { if ( !m_nearestNeighbours ) @@ -539,10 +540,10 @@ namespace Mantid //--------------------------------------------------------------------------------------- /** Converts a list of detector IDs to the corresponding workspace indices. - * - * @param detIdList :: The list of detector IDs required - * @param indexList :: Returns a reference to the vector of indices - */ + * + * @param detIdList :: The list of detector IDs required + * @param indexList :: Returns a reference to the vector of indices + */ void MatrixWorkspace::getIndicesFromDetectorIDs(const std::vector& detIdList, std::vector& indexList) const { std::map> detectorIDtoWSIndices; @@ -574,11 +575,11 @@ namespace Mantid //--------------------------------------------------------------------------------------- /** Converts a list of detector IDs to the corresponding spectrum numbers. Might be slow! - * - * @param detIdList :: The list of detector IDs required - * @param spectraList :: Returns a reference to the vector of spectrum numbers. - * 0 for not-found detectors - */ + * + * @param detIdList :: The list of detector IDs required + * @param spectraList :: Returns a reference to the vector of spectrum numbers. + * 0 for not-found detectors + */ void MatrixWorkspace::getSpectraFromDetectorIDs(const std::vector& detIdList, std::vector& spectraList) const { std::vector::const_iterator it_start = detIdList.begin(); @@ -650,61 +651,61 @@ namespace Mantid //--------------------------------------------------------------------------------------- /** Integrate all the spectra in the matrix workspace within the range given. - * Default implementation, can be overridden by base classes if they know something smarter! - * - * @param out :: returns the vector where there is one entry per spectrum in the workspace. Same - * order as the workspace indices. - * @param minX :: minimum X bin to use in integrating. - * @param maxX :: maximum X bin to use in integrating. - * @param entireRange :: set to true to use the entire range. minX and maxX are then ignored! - */ + * Default implementation, can be overridden by base classes if they know something smarter! + * + * @param out :: returns the vector where there is one entry per spectrum in the workspace. Same + * order as the workspace indices. + * @param minX :: minimum X bin to use in integrating. + * @param maxX :: maximum X bin to use in integrating. + * @param entireRange :: set to true to use the entire range. minX and maxX are then ignored! + */ void MatrixWorkspace::getIntegratedSpectra(std::vector & out, const double minX, const double maxX, const bool entireRange) const { out.resize(this->getNumberHistograms(), 0.0); //Run in parallel if the implementation is threadsafe PARALLEL_FOR_IF( this->threadSafe() ) - for (int wksp_index = 0; wksp_index < static_cast(this->getNumberHistograms()); wksp_index++) - { - // Get Handle to data - const Mantid::MantidVec& x=this->readX(wksp_index); - const Mantid::MantidVec& y=this->readY(wksp_index); - // If it is a 1D workspace, no need to integrate - if ((x.size()<=2) && (y.size() >= 1)) + for (int wksp_index = 0; wksp_index < static_cast(this->getNumberHistograms()); wksp_index++) { - out[wksp_index] = y[0]; - } - else - { - // Iterators for limits - whole range by default - Mantid::MantidVec::const_iterator lowit, highit; - lowit=x.begin(); - highit=x.end()-1; - - //But maybe we don't want the entire range? - if (!entireRange) + // Get Handle to data + const Mantid::MantidVec& x=this->readX(wksp_index); + const Mantid::MantidVec& y=this->readY(wksp_index); + // If it is a 1D workspace, no need to integrate + if ((x.size()<=2) && (y.size() >= 1)) { - // If the first element is lower that the xmin then search for new lowit - if ((*lowit) < minX) - lowit = std::lower_bound(x.begin(),x.end(),minX); - // If the last element is higher that the xmax then search for new lowit - if ((*highit) > maxX) - highit = std::upper_bound(lowit,x.end(),maxX); + out[wksp_index] = y[0]; } - - // Get the range for the y vector - Mantid::MantidVec::difference_type distmin = std::distance(x.begin(), lowit); - Mantid::MantidVec::difference_type distmax = std::distance(x.begin(), highit); - double sum(0.0); - if( distmin <= distmax ) + else { - // Integrate - sum = std::accumulate(y.begin() + distmin,y.begin() + distmax,0.0); + // Iterators for limits - whole range by default + Mantid::MantidVec::const_iterator lowit, highit; + lowit=x.begin(); + highit=x.end()-1; + + //But maybe we don't want the entire range? + if (!entireRange) + { + // If the first element is lower that the xmin then search for new lowit + if ((*lowit) < minX) + lowit = std::lower_bound(x.begin(),x.end(),minX); + // If the last element is higher that the xmax then search for new lowit + if ((*highit) > maxX) + highit = std::upper_bound(lowit,x.end(),maxX); + } + + // Get the range for the y vector + Mantid::MantidVec::difference_type distmin = std::distance(x.begin(), lowit); + Mantid::MantidVec::difference_type distmax = std::distance(x.begin(), highit); + double sum(0.0); + if( distmin <= distmax ) + { + // Integrate + sum = std::accumulate(y.begin() + distmin,y.begin() + distmax,0.0); + } + //Save it in the vector + out[wksp_index] = sum; } - //Save it in the vector - out[wksp_index] = sum; } - } } /** Get the effective detector for the given spectrum @@ -713,7 +714,7 @@ namespace Mantid * to the given spectrum number. If more than one detector contributes then * the returned object's concrete type will be DetectorGroup. * @throw Kernel::Exception::NotFoundError If the Instrument is missing or the - requested workspace index does not have any associated detectors + requested workspace index does not have any associated detectors */ Geometry::IDetector_const_sptr MatrixWorkspace::getDetector(const size_t workspaceIndex) const { @@ -774,10 +775,10 @@ namespace Mantid } /** Returns the 2Theta scattering angle for a detector - * @param det :: A pointer to the detector object (N.B. might be a DetectorGroup) - * @return The scattering angle (0 < theta < pi) - * @throws InstrumentDefinitionError if source or sample is missing, or they are in the same place - */ + * @param det :: A pointer to the detector object (N.B. might be a DetectorGroup) + * @return The scattering angle (0 < theta < pi) + * @throws InstrumentDefinitionError if source or sample is missing, or they are in the same place + */ double MatrixWorkspace::detectorTwoTheta(Geometry::IDetector_const_sptr det) const { Geometry::IComponent_const_sptr source = getInstrument()->getSource(); @@ -877,7 +878,6 @@ namespace Mantid m_axes[axisIndex] = newAxis; } - //---------------------------------------------------------------------------------------------------- /// Returns the units of the data in the workspace std::string MatrixWorkspace::YUnit() const @@ -937,25 +937,63 @@ namespace Mantid /** * Whether the workspace contains histogram data - * @return whether the worksapace contains histogram data + * @return whether the workspace contains histogram data */ bool MatrixWorkspace::isHistogramData() const { return ( readX(0).size()==blocksize() ? false : true ); } + /** + * Whether the workspace contains common X bins + * @return whether the workspace contains common X bins + */ + bool MatrixWorkspace::isCommonBins() const + { + if (!m_isCommonBinsFlagSet) + { + m_isCommonBinsFlag = true; + //there being only one or zero histograms is accepted as not being an error + if ( blocksize() || getNumberHistograms() > 1) + { + //otherwise will compare some of the data, to save time just check two the first and the last + const size_t lastSpec = getNumberHistograms() - 1; + // Quickest check is to see if they are actually the same vector + if ( &(readX(0)[0]) != &(readX(lastSpec)[0]) ) + { + // Now check numerically + const double first = std::accumulate(readX(0).begin(),readX(0).end(),0.); + const double last = std::accumulate(readX(lastSpec).begin(),readX(lastSpec).end(),0.); + if ( std::abs(first-last)/std::abs(first+last) > 1.0E-9 ) + { + m_isCommonBinsFlag = false; + } + + //handle Nan's and inf's + if( (boost::math::isinf(first) != boost::math::isinf(last)) || + ( boost::math::isnan(first) != boost::math::isnan(last))) + { + m_isCommonBinsFlag = false; + } + } + } + m_isCommonBinsFlagSet = true; + } + + return m_isCommonBinsFlag; + } //---------------------------------------------------------------------------------------------------- /** - * Mask a given workspace index, setting the data and error values to zero - * @param index :: The index within the workspace to mask - */ + * Mask a given workspace index, setting the data and error values to zero + * @param index :: The index within the workspace to mask + */ void MatrixWorkspace::maskWorkspaceIndex(const std::size_t index) { if( index >= this->getNumberHistograms() ) { throw Kernel::Exception::IndexError(index,this->getNumberHistograms(), - "MatrixWorkspace::maskWorkspaceIndex,index"); + "MatrixWorkspace::maskWorkspaceIndex,index"); } ISpectrum * spec = this->getSpectrum(index); @@ -1061,19 +1099,19 @@ namespace Mantid } /** Sets the internal monitor workspace to the provided workspace. - * This method is intended for use by data-loading algorithms. - * Note that no checking is performed as to whether this workspace actually contains data - * pertaining to monitors, or that the spectra point to Detector objects marked as monitors. - * It simply has to be of the correct type to be accepted. - * @param monitorWS The workspace containing the monitor data. - */ + * This method is intended for use by data-loading algorithms. + * Note that no checking is performed as to whether this workspace actually contains data + * pertaining to monitors, or that the spectra point to Detector objects marked as monitors. + * It simply has to be of the correct type to be accepted. + * @param monitorWS The workspace containing the monitor data. + */ void MatrixWorkspace::setMonitorWorkspace(const boost::shared_ptr& monitorWS) { m_monitorWorkspace = monitorWS; } /** Returns a pointer to the internal monitor workspace. - */ + */ boost::shared_ptr MatrixWorkspace::monitorWorkspace() const { return m_monitorWorkspace; @@ -1081,8 +1119,8 @@ namespace Mantid //--------------------------------------------------------------------------------------------- /** Return memory used by the workspace, in bytes. - * @return bytes used. - */ + * @return bytes used. + */ size_t MatrixWorkspace::getMemorySize() const { //3 doubles per histogram bin. @@ -1090,8 +1128,8 @@ namespace Mantid } /** Returns the memory used (in bytes) by the X axes, handling ragged bins. - * @return bytes used - */ + * @return bytes used + */ size_t MatrixWorkspace::getMemorySizeForXAxes() const { size_t total = 0; @@ -1110,15 +1148,15 @@ namespace Mantid //----------------------------------------------------------------------------- /** Return the time of the first pulse received, by accessing the run's - * sample logs to find the proton_charge. - * - * NOTE, JZ: Pulse times before 1991 (up to 100) are skipped. This is to avoid - * a DAS bug at SNS around Mar 2011 where the first pulse time is Jan 1, 1990. - * - * @return the time of the first pulse - * @throw runtime_error if the log is not found; or if it is empty. - * @throw invalid_argument if the log is not a double TimeSeriesProperty (should be impossible) - */ + * sample logs to find the proton_charge. + * + * NOTE, JZ: Pulse times before 1991 (up to 100) are skipped. This is to avoid + * a DAS bug at SNS around Mar 2011 where the first pulse time is Jan 1, 1990. + * + * @return the time of the first pulse + * @throw runtime_error if the log is not found; or if it is empty. + * @throw invalid_argument if the log is not a double TimeSeriesProperty (should be impossible) + */ Kernel::DateAndTime MatrixWorkspace::getFirstPulseTime() const { TimeSeriesProperty* log = this->run().getTimeSeriesProperty("proton_charge"); @@ -1141,12 +1179,12 @@ namespace Mantid //----------------------------------------------------------------------------- /** Return the time of the last pulse received, by accessing the run's - * sample logs to find the proton_charge - * - * @return the time of the first pulse - * @throw runtime_error if the log is not found; or if it is empty. - * @throw invalid_argument if the log is not a double TimeSeriesProperty (should be impossible) - */ + * sample logs to find the proton_charge + * + * @return the time of the first pulse + * @throw runtime_error if the log is not found; or if it is empty. + * @throw invalid_argument if the log is not a double TimeSeriesProperty (should be impossible) + */ Kernel::DateAndTime MatrixWorkspace::getLastPulseTime() const { TimeSeriesProperty* log = this->run().getTimeSeriesProperty("proton_charge"); @@ -1227,8 +1265,8 @@ namespace Mantid public: MWDimension(const Axis* axis, const std::string& dimensionId): - m_axis(*axis), m_dimensionId(dimensionId), - m_haveEdges(dynamic_cast(&m_axis) != NULL) + m_axis(*axis), m_dimensionId(dimensionId), + m_haveEdges(dynamic_cast(&m_axis) != NULL) { } @@ -1270,9 +1308,9 @@ namespace Mantid virtual coord_t getX(size_t ind)const {return coord_t(m_axis(ind));} /** - * Return the bin width taking into account if the stored values are actually bin centres or not - * @return A single value for the uniform bin width - */ + * Return the bin width taking into account if the stored values are actually bin centres or not + * @return A single value for the uniform bin width + */ virtual coord_t getBinWidth() const { size_t nsteps = (m_haveEdges) ? this->getNBins() : this->getNBins() - 1; @@ -1293,14 +1331,14 @@ namespace Mantid //=============================================================================== /** An implementation of IMDDimension for MatrixWorkspace that - * points to the X vector of the first spectrum. - */ + * points to the X vector of the first spectrum. + */ class MWXDimension: public Mantid::Geometry::IMDDimension { public: MWXDimension(const MatrixWorkspace * ws, const std::string & dimensionId): - m_ws(ws), m_dimensionId(dimensionId) + m_ws(ws), m_dimensionId(dimensionId) { m_X = ws->readX(0); } @@ -1399,13 +1437,13 @@ namespace Mantid //-------------------------------------------------------------------------------------------- /** Create IMDIterators from this 2D workspace - * - * @param suggestedNumCores :: split the iterators into this many cores (if threadsafe) - * @param function :: implicit function to limit range - * @return MatrixWorkspaceMDIterator vector - */ + * + * @param suggestedNumCores :: split the iterators into this many cores (if threadsafe) + * @param function :: implicit function to limit range + * @return MatrixWorkspaceMDIterator vector + */ std::vector MatrixWorkspace::createIterators(size_t suggestedNumCores, - Mantid::Geometry::MDImplicitFunction * function) const + Mantid::Geometry::MDImplicitFunction * function) const { // Find the right number of cores to use size_t numCores = suggestedNumCores; @@ -1430,34 +1468,34 @@ namespace Mantid //------------------------------------------------------------------------------------ /** Obtain coordinates for a line plot through a MDWorkspace. - * Cross the workspace from start to end points, recording the signal along the line. - * Sets the x,y vectors to the histogram bin boundaries and counts - * - * @param start :: coordinates of the start point of the line - * @param end :: coordinates of the end point of the line - * @param normalize :: how to normalize the signal - * @param x :: is set to the boundaries of the bins, relative to start of the line. - * @param y :: is set to the normalized signal for each bin. Length = length(x) - 1 - * @param e :: is set to the normalized errors for each bin. Length = length(x) - 1 - */ + * Cross the workspace from start to end points, recording the signal along the line. + * Sets the x,y vectors to the histogram bin boundaries and counts + * + * @param start :: coordinates of the start point of the line + * @param end :: coordinates of the end point of the line + * @param normalize :: how to normalize the signal + * @param x :: is set to the boundaries of the bins, relative to start of the line. + * @param y :: is set to the normalized signal for each bin. Length = length(x) - 1 + * @param e :: is set to the normalized errors for each bin. Length = length(x) - 1 + */ void MatrixWorkspace::getLinePlot(const Mantid::Kernel::VMD & start, const Mantid::Kernel::VMD & end, - Mantid::API::MDNormalization normalize, std::vector & x, std::vector & y, std::vector & e) const + Mantid::API::MDNormalization normalize, std::vector & x, std::vector & y, std::vector & e) const { IMDWorkspace::getLinePlot(start,end,normalize,x,y,e); } //------------------------------------------------------------------------------------ /** Returns the (normalized) signal at a given coordinates - * - * @param coords :: bare array, size 2, of coordinates. X, Y - * @param normalization :: how to normalize the signal - * @return normalized signal. - */ + * + * @param coords :: bare array, size 2, of coordinates. X, Y + * @param normalization :: how to normalize the signal + * @return normalized signal. + */ signal_t MatrixWorkspace::getSignalAtCoord(const coord_t * coords, const Mantid::API::MDNormalization & normalization) const { if (this->axes() != 2) throw std::invalid_argument("MatrixWorkspace::getSignalAtCoord() - Workspace can only have 2 axes, found " +\ - boost::lexical_cast(this->axes())); + boost::lexical_cast(this->axes())); coord_t x = coords[0]; coord_t y = coords[1]; @@ -1478,13 +1516,15 @@ namespace Mantid double yBinSize(1.0); // only applies for volume normalization & numeric axis if (normalization == VolumeNormalization && ax1->isNumeric()) { - if (wi + 1 == nhist && nhist > 1) + size_t uVI; // unused vertical index. + double currentVertical = ax1->operator ()(wi, uVI); + if (wi + 1 == nhist && nhist > 1) // On the boundary, look back to get diff { - yBinSize = yVals[wi] - yVals[wi-1]; + yBinSize = currentVertical - ax1->operator ()(wi - 1, uVI); } else { - yBinSize = yVals[wi+1] - yVals[wi]; + yBinSize = ax1->operator ()(wi + 1, uVI) - currentVertical; } } @@ -1530,12 +1570,12 @@ namespace Mantid //-------------------------------------------------------------------------------------------- /** Save the spectra detector map to an open NeXus file. - * @param file :: open NeXus file - * @param spec :: list of the Workspace Indices to save. - * @param compression :: NXcompression int to indicate how to compress - */ + * @param file :: open NeXus file + * @param spec :: list of the Workspace Indices to save. + * @param compression :: NXcompression int to indicate how to compress + */ void MatrixWorkspace::saveSpectraMapNexus(::NeXus::File * file, - const std::vector& spec, const ::NeXus::NXcompression compression) const + const std::vector& spec, const ::NeXus::NXcompression compression) const { // Count the total number of detectors std::size_t nDetectors = 0; @@ -1667,7 +1707,7 @@ namespace Mantid throw std::runtime_error("MatrixWorkspace::clearMDMasking has no implementation"); } - /** + /** @return the special coordinate system used if any. */ Mantid::API::SpecialCoordinateSystem MatrixWorkspace::getSpecialCoordinateSystem() const @@ -1675,6 +1715,288 @@ namespace Mantid return Mantid::API::None; } + /** + * Creates a 2D image. + * @param read :: Pointer to a method returning a MantidVec to provide data for the image. + * @param start :: First workspace index for the image. + * @param stop :: Last workspace index for the image. + * @param width :: Image width. Must divide (stop - start + 1) exactly. + * @param indexStart :: First index of the x integration range. + * @param indexEnd :: Last index of the x integration range. + */ + MantidImage_sptr MatrixWorkspace::getImage(const MantidVec& (MatrixWorkspace::*read)(std::size_t const) const, size_t start, size_t stop, size_t width, size_t indexStart, size_t indexEnd) const + { + // width must be provided (for now) + if ( width == 0 ) + { + throw std::runtime_error("Cannot create image with width 0"); + } + + size_t nHist = getNumberHistograms(); + // use all spectra by default + if ( stop == 0 ) + { + stop = nHist; + } + + // check start and stop + if ( stop < start ) + { + throw std::runtime_error("Cannot create image for an empty data set."); + } + + if ( start >= nHist ) + { + throw std::runtime_error("Cannot create image: start index is out of range"); + } + + if ( stop >= nHist ) + { + throw std::runtime_error("Cannot create image: stop index is out of range"); + } + + // calculate image geometry + size_t dataSize = stop - start + 1; + size_t height = dataSize / width; + + // and check that the data fits exactly into this geometry + if ( height * width != dataSize ) + { + throw std::runtime_error("Cannot create image: the data set cannot form a rectangle."); + } + + size_t nBins = blocksize(); + bool isHisto = isHistogramData(); + + // default indexEnd is the last index of the X vector + if ( indexEnd == 0 ) + { + indexEnd = nBins; + if ( !isHisto && indexEnd > 0 ) --indexEnd; + } + + // check the x-range indices + if ( indexEnd < indexStart ) + { + throw std::runtime_error("Cannot create image for an empty data set."); + } + + if ( indexStart >= nBins || indexEnd > nBins || (!isHisto && indexEnd == nBins) ) + { + throw std::runtime_error("Cannot create image: integration interval is out of range."); + } + + // initialize the image + auto image = boost::make_shared( height ); + if ( !isHisto ) ++indexEnd; + + // deal separately with single-binned workspaces: no integration is required + if ( isHisto && indexEnd == indexStart + 1 ) + { + PARALLEL_FOR_NO_WSP_CHECK() + for(int i = 0; i < static_cast(height); ++i) + { + auto &row = (*image)[i]; + row.resize( width ); + size_t spec = start + static_cast(i) * width; + for(size_t j = 0; j< width; ++j, ++spec) + { + row[j] = (this->*read)(spec)[indexStart]; + } + } + } + else + { + // each image pixel is integrated over the x-range [indexStart,indexEnd) + PARALLEL_FOR_NO_WSP_CHECK() + for(int i = 0; i < static_cast(height); ++i) + { + auto &row = (*image)[i]; + row.resize( width ); + size_t spec = start + static_cast(i) * width; + for(size_t j = 0; j < width; ++j, ++spec) + { + auto &V = (this->*read)(spec); + row[j] = std::accumulate( V.begin() + indexStart, V.begin() + indexEnd, 0.0 ); + } + } + } + + return image; + } + + /** + * Get start and end x indices for images + * @param i :: Histogram index. + * @param startX :: Lower bound of the x integration range. + * @param endX :: Upper bound of the x integration range. + */ + std::pair MatrixWorkspace::getImageStartEndXIndices( size_t i, double startX, double endX ) const + { + if ( startX == EMPTY_DBL() ) startX = readX(i).front(); + auto pStart = getXIndex( i, startX, true ); + if ( pStart.second != 0.0 ) + { + throw std::runtime_error("Start X value is required to be on bin boundary."); + } + if ( endX == EMPTY_DBL() ) endX = readX(i).back(); + auto pEnd = getXIndex( i, endX, false, pStart.first ); + if ( pEnd.second != 0.0 ) + { + throw std::runtime_error("End X value is required to be on bin boundary."); + } + return std::make_pair( pStart.first, pEnd.first ); + } + + /** + * Creates a 2D image of the y values in this workspace. + * @param start :: First workspace index for the image. + * @param stop :: Last workspace index for the image. + * @param width :: Image width. Must divide (stop - start + 1) exactly. + * @param startX :: Lower bound of the x integration range. + * @param endX :: Upper bound of the x integration range. + */ + MantidImage_sptr MatrixWorkspace::getImageY(size_t start, size_t stop, size_t width, double startX, double endX ) const + { + auto p = getImageStartEndXIndices( 0, startX, endX ); + return getImage(&MatrixWorkspace::readY,start,stop,width,p.first,p.second); + } + + /** + * Creates a 2D image of the error values in this workspace. + * @param start :: First workspace index for the image. + * @param stop :: Last workspace index for the image. + * @param width :: Image width. Must divide (stop - start + 1) exactly. + * @param startX :: Lower bound of the x integration range. + * @param endX :: Upper bound of the x integration range. + */ + MantidImage_sptr MatrixWorkspace::getImageE(size_t start, size_t stop, size_t width, double startX, double endX ) const + { + auto p = getImageStartEndXIndices( 0, startX, endX ); + return getImage(&MatrixWorkspace::readE,start,stop,width,p.first,p.second); + } + + /** + * Find an index in the X vector for an x-value close to a given value. It is returned as the first + * member of the pair. The second member is the fraction [0,1] of bin width cut off by the search value. + * If the first member == size of X vector then search failed. + * @param i :: Histogram index. + * @param x :: The value to find the index for. + * @param isLeft :: If true the left bin boundary is returned, if false - the right one. + * @param start :: Index to start the search from. + */ + std::pair MatrixWorkspace::getXIndex(size_t i, double x, bool isLeft, size_t start) const + { + auto &X = readX(i); + auto nx = X.size(); + + // if start out of range - search failed + if ( start >= nx ) return std::make_pair( nx, 0.0 ); + if ( start > 0 && start == nx - 1 ) + { + // starting with the last index is allowed for right boundary search + if ( !isLeft ) return std::make_pair( start, 0.0 ); + return std::make_pair( nx, 0.0 ); + } + + // consider point data with single value + if ( nx == 1 ) + { + assert( start == 0 ); + if ( isLeft ) return x <= X[start] ? std::make_pair( start, 0.0 ) : std::make_pair( nx, 0.0 ); + return x >= X[start] ? std::make_pair( start, 0.0 ) : std::make_pair( nx, 0.0 ); + } + + // left boundaries below start value map to the start value + if ( x <= X[start] ) + { + return isLeft ? std::make_pair( start, 0.0 ) : std::make_pair( nx, 0.0 ); + } + // right boundary search returns last x value for all values above it + if ( x >= X.back() ) + { + return !isLeft ? std::make_pair( nx - 1, 0.0 ) : std::make_pair( nx, 0.0 ); + } + + // general case: find the boundary index and bin fraction + auto end = X.end(); + for(auto ix = X.begin() + start + 1; ix != end; ++ix) + { + if ( *ix >= x ) + { + auto index = static_cast( std::distance(X.begin(),ix) ); + if ( isLeft ) --index; + return std::make_pair( index, fabs( (X[index] - x) / (*ix - *(ix - 1)) ) ); + } + } + // I don't think we can ever get here + return std::make_pair( nx, 0.0 ); + } + + /** + * Copy data from an image. + * @param dataVec :: A method returning non-const references to data vectors to copy the image to. + * @param image :: An image to copy the data from. + * @param start :: Startinf workspace indx to copy data to. + */ + void MatrixWorkspace::setImage( MantidVec& (MatrixWorkspace::*dataVec)(const std::size_t), const MantidImage &image, size_t start ) + { + + if ( image.empty() ) return; + if ( image[0].empty() ) return; + + if ( blocksize() != 1 ) + { + throw std::runtime_error("Cannot set image: a single bin workspace is expected."); + } + + size_t height = image.size(); + size_t width = image.front().size(); + size_t dataSize = width * height; + + if ( start + dataSize > getNumberHistograms() ) + { + throw std::runtime_error("Cannot set image: image is bigger than workspace."); + } + + PARALLEL_FOR_NO_WSP_CHECK() + for(int i = 0; i < static_cast(height); ++i) + { + auto &row = image[i]; + if ( row.size() != width ) + { + throw std::runtime_error("Canot set image: image is corrupted."); + } + size_t spec = start + static_cast(i) * width; + auto rowEnd = row.end(); + for(auto pixel = row.begin(); pixel != rowEnd; ++pixel,++spec) + { + (this->*dataVec)(spec)[0] = *pixel; + } + } + } + + /** + * Copy the data (Y's) from an image to this workspace. + * @param image :: An image to copy the data from. + * @param start :: Startinf workspace indx to copy data to. + */ + void MatrixWorkspace::setImageY( const MantidImage &image, size_t start ) + { + setImage( &MatrixWorkspace::dataY, image, start ); + } + + /** + * Copy the data from an image to this workspace's errors. + * @param image :: An image to copy the data from. + * @param start :: Startinf workspace indx to copy data to. + */ + void MatrixWorkspace::setImageE( const MantidImage &image, size_t start ) + { + setImage( &MatrixWorkspace::dataE, image, start ); + } + + } // namespace API } // Namespace Mantid diff --git a/Code/Mantid/Framework/API/src/MemoryManager.cpp b/Code/Mantid/Framework/API/src/MemoryManager.cpp index 28bdaabb6cb6..0e5699beda59 100644 --- a/Code/Mantid/Framework/API/src/MemoryManager.cpp +++ b/Code/Mantid/Framework/API/src/MemoryManager.cpp @@ -7,7 +7,7 @@ #include "MantidKernel/Memory.h" #ifdef USE_TCMALLOC -#include "google/malloc_extension.h" +#include "gperftools/malloc_extension.h" #endif #include //for endl diff --git a/Code/Mantid/Framework/API/src/NumericAxis.cpp b/Code/Mantid/Framework/API/src/NumericAxis.cpp index 541e34de16c5..9ad103cdaf6f 100644 --- a/Code/Mantid/Framework/API/src/NumericAxis.cpp +++ b/Code/Mantid/Framework/API/src/NumericAxis.cpp @@ -5,7 +5,13 @@ #include "MantidKernel/Exception.h" #include "MantidKernel/VectorHelper.h" -#include +#include + +#include "MantidKernel/Logger.h" +namespace +{ + Mantid::Kernel::Logger g_log("NumericAxis"); +} namespace Mantid { @@ -157,7 +163,28 @@ bool NumericAxis::operator==(const Axis& axis2) const */ std::string NumericAxis::label(const std::size_t& index)const { - return boost::lexical_cast((*this)(index)); + std::string numberLabel = boost::str(boost::format("%.13f") % (*this)(index)); + + // Remove all zeros up to the decimal place or a non zero value + auto it = numberLabel.end() - 1; + for(; it != numberLabel.begin(); --it) + { + if(*it == '0') + { + numberLabel.erase(it); + } + else if(*it == '.') + { + numberLabel.erase(it); + break; + } + else + { + break; + } + } + + return numberLabel; } /** diff --git a/Code/Mantid/Framework/API/src/Sample.cpp b/Code/Mantid/Framework/API/src/Sample.cpp index bfa6c6028ebf..445876129f93 100644 --- a/Code/Mantid/Framework/API/src/Sample.cpp +++ b/Code/Mantid/Framework/API/src/Sample.cpp @@ -2,43 +2,40 @@ // Includes //---------------------------------------------------------------------- #include "MantidAPI/Sample.h" -#include "MantidKernel/Strings.h" #include "MantidAPI/SampleEnvironment.h" #include "MantidGeometry/IComponent.h" #include "MantidGeometry/Crystal/OrientedLattice.h" #include "MantidGeometry/Objects/ShapeFactory.h" +#include "MantidKernel/Strings.h" #include - namespace Mantid { namespace API { using namespace Mantid::Kernel; - using Geometry::ShapeFactory; using Geometry::Object; - using Kernel::Material; using Geometry::OrientedLattice; - using Kernel::V3D; - + using Geometry::ShapeFactory; + /** * Default constructor. Required for cow_ptr. */ - Sample::Sample() : - m_name(), m_shape(), m_material(), m_environment(), + Sample::Sample() : + m_name(), m_shape(), m_environment(), m_lattice(NULL),m_samples(), m_geom_id(0), m_thick(0.0), m_height(0.0), m_width(0.0) { } - /** - * Copy constructor + /** + * Copy constructor * @param copy :: const reference to the sample object */ Sample::Sample(const Sample& copy) : - m_name(copy.m_name), m_shape(copy.m_shape), m_material(copy.m_material), + m_name(copy.m_name), m_shape(copy.m_shape), m_environment(copy.m_environment), m_lattice(NULL),m_samples(copy.m_samples), m_geom_id(copy.m_geom_id), m_thick(copy.m_thick), @@ -54,9 +51,9 @@ namespace Mantid delete m_lattice; } - /** Assignment operator + /** Assignment operator * @param rhs :: const reference to the sample object - * @return A reference to this object, which will have the same + * @return A reference to this object, which will have the same * state as the argument */ Sample& Sample::operator=(const Sample& rhs) @@ -64,7 +61,6 @@ namespace Mantid if (this == &rhs) return *this; m_name = rhs.m_name; m_shape = rhs.m_shape; - m_material = rhs.m_material; m_environment = rhs.m_environment; m_geom_id = rhs.m_geom_id; m_samples = std::vector >(rhs.m_samples); @@ -72,15 +68,15 @@ namespace Mantid m_height = rhs.m_height; m_width = rhs.m_width; if (m_lattice!=NULL) delete m_lattice; - if (rhs.m_lattice) + if (rhs.m_lattice) m_lattice = new OrientedLattice(rhs.getOrientedLattice()); else m_lattice = NULL; return *this; } - - /** + + /** * Returns the name of the sample * @returns The name of this sample */ @@ -89,7 +85,7 @@ namespace Mantid return m_name; } - /** + /** * Update the name of the sample * @param name :: The name of the sample */ @@ -108,22 +104,13 @@ namespace Mantid return m_shape; } - /** Set the object that describes the sample shape. It is assumed that this is defined such - * that its centre is at [0,0,0] + /** Set the object that describes the sample shape. The object is defined within + * its own coordinate system * @param shape :: The object describing the shape - * @throw An std::invalid_argument error if the object does - * not have a valid shape */ void Sample::setShape(const Object & shape) { - if( shape.hasValidShape() ) - { - m_shape = shape; - } - else - { - throw std::invalid_argument("Sample::setShape - Object has an invalid shape."); - } + m_shape = shape; } /** Return the material. @@ -131,16 +118,7 @@ namespace Mantid */ const Material & Sample::getMaterial() const { - return m_material; - } - - /** - * Set the type of material that this sample is composed from - * @param material :: A reference to the material object. It is copied into the sample. - */ - void Sample::setMaterial(const Kernel::Material& material) - { - m_material = material; + return m_shape.material(); } /** @@ -159,7 +137,7 @@ namespace Mantid /** * Attach an environment onto this sample - * @param env :: A pointer to a created sample environment. This takes + * @param env :: A pointer to a created sample environment. This takes * ownership of the object. */ void Sample::setEnvironment(SampleEnvironment * env) @@ -316,7 +294,7 @@ namespace Mantid { return m_samples.size()+1; } - + /** * Adds a sample to the sample collection @@ -340,7 +318,7 @@ namespace Mantid file->putAttr("version", 1); file->putAttr("shape_xml", m_shape.getShapeXML()); - m_material.saveNexus(file, "material"); + m_shape.material().saveNexus(file, "material"); // Write out the other (indexes 1+) samples file->writeData("num_other_samples", int(m_samples.size()) ); for (size_t i=0; i tag*/); } + Kernel::Material material; + material.loadNexus(file, "material"); + m_shape.setMaterial(material); - m_material.loadNexus(file, "material"); // Load other samples int num_other_samples; file->readData("num_other_samples", num_other_samples); diff --git a/Code/Mantid/Framework/API/src/SampleEnvironment.cpp b/Code/Mantid/Framework/API/src/SampleEnvironment.cpp index 04a1014d79a4..e797e30b9788 100644 --- a/Code/Mantid/Framework/API/src/SampleEnvironment.cpp +++ b/Code/Mantid/Framework/API/src/SampleEnvironment.cpp @@ -10,71 +10,47 @@ namespace Mantid { namespace API { - - using Geometry::IComponent; - using Geometry::IObjComponent; - using Kernel::V3D; + using Geometry::BoundingBox; using Geometry::Track; + using Kernel::Material; + using Kernel::V3D; //------------------------------------------------------------------------------ // Public methods //------------------------------------------------------------------------------ - + /** - * Constructor specifying a name for the environment + * Constructor specifying a name for the environment. It is empty by default and + * required by various other users of it * @param name :: A name for the environment kit */ - SampleEnvironment::SampleEnvironment(const std::string & name) : - CompAssembly(name, NULL) + SampleEnvironment::SampleEnvironment(const std::string & name) : + m_name(name), m_elements() { } /** - * Copy constructor - * @param original :: The object whose state is to be copied. + * @return An axis-aligned BoundingBox object that encompasses the whole kit. */ - SampleEnvironment::SampleEnvironment(const SampleEnvironment & original) : - CompAssembly(original) + Geometry::BoundingBox SampleEnvironment::boundingBox() const { + BoundingBox box; + auto itrEnd = m_elements.end(); + for(auto itr = m_elements.begin(); itr != itrEnd; ++itr) + { + box.grow(itr->getBoundingBox()); + } + return box; } /** - * Clone the environment assembly - * @returns A pointer to the clone object + * @param element A shape + material object */ - Geometry::IComponent* SampleEnvironment::clone() const + void SampleEnvironment::add(const Geometry::Object &element) { - return new SampleEnvironment(*this); - } - - /** - * Override the add method so that we can only add physical components that - * have a defined shape, i.e. an ObjComponent with a valid shape - * @param comp :: A pointer to the phyiscal component. This object will take - * ownership of the pointer - * @returns The number of items within the assembly, after this component has - * been added - */ - int SampleEnvironment::add(IComponent * comp) - { - // Check if this is a component with a shape - IObjComponent * physicalComp = dynamic_cast(comp); - if( !physicalComp ) - { - throw std::invalid_argument("CompAssembly::add - Invalid component, it must implement " - "the IObjComponent interface"); - } - if( physicalComp->shape() && physicalComp->shape()->hasValidShape() ) - { - // Accept this component - return CompAssembly::add(comp); - } - else - { - throw std::invalid_argument("CompAssembly::add - Component does not have a defined shape."); - } + m_elements.push_back(element); } - + /** * Is the point given a valid point within the environment * @param point :: Is the point valid within the environment @@ -82,36 +58,31 @@ namespace Mantid */ bool SampleEnvironment::isValid(const V3D & point) const { - const int numElements(nelements()); - for(int i = 0; i < numElements; ++i ) + auto itrEnd = m_elements.end(); + for(auto itr = m_elements.begin(); itr != itrEnd; ++itr) { - boost::shared_ptr part = boost::dynamic_pointer_cast(getChild(i)); - if( part && part->isValid(point) ) - { - return true; - } + if( itr->isValid(point) ) + { + return true; + } } return false; } - + /** - * Update the given track with intersections within the environment + * Update the given track with intersections within the environment * @param track :: The track is updated with an intersection with the * environment */ void SampleEnvironment::interceptSurfaces(Track & track) const { - const int numElements(nelements()); - for(int i = 0; i < numElements; ++i ) + auto itrEnd = m_elements.end(); + for(auto itr = m_elements.begin(); itr != itrEnd; ++itr) { - boost::shared_ptr part = boost::dynamic_pointer_cast(getChild(i)); - if( part ) - { - part->interceptSurface(track); - } - } - } - + itr->interceptSurface(track); + } + } + } } diff --git a/Code/Mantid/Framework/API/src/SampleShapeValidator.cpp b/Code/Mantid/Framework/API/src/SampleShapeValidator.cpp new file mode 100644 index 000000000000..21ef26c0e499 --- /dev/null +++ b/Code/Mantid/Framework/API/src/SampleShapeValidator.cpp @@ -0,0 +1,50 @@ +//----------------------------------------------------------------------------- +// Includes +//----------------------------------------------------------------------------- +#include "MantidAPI/SampleShapeValidator.h" +#include "MantidGeometry/Objects/Object.h" + +namespace Mantid +{ + namespace API + { + //----------------------------------------------------------------------------- + // Public methods + //----------------------------------------------------------------------------- + + /// @return A string identifier for the type of validator + std::string SampleShapeValidator::getType() const + { + return "SampleShape"; + } + + /// @return A copy of the validator as a new object + Kernel::IValidator_sptr SampleShapeValidator::clone() const + { + return boost::make_shared(); + } + + //----------------------------------------------------------------------------- + // Private methods + //----------------------------------------------------------------------------- + + /** + * Checks that the workspace has a valid sample shape defined + * @param value :: The workspace to test + * @return A user level description if a problem exists or "" + */ + std::string SampleShapeValidator::checkValidity( const boost::shared_ptr& value ) const + { + const auto & sampleShape = value->sample().getShape(); + if(sampleShape.hasValidShape()) + { + return ""; + } + else + { + return "Invalid or no shape defined for sample"; + } + } + + } // namespace API +} // namespace Mantid diff --git a/Code/Mantid/Framework/API/src/ScriptBuilder.cpp b/Code/Mantid/Framework/API/src/ScriptBuilder.cpp index 5bcad6e097a9..473109bf939f 100644 --- a/Code/Mantid/Framework/API/src/ScriptBuilder.cpp +++ b/Code/Mantid/Framework/API/src/ScriptBuilder.cpp @@ -176,10 +176,16 @@ const std::string ScriptBuilder::buildPropertyString(PropertyHistory_const_sptr { std::string value = (propHistory->value() == "1" ? "True" : "False"); prop = propHistory->name() + "=" + value; - } + } else { - prop = propHistory->name() + "='" + propHistory->value() + "'"; + std::string opener = "='"; + if (propHistory->value().find('\\') != std::string::npos ) + { + opener= "=r'"; + } + + prop = propHistory->name() + opener + propHistory->value() + "'"; } } diff --git a/Code/Mantid/Framework/API/src/WorkspaceHistory.cpp b/Code/Mantid/Framework/API/src/WorkspaceHistory.cpp index 0cc4528b5822..20ae8b904f75 100644 --- a/Code/Mantid/Framework/API/src/WorkspaceHistory.cpp +++ b/Code/Mantid/Framework/API/src/WorkspaceHistory.cpp @@ -276,11 +276,11 @@ void WorkspaceHistory::loadNexus(::NeXus::File * file) } /** Load every algorithm history object at this point in the hierarchy. - * This method will recurse over every algorithm entry in the nexus file and + * This method will recurse over every algorithm entry in the nexus file and * load both the record and its children. - * + * * @param file :: The handle to the nexus file - * @param parent :: Pointer to the parent AlgorithmHistory object. If null then loaded histories are added to + * @param parent :: Pointer to the parent AlgorithmHistory object. If null then loaded histories are added to * the workspace history. */ void WorkspaceHistory::loadNestedHistory(::NeXus::File * file, AlgorithmHistory_sptr parent) @@ -293,9 +293,9 @@ void WorkspaceHistory::loadNestedHistory(::NeXus::File * file, AlgorithmHistory_ std::string rawData; file->openGroup(entryName, "NXnote"); file->readData("data", rawData); - + try - { + { AlgorithmHistory_sptr history = parseAlgorithmHistory(rawData); loadNestedHistory(file, history); if(parent) @@ -305,7 +305,7 @@ void WorkspaceHistory::loadNestedHistory(::NeXus::File * file, AlgorithmHistory_ else { //if not parent point is supplied, assume we're at the top - //and attach the history to the workspace + //and attach the history to the workspace this->addHistory(history); } } @@ -320,7 +320,7 @@ void WorkspaceHistory::loadNestedHistory(::NeXus::File * file, AlgorithmHistory_ } -/** Find all the algorithm entries at a particular point the the nexus file +/** Find all the algorithm entries at a particular point the the nexus file * @param file :: The handle to the nexus file * @returns set of integers. One for each algorithm at the level in the file. */ @@ -431,7 +431,7 @@ AlgorithmHistory_sptr WorkspaceHistory::parseAlgorithmHistory(const std::string& unsigned int direc(Mantid::Kernel::Direction::asEnum(direction)); alg_hist.addProperty(prop_name, prop_value, (is_def[0] == 'Y'), direc); } - + AlgorithmHistory_sptr history = boost::make_shared(alg_hist); return history; } @@ -441,7 +441,7 @@ AlgorithmHistory_sptr WorkspaceHistory::parseAlgorithmHistory(const std::string& */ boost::shared_ptr WorkspaceHistory::createView() const { - return boost::make_shared(*this); + return boost::make_shared(*this); } diff --git a/Code/Mantid/Framework/API/test/HistoryViewTest.h b/Code/Mantid/Framework/API/test/HistoryViewTest.h index b0947d9be7d1..ff93c52b0a7e 100644 --- a/Code/Mantid/Framework/API/test/HistoryViewTest.h +++ b/Code/Mantid/Framework/API/test/HistoryViewTest.h @@ -7,6 +7,7 @@ using namespace Mantid::API; using namespace Mantid::Kernel; +using Mantid::Kernel::DateAndTime; class HistoryViewTest : public CxxTest::TestSuite @@ -25,45 +26,44 @@ class HistoryViewTest : public CxxTest::TestSuite void init() { - declareProperty("name","",Direction::Input); + declareProperty("name", "", Direction::Input); } + void exec() {} }; private: - AlgorithmHistory_sptr createFromTestAlg(const std::string& name ) - { + AlgorithmHistory_sptr createFromTestAlg(const std::string& name, DateAndTime execTime = DateAndTime::defaultTime()) + { testalg alg; alg.initialize(); alg.setPropertyValue("name", name); alg.execute(); - Mantid::Kernel::DateAndTime execTime = Mantid::Kernel::DateAndTime::defaultTime(); - AlgorithmHistory history(&alg, execTime, 14.0, m_execCount++); return boost::make_shared(history); } - + public: HistoryViewTest() : m_wsHist(), m_execCount(0) { //create dummy history structure - auto alg1 = createFromTestAlg("alg1"); - auto child1 = createFromTestAlg("child1"); + auto alg1 = createFromTestAlg("alg1", DateAndTime(100, 0)); + auto child1 = createFromTestAlg("child1", DateAndTime(110, 0)); alg1->addChildHistory(child1); - - auto alg2 = createFromTestAlg("alg2"); - auto child2 = createFromTestAlg("child2"); - - auto subChild21 = createFromTestAlg("subChild21"); - auto subChild22 = createFromTestAlg("subChild22"); - + + auto alg2 = createFromTestAlg("alg2", DateAndTime(200, 0)); + auto child2 = createFromTestAlg("child2", DateAndTime(210, 0)); + + auto subChild21 = createFromTestAlg("subChild21", DateAndTime(211, 0)); + auto subChild22 = createFromTestAlg("subChild22", DateAndTime(212, 0)); + child2->addChildHistory(subChild21); child2->addChildHistory(subChild22); alg2->addChildHistory(child2); - - auto alg3 = createFromTestAlg("alg3"); + + auto alg3 = createFromTestAlg("alg3", DateAndTime(300, 0)); m_wsHist.addHistory(alg1); m_wsHist.addHistory(alg2); @@ -92,7 +92,6 @@ class HistoryViewTest : public CxxTest::TestSuite auto props = history->getProperties(); TS_ASSERT_EQUALS(props[0]->value(), "alg" + boost::lexical_cast(i+1) ); } - } void test_Unroll_History() @@ -100,7 +99,7 @@ class HistoryViewTest : public CxxTest::TestSuite HistoryView view(m_wsHist); //unroll alg 2 TS_ASSERT_THROWS_NOTHING( view.unroll(0) ); - TS_ASSERT_EQUALS(view.size(), 4); + TS_ASSERT_EQUALS(view.size(), 4); auto items = view.getAlgorithmsList(); TS_ASSERT_EQUALS(items.size(), 4); @@ -110,7 +109,7 @@ class HistoryViewTest : public CxxTest::TestSuite { propNames[i] = items[i].getAlgorithmHistory()->getProperties()[0]->value(); } - + TS_ASSERT_EQUALS(propNames[0], "alg1") TS_ASSERT_EQUALS(propNames[1], "child1") TS_ASSERT_EQUALS(propNames[2], "alg2") @@ -124,7 +123,7 @@ class HistoryViewTest : public CxxTest::TestSuite //unroll alg 2 TS_ASSERT_THROWS_NOTHING( view.unroll(0) ); - + TS_ASSERT_EQUALS(view.size(), 4); auto items = view.getAlgorithmsList(); TS_ASSERT_EQUALS(items.size(), 4); @@ -134,7 +133,7 @@ class HistoryViewTest : public CxxTest::TestSuite { propNames[i] = items[i].getAlgorithmHistory()->getProperties()[0]->value(); } - + //check it unrolled properly TS_ASSERT_EQUALS(propNames[0], "alg1") TS_ASSERT_EQUALS(propNames[1], "child1") @@ -165,7 +164,7 @@ class HistoryViewTest : public CxxTest::TestSuite { //tests the case where we have multiple layers of history unrolled HistoryView view(m_wsHist); - + //unroll alg2 TS_ASSERT_THROWS_NOTHING( view.unroll(1) ); @@ -207,7 +206,7 @@ class HistoryViewTest : public CxxTest::TestSuite //now roll everything back up to the top level TS_ASSERT_THROWS_NOTHING( view.roll(1) ) - + TS_ASSERT_EQUALS(view.size(), 3); items = view.getAlgorithmsList(); TS_ASSERT_EQUALS(items.size(), 3); @@ -227,7 +226,7 @@ class HistoryViewTest : public CxxTest::TestSuite void test_Unroll_All() { HistoryView view(m_wsHist); - + TS_ASSERT_THROWS_NOTHING( view.unrollAll() ); TS_ASSERT_EQUALS(view.size(), 7); @@ -252,13 +251,13 @@ class HistoryViewTest : public CxxTest::TestSuite void test_Roll_All() { HistoryView view(m_wsHist); - + TS_ASSERT_THROWS_NOTHING( view.unrollAll() ); TS_ASSERT_EQUALS(view.size(), 7); auto items = view.getAlgorithmsList(); TS_ASSERT_EQUALS(items.size(), 7); - + std::vector propNames(items.size()); for (size_t i=0;i propNames(items.size()); + for (size_t i=0;igetProperties()[0]->value(); + } + + TS_ASSERT_EQUALS(propNames[0], "alg2") + TS_ASSERT_EQUALS(propNames[1], "child2") + TS_ASSERT_EQUALS(propNames[2], "subChild21") + } + + void test_Filter_By_Exec_Time_Start_Only() + { + HistoryView view(m_wsHist); + + // Unroll to get all algorithms + TS_ASSERT_THROWS_NOTHING( view.unrollAll() ); + TS_ASSERT_EQUALS(view.size(), 7); + + // Filter by time with a start time only + TS_ASSERT_THROWS_NOTHING( view.filterBetweenExecDate(DateAndTime(200, 0)) ); + TS_ASSERT_EQUALS(view.size(), 5); + + // Get algorithm list and compare results + auto items = view.getAlgorithmsList(); + TS_ASSERT_EQUALS(items.size(), 5); + + std::vector propNames(items.size()); + for (size_t i=0;igetProperties()[0]->value(); + } + + TS_ASSERT_EQUALS(propNames[0], "alg2") + TS_ASSERT_EQUALS(propNames[1], "child2") + TS_ASSERT_EQUALS(propNames[2], "subChild21") + TS_ASSERT_EQUALS(propNames[3], "subChild22") + TS_ASSERT_EQUALS(propNames[4], "alg3") + } + WorkspaceHistory m_wsHist; size_t m_execCount; diff --git a/Code/Mantid/Framework/API/test/MatrixWorkspaceTest.h b/Code/Mantid/Framework/API/test/MatrixWorkspaceTest.h index e7bbb7f5a1bd..d7d490e1c59c 100644 --- a/Code/Mantid/Framework/API/test/MatrixWorkspaceTest.h +++ b/Code/Mantid/Framework/API/test/MatrixWorkspaceTest.h @@ -700,6 +700,47 @@ class MatrixWorkspaceTest : public CxxTest::TestSuite TS_ASSERT_DELTA(ws.getSignalAtCoord(coords, Mantid::API::NoNormalization), 1.0, 1e-5); } + void test_getCoordAtSignal_regression() + { + /* + Having more spectrum numbers (acutally vertical axis increments) than x bins in VolumeNormalisation mode + should not cause any issues. + */ + WorkspaceTester ws; + const int nVertical = 4; + + const int nBins = 2; + const int nYValues = 1; + ws.initialize(nVertical, nBins, nYValues); + NumericAxis* verticalAxis = new NumericAxis(nVertical); + for(int i = 0; i < nVertical; ++i) + { + for(int j = 0; j < nBins; ++j) + { + if( j < nYValues ) + { + ws.dataY(i)[j] = 1.0; // All y values are 1. + ws.dataE(i)[j] = j; + } + ws.dataX(i)[j] = j; // x increments by 1 + } + verticalAxis->setValue(i, double(i)); // Vertical axis increments by 1. + } + ws.replaceAxis(1, verticalAxis); + // Signal is always 1 and volume of each box is 1. Therefore normalized signal values by volume should always be 1. + + // Test at the top right. + coord_t coord_top_right[2] = {static_cast(ws.readX(0).back()), float(0)}; + signal_t value = 0; + TS_ASSERT_THROWS_NOTHING(value = ws.getSignalAtCoord(coord_top_right, VolumeNormalization)); + TS_ASSERT_EQUALS(1.0, value); + + // Test at another location just to be sure. + coord_t coord_bottom_left[2] = {static_cast(ws.readX(nVertical-1)[1]), float(nVertical-1) }; + TS_ASSERT_THROWS_NOTHING(value = ws.getSignalAtCoord(coord_bottom_left, VolumeNormalization)); + TS_ASSERT_EQUALS(1.0, value); + } + void test_setMDMasking() { WorkspaceTester ws; @@ -800,7 +841,478 @@ class MatrixWorkspaceTest : public CxxTest::TestSuite TSM_ASSERT( "Monitor workspace not successfully reset", ! ws->monitorWorkspace() ) } + void test_getXIndex() + { + WorkspaceTester ws; + ws.init(1,4,3); + auto &X = ws.dataX(0); + X[0] = 1.0; + X[1] = 2.0; + X[2] = 3.0; + X[3] = 4.0; + + auto ip = ws.getXIndex( 0, 0.0, true ); + TS_ASSERT_EQUALS( ip.first, 0 ); + TS_ASSERT_DELTA( ip.second, 0.0, 1e-15 ); + + ip = ws.getXIndex( 0, 0.0, false ); + TS_ASSERT_EQUALS( ip.first, 4 ); + TS_ASSERT_DELTA( ip.second, 0.0, 1e-15 ); + + ip = ws.getXIndex( 0, 1.0, true ); + TS_ASSERT_EQUALS( ip.first, 0 ); + TS_ASSERT_DELTA( ip.second, 0.0, 1e-15 ); + + ip = ws.getXIndex( 0, 1.0, false ); + TS_ASSERT_EQUALS( ip.first, 4 ); + TS_ASSERT_DELTA( ip.second, 0.0, 1e-15 ); + + ip = ws.getXIndex( 0, 5.0, true ); + TS_ASSERT_EQUALS( ip.first, 4 ); + TS_ASSERT_DELTA( ip.second, 0.0, 1e-15 ); + + ip = ws.getXIndex( 0, 5.0, false ); + TS_ASSERT_EQUALS( ip.first, 3 ); + TS_ASSERT_DELTA( ip.second, 0.0, 1e-15 ); + + ip = ws.getXIndex( 0, 4.0, true ); + TS_ASSERT_EQUALS( ip.first, 4 ); + TS_ASSERT_DELTA( ip.second, 0.0, 1e-15 ); + + ip = ws.getXIndex( 0, 4.0, false ); + TS_ASSERT_EQUALS( ip.first, 3 ); + TS_ASSERT_DELTA( ip.second, 0.0, 1e-15 ); + + ip = ws.getXIndex( 0, 5.0, true, 5 ); + TS_ASSERT_EQUALS( ip.first, 4 ); + TS_ASSERT_DELTA( ip.second, 0.0, 1e-15 ); + + ip = ws.getXIndex( 0, 5.0, false, 5 ); + TS_ASSERT_EQUALS( ip.first, 4 ); + TS_ASSERT_DELTA( ip.second, 0.0, 1e-15 ); + + ip = ws.getXIndex( 0, 3.0, true, 5 ); + TS_ASSERT_EQUALS( ip.first, 4 ); + TS_ASSERT_DELTA( ip.second, 0.0, 1e-15 ); + + ip = ws.getXIndex( 0, 3.0, false, 5 ); + TS_ASSERT_EQUALS( ip.first, 4 ); + TS_ASSERT_DELTA( ip.second, 0.0, 1e-15 ); + + ip = ws.getXIndex( 0, 4.0, true, 5 ); + TS_ASSERT_EQUALS( ip.first, 4 ); + TS_ASSERT_DELTA( ip.second, 0.0, 1e-15 ); + + ip = ws.getXIndex( 0, 4.0, false, 5 ); + TS_ASSERT_EQUALS( ip.first, 4 ); + TS_ASSERT_DELTA( ip.second, 0.0, 1e-15 ); + + ip = ws.getXIndex( 0, 4.0, true, 4 ); + TS_ASSERT_EQUALS( ip.first, 4 ); + TS_ASSERT_DELTA( ip.second, 0.0, 1e-15 ); + + ip = ws.getXIndex( 0, 4.0, false, 4 ); + TS_ASSERT_EQUALS( ip.first, 4 ); + TS_ASSERT_DELTA( ip.second, 0.0, 1e-15 ); + + ip = ws.getXIndex( 0, 4.0, true, 3 ); + TS_ASSERT_EQUALS( ip.first, 4 ); + TS_ASSERT_DELTA( ip.second, 0.0, 1e-15 ); + + ip = ws.getXIndex( 0, 4.0, false, 3 ); + TS_ASSERT_EQUALS( ip.first, 3 ); + TS_ASSERT_DELTA( ip.second, 0.0, 1e-15 ); + + ip = ws.getXIndex( 0, 4.0, true ); + TS_ASSERT_EQUALS( ip.first, 4 ); + TS_ASSERT_DELTA( ip.second, 0.0, 1e-15 ); + + ip = ws.getXIndex( 0, 4.0, false ); + TS_ASSERT_EQUALS( ip.first, 3 ); + TS_ASSERT_DELTA( ip.second, 0.0, 1e-15 ); + + ip = ws.getXIndex( 0, 2.0, true, 3 ); + TS_ASSERT_EQUALS( ip.first, 4 ); + TS_ASSERT_DELTA( ip.second, 0.0, 1e-15 ); + + ip = ws.getXIndex( 0, 2.0, false, 3 ); + TS_ASSERT_EQUALS( ip.first, 3 ); + TS_ASSERT_DELTA( ip.second, 0.0, 1e-15 ); + + ip = ws.getXIndex( 0, 1.0, true, 3 ); + TS_ASSERT_EQUALS( ip.first, 4 ); + TS_ASSERT_DELTA( ip.second, 0.0, 1e-15 ); + + ip = ws.getXIndex( 0, 1.0, false, 3 ); + TS_ASSERT_EQUALS( ip.first, 3 ); + TS_ASSERT_DELTA( ip.second, 0.0, 1e-15 ); + + ip = ws.getXIndex( 0, 2.1, true ); + TS_ASSERT_EQUALS( ip.first, 1 ); + TS_ASSERT_DELTA( ip.second, 0.1, 1e-15 ); + + ip = ws.getXIndex( 0, 2.1, false ); + TS_ASSERT_EQUALS( ip.first, 2 ); + TS_ASSERT_DELTA( ip.second, 0.9, 1e-15 ); + } + + void test_getImage_0_width() + { + WorkspaceTester ws; + ws.init(9,2,1); + auto &X = ws.dataX(0); + X[0] = 1.0; + X[1] = 2.0; + const size_t start = 0; + const size_t stop = 8; + size_t width = 0; + TS_ASSERT_THROWS( ws.getImageY(start,stop,width), std::runtime_error ); + width = 3; + TS_ASSERT_THROWS_NOTHING( ws.getImageY(start,stop,width) ); + } + + void test_getImage_wrong_start() + { + WorkspaceTester ws; + ws.init(9,2,1); + auto &X = ws.dataX(0); + X[0] = 1.0; + X[1] = 2.0; + size_t start = 10; + size_t stop = 8; + size_t width = 3; + TS_ASSERT_THROWS( ws.getImageY(start,stop,width), std::runtime_error ); + start = 9; + TS_ASSERT_THROWS( ws.getImageY(start,stop,width), std::runtime_error ); + start = 0; + TS_ASSERT_THROWS_NOTHING( ws.getImageY(start,stop,width) ); + } + + void test_getImage_wrong_stop() + { + WorkspaceTester ws; + ws.init(9,2,1); + auto &X = ws.dataX(0); + X[0] = 1.0; + X[1] = 2.0; + size_t start = 0; + size_t stop = 18; + size_t width = 3; + TS_ASSERT_THROWS( ws.getImageY(start,stop,width), std::runtime_error ); + stop = 9; + TS_ASSERT_THROWS( ws.getImageY(start,stop,width), std::runtime_error ); + stop = 8; + TS_ASSERT_THROWS_NOTHING( ws.getImageY(start,stop,width) ); + } + + void test_getImage_empty_set() + { + WorkspaceTester ws; + ws.init(9,2,1); + auto &X = ws.dataX(0); + X[0] = 1.0; + X[1] = 2.0; + size_t start = 1; + size_t stop = 0; + size_t width = 1; + TS_ASSERT_THROWS( ws.getImageY(start,stop,width), std::runtime_error ); + stop = 1; + TS_ASSERT_THROWS_NOTHING( ws.getImageY(start,stop,width) ); + } + + void test_getImage_non_rectangular() + { + WorkspaceTester ws; + ws.init(9,2,1); + auto &X = ws.dataX(0); + X[0] = 1.0; + X[1] = 2.0; + size_t start = 0; + size_t stop = 7; + size_t width = 3; + TS_ASSERT_THROWS( ws.getImageY(start,stop,width), std::runtime_error ); + } + + void test_getImage_wrong_indexStart() + { + WorkspaceTester ws; + ws.init(9,2,1); + auto &X = ws.dataX(0); + X[0] = 1.0; + X[1] = 2.0; + const size_t start = 0; + const size_t stop = 8; + const size_t width = 3; + double startX = 3; + double endX = 4; + TS_ASSERT_THROWS( ws.getImageY(start,stop,width,startX,endX), std::runtime_error ); + + WorkspaceTester wsh; + wsh.init(9,1,1); + startX = 2; + endX = 2; + TS_ASSERT_THROWS( wsh.getImageY(start,stop,width,startX,endX), std::runtime_error ); + } + + void test_getImage_wrong_indexEnd() + { + WorkspaceTester ws; + ws.init(9,2,1); + auto &X = ws.dataX(0); + X[0] = 1.0; + X[1] = 2.0; + const size_t start = 0; + const size_t stop = 8; + const size_t width = 3; + double startX = 1.0; + double endX = 0.0; + TS_ASSERT_THROWS( ws.getImageY(start,stop,width,startX,endX), std::runtime_error ); + + WorkspaceTester wsh; + wsh.init(9,2,2); + auto &X1 = ws.dataX(0); + X1[0] = 1.0; + X1[1] = 2.0; + startX = 1.0; + endX = 0.0; + TS_ASSERT_THROWS( wsh.getImageY(start,stop,width,startX,endX), std::runtime_error ); + } + + void test_getImage_single_bin_histo() + { + WorkspaceTester ws; + ws.init(9,2,1); + auto &X = ws.dataX(0); + X[0] = 1.0; + X[1] = 2.0; + for(size_t i = 0; i < ws.getNumberHistograms(); ++i) + { + ws.dataY(i)[0] = static_cast( i + 1 ); + } + const size_t start = 0; + const size_t stop = 8; + const size_t width = 3; + double startX = 0; + double endX = 3; + Mantid::API::MantidImage_sptr image; + TS_ASSERT_THROWS_NOTHING( image = ws.getImageY(start,stop,width,startX,endX) ); + if ( !image ) return; + TS_ASSERT_EQUALS( image->size(), 3 ); + TS_ASSERT_EQUALS( (*image)[0].size(), 3 ); + TS_ASSERT_EQUALS( (*image)[1].size(), 3 ); + TS_ASSERT_EQUALS( (*image)[2].size(), 3 ); + + TS_ASSERT_EQUALS( (*image)[0][0], 1 ); + TS_ASSERT_EQUALS( (*image)[0][1], 2 ); + TS_ASSERT_EQUALS( (*image)[0][2], 3 ); + TS_ASSERT_EQUALS( (*image)[1][0], 4 ); + TS_ASSERT_EQUALS( (*image)[1][1], 5 ); + TS_ASSERT_EQUALS( (*image)[1][2], 6 ); + TS_ASSERT_EQUALS( (*image)[2][0], 7 ); + TS_ASSERT_EQUALS( (*image)[2][1], 8 ); + TS_ASSERT_EQUALS( (*image)[2][2], 9 ); + + } + + void test_getImage_single_bin_points() + { + WorkspaceTester ws; + ws.init(9,1,1); + auto &X = ws.dataX(0); + X[0] = 1.0; + for(size_t i = 0; i < ws.getNumberHistograms(); ++i) + { + ws.dataY(i)[0] = static_cast( i + 1 ); + } + const size_t start = 0; + const size_t stop = 8; + const size_t width = 3; + double startX = 1; + double endX = 1; + Mantid::API::MantidImage_sptr image; + TS_ASSERT_THROWS_NOTHING( image = ws.getImageY(start,stop,width,startX,endX) ); + if ( !image ) return; + TS_ASSERT_EQUALS( image->size(), 3 ); + TS_ASSERT_EQUALS( (*image)[0].size(), 3 ); + TS_ASSERT_EQUALS( (*image)[1].size(), 3 ); + TS_ASSERT_EQUALS( (*image)[2].size(), 3 ); + + TS_ASSERT_EQUALS( (*image)[0][0], 1 ); + TS_ASSERT_EQUALS( (*image)[0][1], 2 ); + TS_ASSERT_EQUALS( (*image)[0][2], 3 ); + TS_ASSERT_EQUALS( (*image)[1][0], 4 ); + TS_ASSERT_EQUALS( (*image)[1][1], 5 ); + TS_ASSERT_EQUALS( (*image)[1][2], 6 ); + TS_ASSERT_EQUALS( (*image)[2][0], 7 ); + TS_ASSERT_EQUALS( (*image)[2][1], 8 ); + TS_ASSERT_EQUALS( (*image)[2][2], 9 ); + + } + + void test_getImage_multi_bin_histo() + { + WorkspaceTester ws; + ws.init(9,4,3); + auto &X = ws.dataX(0); + X[0] = 1.0; + X[1] = 2.0; + X[2] = 3.0; + X[3] = 4.0; + for(size_t i = 0; i < ws.getNumberHistograms(); ++i) + { + ws.dataY(i)[0] = static_cast( i + 1 ); + ws.dataY(i)[1] = static_cast( i + 2 ); + ws.dataY(i)[2] = static_cast( i + 3 ); + } + const size_t start = 0; + const size_t stop = 8; + const size_t width = 3; + Mantid::API::MantidImage_sptr image; + TS_ASSERT_THROWS_NOTHING( image = ws.getImageY(start,stop,width) ); + if ( !image ) return; + TS_ASSERT_EQUALS( image->size(), 3 ); + TS_ASSERT_EQUALS( (*image)[0].size(), 3 ); + TS_ASSERT_EQUALS( (*image)[1].size(), 3 ); + TS_ASSERT_EQUALS( (*image)[2].size(), 3 ); + + TS_ASSERT_EQUALS( (*image)[0][0], 6 ); + TS_ASSERT_EQUALS( (*image)[0][1], 9 ); + TS_ASSERT_EQUALS( (*image)[0][2], 12 ); + TS_ASSERT_EQUALS( (*image)[1][0], 15 ); + TS_ASSERT_EQUALS( (*image)[1][1], 18 ); + TS_ASSERT_EQUALS( (*image)[1][2], 21 ); + TS_ASSERT_EQUALS( (*image)[2][0], 24 ); + TS_ASSERT_EQUALS( (*image)[2][1], 27 ); + TS_ASSERT_EQUALS( (*image)[2][2], 30 ); + + } + + void test_getImage_multi_bin_points() + { + WorkspaceTester ws; + ws.init(9,3,3); + auto &X = ws.dataX(0); + X[0] = 1.0; + X[1] = 2.0; + X[2] = 3.0; + for(size_t i = 0; i < ws.getNumberHistograms(); ++i) + { + ws.dataY(i)[0] = static_cast( i + 1 ); + ws.dataY(i)[1] = static_cast( i + 2 ); + ws.dataY(i)[2] = static_cast( i + 3 ); + } + const size_t start = 0; + const size_t stop = 8; + const size_t width = 3; + Mantid::API::MantidImage_sptr image; + TS_ASSERT_THROWS_NOTHING( image = ws.getImageY(start,stop,width) ); + if ( !image ) return; + TS_ASSERT_EQUALS( image->size(), 3 ); + TS_ASSERT_EQUALS( (*image)[0].size(), 3 ); + TS_ASSERT_EQUALS( (*image)[1].size(), 3 ); + TS_ASSERT_EQUALS( (*image)[2].size(), 3 ); + + TS_ASSERT_EQUALS( (*image)[0][0], 6 ); + TS_ASSERT_EQUALS( (*image)[0][1], 9 ); + TS_ASSERT_EQUALS( (*image)[0][2], 12 ); + TS_ASSERT_EQUALS( (*image)[1][0], 15 ); + TS_ASSERT_EQUALS( (*image)[1][1], 18 ); + TS_ASSERT_EQUALS( (*image)[1][2], 21 ); + TS_ASSERT_EQUALS( (*image)[2][0], 24 ); + TS_ASSERT_EQUALS( (*image)[2][1], 27 ); + TS_ASSERT_EQUALS( (*image)[2][2], 30 ); + + } + + void test_setImage_too_large() + { + auto image = createImage(2,3); + WorkspaceTester ws; + ws.init(2,2,1); + TS_ASSERT_THROWS( ws.setImageY( *image ), std::runtime_error ); + } + + void test_setImage_not_single_bin() + { + auto image = createImage(2,3); + WorkspaceTester ws; + ws.init(20,3,2); + TS_ASSERT_THROWS( ws.setImageY( *image ), std::runtime_error ); + } + + void test_setImageY() + { + auto image = createImage(2,3); + WorkspaceTester ws; + ws.init(6,2,1); + TS_ASSERT_THROWS_NOTHING( ws.setImageY( *image ) ); + TS_ASSERT_EQUALS( ws.readY(0)[0], 1 ); + TS_ASSERT_EQUALS( ws.readY(1)[0], 2 ); + TS_ASSERT_EQUALS( ws.readY(2)[0], 3 ); + TS_ASSERT_EQUALS( ws.readY(3)[0], 4 ); + TS_ASSERT_EQUALS( ws.readY(4)[0], 5 ); + TS_ASSERT_EQUALS( ws.readY(5)[0], 6 ); + } + + void test_setImageE() + { + auto image = createImage(2,3); + WorkspaceTester ws; + ws.init(6,2,1); + TS_ASSERT_THROWS_NOTHING( ws.setImageE( *image ) ); + TS_ASSERT_EQUALS( ws.readE(0)[0], 1 ); + TS_ASSERT_EQUALS( ws.readE(1)[0], 2 ); + TS_ASSERT_EQUALS( ws.readE(2)[0], 3 ); + TS_ASSERT_EQUALS( ws.readE(3)[0], 4 ); + TS_ASSERT_EQUALS( ws.readE(4)[0], 5 ); + TS_ASSERT_EQUALS( ws.readE(5)[0], 6 ); + } + + void test_setImageY_start() + { + auto image = createImage(2,3); + WorkspaceTester ws; + ws.init(9,2,1); + TS_ASSERT_THROWS_NOTHING( ws.setImageY( *image, 3 ) ); + TS_ASSERT_EQUALS( ws.readY(3)[0], 1 ); + TS_ASSERT_EQUALS( ws.readY(4)[0], 2 ); + TS_ASSERT_EQUALS( ws.readY(5)[0], 3 ); + TS_ASSERT_EQUALS( ws.readY(6)[0], 4 ); + TS_ASSERT_EQUALS( ws.readY(7)[0], 5 ); + TS_ASSERT_EQUALS( ws.readY(8)[0], 6 ); + } + + void test_setImageE_start() + { + auto image = createImage(2,3); + WorkspaceTester ws; + ws.init(9,2,1); + TS_ASSERT_THROWS_NOTHING( ws.setImageE( *image, 2 ) ); + TS_ASSERT_EQUALS( ws.readE(2)[0], 1 ); + TS_ASSERT_EQUALS( ws.readE(3)[0], 2 ); + TS_ASSERT_EQUALS( ws.readE(4)[0], 3 ); + TS_ASSERT_EQUALS( ws.readE(5)[0], 4 ); + TS_ASSERT_EQUALS( ws.readE(6)[0], 5 ); + TS_ASSERT_EQUALS( ws.readE(7)[0], 6 ); + } + private: + + Mantid::API::MantidImage_sptr createImage(size_t width, size_t height) + { + auto image = new Mantid::API::MantidImage(height); + double value = 1.0; + for(auto row = image->begin(); row != image->end(); ++row) + { + row->resize( width ); + for(auto pixel = row->begin(); pixel != row->end(); ++pixel, value += 1.0) + { + *pixel = value; + } + } + return Mantid::API::MantidImage_sptr( image ); + } + boost::shared_ptr ws; }; diff --git a/Code/Mantid/Framework/API/test/SampleEnvironmentTest.h b/Code/Mantid/Framework/API/test/SampleEnvironmentTest.h index c4dd8bb0ce5d..2b8806e2cbdd 100644 --- a/Code/Mantid/Framework/API/test/SampleEnvironmentTest.h +++ b/Code/Mantid/Framework/API/test/SampleEnvironmentTest.h @@ -2,76 +2,96 @@ #define TESTSAMPLEENVIRONMENT_H_ #include "MantidAPI/SampleEnvironment.h" -#include "MantidGeometry/Instrument/Component.h" -#include "MantidGeometry/Instrument/ObjComponent.h" -#include "MantidGeometry/Objects/Object.h" -#include "MantidGeometry/Objects/ShapeFactory.h" -#include "MantidKernel/NeutronAtom.h" #include "MantidKernel/V3D.h" +#include "MantidTestHelpers/ComponentCreationHelper.h" + +#include #include + using Mantid::API::SampleEnvironment; -using namespace Mantid::PhysicalConstants; -using namespace Mantid::Geometry; -using namespace Mantid::Kernel; class SampleEnvironmentTest : public CxxTest::TestSuite { - public: - - void test_That_Constructor_Giving_Name_Creates_The_Correct_Name() + // This pair of boilerplate methods prevent the suite being created statically + // This means the constructor isn't called when running other tests + static SampleEnvironmentTest *createSuite() { return new SampleEnvironmentTest(); } + static void destroySuite( SampleEnvironmentTest *suite ) { delete suite; } + + void testThatConstructorGivingNameCreatesTheCorrectName() { SampleEnvironment kit("TestKit"); - TS_ASSERT_EQUALS(kit.getName(), "TestKit"); + TS_ASSERT_EQUALS(kit.name(), "TestKit"); } - void test_That_Type_Is_SampleEnvironment() + void testAddingElementIncreasesSizeByOne() { - SampleEnvironment kit("kit1"); - TS_ASSERT_EQUALS(kit.type(), "SampleEnvironment"); + using namespace Mantid::Geometry; + using namespace Mantid::Kernel; + SampleEnvironment kit("TestKit"); + + TS_ASSERT_EQUALS(0, kit.nelements()); + auto shape = ComponentCreationHelper::createSphere(1.0); + TS_ASSERT_THROWS_NOTHING(kit.add(*shape)); + TS_ASSERT_EQUALS(1, kit.nelements()); + + TS_ASSERT_THROWS_NOTHING(kit.add(*shape)); + TS_ASSERT_EQUALS(2, kit.nelements()); } - void test_That_Adding_A_Component_Without_A_Shape_Throws_Invalid_Argument() + void testIsValidTestsAllElements() { - Component part("part"); - SampleEnvironment kit("TestKit"); - TS_ASSERT_THROWS(kit.add(&part), std::invalid_argument); - } + using namespace Mantid::Geometry; + using namespace Mantid::Kernel; + auto kit = createTestKit(); - //-------------------------------------------------------------------------------------------- - Object_sptr createCappedCylinder(double radius, double height, const V3D & baseCentre, const V3D & axis, const std::string & id) - { - std::ostringstream xml; - xml << "" - << "" - << "" - << "" - << "" - << ""; - - ShapeFactory shapeMaker; - return shapeMaker.createShape(xml.str()); + V3D pt(0.1,0.0,0.0); //inside first, outside second + TS_ASSERT(kit->isValid(pt)); + pt = V3D(0.3,0.0,0.0); //outside first, inside second + TS_ASSERT(kit->isValid(pt)); } - ObjComponent * createSingleObjectComponent() + + void testTrackIntersectionTestsAllElements() { - Object_sptr pixelShape = createCappedCylinder(0.5, 1.5, V3D(0.0,0.0,0.0), V3D(0.,1.0,0.), "tube"); - return new ObjComponent("pixel", pixelShape); + using namespace Mantid::Geometry; + using namespace Mantid::Kernel; + + auto kit = createTestKit(); + + Track ray(V3D(), V3D(1.0,0.0,0.0)); + TS_ASSERT_THROWS_NOTHING(kit->interceptSurfaces(ray)); + TS_ASSERT_EQUALS(2, ray.count()); } - void test_That_Adding_Valid_Components_Gives_The_Correct_Number_Of_Elements_In_The_Environment() + void testBoundingBoxEncompassesWholeObject() { - ObjComponent *physicalObject = createSingleObjectComponent(); - SampleEnvironment kit("TestKit"); - - int numElements(0); - TS_ASSERT_THROWS_NOTHING(numElements = kit.add(physicalObject)); - TS_ASSERT_EQUALS(numElements, 1); + using namespace Mantid::Geometry; + using namespace Mantid::Kernel; + + auto kit = createTestKit(); + auto bbox = kit->boundingBox(); + + auto widths = bbox.width(); + TS_ASSERT_DELTA(0.45, widths.X(), 1e-12); + TS_ASSERT_DELTA(0.2, widths.Y(), 1e-12); + TS_ASSERT_DELTA(0.2, widths.Z(), 1e-12); } +private: + + boost::shared_ptr createTestKit() + { + using namespace Mantid::Geometry; + using namespace Mantid::Kernel; + auto kit = boost::make_shared("TestKit"); + kit->add(*ComponentCreationHelper::createSphere(0.1)); //origin + kit->add(*ComponentCreationHelper::createSphere(0.1, V3D(0.25,0.0,0.0))); //shifted in +x + return kit; + } }; diff --git a/Code/Mantid/Framework/API/test/SampleShapeValidatorTest.h b/Code/Mantid/Framework/API/test/SampleShapeValidatorTest.h new file mode 100644 index 000000000000..e61bcef54ef4 --- /dev/null +++ b/Code/Mantid/Framework/API/test/SampleShapeValidatorTest.h @@ -0,0 +1,46 @@ +#ifndef MANTID_API_SAMPLESHAPEVALIDATORTEST_H_ +#define MANTID_API_SAMPLESHAPEVALIDATORTEST_H_ + +#include + +#include "MantidAPI/SampleShapeValidator.h" +#include "MantidTestHelpers/ComponentCreationHelper.h" +#include "MantidTestHelpers/FakeObjects.h" + +#include "boost/make_shared.hpp" + +using Mantid::API::SampleShapeValidator; + +class SampleShapeValidatorTest : 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 SampleShapeValidatorTest *createSuite() { return new SampleShapeValidatorTest(); } + static void destroySuite( SampleShapeValidatorTest *suite ) { delete suite; } + + void test_validator_passes_for_workspace_with_defined_sample_shape() + { + auto fakeWS = boost::make_shared(); + // Add a sample shape + auto sphere = ComponentCreationHelper::createSphere(1.0, V3D(), "sphere"); + fakeWS->mutableSample().setShape(*sphere); + + auto sampleValidator = boost::make_shared(); + TS_ASSERT_EQUALS( sampleValidator->isValid(fakeWS), "" ); + } + + void test_validator_throws_error_for_workspace_without_shape() + { + auto fakeWS = boost::make_shared(); + + auto sampleValidator = boost::make_shared(); + TS_ASSERT_EQUALS( sampleValidator->isValid(fakeWS), + "Invalid or no shape defined for sample" ); + } + + +}; + + +#endif /* MANTID_API_SAMPLESHAPEVALIDATORTEST_H_ */ diff --git a/Code/Mantid/Framework/API/test/SampleTest.h b/Code/Mantid/Framework/API/test/SampleTest.h index ea38133089d0..7e6de0f0a656 100644 --- a/Code/Mantid/Framework/API/test/SampleTest.h +++ b/Code/Mantid/Framework/API/test/SampleTest.h @@ -4,13 +4,12 @@ #include "MantidAPI/Sample.h" #include "MantidAPI/SampleEnvironment.h" #include "MantidGeometry/Crystal/OrientedLattice.h" -#include "MantidGeometry/Instrument/ObjComponent.h" -#include "MantidGeometry/Objects/Object.h" -#include "MantidGeometry/Objects/ShapeFactory.h" #include "MantidKernel/Exception.h" -#include +#include "MantidTestHelpers/ComponentCreationHelper.h" #include "MantidTestHelpers/NexusTestHelper.h" +#include + using namespace Mantid; using namespace Mantid::Kernel; using namespace Mantid::Geometry; @@ -29,39 +28,23 @@ class SampleTest : public CxxTest::TestSuite } //-------------------------------------------------------------------------------------------- - Object_sptr createCappedCylinder(double radius, double height, const V3D & baseCentre, const V3D & axis, const std::string & id) - { - std::ostringstream xml; - xml << "" - << "" - << "" - << "" - << "" << ""; - ShapeFactory shapeMaker; - return shapeMaker.createShape(xml.str()); - } - ObjComponent * createSingleObjectComponent() - { - Object_sptr pixelShape = createCappedCylinder(0.5, 1.5, V3D(0.0,0.0,0.0), V3D(0.,1.0,0.), "tube"); - return new ObjComponent("pixel", pixelShape); - } void testShape() { - Object_sptr shape_sptr = - createCappedCylinder(0.0127, 1.0, V3D(), V3D(0.0, 1.0, 0.0), "cyl"); + Object_sptr shape_sptr = \ + ComponentCreationHelper::createCappedCylinder(0.0127, 1.0, V3D(), V3D(0.0, 1.0, 0.0), "cyl"); Sample sample; TS_ASSERT_THROWS_NOTHING(sample.setShape(*shape_sptr)) const Object & sampleShape = sample.getShape(); TS_ASSERT_EQUALS(shape_sptr->getName(), sampleShape.getName()); } - void test_That_An_Setting_An_Invalid_Shape_Throws_An_Invalid_Argument() + void test_Setting_Default_Shape_Is_Accepted() { Sample sample; Object object; TS_ASSERT_EQUALS(object.hasValidShape(), false); - TS_ASSERT_THROWS(sample.setShape(object), std::invalid_argument); + TS_ASSERT_THROWS_NOTHING(sample.setShape(object)); } void test_That_Requests_For_An_Undefined_Environment_Throw() @@ -75,14 +58,14 @@ class SampleTest : public CxxTest::TestSuite Sample sample; const std::string envName("TestKit"); SampleEnvironment *kit = new SampleEnvironment(envName); - kit->add(createSingleObjectComponent()); - + kit->add(Object()); + TS_ASSERT_THROWS_NOTHING(sample.setEnvironment(kit)); - + const SampleEnvironment & sampleKit = sample.getEnvironment(); // Test that this references the correct object TS_ASSERT_EQUALS(&sampleKit, kit); - TS_ASSERT_EQUALS(sampleKit.getName(), envName); + TS_ASSERT_EQUALS(sampleKit.name(), envName); TS_ASSERT_EQUALS(sampleKit.nelements(), 1); } @@ -229,7 +212,9 @@ class SampleTest : public CxxTest::TestSuite { Material vanBlock("vanBlock", Mantid::PhysicalConstants::getNeutronAtom(23, 0), 0.072); Sample sample; - sample.setMaterial(vanBlock); + Object shape; + shape.setMaterial(vanBlock); + sample.setShape(shape); const Material& mat = sample.getMaterial(); const double lambda(2.1); @@ -261,7 +246,7 @@ class SampleTest : public CxxTest::TestSuite sample.setName("test name for test_Multiple_Sample"); boost::shared_ptr sample2 = boost::shared_ptr(new Sample()); sample2->setName("test name for test_Multiple_Sample - 2"); - + TS_ASSERT_EQUALS(sample.size(),1); sample.addSample(sample2); TS_ASSERT_EQUALS(sample.size(),2); @@ -274,7 +259,7 @@ class SampleTest : public CxxTest::TestSuite TS_ASSERT(sample[1].getName()==sample2->getName()); TS_ASSERT(sample[2].getName()==sample2->getName()); ); - + TS_ASSERT_THROWS_ANYTHING(Sample& sampleRef = sample[3]; (void) sampleRef; ); } @@ -283,7 +268,8 @@ class SampleTest : public CxxTest::TestSuite NexusTestHelper th(true); th.createFile("SampleTest.nxs"); - Object_sptr shape_sptr = createCappedCylinder(0.0127, 1.0, V3D(), V3D(0.0, 1.0, 0.0), "cyl"); + Object_sptr shape_sptr = \ + ComponentCreationHelper::createCappedCylinder(0.0127, 1.0, V3D(), V3D(0.0, 1.0, 0.0), "cyl"); Sample sample; sample.setShape(*shape_sptr); sample.setName("NameOfASample"); @@ -316,7 +302,7 @@ class SampleTest : public CxxTest::TestSuite } - + }; #endif /*TESTSAMPLE_H_*/ diff --git a/Code/Mantid/Framework/API/test/ScriptBuilderTest.h b/Code/Mantid/Framework/API/test/ScriptBuilderTest.h index 2910000861ac..8bd1da860939 100644 --- a/Code/Mantid/Framework/API/test/ScriptBuilderTest.h +++ b/Code/Mantid/Framework/API/test/ScriptBuilderTest.h @@ -305,6 +305,42 @@ class ScriptBuilderTest : public CxxTest::TestSuite AnalysisDataService::Instance().remove("test_input_workspace"); } + + void test_Build_Simple_with_backslash() + { + //checks that property values with \ get prefixed with r, eg. filename=r'c:\test\data.txt' + std::string result[] = { + "TopLevelAlgorithm(InputWorkspace=r'test_inp\\ut_workspace', OutputWorkspace='test_output_workspace')", + "" + }; + boost::shared_ptr input(new WorkspaceTester()); + AnalysisDataService::Instance().addOrReplace("test_inp\\ut_workspace", input); + + auto alg = AlgorithmFactory::Instance().create("TopLevelAlgorithm", 1); + alg->initialize(); + alg->setRethrows(true); + alg->setProperty("InputWorkspace", input); + alg->setPropertyValue("OutputWorkspace", "test_output_workspace"); + alg->execute(); + + auto ws = AnalysisDataService::Instance().retrieveWS("test_output_workspace"); + auto wsHist = ws->getHistory(); + + ScriptBuilder builder(wsHist.createView()); + std::string scriptText = builder.build(); + + std::vector scriptLines; + boost::split(scriptLines, scriptText, boost::is_any_of("\n")); + + int i=0; + for (auto it = scriptLines.begin(); it != scriptLines.end(); ++it, ++i) + { + TS_ASSERT_EQUALS(*it, result[i]) + } + + AnalysisDataService::Instance().remove("test_output_workspace"); + AnalysisDataService::Instance().remove("test_inp\\ut_workspace"); + } }; diff --git a/Code/Mantid/Framework/Algorithms/CMakeLists.txt b/Code/Mantid/Framework/Algorithms/CMakeLists.txt index 1ca9d718127b..e292a623c7f8 100644 --- a/Code/Mantid/Framework/Algorithms/CMakeLists.txt +++ b/Code/Mantid/Framework/Algorithms/CMakeLists.txt @@ -9,6 +9,7 @@ set ( SRC_FILES src/AddTimeSeriesLog.cpp src/AlignDetectors.cpp src/AlphaCalc.cpp + src/AnnularRingAbsorption.cpp src/AnyShapeAbsorption.cpp src/AppendSpectra.cpp src/ApplyCalibration.cpp @@ -53,6 +54,7 @@ set ( SRC_FILES src/CopyInstrumentParameters.cpp src/CopyLogs.cpp src/CopySample.cpp + src/CorelliCrossCorrelate.cpp src/CorrectFlightPaths.cpp src/CorrectKiKf.cpp src/CorrectToFile.cpp @@ -134,6 +136,7 @@ set ( SRC_FILES src/InterpolatingRebin.cpp src/InvertMask.cpp src/Logarithm.cpp + src/LorentzCorrection.cpp src/MaskBins.cpp src/MaskBinsFromTable.cpp src/MaskDetectorsIf.cpp @@ -221,6 +224,7 @@ set ( SRC_FILES src/SpecularReflectionPositionCorrect.cpp src/SphericalAbsorption.cpp src/Stitch1D.cpp + src/Stitch1DMany.cpp src/StripPeaks.cpp src/StripVanadiumPeaks.cpp src/StripVanadiumPeaks2.cpp @@ -238,6 +242,7 @@ set ( SRC_FILES src/WeightedMean.cpp src/WeightedMeanOfWorkspace.cpp src/WeightingStrategy.cpp + src/WienerSmooth.cpp src/WorkspaceJoiners.cpp src/XDataConverter.cpp ) @@ -253,6 +258,7 @@ set ( INC_FILES inc/MantidAlgorithms/AddTimeSeriesLog.h inc/MantidAlgorithms/AlignDetectors.h inc/MantidAlgorithms/AlphaCalc.h + inc/MantidAlgorithms/AnnularRingAbsorption.h inc/MantidAlgorithms/AnyShapeAbsorption.h inc/MantidAlgorithms/AppendSpectra.h inc/MantidAlgorithms/ApplyCalibration.h @@ -297,6 +303,7 @@ set ( INC_FILES inc/MantidAlgorithms/CopyInstrumentParameters.h inc/MantidAlgorithms/CopyLogs.h inc/MantidAlgorithms/CopySample.h + inc/MantidAlgorithms/CorelliCrossCorrelate.h inc/MantidAlgorithms/CorrectFlightPaths.h inc/MantidAlgorithms/CorrectKiKf.h inc/MantidAlgorithms/CorrectToFile.h @@ -379,6 +386,7 @@ set ( INC_FILES inc/MantidAlgorithms/InterpolatingRebin.h inc/MantidAlgorithms/InvertMask.h inc/MantidAlgorithms/Logarithm.h + inc/MantidAlgorithms/LorentzCorrection.h inc/MantidAlgorithms/MaskBins.h inc/MantidAlgorithms/MaskBinsFromTable.h inc/MantidAlgorithms/MaskDetectorsIf.h @@ -466,6 +474,7 @@ set ( INC_FILES inc/MantidAlgorithms/SpecularReflectionPositionCorrect.h inc/MantidAlgorithms/SphericalAbsorption.h inc/MantidAlgorithms/Stitch1D.h + inc/MantidAlgorithms/Stitch1DMany.h inc/MantidAlgorithms/StripPeaks.h inc/MantidAlgorithms/StripVanadiumPeaks.h inc/MantidAlgorithms/StripVanadiumPeaks2.h @@ -483,6 +492,7 @@ set ( INC_FILES inc/MantidAlgorithms/WeightedMean.h inc/MantidAlgorithms/WeightedMeanOfWorkspace.h inc/MantidAlgorithms/WeightingStrategy.h + inc/MantidAlgorithms/WienerSmooth.h inc/MantidAlgorithms/WorkspaceJoiners.h inc/MantidAlgorithms/XDataConverter.h ) @@ -509,6 +519,7 @@ set ( TEST_FILES AddTimeSeriesLogTest.h AlignDetectorsTest.h AlphaCalcTest.h + AnnularRingAbsorptionTest.h AnyShapeAbsorptionTest.h AppendSpectraTest.h ApplyCalibrationTest.h @@ -553,6 +564,7 @@ set ( TEST_FILES CopyInstrumentParametersTest.h CopyLogsTest.h CopySampleTest.h + CorelliCrossCorrelateTest.h CorrectFlightPathsTest.h CorrectKiKfTest.h CorrectToFileTest.h @@ -582,6 +594,7 @@ set ( TEST_FILES DiffractionFocussingTest.h DivideTest.h EditInstrumentGeometryTest.h + ElasticWindowTest.h EstimatePDDetectorResolutionTest.h ExponentialCorrectionTest.h ExponentialTest.h @@ -625,6 +638,7 @@ set ( TEST_FILES InterpolatingRebinTest.h InvertMaskTest.h LogarithmTest.h + LorentzCorrectionTest.h MaskBinsFromTableTest.h MaskBinsTest.h MaxMinTest.h @@ -714,6 +728,7 @@ set ( TEST_FILES WeightedMeanOfWorkspaceTest.h WeightedMeanTest.h WeightingStrategyTest.h + WienerSmoothTest.h WorkspaceCreationHelperTest.h WorkspaceGroupTest.h ) diff --git a/Code/Mantid/Framework/Algorithms/inc/MantidAlgorithms/AnnularRingAbsorption.h b/Code/Mantid/Framework/Algorithms/inc/MantidAlgorithms/AnnularRingAbsorption.h new file mode 100644 index 000000000000..920c2da51b75 --- /dev/null +++ b/Code/Mantid/Framework/Algorithms/inc/MantidAlgorithms/AnnularRingAbsorption.h @@ -0,0 +1,76 @@ +#ifndef MANTID_ALGORITHMS_ANNULARRINGABSORPTION_H_ +#define MANTID_ALGORITHMS_ANNULARRINGABSORPTION_H_ + +#include "MantidAPI/Algorithm.h" + +namespace Mantid +{ + //----------------------------------------------------------------------------------------------- + // Forward declarations + //----------------------------------------------------------------------------------------------- + namespace Kernel + { + class Material; + class V3D; + } + namespace Geometry + { + class Object; + } + + namespace Algorithms + { + + /** + Constructs a hollow sample shape, defines material for the sample and runs the + MonteCarloAbsorption algorithm. + + Copyright © 2014 ISIS Rutherford Appleton Laboratory & NScD Oak Ridge National Laboratory + + This file is part of Mantid. + + Mantid is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + Mantid is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + + File change history is stored at: + Code Documentation is available at: + */ + class DLLExport AnnularRingAbsorption : public API::Algorithm + { + public: + AnnularRingAbsorption(); + virtual ~AnnularRingAbsorption(); + + virtual const std::string name() const; + virtual int version() const; + virtual const std::string category() const; + virtual const std::string summary() const; + + private: + void init(); + void exec(); + + void attachSample(API::MatrixWorkspace_sptr & workspace); + void runCreateSampleShape(API::MatrixWorkspace_sptr & workspace); + std::string createSampleShapeXML(const Kernel::V3D &upAxis) const; + const std::string cylinderXML(const std::string &id, const Kernel::V3D & bottomCentre, const double radius, + const Kernel::V3D & axis, const double height) const; + void runSetSampleMaterial(API::MatrixWorkspace_sptr & workspace); + API::MatrixWorkspace_sptr runMonteCarloAbsorptionCorrection(const API::MatrixWorkspace_sptr & workspace); + }; + + + } // namespace Algorithms +} // namespace Mantid + +#endif /* MANTID_ALGORITHMS_ANNULARRINGABSORPTION_H_ */ diff --git a/Code/Mantid/Framework/Algorithms/inc/MantidAlgorithms/ConvertMDHistoToMatrixWorkspace.h b/Code/Mantid/Framework/Algorithms/inc/MantidAlgorithms/ConvertMDHistoToMatrixWorkspace.h index 02dad640d15f..758603d89c5e 100644 --- a/Code/Mantid/Framework/Algorithms/inc/MantidAlgorithms/ConvertMDHistoToMatrixWorkspace.h +++ b/Code/Mantid/Framework/Algorithms/inc/MantidAlgorithms/ConvertMDHistoToMatrixWorkspace.h @@ -8,6 +8,12 @@ namespace Mantid { + +namespace API +{ + class IMDHistoWorkspace; +} + namespace Algorithms { /** Creates a single spectrum Workspace2D with X,Y, and E copied from an first non-integrated dimension of a IMDHistoWorkspace. @@ -55,7 +61,7 @@ class DLLExport ConvertMDHistoToMatrixWorkspace : public API::Algorithm virtual const std::string name() const { return "ConvertMDHistoToMatrixWorkspace";}; ///Summary of algorithms purpose - virtual const std::string summary() const {return "Creates a single spectrum Workspace2D with X,Y, and E copied from an first non-integrated dimension of a IMDHistoWorkspace.";} + virtual const std::string summary() const {return "Converts if it can a IMDHistoWorkspace to a Workspace2D.";} /// Algorithm's version virtual int version() const @@ -70,6 +76,13 @@ class DLLExport ConvertMDHistoToMatrixWorkspace : public API::Algorithm void init(); /// Execution code void exec(); + + /// Make MatrixWorkspace with 1 spectrum + void make1DWorkspace(); + /// Make 2D MatrixWorkspace + void make2DWorkspace(); + /// Calculate the stride for a dimension + size_t calcStride(const API::IMDHistoWorkspace& workspace, size_t dim) const; }; } // namespace Algorithms diff --git a/Code/Mantid/Framework/Algorithms/inc/MantidAlgorithms/CorelliCrossCorrelate.h b/Code/Mantid/Framework/Algorithms/inc/MantidAlgorithms/CorelliCrossCorrelate.h new file mode 100644 index 000000000000..af9975c5aa99 --- /dev/null +++ b/Code/Mantid/Framework/Algorithms/inc/MantidAlgorithms/CorelliCrossCorrelate.h @@ -0,0 +1,59 @@ +#ifndef MANTID_ALGORITHMS_CORELLICROSSCORRELATE_H_ +#define MANTID_ALGORITHMS_CORELLICROSSCORRELATE_H_ + +#include "MantidKernel/System.h" +#include "MantidAPI/Algorithm.h" +#include "MantidDataObjects/EventWorkspace.h" + +namespace Mantid { +namespace Algorithms { + +/** CorelliCrossCorrelate : TODO: DESCRIPTION + + Copyright © 2014 ISIS Rutherford Appleton Laboratory & NScD Oak Ridge + National Laboratory + + This file is part of Mantid. + + Mantid is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + Mantid is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + + File change history is stored at: + Code Documentation is available at: +*/ +class DLLExport CorelliCrossCorrelate : public API::Algorithm { +public: + CorelliCrossCorrelate(); + virtual ~CorelliCrossCorrelate(); + + virtual const std::string name() const { return "CorelliCrossCorrelate"; }; + virtual int version() const { return 1; }; + virtual const std::string category() const { return "Diffraction;Events"; }; + virtual const std::string summary() const { + return "Cross-correlation calculation for the elastic signal from Corelli."; + }; + +private: + std::map validateInputs(); + void init(); + void exec(); + + /// Input workspace + DataObjects::EventWorkspace_const_sptr inputWS; + DataObjects::EventWorkspace_sptr outputWS; +}; + +} // namespace Algorithms +} // namespace Mantid + +#endif /* MANTID_ALGORITHMS_CORELLICROSSCORRELATE_H_ */ diff --git a/Code/Mantid/Framework/Algorithms/inc/MantidAlgorithms/CreateWorkspace.h b/Code/Mantid/Framework/Algorithms/inc/MantidAlgorithms/CreateWorkspace.h index 3c53ca2d1550..73a3b495488d 100644 --- a/Code/Mantid/Framework/Algorithms/inc/MantidAlgorithms/CreateWorkspace.h +++ b/Code/Mantid/Framework/Algorithms/inc/MantidAlgorithms/CreateWorkspace.h @@ -57,6 +57,8 @@ class DLLExport CreateWorkspace : public API::Algorithm virtual const std::string category() const { return "Utility\\Workspaces"; } ///< @return the algorithms category virtual int version() const { return (1); } ///< @return version number of algorithm + virtual std::map validateInputs(); + private: /// Initialise the Algorithm (declare properties) diff --git a/Code/Mantid/Framework/Algorithms/inc/MantidAlgorithms/DiffractionFocussing2.h b/Code/Mantid/Framework/Algorithms/inc/MantidAlgorithms/DiffractionFocussing2.h index edf8124dac2e..ab30033206ae 100644 --- a/Code/Mantid/Framework/Algorithms/inc/MantidAlgorithms/DiffractionFocussing2.h +++ b/Code/Mantid/Framework/Algorithms/inc/MantidAlgorithms/DiffractionFocussing2.h @@ -9,13 +9,6 @@ #include "MantidDataObjects/GroupingWorkspace.h" #include "MantidKernel/System.h" -// To be compatible with VSC Express edition that does not have tr1 -#ifndef HAS_UNORDERED_MAP_H -#include -#else -#include -#endif - namespace Mantid { namespace Algorithms diff --git a/Code/Mantid/Framework/Algorithms/inc/MantidAlgorithms/FindPeaks.h b/Code/Mantid/Framework/Algorithms/inc/MantidAlgorithms/FindPeaks.h index e5e236ca5595..70d5c3dd4d18 100644 --- a/Code/Mantid/Framework/Algorithms/inc/MantidAlgorithms/FindPeaks.h +++ b/Code/Mantid/Framework/Algorithms/inc/MantidAlgorithms/FindPeaks.h @@ -203,6 +203,8 @@ class DLLExport FindPeaks : public API::Algorithm /// Minimum peak height double m_minHeight; + /// Minimum value of peak's observed maximum Y value + double m_leastMaxObsY; /// Start values bool m_useObsCentre; diff --git a/Code/Mantid/Framework/Algorithms/inc/MantidAlgorithms/GetDetOffsetsMultiPeaks.h b/Code/Mantid/Framework/Algorithms/inc/MantidAlgorithms/GetDetOffsetsMultiPeaks.h index bb560f12c4cb..c39fd11ab217 100644 --- a/Code/Mantid/Framework/Algorithms/inc/MantidAlgorithms/GetDetOffsetsMultiPeaks.h +++ b/Code/Mantid/Framework/Algorithms/inc/MantidAlgorithms/GetDetOffsetsMultiPeaks.h @@ -150,9 +150,10 @@ class DLLExport GetDetOffsetsMultiPeaks: public API::Algorithm std::string m_backType; /// Peak profile type std::string m_peakType; + /// Criterias for fitting peak double m_maxChiSq; double m_minPeakHeight; - + double m_leastMaxObsY; double m_maxOffset; std::vector m_peakPositions; diff --git a/Code/Mantid/Framework/Algorithms/inc/MantidAlgorithms/He3TubeEfficiency.h b/Code/Mantid/Framework/Algorithms/inc/MantidAlgorithms/He3TubeEfficiency.h index 16f855d7e0e2..436944e8ad83 100644 --- a/Code/Mantid/Framework/Algorithms/inc/MantidAlgorithms/He3TubeEfficiency.h +++ b/Code/Mantid/Framework/Algorithms/inc/MantidAlgorithms/He3TubeEfficiency.h @@ -20,12 +20,12 @@ namespace Algorithms \f] where \f$A\f$ is a dimensionless scaling factor, \f$\alpha\f$ is a constant - with units \f$(Kelvin / (metres\: \AA\: atm))\f$, \f$P\f$ is pressure in + with units \f$(Kelvin / (metres\: \mbox{\AA}\: atm))\f$, \f$P\f$ is pressure in units of \f$atm\f$, \f$L\f$ is the tube diameter in units of \f$metres\f$, \f$W\f$ is the tube thickness in units of \f$metres\f$, \f$T\f$ is the temperature in units of \f$Kelvin\f$, \f$sin(\theta)\f$ is the angle of the neutron trajectory with respect to the long axis of the He3 tube and - \f$\lambda\f$ is in units of \f$\AA\f$. + \f$\lambda\f$ is in units of \f$\mbox{\AA}\f$. @author Michael Reuter @date 30/09/2010 diff --git a/Code/Mantid/Framework/Algorithms/inc/MantidAlgorithms/LorentzCorrection.h b/Code/Mantid/Framework/Algorithms/inc/MantidAlgorithms/LorentzCorrection.h new file mode 100644 index 000000000000..fdfca91cc8a2 --- /dev/null +++ b/Code/Mantid/Framework/Algorithms/inc/MantidAlgorithms/LorentzCorrection.h @@ -0,0 +1,56 @@ +#ifndef MANTID_ALGORITHMS_LORENTZCORRECTION_H_ +#define MANTID_ALGORITHMS_LORENTZCORRECTION_H_ + +#include "MantidKernel/System.h" +#include "MantidAPI/Algorithm.h" + +namespace Mantid +{ +namespace Algorithms +{ + + /** LorentzCorrection : Algorithm Performs a lorentz correction (sin(theta)^2)/(wavelength^4) on a MatrixWorkspace in units of wavelength + + Copyright © 2014 ISIS Rutherford Appleton Laboratory & NScD Oak Ridge National Laboratory + + This file is part of Mantid. + + Mantid is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + Mantid is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + + File change history is stored at: + Code Documentation is available at: + */ + class DLLExport LorentzCorrection : public API::Algorithm + { + public: + LorentzCorrection(); + virtual ~LorentzCorrection(); + + virtual const std::string name() const; + virtual int version() const; + virtual const std::string category() const; + virtual const std::string summary() const; + + private: + void init(); + void exec(); + + + }; + + +} // namespace Algorithms +} // namespace Mantid + +#endif /* MANTID_ALGORITHMS_LORENTZCORRECTION_H_ */ \ No newline at end of file diff --git a/Code/Mantid/Framework/Algorithms/inc/MantidAlgorithms/MaskDetectorsIf.h b/Code/Mantid/Framework/Algorithms/inc/MantidAlgorithms/MaskDetectorsIf.h index 8b11d899f262..0727b6198378 100644 --- a/Code/Mantid/Framework/Algorithms/inc/MantidAlgorithms/MaskDetectorsIf.h +++ b/Code/Mantid/Framework/Algorithms/inc/MantidAlgorithms/MaskDetectorsIf.h @@ -9,11 +9,9 @@ #include // To be compatible with VSC Express edition that does not have tr1 -#ifndef HAS_UNORDERED_MAP_H -#include -#else -#include -#endif + +#include + namespace Mantid { @@ -56,8 +54,8 @@ class DLLExport MaskDetectorsIf: public API::Algorithm virtual ~MaskDetectorsIf(); /// Algorithm's name for identification overriding a virtual method virtual const std::string name() const { return "MaskDetectorsIf"; } - ///Summary of algorithms purpose - virtual const std::string summary() const {return "Adjusts the selected field for a CalFile depending on the values in the input workspace.";} + ///Summary of algorithms purpose + virtual const std::string summary() const {return "Adjusts the selected field for a CalFile depending on the values in the input workspace.";} /// Algorithm's version for identification overriding a virtual method virtual int version() const { return 1; } @@ -68,32 +66,26 @@ class DLLExport MaskDetectorsIf: public API::Algorithm /// Returns an allowed values statement to insert into decumentation std::string allowedValuesStatement( std::vector vals); -#ifndef HAS_UNORDERED_MAP_H - /// Typedef for detector to value map - typedef std::map udet2valuem; -#else // Typedef for det to value map - typedef std::tr1::unordered_map udet2valuem; -#endif - /// A map of detector numbers to mask boolean - udet2valuem umap; - /// Get the properties - void retrieveProperties(); - /// Create a new cal file - void createNewCalFile(const std::string& oldfile,const std::string& newfile); - /// The input workspace - API::MatrixWorkspace_const_sptr inputW; - /// The Value parameter - double value; - /// A comparator function - boost::function compar_f; - /// Whether select is on or off - bool select_on; - /// Overidden init - void init(); - /// Overidden exec - void exec(); - + typedef boost::unordered_map udet2valuem; + /// A map of detector numbers to mask boolean + udet2valuem umap; + /// Get the properties + void retrieveProperties(); + /// Create a new cal file + void createNewCalFile(const std::string& oldfile,const std::string& newfile); + /// The input workspace + API::MatrixWorkspace_const_sptr inputW; + /// The Value parameter + double value; + /// A comparator function + boost::function compar_f; + /// Whether select is on or off + bool select_on; + /// Overidden init + void init(); + /// Overidden exec + void exec(); }; } // namespace Algorithm diff --git a/Code/Mantid/Framework/Algorithms/inc/MantidAlgorithms/MonteCarloAbsorption.h b/Code/Mantid/Framework/Algorithms/inc/MantidAlgorithms/MonteCarloAbsorption.h index 59c2fa12f310..c5ccbaafc972 100644 --- a/Code/Mantid/Framework/Algorithms/inc/MantidAlgorithms/MonteCarloAbsorption.h +++ b/Code/Mantid/Framework/Algorithms/inc/MantidAlgorithms/MonteCarloAbsorption.h @@ -5,9 +5,10 @@ // Includes //------------------------------------------------------------------------------ #include "MantidAPI/Algorithm.h" -#include "MantidKernel/PseudoRandomNumberGenerator.h" #include "MantidGeometry/IComponent.h" +#include + namespace Mantid { namespace Geometry @@ -18,36 +19,36 @@ namespace Mantid namespace Algorithms { - /** + /** Calculates attenuation due to absorption and scattering in a sample + its environment using a weighted Monte Carlo. - + @author Martyn Gigg, Tessella plc @date 22/11/2010 Copyright © 2010 ISIS Rutherford Appleton Laboratory & NScD Oak Ridge National Laboratory - + This file is part of Mantid. - + Mantid is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. - + Mantid is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. - + You should have received a copy of the GNU General Public License along with this program. If not, see . - + File change history is stored at: Code Documentation is available at: */ class DLLExport MonteCarloAbsorption : public API::Algorithm { - + public: /// Constructor MonteCarloAbsorption(); @@ -63,41 +64,70 @@ namespace Mantid ///Summary of algorithms purpose virtual const std::string summary() const {return "Calculates attenuation due to absorption and scattering in a sample & its environment using a weighted Monte Carlo.";} - private: /// Initialize the algorithm void init(); /// Execution code void exec(); - + /// Do the simulation for the given detector and wavelength - void doSimulation(const Geometry::IDetector * const detector, - const double lambda, double & attenFactor, double & error); + void doSimulation(const Geometry::IDetector * const detector, + const double lambda, double & attenFactor, double & error); /// Randomly select the location initial point within the beam from a square /// distribution Kernel::V3D sampleBeamProfile() const; /// Select a random location within the sample + container environment Kernel::V3D selectScatterPoint() const; /// Calculate the attenuation factor for the given single scatter setup - double attenuationFactor(const Kernel::V3D & startPos, - const Kernel::V3D & scatterPoint, - const Kernel::V3D & finalPos, const double lambda); + bool attenuationFactor(const Kernel::V3D & startPos, + const Kernel::V3D & scatterPoint, + const Kernel::V3D & finalPos, + const double lambda, double &factor); /// Calculate the attenuation for a given length, material and wavelength double attenuation(const double length, const Kernel::Material& material, - const double lambda) const; + const double lambda) const; /// Check the input and throw if invalid void retrieveInput(); - /// Initialise the caches used here including setting up the random - /// number generator + /// Initialise the caches used void initCaches(); + /// Setting up the random number generator + void initRNG(); + /// Return the random number generator for the current thread + boost::mt19937 & rgen() const; + /// Checks if a given box has any corners inside the sample or container + bool boxIntersectsSample(const double xmax, const double ymax, const double zmax, + const double xmin, const double ymin, const double zmin) const; + /// Checks if the given point is inside the sample or container + bool ptIntersectsSample(const Kernel::V3D & pt) const; private: + /** @name Cached values */ + //@{ + /// The sample position + Kernel::V3D m_samplePos; + /// The source position + Kernel::V3D m_sourcePos; + /// + size_t m_numVolumeElements; + /// Object divided into little boxes + std::vector m_blocks; + + /// Half a single block width in X + double m_blkHalfX; + /// Half a single block width in Y + double m_blkHalfY; + /// Half a single block width in Z + double m_blkHalfZ; + /// Random number generator + std::vector m_rngs; + //@} + /// The input workspace API::MatrixWorkspace_sptr m_inputWS; /// The sample's shape const Geometry::Object *m_sampleShape; - /// The sample's material + /// The sample's material const Kernel::Material *m_sampleMaterial; /// The container(s) const API::SampleEnvironment *m_container; @@ -107,29 +137,6 @@ namespace Mantid int m_xStepSize; /// The number of events per point int m_numberOfEvents; - - /** @name Cached values */ - //@{ - /// The sample position - Kernel::V3D m_samplePos; - /// The source position - Kernel::V3D m_sourcePos; - /// Bounding box length - double m_bbox_length; - /// Half the bounding box length - double m_bbox_halflength; - /// Bounding box width - double m_bbox_width; - /// Half the bounding box width - double m_bbox_halfwidth; - /// Bounding box height - double m_bbox_height; - /// Bounding box height - double m_bbox_halfheight; - //@} - - /// A pointer to the random number generator - Kernel::PseudoRandomNumberGenerator *m_randGen; }; } diff --git a/Code/Mantid/Framework/Algorithms/inc/MantidAlgorithms/ReadGroupsFromFile.h b/Code/Mantid/Framework/Algorithms/inc/MantidAlgorithms/ReadGroupsFromFile.h index b9928d369868..d2f8f75326fb 100644 --- a/Code/Mantid/Framework/Algorithms/inc/MantidAlgorithms/ReadGroupsFromFile.h +++ b/Code/Mantid/Framework/Algorithms/inc/MantidAlgorithms/ReadGroupsFromFile.h @@ -5,12 +5,7 @@ // Includes //---------------------------------------------------------------------- -// To be compatible with MSVC++ Express Edition that does not have TR1 headers -#ifndef HAS_UNORDERED_MAP_H -#include -#else -#include -#endif +#include #include "MantidAPI/Algorithm.h" #include "MantidDataObjects/Workspace2D.h" @@ -77,8 +72,8 @@ class DLLExport ReadGroupsFromFile : public API::Algorithm virtual ~ReadGroupsFromFile() {} /// Algorithm's name virtual const std::string name() const { return "ReadGroupsFromFile"; } - ///Summary of algorithms purpose - virtual const std::string summary() const {return "Read a diffraction calibration file (*.cal) or an XML grouping file (*.xml) and an instrument name, and output a 2D workspace containing on the Y-axis the values of the Group each detector belongs to. This is used to visualise the grouping scheme for powder diffractometers, where a large number of detectors are grouped together. The output 2D workspace can be visualize using the show instrument method.";} + ///Summary of algorithms purpose + virtual const std::string summary() const {return "Read a diffraction calibration file (*.cal) or an XML grouping file (*.xml) and an instrument name, and output a 2D workspace containing on the Y-axis the values of the Group each detector belongs to. This is used to visualise the grouping scheme for powder diffractometers, where a large number of detectors are grouped together. The output 2D workspace can be visualize using the show instrument method.";} /// Algorithm's version virtual int version() const { return (1); } @@ -86,14 +81,9 @@ class DLLExport ReadGroupsFromFile : public API::Algorithm virtual const std::string category() const { return "Diffraction"; } private: - - /// Map containing the detector entries found in the *.cal file. The key is the udet number, the value of is a pair of . - #ifndef HAS_UNORDERED_MAP_H - typedef std::map > calmap; - #else - typedef std::tr1::unordered_map > calmap; - #endif - /// Initialisation code + /// Map containing the detector entries found in the *.cal file. The key is the udet number, the value of is a pair of . + typedef boost::unordered_map > calmap; + /// Initialisation code void init(); /// Execution code void exec(); diff --git a/Code/Mantid/Framework/Algorithms/inc/MantidAlgorithms/Stitch1DMany.h b/Code/Mantid/Framework/Algorithms/inc/MantidAlgorithms/Stitch1DMany.h new file mode 100644 index 000000000000..3ad1dd6ca3de --- /dev/null +++ b/Code/Mantid/Framework/Algorithms/inc/MantidAlgorithms/Stitch1DMany.h @@ -0,0 +1,86 @@ +#ifndef MANTID_ALGORITHMS_STITCH1DMANY_H_ +#define MANTID_ALGORITHMS_STITCH1DMANY_H_ + +#include "MantidKernel/System.h" +#include "MantidAPI/Algorithm.h" + +namespace Mantid +{ + namespace Algorithms + { + + /** Stitch1DMany : Stitches multiple Matrix Workspaces together into a single output. + + Copyright © 2014 ISIS Rutherford Appleton Laboratory & NScD Oak Ridge National Laboratory + + This file is part of Mantid. + + Mantid is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + Mantid is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + + File change history is stored at: + Code Documentation is available at: + */ + class DLLExport Stitch1DMany : public API::Algorithm + { + public: + /// Default constructor + Stitch1DMany() : m_numWorkspaces(0), m_manualScaleFactor(1.0), m_scaleRHSWorkspace(true), m_useManualScaleFactor(false) {}; + /// Destructor + virtual ~Stitch1DMany() {}; + /// Algorithm's name for identification. @see Algorithm::name + virtual const std::string name() const + { + return "Stitch1DMany"; + } + /// Algorithm's version for identification. @see Algorithm::version + virtual int version() const + { + return 1; + } + /// Algorithm's category for identification. @see Algorithm::category + virtual const std::string category() const + { + return "Reflectometry"; + } + /// Summary of algorithm's purpose + virtual const std::string summary() const + { + return "Stitches histogram matrix workspaces together"; + } + /// Validates algorithm inputs + virtual std::map validateInputs(); + private: + /// Overwrites Algorithm method. + void init(); + /// Overwrites Algorithm method. + void exec(); + + //Data + std::vector m_inputWorkspaces; + std::vector m_startOverlaps; + std::vector m_endOverlaps; + std::vector m_params; + std::vector m_scaleFactors; + Mantid::API::Workspace_sptr m_outputWorkspace; + + size_t m_numWorkspaces; + double m_manualScaleFactor; + bool m_scaleRHSWorkspace; + bool m_useManualScaleFactor; + }; + + } // namespace Algorithms +} // namespace Mantid + +#endif /* MANTID_ALGORITHMS_STITCH1DMANY_H_ */ diff --git a/Code/Mantid/Framework/Algorithms/inc/MantidAlgorithms/WienerSmooth.h b/Code/Mantid/Framework/Algorithms/inc/MantidAlgorithms/WienerSmooth.h new file mode 100644 index 000000000000..708c8afbfea3 --- /dev/null +++ b/Code/Mantid/Framework/Algorithms/inc/MantidAlgorithms/WienerSmooth.h @@ -0,0 +1,59 @@ +#ifndef MANTID_ALGORITHMS_WIENERSMOOTH_H_ +#define MANTID_ALGORITHMS_WIENERSMOOTH_H_ + +#include "MantidKernel/System.h" +#include "MantidAPI/Algorithm.h" + +namespace Mantid +{ +namespace Algorithms +{ + + /** WienerSmooth algorithm performes smoothing data in a spectrum of a matrix workspace + using the Wiener filter smoothing. + + Copyright © 2014 ISIS Rutherford Appleton Laboratory & NScD Oak Ridge National Laboratory + + This file is part of Mantid. + + Mantid is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + Mantid is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + + File change history is stored at: + Code Documentation is available at: + */ + class DLLExport WienerSmooth : public API::Algorithm + { + public: + WienerSmooth(); + virtual ~WienerSmooth(); + + virtual const std::string name() const {return "WienerSmooth";} + virtual int version() const; + virtual const std::string category() const; + virtual const std::string summary() const; + + private: + void init(); + void exec(); + + std::pair getStartEnd( const MantidVec& X, bool isHistogram ) const; + API::MatrixWorkspace_sptr copyInput(API::MatrixWorkspace_sptr inputWS, size_t wsIndex); + + }; + + +} // namespace Algorithms +} // namespace Mantid + +#endif /* MANTID_ALGORITHMS_WIENERSMOOTH_H_ */ \ No newline at end of file diff --git a/Code/Mantid/Framework/Algorithms/src/AbsorptionCorrection.cpp b/Code/Mantid/Framework/Algorithms/src/AbsorptionCorrection.cpp index 02baf20f739c..9849307926ad 100644 --- a/Code/Mantid/Framework/Algorithms/src/AbsorptionCorrection.cpp +++ b/Code/Mantid/Framework/Algorithms/src/AbsorptionCorrection.cpp @@ -225,7 +225,7 @@ void AbsorptionCorrection::retrieveBaseProperties() double sigma_atten = getProperty("AttenuationXSection"); // in barns double sigma_s = getProperty("ScatteringXSection"); // in barns double rho = getProperty("SampleNumberDensity"); // in Angstroms-3 - const Material& sampleMaterial = m_inputWS->sample().getMaterial(); + const Material& sampleMaterial = m_inputWS->sample().getShape().material(); if( sampleMaterial.totalScatterXSection(NeutronAtom::ReferenceLambda) != 0.0) { if (rho == EMPTY_DBL()) rho = sampleMaterial.numberDensity(); @@ -236,8 +236,10 @@ void AbsorptionCorrection::retrieveBaseProperties() { NeutronAtom neutron(static_cast(EMPTY_DBL()), static_cast(0), 0.0, 0.0, sigma_s, 0.0, sigma_s, sigma_atten); - Material mat("SetInAbsorptionCorrection", neutron, rho); - m_inputWS->mutableSample().setMaterial(mat); + + Object shape = m_inputWS->sample().getShape(); // copy + shape.setMaterial(Material("SetInAbsorptionCorrection", neutron, rho)); + m_inputWS->mutableSample().setShape(shape); } rho *= 100; // Needed to get the units right m_refAtten = -sigma_atten * rho / 1.798; diff --git a/Code/Mantid/Framework/Algorithms/src/AnnularRingAbsorption.cpp b/Code/Mantid/Framework/Algorithms/src/AnnularRingAbsorption.cpp new file mode 100644 index 000000000000..59681e670d7d --- /dev/null +++ b/Code/Mantid/Framework/Algorithms/src/AnnularRingAbsorption.cpp @@ -0,0 +1,287 @@ +#include "MantidAlgorithms/AnnularRingAbsorption.h" + +#include "MantidAPI/SampleEnvironment.h" +#include "MantidAPI/WorkspaceValidators.h" + +#include "MantidGeometry/Instrument/ObjComponent.h" +#include "MantidGeometry/Instrument/ReferenceFrame.h" +#include "MantidGeometry/Objects/Object.h" +#include "MantidGeometry/Objects/ShapeFactory.h" + +#include "MantidKernel/Atom.h" +#include "MantidKernel/NeutronAtom.h" +#include "MantidKernel/BoundedValidator.h" +#include "MantidKernel/Material.h" +#include "MantidKernel/MandatoryValidator.h" +#include "MantidKernel/V3D.h" + +#include +#include + +namespace Mantid +{ + namespace Algorithms + { + using namespace Mantid::API; + using Mantid::Geometry::ObjComponent; + using namespace Mantid::Kernel; + + // Register the algorithm into the AlgorithmFactory + DECLARE_ALGORITHM(AnnularRingAbsorption) + + + //---------------------------------------------------------------------------------------------- + /** Constructor + */ + AnnularRingAbsorption::AnnularRingAbsorption() + { + } + + //---------------------------------------------------------------------------------------------- + /** Destructor + */ + AnnularRingAbsorption::~AnnularRingAbsorption() + { + } + + //---------------------------------------------------------------------------------------------- + + + /// Algorithm's name for identification. @see Algorithm::version + const std::string AnnularRingAbsorption::name() const + { + return "AnnularRingAbsorption"; + } + + /// Algorithm's version for identification. @see Algorithm::version + int AnnularRingAbsorption::version() const + { + return 1; + } + + /// Algorithm's category for identification. @see Algorithm::category + const std::string AnnularRingAbsorption::category() const + { + return "CorrectionFunctions\\AbsorptionCorrections"; + } + + /// Algorithm's summary for use in the GUI and help. @see Algorithm::summary + const std::string AnnularRingAbsorption::summary() const + { + return "Calculates bin-by-bin correction factors for attenuation due to absorption " + "in a cylindrical sample in the wall of a hollow can"; + } + + //---------------------------------------------------------------------------------------------- + /** + * Initialize the algorithm's properties. + */ + void AnnularRingAbsorption::init() + { + // The input workspace must have an instrument and units of wavelength + auto wsValidator = boost::make_shared(); + wsValidator->add("Wavelength"); + wsValidator->add(); + declareProperty(new WorkspaceProperty<>("InputWorkspace","",Direction::Input, + wsValidator), + "The input workspace in units of wavelength."); + + declareProperty(new WorkspaceProperty<>("OutputWorkspace","",Direction::Output), + "The name to use for the output workspace."); + + // -- can properties -- + auto mustBePositive = boost::make_shared >(); + mustBePositive->setLower(0.0); + declareProperty("CanOuterRadius", -1.0, mustBePositive, + "The outer radius of the can in centimetres"); + declareProperty("CanInnerRadius", -1.0, mustBePositive, + "The inner radius of the can in centimetres"); + + // -- sample properties -- + declareProperty("SampleHeight", -1.0, mustBePositive, + "The height of the sample in centimetres"); + declareProperty("SampleThickness", -1.0, mustBePositive, + "The thickness of the sample in centimetres"); + auto nonEmptyString = boost::make_shared>(); + declareProperty("SampleChemicalFormula", "", + "Chemical composition of the sample material", + nonEmptyString); + declareProperty("SampleNumberDensity", -1.0, mustBePositive, + "The number density of the sample in number of formulas per cubic angstrom"); + + // -- Monte Carlo properties -- + auto positiveInt = boost::make_shared >(); + positiveInt->setLower(1); + declareProperty("NumberOfWavelengthPoints", EMPTY_INT(), positiveInt, + "The number of wavelength points for which a simulation is atttempted (default: all points)"); + declareProperty("EventsPerPoint", 300, positiveInt, + "The number of \"neutron\" events to generate per simulated point"); + declareProperty("SeedValue", 123456789, positiveInt, + "Seed the random number generator with this value"); + } + + //---------------------------------------------------------------------------------------------- + /** + * Execute the algorithm. + */ + void AnnularRingAbsorption::exec() + { + MatrixWorkspace_sptr inputWS = getProperty("InputWorkspace"); + // We neglect any absorption in the can so the actual shape defined is a hollow cylinder + // where the sample is in the centre of the can wall + attachSample(inputWS); + + MatrixWorkspace_sptr factors = runMonteCarloAbsorptionCorrection(inputWS); + setProperty("OutputWorkspace", factors); + } + + //--------------------------------------------------------------------------------------------- + // Private members + //--------------------------------------------------------------------------------------------- + + /** + * @param workspace The workspace where the environment should be attached + */ + void AnnularRingAbsorption::attachSample(MatrixWorkspace_sptr &workspace) + { + runCreateSampleShape(workspace); + runSetSampleMaterial(workspace); + } + + /** + * @return Creates a new shape object for the sample + */ + void AnnularRingAbsorption::runCreateSampleShape(API::MatrixWorkspace_sptr & workspace) + { + auto inst = workspace->getInstrument(); + auto refFrame = inst->getReferenceFrame(); + + bool childLog = g_log.is(Logger::Priority::PRIO_DEBUG); + auto alg = this->createChildAlgorithm("CreateSampleShape", -1,-1, childLog); + alg->setProperty("InputWorkspace", workspace); + alg->setPropertyValue("ShapeXML", createSampleShapeXML(refFrame->vecPointingUp())); + try + { + alg->executeAsChildAlg(); + } + catch(std::exception & exc) + { + throw std::invalid_argument(std::string("Unable to create sample shape: '") + exc.what() + "'"); + } + } + + /** + * Create the XML that defines a hollow cylinder with dimensions provided by the user + * The shape is a hollow cylinder where the inner/outer radius is defined by + * \f[ + * r_{\pm} = r_l + \frac{r_u-r_l}{2} \pm \frac{t}{2} + * \f] + * where \f$r_{l,u}\f$ are the inner & outer can radii respectively and \f$t\f$ is the sample + * thickness + * @param upAxis A vector pointing up + * @returns A string containing the shape XML + */ + std::string AnnularRingAbsorption::createSampleShapeXML(const V3D & upAxis) const + { + // User input + const double canLowRadiusCM = getProperty("CanInnerRadius"); + const double canUppRadiusCM = getProperty("CanOuterRadius"); + const double sampleHeightCM = getProperty("SampleHeight"); + const double sampleThickCM = getProperty("SampleThickness"); + // Sample dimensions for approximation (converted to metres) + const double wallMidPtCM = canLowRadiusCM + 0.5*(canUppRadiusCM - canLowRadiusCM); + const double lowRadiusMtr = (wallMidPtCM - 0.5*sampleThickCM)/100.; + const double uppRadiusMtr = (wallMidPtCM + 0.5*sampleThickCM)/100.; + + // Cylinders oriented along Y, with origin at centre of bottom base + const std::string innerCylID = std::string("inner-cyl"); + const std::string innerCyl = cylinderXML(innerCylID, V3D(), lowRadiusMtr, upAxis, + sampleHeightCM/100.0); + const std::string outerCylID = std::string("outer-cyl"); + const std::string outerCyl = cylinderXML(outerCylID, V3D(), uppRadiusMtr, upAxis, + sampleHeightCM/100.0); + + // Combine shapes + boost::format algebra(""); + algebra % outerCylID % innerCylID; + auto xml = outerCyl + "\n" + innerCyl + "\n" + algebra.str(); + g_log.debug() << "Sample shape XML:\n" << xml << "\n"; + return xml; + } + + /** + * @param id String id of object + * @param bottomCentre Point of centre of bottom base + * @param radius Radius of cylinder + * @param axis Cylinder will point along this axis + * @param height The height of the cylinder + * @return A string defining the XML + */ + const std::string AnnularRingAbsorption::cylinderXML(const std::string &id, const V3D &bottomCentre, + const double radius, const V3D &axis, + const double height) const + { + // The newline characters are not necessary for the XML but they make it easier to read for debugging + static const char * CYL_TEMPLATE = \ + "\n" + "\n" + " \n" + " \n" + " \n" + ""; + + boost::format xml(CYL_TEMPLATE); + xml % id + % bottomCentre.X() % bottomCentre.Y() % bottomCentre.Z() + % axis.X() % axis.Y() % axis.Z() + % radius % height; + return xml.str(); + } + + /** + * @return Attaches a new Material object to the sample + */ + void AnnularRingAbsorption::runSetSampleMaterial(API::MatrixWorkspace_sptr & workspace) + { + bool childLog = g_log.is(Logger::Priority::PRIO_DEBUG); + auto alg = this->createChildAlgorithm("SetSampleMaterial", -1,-1, childLog); + alg->setProperty("InputWorkspace", workspace); + alg->setProperty("ChemicalFormula", getPropertyValue("SampleChemicalFormula")); + alg->setProperty("SampleNumberDensity", getProperty("SampleNumberDensity")); + try + { + alg->executeAsChildAlg(); + } + catch(std::exception & exc) + { + throw std::invalid_argument(std::string("Unable to set sample material: '") + exc.what() + "'"); + } + } + + /** + * Run the MonteCarloAbsorption algorithm on the given workspace and return the calculated factors + * @param workspace The input workspace that has the sample and can defined + * @return A 2D workspace of attenuation factors + */ + MatrixWorkspace_sptr AnnularRingAbsorption::runMonteCarloAbsorptionCorrection(const MatrixWorkspace_sptr &workspace) + { + bool childLog = g_log.is(Logger::Priority::PRIO_DEBUG); + auto alg = this->createChildAlgorithm("MonteCarloAbsorption", 0.1,1.0, childLog); + alg->setProperty("InputWorkspace", workspace); + alg->setProperty("NumberOfWavelengthPoints", getProperty("NumberOfWavelengthPoints")); + alg->setProperty("EventsPerPoint", getProperty("EventsPerPoint")); + alg->setProperty("SeedValue", getProperty("SeedValue")); + try + { + alg->executeAsChildAlg(); + } + catch(std::exception & exc) + { + throw std::invalid_argument(std::string("Error running absorption correction: '") + exc.what() + "'"); + } + + return alg->getProperty("OutputWorkspace"); + } + + } // namespace Algorithms +} // namespace Mantid diff --git a/Code/Mantid/Framework/Algorithms/src/CheckWorkspacesMatch.cpp b/Code/Mantid/Framework/Algorithms/src/CheckWorkspacesMatch.cpp index e8267d6f02ea..f61a11c96413 100644 --- a/Code/Mantid/Framework/Algorithms/src/CheckWorkspacesMatch.cpp +++ b/Code/Mantid/Framework/Algorithms/src/CheckWorkspacesMatch.cpp @@ -488,7 +488,6 @@ bool CheckWorkspacesMatch::compareEventWorkspaces(DataObjects::EventWorkspace_co } else { - result = "Success!"; wsmatch = true; } @@ -836,27 +835,24 @@ bool CheckWorkspacesMatch::checkRunProperties(const API::Run& run1, const API::R } // Now loop over the individual logs - for ( size_t i = 0; i < ws1logs.size(); ++i ) + bool matched(true); + int64_t length(static_cast(ws1logs.size())); + PARALLEL_FOR_IF(true) + for ( int64_t i = 0; i < length; ++i ) { - // Check the log name - if ( ws1logs[i]->name() != ws2logs[i]->name() ) - { - g_log.debug() << "WS1 log " << i << " name: " << ws1logs[i]->name() << "\n"; - g_log.debug() << "WS2 log " << i << " name: " << ws2logs[i]->name() << "\n"; - result = "Log name mismatch"; - return false; - } - - // Now check the log entry itself, using the method that gives it back as a string - if ( ws1logs[i]->value() != ws2logs[i]->value() ) + PARALLEL_START_INTERUPT_REGION + if (matched) { - g_log.debug() << "WS1 log " << ws1logs[i]->name() << ": " << ws1logs[i]->value() << "\n"; - g_log.debug() << "WS2 log " << ws2logs[i]->name() << ": " << ws2logs[i]->value() << "\n"; - result = "Log value mismatch"; - return false; + if ( *(ws1logs[i]) != *(ws2logs[i])) + { + matched = false; + result = "Log mismatch"; + } } + PARALLEL_END_INTERUPT_REGION } - return true; + PARALLEL_CHECK_INTERUPT_REGION + return matched; } //------------------------------------------------------------------------------------------------ diff --git a/Code/Mantid/Framework/Algorithms/src/ConvertMDHistoToMatrixWorkspace.cpp b/Code/Mantid/Framework/Algorithms/src/ConvertMDHistoToMatrixWorkspace.cpp index 83e311fc1beb..b84c97fa82e0 100644 --- a/Code/Mantid/Framework/Algorithms/src/ConvertMDHistoToMatrixWorkspace.cpp +++ b/Code/Mantid/Framework/Algorithms/src/ConvertMDHistoToMatrixWorkspace.cpp @@ -8,6 +8,7 @@ #include "MantidKernel/MandatoryValidator.h" #include "MantidKernel/ListValidator.h" #include "MantidAPI/NullCoordTransform.h" +#include "MantidAPI/NumericAxis.h" #include #include @@ -15,7 +16,10 @@ namespace { - struct null_deleter + /** + * A shared pointer deleter that doesn't delete. + */ + struct NullDeleter { void operator()(void const *) const { // Do nothing @@ -52,11 +56,36 @@ void ConvertMDHistoToMatrixWorkspace::init() /// Execute the algorithm void ConvertMDHistoToMatrixWorkspace::exec() +{ + + IMDHistoWorkspace_sptr inputWorkspace = getProperty("InputWorkspace"); + Mantid::Geometry::VecIMDDimension_const_sptr nonIntegDims = inputWorkspace->getNonIntegratedDimensions(); + + if ( nonIntegDims.size() == 1 ) + { + make1DWorkspace(); + } + else if ( nonIntegDims.size() == 2 ) + { + make2DWorkspace(); + } + else + { + throw std::invalid_argument("Cannot convert MD workspace with more than 2 dimensions."); + } + +} + +/** + * Make 1D MatrixWorkspace + */ +void ConvertMDHistoToMatrixWorkspace::make1DWorkspace() { IMDHistoWorkspace_sptr inputWorkspace = getProperty("InputWorkspace"); // This code is copied from MantidQwtIMDWorkspaceData Mantid::Geometry::VecIMDDimension_const_sptr nonIntegDims = inputWorkspace->getNonIntegratedDimensions(); + std::string alongDim = ""; if (!nonIntegDims.empty()) alongDim = nonIntegDims[0]->getName(); @@ -117,7 +146,6 @@ void ConvertMDHistoToMatrixWorkspace::exec() inputWorkspace->getLinePlot(start, end, normalization, X, Y, E); MatrixWorkspace_sptr outputWorkspace = WorkspaceFactory::Instance().create("Workspace2D",1,X.size(),Y.size()); - //outputWorkspace->dataX(0).assign(X.begin(),X.end()); outputWorkspace->dataY(0).assign(Y.begin(),Y.end()); outputWorkspace->dataE(0).assign(E.begin(),E.end()); @@ -127,7 +155,7 @@ void ConvertMDHistoToMatrixWorkspace::exec() if(numberTransformsToOriginal > 0) { const size_t indexToLastTransform = numberTransformsToOriginal - 1 ; - transform = boost::shared_ptr(inputWorkspace->getTransformToOriginal(indexToLastTransform), null_deleter()); + transform = boost::shared_ptr(inputWorkspace->getTransformToOriginal(indexToLastTransform), NullDeleter()); } assert(X.size() == outputWorkspace->dataX(0).size()); @@ -149,8 +177,141 @@ void ConvertMDHistoToMatrixWorkspace::exec() outputWorkspace->setYUnitLabel("Signal"); setProperty("OutputWorkspace", outputWorkspace); +} + +/** + * Make 2D MatrixWorkspace + */ +void ConvertMDHistoToMatrixWorkspace::make2DWorkspace() +{ + // get the input workspace + IMDHistoWorkspace_sptr inputWorkspace = getProperty("InputWorkspace"); + + // find the non-integrated dimensions + Mantid::Geometry::VecIMDDimension_const_sptr nonIntegDims = inputWorkspace->getNonIntegratedDimensions(); + + auto xDim = nonIntegDims[0]; + auto yDim = nonIntegDims[1]; + size_t nx = xDim->getNBins(); + size_t ny = yDim->getNBins(); + + size_t xDimIndex = inputWorkspace->getDimensionIndexById(xDim->getDimensionId()); + size_t xStride = calcStride(*inputWorkspace, xDimIndex); + + size_t yDimIndex = inputWorkspace->getDimensionIndexById(yDim->getDimensionId()); + size_t yStride = calcStride(*inputWorkspace, yDimIndex); + + // get the normalization of the output + std::string normProp = getPropertyValue("Normalization"); + Mantid::API::MDNormalization normalization; + if (normProp == "NoNormalization") + { + normalization = NoNormalization; + } + else if (normProp == "VolumeNormalization") + { + normalization = VolumeNormalization; + } + else if (normProp == "NumEventsNormalization") + { + normalization = NumEventsNormalization; + } + else + { + normalization = NoNormalization; + } + signal_t inverseVolume = static_cast(inputWorkspace->getInverseVolume()); + + // create the output workspace + MatrixWorkspace_sptr outputWorkspace = WorkspaceFactory::Instance().create("Workspace2D",ny,nx+1,nx); + + // set the x-values + Mantid::MantidVec& X = outputWorkspace->dataX(0); + double dx = xDim->getBinWidth(); + double x = xDim->getMinimum(); + for(auto ix = X.begin(); ix != X.end(); ++ix, x += dx) + { + *ix = x; + } + + // set the y-values and errors + for(size_t i = 0; i < ny; ++i) + { + if ( i > 0 ) outputWorkspace->setX(i,X); + auto &Y = outputWorkspace->dataY(i); + auto &E = outputWorkspace->dataE(i); + + size_t yOffset = i * yStride; + for(size_t j = 0; j < nx; ++j) + { + size_t linearIndex = yOffset + j * xStride; + signal_t signal = inputWorkspace->getSignalArray()[linearIndex]; + signal_t error = inputWorkspace->getErrorSquaredArray()[linearIndex]; + // apply normalization + if ( normalization != NoNormalization ) + { + if ( normalization == VolumeNormalization ) + { + signal *= inverseVolume; + error *= inverseVolume; + } + else // normalization == NumEventsNormalization + { + signal_t factor = inputWorkspace->getNumEventsArray()[linearIndex]; + factor = factor != 0.0 ? 1.0 / factor : 1.0; + signal *= factor; + error *= factor; + } + } + Y[j] = signal; + E[j] = sqrt(error); + } + } + + // set the first axis + auto labelX = boost::dynamic_pointer_cast( + Kernel::UnitFactory::Instance().create("Label") + ); + labelX->setLabel(xDim->getName()); + outputWorkspace->getAxis(0)->unit() = labelX; + + // set the second axis + auto yAxis = new NumericAxis(ny); + for(size_t i = 0; i < ny; ++i) + { + yAxis->setValue(i, yDim->getX(i)); + } + auto labelY = boost::dynamic_pointer_cast( + Kernel::UnitFactory::Instance().create("Label") + ); + labelY->setLabel(yDim->getName()); + yAxis->unit() = labelY; + outputWorkspace->replaceAxis(1, yAxis); + + // set the "units" for the y values + outputWorkspace->setYUnitLabel("Signal"); + + // done + setProperty("OutputWorkspace", outputWorkspace); +} + +/** + * Calculate the stride for a dimension. + * @param workspace :: An MD workspace. + * @param dim :: A dimension index to calculate the stride for. + */ +size_t ConvertMDHistoToMatrixWorkspace::calcStride(const API::IMDHistoWorkspace& workspace, size_t dim) const +{ + size_t stride = 1; + for(size_t i = 0; i < dim; ++i) + { + auto dimension = workspace.getDimension(i); + stride *= dimension->getNBins(); + } + return stride; } + } // namespace Algorithms } // namespace Mantid diff --git a/Code/Mantid/Framework/Algorithms/src/CopySample.cpp b/Code/Mantid/Framework/Algorithms/src/CopySample.cpp index e7ee71c3b16b..9c2ce0c45fbe 100644 --- a/Code/Mantid/Framework/Algorithms/src/CopySample.cpp +++ b/Code/Mantid/Framework/Algorithms/src/CopySample.cpp @@ -137,16 +137,29 @@ namespace Algorithms void CopySample::copyParameters(Sample& from,Sample& to,bool nameFlag,bool materialFlag, bool environmentFlag, bool shapeFlag,bool latticeFlag, bool orientationOnlyFlag) { if (nameFlag) to.setName(from.getName()); - if (materialFlag) to.setMaterial(from.getMaterial()); if (environmentFlag) to.setEnvironment(new SampleEnvironment(from.getEnvironment())); if (shapeFlag) { - to.setShape(from.getShape()); + auto rhsObject = from.getShape(); //copy + const auto & lhsMaterial = to.getMaterial(); + // reset to original lhs material + if(!materialFlag) + { + rhsObject.setMaterial(lhsMaterial); + } + to.setShape(rhsObject); to.setGeometryFlag(from.getGeometryFlag()); to.setHeight(from.getHeight()); to.setThickness(from.getThickness()); to.setWidth(from.getWidth()); } + else if(materialFlag) + { + auto lhsObject = to.getShape(); //copy + lhsObject.setMaterial(from.getMaterial()); + to.setShape(lhsObject); + } + if ((latticeFlag) && from.hasOrientedLattice()) { if (to.hasOrientedLattice() && orientationOnlyFlag) diff --git a/Code/Mantid/Framework/Algorithms/src/CorelliCrossCorrelate.cpp b/Code/Mantid/Framework/Algorithms/src/CorelliCrossCorrelate.cpp new file mode 100644 index 000000000000..71ef6d998893 --- /dev/null +++ b/Code/Mantid/Framework/Algorithms/src/CorelliCrossCorrelate.cpp @@ -0,0 +1,280 @@ +#include "MantidAlgorithms/CorelliCrossCorrelate.h" +#include "MantidDataObjects/EventWorkspace.h" +#include "MantidAPI/WorkspaceValidators.h" +#include "MantidGeometry/IComponent.h" +#include "MantidKernel/MandatoryValidator.h" +#include "MantidKernel/TimeSeriesProperty.h" +#include "MantidGeometry/muParser_Silent.h" + +namespace Mantid { +namespace Algorithms { + +using namespace Kernel; +using namespace API; +using namespace Geometry; +using namespace DataObjects; + +// Register the algorithm into the AlgorithmFactory +DECLARE_ALGORITHM(CorelliCrossCorrelate) + +//---------------------------------------------------------------------------------------------- +/** Constructor + */ +CorelliCrossCorrelate::CorelliCrossCorrelate() {} + +//---------------------------------------------------------------------------------------------- +/** Destructor + */ +CorelliCrossCorrelate::~CorelliCrossCorrelate() {} + +//---------------------------------------------------------------------------------------------- +/** Initialize the algorithm's properties. + */ +void CorelliCrossCorrelate::init() { + auto wsValidator = boost::make_shared(); + wsValidator->add("TOF"); + wsValidator->add(); + + declareProperty(new WorkspaceProperty( + "InputWorkspace", "", Direction::Input, wsValidator), + "An input workspace."); + declareProperty(new WorkspaceProperty("OutputWorkspace", "", + Direction::Output), + "An output workspace."); + + declareProperty("TimingOffset", EMPTY_INT(), + boost::make_shared>(), + "Correlation chopper TDC timing offset in nanoseconds."); +} + +// Validate inputs workspace first. +std::map CorelliCrossCorrelate::validateInputs() { + std::map errors; + + inputWS = getProperty("InputWorkspace"); + + // check for null pointers - this is to protect against workspace groups + if (!inputWS) { + return errors; + } + + // This algorithm will only work for CORELLI, check for CORELLI. + if (inputWS->getInstrument()->getName() != "CORELLI") + errors["InputWorkspace"] = "This Algorithm will only work for Corelli."; + + // Must include the correlation-chopper in the IDF. + else if (!inputWS->getInstrument()->getComponentByName("correlation-chopper")) + errors["InputWorkspace"] = "Correlation chopper not found."; + + // The chopper must have a sequence parameter + else if (inputWS->getInstrument() + ->getComponentByName("correlation-chopper") + ->getStringParameter("sequence") + .empty()) + errors["InputWorkspace"] = + "Found the correlation chopper but no chopper sequence?"; + + // Check for the sample and source. + else if (!inputWS->getInstrument()->getSource() || + !inputWS->getInstrument()->getSample()) + errors["InputWorkspace"] = "Instrument not sufficiently defined: failed to " + "get source and/or sample"; + + // Must include the chopper4 TDCs. + else if (!inputWS->run().hasProperty("chopper4_TDC")) + errors["InputWorkspace"] = "Workspace is missing chopper4 TDCs."; + + // Check if input workspace is sorted. + else if (inputWS->getSortType() == UNSORTED) + errors["InputWorkspace"] = "The workspace needs to be a sorted."; + + // Check event type for pulse times + else if (inputWS->getEventType() == WEIGHTED_NOTIME) + errors["InputWorkspace"] = "This workspace has no pulse time information."; + + return errors; +} + +//---------------------------------------------------------------------------------------------- +/** Execute the algorithm. + */ +void CorelliCrossCorrelate::exec() { + inputWS = getProperty("InputWorkspace"); + outputWS = getProperty("OutputWorkspace"); + + if (outputWS != inputWS) { + // Make a brand new EventWorkspace + outputWS = boost::dynamic_pointer_cast( + API::WorkspaceFactory::Instance().create( + "EventWorkspace", inputWS->getNumberHistograms(), 2, 1)); + // Copy geometry over. + API::WorkspaceFactory::Instance().initializeFromParent(inputWS, outputWS, + false); + // You need to copy over the data as well. + outputWS->copyDataFrom((*inputWS)); + } + + // Read in chopper sequence from IDF. + // Chopper sequence, alternating between open and closed. If index%2==0 than + // absorbing else transparent. + IComponent_const_sptr chopper = + inputWS->getInstrument()->getComponentByName("correlation-chopper"); + std::vector chopperSequence = + chopper->getStringParameter("sequence"); + g_log.information("Found chopper sequence: " + chopperSequence[0]); + + std::vector chopperSequenceSplit; + boost::split(chopperSequenceSplit, chopperSequence[0], boost::is_space()); + + std::vector sequence; + sequence.resize(chopperSequenceSplit.size()); + sequence[0] = boost::lexical_cast(chopperSequenceSplit[0]); + + // Need the cumulative sum of the chopper sequence and total transparent + double totalOpen = 0; + for (unsigned int i = 1; i < chopperSequenceSplit.size(); i++) { + double seqAngle = boost::lexical_cast(chopperSequenceSplit[i]); + sequence[i] = sequence[i - 1] + seqAngle; + if (i % 2 == 1) + totalOpen += seqAngle; + } + + // Calculate the duty cycle and the event weights from the duty cycle. + double dutyCycle = totalOpen / sequence.back(); + float weightTransparent = static_cast(1.0 / dutyCycle); + float weightAbsorbing = static_cast(-1.0 / (1.0 - dutyCycle)); + g_log.information() << "dutyCycle = " << dutyCycle + << " weightTransparent = " << weightTransparent + << " weightAbsorbing = " << weightAbsorbing << "\n"; + + // Read in the TDC timings for the correlation chopper and apply the timing + // offset. + std::vector tdc = + dynamic_cast( + inputWS->run().getLogData("chopper4_TDC"))->timesAsVector(); + int offset_int = getProperty("TimingOffset"); + const int64_t offset = static_cast(offset_int); + for (unsigned long i = 0; i < tdc.size(); ++i) + tdc[i] += offset; + + // Determine period from TDC. + double period = static_cast(tdc[tdc.size() - 1].totalNanoseconds() - + tdc[1].totalNanoseconds()) / + double(tdc.size() - 2); + g_log.information() << "Frequency = " << 1e9 / period + << "Hz Period = " << period << "ns\n"; + + // Get the sample and source, calculate distances. + IComponent_const_sptr sample = inputWS->getInstrument()->getSample(); + const double distanceChopperToSource = + inputWS->getInstrument()->getSource()->getDistance(*chopper); + const double distanceSourceToSample = + inputWS->getInstrument()->getSource()->getDistance(*sample); + + // extract formula from instrument parameters + std::vector t0_formula = + inputWS->getInstrument()->getStringParameter("t0_formula"); + if (t0_formula.empty()) + throw Exception::InstrumentDefinitionError( + "Unable to retrieve t0_formula among instrument parameters"); + std::string formula = t0_formula[0]; + g_log.debug() << formula << "\n"; + + const double m_convfactor = 0.5e+12 * Mantid::PhysicalConstants::NeutronMass / + Mantid::PhysicalConstants::meV; + + // Do the cross correlation. + int64_t numHistograms = static_cast(inputWS->getNumberHistograms()); + g_log.notice("Start cross-correlation\n"); + API::Progress prog = API::Progress(this, 0.0, 1.0, numHistograms); + PARALLEL_FOR1(outputWS) + for (int64_t i = 0; i < numHistograms; ++i) { + PARALLEL_START_INTERUPT_REGION + + EventList *evlist = outputWS->getEventListPtr(i); + IDetector_const_sptr detector = inputWS->getDetector(i); + + switch (evlist->getEventType()) { + case TOF: + // Switch to weights if needed. + evlist->switchTo(WEIGHTED); + /* no break */ + // Fall through + case WEIGHTED: + break; + case WEIGHTED_NOTIME: + // Should never get here + throw std::runtime_error( + "This event list has no pulse time information."); + break; + } + + std::vector &events = evlist->getWeightedEvents(); + + // Skip if empty. + if (events.empty()) + continue; + + // Check for duplicate pulse problem in Corelli. + DateAndTime emptyTime; + if (events.back().pulseTime() == emptyTime) + throw std::runtime_error( + "Missing pulse times on events. This will not work."); + + // Scale for elastic scattering. + double distanceSourceToDetector = + distanceSourceToSample + detector->getDistance(*sample); + double tofScale = distanceChopperToSource / distanceSourceToDetector; + + double E1; + mu::Parser parser; + parser.DefineVar("incidentEnergy", + &E1); // associate variable E1 to this parser + parser.SetExpr(formula); + + uint64_t tdc_i = 0; + std::vector::iterator it; + for (it = events.begin(); it != events.end(); ++it) { + double tof = it->tof(); + E1 = m_convfactor * (distanceSourceToDetector / tof) * + (distanceSourceToDetector / tof); + double t0 = parser.Eval(); + + DateAndTime tofTime = + it->pulseTime() + + static_cast(((tof - t0) * tofScale + t0) * 1000.); + while (tdc_i != tdc.size() && tofTime > tdc[tdc_i]) + tdc_i += 1; + + double angle = 360. * + static_cast(tofTime.totalNanoseconds() - + tdc[tdc_i - 1].totalNanoseconds()) / + period; + + std::vector::iterator location; + location = std::lower_bound(sequence.begin(), sequence.end(), angle); + + if ((location - sequence.begin()) % 2 == 0) { + it->m_weight *= weightAbsorbing; + it->m_errorSquared *= weightAbsorbing * weightAbsorbing; + } else { + it->m_weight *= weightTransparent; + it->m_errorSquared *= weightTransparent * weightTransparent; + } + } + + // Warn if the tdc signal has stopped during the run + if ((events.back().pulseTime() + + static_cast(events.back().tof() * 1000.)) > + (tdc.back() + static_cast(period * 2))) + g_log.warning("Events occurred long after last TDC."); + + prog.report(); + PARALLEL_END_INTERUPT_REGION + } + PARALLEL_CHECK_INTERUPT_REGION + setProperty("OutputWorkspace", outputWS); +} + +} // namespace Algorithms +} // namespace Mantid diff --git a/Code/Mantid/Framework/Algorithms/src/CreateGroupingWorkspace.cpp b/Code/Mantid/Framework/Algorithms/src/CreateGroupingWorkspace.cpp index e3ff69f76350..cc0b6bc3de03 100644 --- a/Code/Mantid/Framework/Algorithms/src/CreateGroupingWorkspace.cpp +++ b/Code/Mantid/Framework/Algorithms/src/CreateGroupingWorkspace.cpp @@ -11,6 +11,11 @@ #include "MantidAPI/FileProperty.h" #include "MantidKernel/ListValidator.h" +namespace +{ + Mantid::Kernel::Logger g_log("CreateGroupingWorkspace"); +} + namespace Mantid { namespace Algorithms @@ -89,6 +94,9 @@ namespace Algorithms declareProperty("MaxRecursionDepth", 5, "Number of levels to search into the instrument (default=5)"); + declareProperty("FixedGroupCount", 0, "Used to distribute the detectors of a given component into a fixed number of groups"); + declareProperty("ComponentName", "", "Specify the instrument component to group into a fixed number of groups"); + declareProperty(new WorkspaceProperty("OutputWorkspace","",Direction::Output), "An output GroupingWorkspace."); @@ -101,6 +109,8 @@ namespace Algorithms setPropertyGroup("GroupNames", groupby); setPropertyGroup("GroupDetectorsBy", groupby); setPropertyGroup("MaxRecursionDepth", groupby); + setPropertyGroup("FixedGroupCount", groupby); + setPropertyGroup("ComponentName", groupby); // output properties declareProperty("NumberGroupedSpectraResult", EMPTY_INT(), "The number of spectra in groups", Direction::Output); @@ -142,6 +152,38 @@ namespace Algorithms return; } + /** Creates a mapping based on a fixed number of groups for a given instrument component + * + * @param compName Name of component in instrument + * @param numGroups Number of groups to group detectors into + * @param inst Pointer to instrument + * @param detIDtoGroup Map of detector IDs to group number + * @param prog Progress reporter + */ + void makeGroupingByNumGroups(const std::string compName, int numGroups, Instrument_const_sptr inst, + std::map &detIDtoGroup, Progress &prog) + { + // Get detectors for given instument component + std::vector detectors; + inst->getDetectorsInBank(detectors, compName); + + // Calculate number of detectors per group + int detectorsPerGroup = static_cast(detectors.size()) / numGroups; + + // Map detectors to group + for(unsigned int detIndex = 0; detIndex < detectors.size(); detIndex++) + { + int detectorID = detectors[detIndex]->getID(); + int groupNum = (detIndex / detectorsPerGroup) + 1; + + // Ignore any detectors the do not fit nicely into the group divisions + if(groupNum <= numGroups) + detIDtoGroup[detectorID] = groupNum; + + prog.report(); + } + } + //------------------------------------------------------------------------------------------------ /** Use group numbers for sorting * @@ -271,6 +313,8 @@ namespace Algorithms std::string OldCalFilename = getPropertyValue("OldCalFilename"); std::string GroupNames = getPropertyValue("GroupNames"); std::string grouping = getPropertyValue("GroupDetectorsBy"); + int numGroups = getProperty("FixedGroupCount"); + std::string componentName = getPropertyValue("ComponentName"); // Some validation int numParams = 0; @@ -337,8 +381,6 @@ namespace Algorithms } } - - // --------------------------- Create the output -------------------------- GroupingWorkspace_sptr outWS(new GroupingWorkspace(inst)); this->setProperty("OutputWorkspace", outWS); @@ -352,6 +394,8 @@ namespace Algorithms makeGroupingByNames(GroupNames, inst, detIDtoGroup, prog, sortnames); else if (!OldCalFilename.empty()) readGroupingFile(OldCalFilename, detIDtoGroup, prog); + else if ((numGroups > 0) && !componentName.empty()) + makeGroupingByNumGroups(componentName, numGroups, inst, detIDtoGroup, prog); g_log.information() << detIDtoGroup.size() << " entries in the detectorID-to-group map.\n"; setProperty("NumberGroupedSpectraResult", static_cast(detIDtoGroup.size())); diff --git a/Code/Mantid/Framework/Algorithms/src/CreateWorkspace.cpp b/Code/Mantid/Framework/Algorithms/src/CreateWorkspace.cpp index d83cf177af0f..6c733bcdc50d 100644 --- a/Code/Mantid/Framework/Algorithms/src/CreateWorkspace.cpp +++ b/Code/Mantid/Framework/Algorithms/src/CreateWorkspace.cpp @@ -67,6 +67,20 @@ void CreateWorkspace::init() "Name of a parent workspace."); } +/// Input validation +std::map CreateWorkspace::validateInputs() +{ + std::map issues; + + const std::string vUnit = getProperty("VerticalAxisUnit"); + const std::vector vAxis = getProperty("VerticalAxisValues"); + + if ( vUnit == "SpectraNumber" && vAxis.size() > 0 ) + issues["VerticalAxisValues"] = "Axis values cannot be provided when using a spectra axis"; + + return issues; +} + /// Exec function void CreateWorkspace::exec() { diff --git a/Code/Mantid/Framework/Algorithms/src/EditInstrumentGeometry.cpp b/Code/Mantid/Framework/Algorithms/src/EditInstrumentGeometry.cpp index 58c88f2d4dec..5f5c4c974fe0 100644 --- a/Code/Mantid/Framework/Algorithms/src/EditInstrumentGeometry.cpp +++ b/Code/Mantid/Framework/Algorithms/src/EditInstrumentGeometry.cpp @@ -113,14 +113,28 @@ namespace Algorithms // everything depends on being parallel to the workspace # histo size_t numHist(0); + bool hasWorkspacePtr(false); { MatrixWorkspace_const_sptr workspace = getProperty("Workspace"); - numHist = workspace->getNumberHistograms(); + // this is to guard against WorkspaceGroups + // fallthrough is to skip workspace check and make sure + if (bool(workspace)) { + hasWorkspacePtr = true; + numHist = workspace->getNumberHistograms(); + } } std::string error; const std::vector specids = this->getProperty("SpectrumIDs"); + if (!hasWorkspacePtr) { + // use the number of spectra for the number of histograms + numHist = specids.size(); + // give up if it is empty + if (numHist == 0) { + return result; + } + } error = checkValues(specids, numHist); if (!error.empty()) result["SpectrumIDs"] = error; diff --git a/Code/Mantid/Framework/Algorithms/src/ElasticWindow.cpp b/Code/Mantid/Framework/Algorithms/src/ElasticWindow.cpp index 7ca3cd780b56..4e988cc057d9 100644 --- a/Code/Mantid/Framework/Algorithms/src/ElasticWindow.cpp +++ b/Code/Mantid/Framework/Algorithms/src/ElasticWindow.cpp @@ -14,7 +14,6 @@ namespace Algorithms // Register the algorithm into the AlgorithmFactory DECLARE_ALGORITHM(ElasticWindow) - using namespace Kernel; using namespace API; @@ -48,16 +47,31 @@ void ElasticWindow::exec() MatrixWorkspace_sptr outputQ; MatrixWorkspace_sptr outputQSquared; - + const bool childAlgLogging(true); - double startProgress(0.0), stepProgress(0.0), endProgress(0.0); + double startProgress(0.0), endProgress(0.0); + + // Determine if we are converting from spectra number (red) or Q (Sqw) + const bool axisIsSpectrumNumber = inputWorkspace->getAxis(1)->isSpectra(); + g_log.information() << "Axis is spectrum number: " << axisIsSpectrumNumber << std::endl; + // Determine if we need to use the second time range... - if ( ! ( ( enR2S == enR2E ) && ( enR2S == EMPTY_DBL() ) ) ) + const bool backgroundSubtraction = !((enR2S == enR2E) && (enR2S == EMPTY_DBL())); + g_log.information() << "Use background subtraction: " << backgroundSubtraction << std::endl; + + // Calculate number of steps + size_t numSteps = 4; + if(backgroundSubtraction) + numSteps += 1; + if(axisIsSpectrumNumber) + numSteps += 1; + + double stepProgress = 1.0 / static_cast(numSteps); + + if(backgroundSubtraction) { - stepProgress = 1.0/6.0; - // ... CalculateFlatBackground, Minus, Integration... - IAlgorithm_sptr flatBG = createChildAlgorithm("CalculateFlatBackground",startProgress, endProgress,childAlgLogging); + IAlgorithm_sptr flatBG = createChildAlgorithm("CalculateFlatBackground", startProgress, endProgress, childAlgLogging); flatBG->setProperty("InputWorkspace", inputWorkspace); flatBG->setProperty("StartX", enR2S); flatBG->setProperty("EndX", enR2E); @@ -69,7 +83,7 @@ void ElasticWindow::exec() MatrixWorkspace_sptr flatBGws = flatBG->getProperty("OutputWorkspace"); - IAlgorithm_sptr integ = createChildAlgorithm("Integration",startProgress, endProgress,childAlgLogging); + IAlgorithm_sptr integ = createChildAlgorithm("Integration", startProgress, endProgress, childAlgLogging); integ->setProperty("InputWorkspace", flatBGws); integ->setProperty("RangeLower", enR1S); integ->setProperty("RangeUpper", enR1E); @@ -80,10 +94,8 @@ void ElasticWindow::exec() } else { - stepProgress = 1.0/5.0; - // ... Just Integration ... - IAlgorithm_sptr integ = createChildAlgorithm("Integration",startProgress, endProgress,childAlgLogging); + IAlgorithm_sptr integ = createChildAlgorithm("Integration", startProgress, endProgress, childAlgLogging); integ->setProperty("InputWorkspace", inputWorkspace); integ->setProperty("RangeLower", enR1S); integ->setProperty("RangeUpper", enR1E); @@ -95,45 +107,80 @@ void ElasticWindow::exec() startProgress += stepProgress; endProgress += stepProgress; - // ... ConvertSpectrumAxis (ElasticQ). Version 2 to give the correct number - const int version = 2; - IAlgorithm_sptr csaQ = createChildAlgorithm("ConvertSpectrumAxis",startProgress,endProgress,childAlgLogging,version); - csaQ->setProperty("InputWorkspace", integWS); - csaQ->setPropertyValue("Target", "ElasticQ"); - csaQ->setPropertyValue("EMode", "Indirect"); - csaQ->setPropertyValue("OutputWorkspace", "csaQ"); - csaQ->execute(); - MatrixWorkspace_sptr csaQws = csaQ->getProperty("OutputWorkspace"); - startProgress += stepProgress; - endProgress += stepProgress; - - // ... ConvertSpectrumAxis (Q2) ... - IAlgorithm_sptr csaQ2 = createChildAlgorithm("ConvertSpectrumAxis",startProgress,endProgress,childAlgLogging,version); - csaQ2->setProperty("InputWorkspace", integWS); - csaQ2->setPropertyValue("Target", "ElasticQSquared"); - csaQ2->setPropertyValue("EMode", "Indirect"); - csaQ2->setPropertyValue("OutputWorkspace", "csaQ2"); - csaQ2->execute(); - MatrixWorkspace_sptr csaQ2ws = csaQ2->getProperty("OutputWorkspace"); - startProgress += stepProgress; - endProgress += stepProgress; + if(axisIsSpectrumNumber) + { + // Use ConvertSpectrumAxis v2 for correct result + const int version = 2; + + // ... ConvertSpectrumAxis (Q) ... + IAlgorithm_sptr csaQ = createChildAlgorithm("ConvertSpectrumAxis", startProgress, endProgress, childAlgLogging, version); + csaQ->setProperty("InputWorkspace", integWS); + csaQ->setPropertyValue("Target", "ElasticQ"); + csaQ->setPropertyValue("EMode", "Indirect"); + csaQ->setPropertyValue("OutputWorkspace", "csaQ"); + csaQ->execute(); + MatrixWorkspace_sptr csaQws = csaQ->getProperty("OutputWorkspace"); + startProgress += stepProgress; + endProgress += stepProgress; + // ... ConvertSpectrumAxis (Q2) ... + IAlgorithm_sptr csaQ2 = createChildAlgorithm("ConvertSpectrumAxis", startProgress, endProgress, childAlgLogging, version); + csaQ2->setProperty("InputWorkspace", integWS); + csaQ2->setPropertyValue("Target", "ElasticQSquared"); + csaQ2->setPropertyValue("EMode", "Indirect"); + csaQ2->setPropertyValue("OutputWorkspace", "csaQ2"); + csaQ2->execute(); + MatrixWorkspace_sptr csaQ2ws = csaQ2->getProperty("OutputWorkspace"); + startProgress += stepProgress; + endProgress += stepProgress; - // ... Transpose A ... - IAlgorithm_sptr tranQ = createChildAlgorithm("Transpose",startProgress,endProgress,childAlgLogging); - tranQ->setProperty("InputWorkspace",csaQws); - tranQ->setPropertyValue("OutputWorkspace", "outQ"); - tranQ->execute(); - outputQ = tranQ->getProperty("OutputWorkspace"); - startProgress += stepProgress; - endProgress += stepProgress; + // ... Transpose (Q) ... + IAlgorithm_sptr tranQ = createChildAlgorithm("Transpose", startProgress, endProgress, childAlgLogging); + tranQ->setProperty("InputWorkspace", csaQws); + tranQ->setPropertyValue("OutputWorkspace", "outQ"); + tranQ->execute(); + outputQ = tranQ->getProperty("OutputWorkspace"); + startProgress += stepProgress; + endProgress += stepProgress; + + // ... Transpose (Q2) ... + IAlgorithm_sptr tranQ2 = createChildAlgorithm("Transpose", startProgress, endProgress, childAlgLogging); + tranQ2->setProperty("InputWorkspace", csaQ2ws); + tranQ2->setPropertyValue("OutputWorkspace", "outQSquared"); + tranQ2->execute(); + outputQSquared = tranQ2->getProperty("OutputWorkspace"); + startProgress += stepProgress; + endProgress += stepProgress; + } + else + { + // ... Transpose (Q) ... + IAlgorithm_sptr tranQ = createChildAlgorithm("Transpose", startProgress, endProgress, childAlgLogging); + tranQ->setProperty("InputWorkspace", integWS); + tranQ->setPropertyValue("OutputWorkspace", "outQ"); + tranQ->execute(); + outputQ = tranQ->getProperty("OutputWorkspace"); + startProgress += stepProgress; + endProgress += stepProgress; - // ... Transpose B ... - IAlgorithm_sptr tranQ2 = createChildAlgorithm("Transpose", startProgress,endProgress,childAlgLogging); - tranQ2->setProperty("InputWorkspace",csaQ2ws); - tranQ2->setPropertyValue("OutputWorkspace", "outQSquared"); - tranQ2->execute(); - outputQSquared = tranQ2->getProperty("OutputWorkspace"); + // ... Convert to Histogram (Q2) ... + IAlgorithm_sptr histQ2 = createChildAlgorithm("ConvertToHistogram", startProgress, endProgress, childAlgLogging); + histQ2->setProperty("InputWorkspace", outputQ); + histQ2->setPropertyValue("OutputWorkspace", "outQ"); + histQ2->execute(); + MatrixWorkspace_sptr qHistWS = histQ2->getProperty("OutputWorkspace"); + startProgress += stepProgress; + endProgress += stepProgress; + + // ... Convert Units (Q2) ... + IAlgorithm_sptr convUnitQ2 = createChildAlgorithm("ConvertUnits", startProgress, endProgress, childAlgLogging); + convUnitQ2->setProperty("InputWorkspace", qHistWS); + convUnitQ2->setPropertyValue("Target", "QSquared"); + convUnitQ2->setPropertyValue("EMode", "Indirect"); + convUnitQ2->setPropertyValue("OutputWorkspace", "outQSquared"); + convUnitQ2->execute(); + outputQSquared = convUnitQ2->getProperty("OutputWorkspace"); + } setProperty("OutputInQ", outputQ); setProperty("OutputInQSquared", outputQSquared); diff --git a/Code/Mantid/Framework/Algorithms/src/FilterByLogValue.cpp b/Code/Mantid/Framework/Algorithms/src/FilterByLogValue.cpp index 464673b57699..b2683a815f49 100644 --- a/Code/Mantid/Framework/Algorithms/src/FilterByLogValue.cpp +++ b/Code/Mantid/Framework/Algorithms/src/FilterByLogValue.cpp @@ -83,8 +83,13 @@ std::map FilterByLogValue::validateInputs() { std::map errors; - // Check that the log exists for the given input workspace + // check for null pointers - this is to protect against workspace groups EventWorkspace_const_sptr inputWS = this->getProperty("InputWorkspace"); + if (!inputWS) { + return errors; + } + + // Check that the log exists for the given input workspace std::string logname = getPropertyValue("LogName"); try { ITimeSeriesProperty * log = dynamic_cast( inputWS->run().getLogData(logname) ); diff --git a/Code/Mantid/Framework/Algorithms/src/FindPeaks.cpp b/Code/Mantid/Framework/Algorithms/src/FindPeaks.cpp index a22db12fd981..9b210cf849f6 100644 --- a/Code/Mantid/Framework/Algorithms/src/FindPeaks.cpp +++ b/Code/Mantid/Framework/Algorithms/src/FindPeaks.cpp @@ -123,6 +123,10 @@ namespace Algorithms declareProperty("MinimumPeakHeight", DBL_MIN, "Minimum allowed peak height. "); + declareProperty("MinimumPeakHeightObs", 0.0, "Least value of the maximum observed Y value of a peak within " + "specified region. If any peak's maximum observed Y value is smaller, then " + "this peak will not be fit. It is designed for EventWorkspace with integer counts."); + std::vector costFuncOptions; costFuncOptions.push_back("Chi-Square"); costFuncOptions.push_back("Rwp"); @@ -255,6 +259,8 @@ namespace Algorithms m_useObsCentre = getProperty("StartFromObservedPeakCentre"); + m_leastMaxObsY = getProperty("MinimumPeakHeightObs"); + return; } @@ -890,6 +896,23 @@ namespace Algorithms const MantidVec& vecX = input->readX(spectrum); const MantidVec& vecY = input->readY(spectrum); + // Exclude peak with peak counts + bool hasHighCounts = false; + for (int i = i_min; i <= i_max; ++i) + if (vecY[i] > m_leastMaxObsY) + { + hasHighCounts = true; + break; + } + if (!hasHighCounts) + { + std::stringstream ess; + ess << "Peak supposed at " << vecY[i_centre] << " does not have enough counts as " << m_leastMaxObsY; + g_log.debug(ess.str()); + addNonFitRecord(spectrum); + return; + } + //------------------------------------------------------------------------- // Estimate peak and background parameters for better fitting //------------------------------------------------------------------------- @@ -1094,6 +1117,10 @@ namespace Algorithms height = vecY[i_min] - (bg0 + bg1*tmpx + bg2*tmpx*tmpx); double lowest = height; + // Extreme case + if (i_max == vecY.size()) + i_max = i_max - 1; + // Searching for (size_t i = i_min+1; i <= i_max; ++i) { diff --git a/Code/Mantid/Framework/Algorithms/src/FitPeak.cpp b/Code/Mantid/Framework/Algorithms/src/FitPeak.cpp index 4d64b5671a7e..6c02445fa561 100644 --- a/Code/Mantid/Framework/Algorithms/src/FitPeak.cpp +++ b/Code/Mantid/Framework/Algorithms/src/FitPeak.cpp @@ -399,8 +399,18 @@ namespace Algorithms MantidVec& dataE = purePeakWS->dataE(0); dataX.assign(vecX.begin() + i_minFitX, vecX.begin() + i_maxFitX+1); - dataY.assign(vecY.begin() + i_minFitX, vecY.begin() + i_maxFitX+1); - dataE.assign(vecE.begin() + i_minFitX, vecE.begin() + i_maxFitX+1); + size_t ishift = i_maxFitX+1; + if (ishift < vecY.size()) + { + dataY.assign(vecY.begin() + i_minFitX, vecY.begin() + i_maxFitX+1); + dataE.assign(vecE.begin() + i_minFitX, vecE.begin() + i_maxFitX+1); + } + else + { + dataY.assign(vecY.begin() + i_minFitX, vecY.end()); + dataE.assign(vecE.begin() + i_minFitX, vecE.end()); + } + return purePeakWS; } diff --git a/Code/Mantid/Framework/Algorithms/src/GeneratePythonScript.cpp b/Code/Mantid/Framework/Algorithms/src/GeneratePythonScript.cpp index 475f479792d4..a66d07d86845 100644 --- a/Code/Mantid/Framework/Algorithms/src/GeneratePythonScript.cpp +++ b/Code/Mantid/Framework/Algorithms/src/GeneratePythonScript.cpp @@ -26,22 +26,25 @@ DECLARE_ALGORITHM(GeneratePythonScript) */ void GeneratePythonScript::init() { - declareProperty(new WorkspaceProperty("InputWorkspace","",Direction::Input), "An input workspace."); + declareProperty(new WorkspaceProperty("InputWorkspace", "", Direction::Input), "An input workspace."); std::vector exts; exts.push_back(".py"); - declareProperty(new API::FileProperty("Filename","", API::FileProperty::OptionalSave, exts), + declareProperty(new API::FileProperty("Filename", "", API::FileProperty::OptionalSave, exts), "The name of the file into which the workspace history will be generated."); declareProperty("ScriptText", std::string(""), "Saves the history of the workspace to a variable.", Direction::Output); declareProperty("UnrollAll", false, "Unroll all algorithms to show just their child algorithms.", Direction::Input); + declareProperty("StartTimestamp", std::string(""), "The filter start time in the format YYYY-MM-DD HH:mm:ss", Direction::Input); + declareProperty("EndTimestamp", std::string(""), "The filter end time in the format YYYY-MM-DD HH:mm:ss", Direction::Input); + std::vector saveVersions; saveVersions.push_back("Specify Old"); saveVersions.push_back("Specify All"); saveVersions.push_back("Specify None"); - declareProperty("SpecifyAlgorithmVersions","Specify Old",boost::make_shared(saveVersions), + declareProperty("SpecifyAlgorithmVersions", "Specify Old", boost::make_shared(saveVersions), "When to specify which algorithm version was used by Mantid."); } @@ -52,6 +55,8 @@ void GeneratePythonScript::exec() { const Workspace_const_sptr ws = getProperty("InputWorkspace"); const bool unrollAll = getProperty("UnrollAll"); + const std::string startTime = getProperty("StartTimestamp"); + const std::string endTime = getProperty("EndTimestamp"); const std::string saveVersions = getProperty("SpecifyAlgorithmVersions"); // Get the algorithm histories of the workspace. @@ -64,6 +69,20 @@ void GeneratePythonScript::exec() view->unrollAll(); } + // Need at least a start time to do time filter + if(startTime != "") + { + if(endTime == "") + { + // If no end time was given then filter up to now + view->filterBetweenExecDate(DateAndTime(startTime)); + } + else + { + view->filterBetweenExecDate(DateAndTime(startTime), DateAndTime(endTime)); + } + } + std::string versionSpecificity; if(saveVersions == "Specify Old") versionSpecificity = "old"; diff --git a/Code/Mantid/Framework/Algorithms/src/GetDetOffsetsMultiPeaks.cpp b/Code/Mantid/Framework/Algorithms/src/GetDetOffsetsMultiPeaks.cpp index 879070165dd0..2d7c5cad07d9 100644 --- a/Code/Mantid/Framework/Algorithms/src/GetDetOffsetsMultiPeaks.cpp +++ b/Code/Mantid/Framework/Algorithms/src/GetDetOffsetsMultiPeaks.cpp @@ -186,6 +186,11 @@ namespace Algorithms declareProperty("MaxChiSq", 100., "Maximum chisq value for individual peak fit allowed. (Default: 100)"); declareProperty("MinimumPeakHeight", 2.0, "Minimum value allowed for peak height."); + + declareProperty("MinimumPeakHeightObs", 0.0, "Least value of the maximum observed Y value of a peak within " + "specified region. If any peak's maximum observed Y value is smaller, then " + "this peak will not be fit. It is designed for EventWorkspace with integer counts."); + //Disable default gsl error handler (which is to call abort!) gsl_set_error_handler_off(); @@ -314,6 +319,7 @@ namespace Algorithms m_maxChiSq = this->getProperty("MaxChiSq"); m_minPeakHeight = this->getProperty("MinimumPeakHeight"); m_maxOffset=getProperty("MaxOffset"); + m_leastMaxObsY = getProperty("MinimumPeakHeightObs"); // Create output workspaces outputW = boost::make_shared(m_inputWS->getInstrument()); diff --git a/Code/Mantid/Framework/Algorithms/src/HRPDSlabCanAbsorption.cpp b/Code/Mantid/Framework/Algorithms/src/HRPDSlabCanAbsorption.cpp index dc64b2a511ce..47743d68ff91 100644 --- a/Code/Mantid/Framework/Algorithms/src/HRPDSlabCanAbsorption.cpp +++ b/Code/Mantid/Framework/Algorithms/src/HRPDSlabCanAbsorption.cpp @@ -171,8 +171,10 @@ API::MatrixWorkspace_sptr HRPDSlabCanAbsorption::runFlatPlateAbsorption() { NeutronAtom neutron(static_cast(EMPTY_DBL()), static_cast(0), 0.0, 0.0, sigma_s, 0.0, sigma_s, sigma_atten); - Material mat("SetInSphericalAbsorption", neutron, rho); - m_inputWS->mutableSample().setMaterial(mat); + Object shape = m_inputWS->sample().getShape(); // copy + shape.setMaterial(Material("SetInSphericalAbsorption", neutron, rho)); + m_inputWS->mutableSample().setShape(shape); + } // Call FlatPlateAbsorption as a Child Algorithm diff --git a/Code/Mantid/Framework/Algorithms/src/Integration.cpp b/Code/Mantid/Framework/Algorithms/src/Integration.cpp index 5c9ce61cc666..1e906c79ea0a 100644 --- a/Code/Mantid/Framework/Algorithms/src/Integration.cpp +++ b/Code/Mantid/Framework/Algorithms/src/Integration.cpp @@ -9,6 +9,7 @@ #include "MantidAPI/Progress.h" #include +#include "MantidAPI/NumericAxis.h" #include "MantidAPI/TextAxis.h" #include "MantidKernel/BoundedValidator.h" @@ -46,6 +47,20 @@ void Integration::init() declareProperty("IncludePartialBins", false, "If true then partial bins from the beginning and end of the input range are also included in the integration."); } +/** + * Std-style comparision function object (satisfies the requirements of Compare) + * @return true if first argument < second argument (with some tolerance/epsilon) + */ +struct tolerant_less: public std::binary_function +{ +public: + bool operator()(const double &left, const double &right) const + { + // soft equal, if the diff left-right is below a numerical error (uncertainty) threshold, we cannot say + return (left < right) && (std::abs(left - right) > 1*std::numeric_limits::epsilon()); + } +}; + /** Executes the algorithm * * @throw runtime_error Thrown if algorithm cannot execute @@ -89,6 +104,7 @@ void Integration::exec() Progress progress(this, 0, 1, m_MaxSpec-m_MinSpec+1); const bool axisIsText = localworkspace->getAxis(1)->isText(); + const bool axisIsNumeric = localworkspace->getAxis(1)->isNumeric(); // Loop over spectra PARALLEL_FOR2(localworkspace,outputWorkspace) @@ -104,6 +120,11 @@ void Integration::exec() Mantid::API::TextAxis* newAxis = dynamic_cast(outputWorkspace->getAxis(1)); newAxis->setLabel(outWI, localworkspace->getAxis(1)->label(i)); } + else if ( axisIsNumeric ) + { + Mantid::API::NumericAxis* newAxis = dynamic_cast(outputWorkspace->getAxis(1)); + newAxis->setValue(outWI, (*(localworkspace->getAxis(1)))(i)); + } // This is the output ISpectrum * outSpec = outputWorkspace->getSpectrum(outWI); @@ -129,17 +150,29 @@ void Integration::exec() // Find the range [min,max] MantidVec::const_iterator lowit, highit; - if (m_MinRange == EMPTY_DBL()) lowit=X.begin(); - else lowit=std::lower_bound(X.begin(),X.end(),m_MinRange); + if (m_MinRange == EMPTY_DBL()) + { + lowit=X.begin(); + } + else + { + lowit = std::lower_bound(X.begin(), X.end(), m_MinRange, tolerant_less()); + } - if (m_MaxRange == EMPTY_DBL()) highit=X.end(); - else highit=std::find_if(lowit,X.end(),std::bind2nd(std::greater(),m_MaxRange)); + if (m_MaxRange == EMPTY_DBL()) + { + highit=X.end(); + } + else + { + highit = std::upper_bound(lowit, X.end(), m_MaxRange, tolerant_less()); + } // If range specified doesn't overlap with this spectrum then bail out if ( lowit == X.end() || highit == X.begin() ) continue; // Upper limit is the bin before, i.e. the last value smaller than MaxRange - --highit; + --highit; // (note: decrementing 'end()' is safe for vectors, at least according to the C++ standard) MantidVec::difference_type distmin = std::distance(X.begin(),lowit); MantidVec::difference_type distmax = std::distance(X.begin(),highit); diff --git a/Code/Mantid/Framework/Algorithms/src/LorentzCorrection.cpp b/Code/Mantid/Framework/Algorithms/src/LorentzCorrection.cpp new file mode 100644 index 000000000000..e58e67ebe457 --- /dev/null +++ b/Code/Mantid/Framework/Algorithms/src/LorentzCorrection.cpp @@ -0,0 +1,150 @@ +#include "MantidAlgorithms/LorentzCorrection.h" +#include "MantidAPI/MatrixWorkspace.h" +#include "MantidAPI/Progress.h" +#include "MantidAPI/WorkspaceValidators.h" +#include "MantidKernel/MultiThreaded.h" +#include +#include +#include + +namespace Mantid +{ + namespace Algorithms + { + using namespace Mantid::Kernel; + using namespace Mantid::API; + using namespace Mantid::Geometry; + using namespace Mantid::Kernel; + using Mantid::API::WorkspaceProperty; + + // Register the algorithm into the AlgorithmFactory + DECLARE_ALGORITHM(LorentzCorrection) + + //---------------------------------------------------------------------------------------------- + /** Constructor + */ + LorentzCorrection::LorentzCorrection() + { + } + + //---------------------------------------------------------------------------------------------- + /** Destructor + */ + LorentzCorrection::~LorentzCorrection() + { + } + + //---------------------------------------------------------------------------------------------- + + /// Algorithm's version for identification. @see Algorithm::version + int LorentzCorrection::version() const + { + return 1; + } + ; + + /// Algorithm's category for identification. @see Algorithm::category + 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"; + } + + //---------------------------------------------------------------------------------------------- + /** Initialize the algorithm's properties. + */ + void LorentzCorrection::init() + { + + declareProperty( + new WorkspaceProperty("InputWorkspace", "", Direction::Input, + PropertyMode::Mandatory, boost::make_shared("Wavelength")), + "Input workspace to correct in Wavelength."); + declareProperty(new WorkspaceProperty("OutputWorkspace", "", Direction::Output), + "An output workspace."); + } + + //---------------------------------------------------------------------------------------------- + /** Execute the algorithm. + */ + void LorentzCorrection::exec() + { + MatrixWorkspace_sptr inWS = this->getProperty("InputWorkspace"); + + auto cloneAlg = this->createChildAlgorithm("CloneWorkspace", 0, 0.1); + cloneAlg->initialize(); + cloneAlg->setProperty("InputWorkspace", inWS); + cloneAlg->execute(); + Workspace_sptr temp = cloneAlg->getProperty("OutputWorkspace"); + MatrixWorkspace_sptr outWS = boost::dynamic_pointer_cast(temp); + + const auto numHistos = inWS->getNumberHistograms(); + Progress prog(this, 0, 1, numHistos); + const bool isHist = inWS->isHistogramData(); + + PARALLEL_FOR1(inWS) + for (int64_t i = 0; i < int64_t(numHistos); ++i) + { + PARALLEL_START_INTERUPT_REGION + + const MantidVec& inY = inWS->readY(i); + const MantidVec& inX = inWS->readX(i); + + MantidVec& outY = outWS->dataY(i); + MantidVec& outE = outWS->dataE(i); + + IDetector_const_sptr detector; + try + { + detector = inWS->getDetector(i); + } catch (Exception::NotFoundError&) + { + // Catch if no detector. Next line tests whether this happened - test placed + // outside here because Mac Intel compiler doesn't like 'continue' in a catch + // in an openmp block. + } + // If no detector found, skip onto the next spectrum + if (!detector) + continue; + + const double twoTheta = inWS->detectorTwoTheta(detector); + const double sinTheta = std::sin(twoTheta / 2); + double sinThetaSq = sinTheta * sinTheta; + + for (size_t j = 0; j < inY.size(); ++j) + { + const double wL = isHist ? (0.5 * (inX[j] + inX[j + 1])) : inX[j]; + if(wL == 0) + { + std::stringstream buffer; + buffer << "Cannot have zero values Wavelength. At workspace index: " << i; + throw std::runtime_error(buffer.str()); + } + + double weight = sinThetaSq / (wL * wL * wL * wL); + outY[j] *= weight; + outE[j] *= weight; + } + + prog.report(); + + PARALLEL_END_INTERUPT_REGION + } + PARALLEL_CHECK_INTERUPT_REGION + + this->setProperty("OutputWorkspace", outWS); + } + +} // namespace Algorithms +} // namespace Mantid diff --git a/Code/Mantid/Framework/Algorithms/src/MaskBinsFromTable.cpp b/Code/Mantid/Framework/Algorithms/src/MaskBinsFromTable.cpp index c008586311fa..fe1562951fae 100644 --- a/Code/Mantid/Framework/Algorithms/src/MaskBinsFromTable.cpp +++ b/Code/Mantid/Framework/Algorithms/src/MaskBinsFromTable.cpp @@ -48,7 +48,7 @@ namespace Algorithms this->declareProperty(new WorkspaceProperty<>("OutputWorkspace","",Direction::Output), "Output Workspace with bins masked."); this->declareProperty(new WorkspaceProperty("MaskingInformation", "", Direction::Input), - "Input TableWorkspace containing parameters, SpectraList, XMin and XMax."); + "Input TableWorkspace containing parameters, XMin and XMax and either SprectaList or DetectorIDsList"); return; } @@ -188,7 +188,7 @@ namespace Algorithms if (id_xmin < 0 || id_xmax < 0 || id_xmin == id_xmax) throw runtime_error("Either Xmin nor Xmax is not given. "); if (id_spec == id_dets) - throw runtime_error("Neither SpectraList nor DetectorIDList is not given."); + throw runtime_error("Neither SpectraList nor DetectorIDList is given."); else if (id_dets >= 0) m_useDetectorID = true; else diff --git a/Code/Mantid/Framework/Algorithms/src/MonteCarloAbsorption.cpp b/Code/Mantid/Framework/Algorithms/src/MonteCarloAbsorption.cpp index 08025459c243..aee3e72c857f 100644 --- a/Code/Mantid/Framework/Algorithms/src/MonteCarloAbsorption.cpp +++ b/Code/Mantid/Framework/Algorithms/src/MonteCarloAbsorption.cpp @@ -5,20 +5,24 @@ #include "MantidAPI/WorkspaceProperty.h" #include "MantidAPI/WorkspaceValidators.h" #include "MantidAPI/SampleEnvironment.h" -#include "MantidKernel/BoundedValidator.h" #include "MantidGeometry/IDetector.h" #include "MantidGeometry/Objects/Track.h" -#include "MantidKernel/VectorHelper.h" +#include "MantidKernel/BoundedValidator.h" #include "MantidKernel/NeutronAtom.h" +#include "MantidKernel/VectorHelper.h" -// @todo: This needs a factory -#include "MantidKernel/MersenneTwister.h" +#include +#include +#include /// @cond namespace { /// Number of attempts to choose a random point within the object before it gives up - const int MaxRandPointAttempts(20); + const int MaxRandPointAttempts(500); + + /// Element size in mm + const double ELEMENT_SIZE = 1.0; } /// @endcond @@ -26,15 +30,10 @@ namespace Mantid { namespace Algorithms { - + DECLARE_ALGORITHM(MonteCarloAbsorption) - using API::WorkspaceProperty; - using API::WorkspaceUnitValidator; - using API::InstrumentValidator; - using API::MatrixWorkspace_sptr; - using API::WorkspaceFactory; - using API::Progress; + using namespace API; using namespace Geometry; using namespace Kernel; @@ -45,28 +44,26 @@ namespace Mantid /** * Constructor */ - MonteCarloAbsorption::MonteCarloAbsorption() : - m_inputWS(), m_sampleShape(NULL), m_container(NULL), m_numberOfPoints(0), - m_xStepSize(0), m_numberOfEvents(1), m_samplePos(), m_sourcePos(), - m_bbox_length(0.0), m_bbox_halflength(0.0), m_bbox_width(0.0), - m_bbox_halfwidth(0.0), m_bbox_height(0.0), m_bbox_halfheight(0.0), - m_randGen(NULL) + MonteCarloAbsorption::MonteCarloAbsorption() : + m_samplePos(), m_sourcePos(), m_blocks(), + m_blkHalfX(0.0), m_blkHalfY(0.0), m_blkHalfZ(0.0), + m_rngs(0), m_inputWS(), m_sampleShape(NULL), m_container(NULL), m_numberOfPoints(0), + m_xStepSize(0), m_numberOfEvents(300) { } - + /** * Destructor */ MonteCarloAbsorption::~MonteCarloAbsorption() { - delete m_randGen; } //------------------------------------------------------------------------------ // Private methods //------------------------------------------------------------------------------ - - /** + + /** * Initialize the algorithm */ void MonteCarloAbsorption::init() @@ -77,49 +74,50 @@ namespace Mantid wsValidator->add(); declareProperty(new WorkspaceProperty<>("InputWorkspace", "", Direction::Input, - wsValidator), - "The name of the input workspace. The input workspace must have X units of wavelength."); + wsValidator), + "The name of the input workspace. The input workspace must have X units of wavelength."); declareProperty(new WorkspaceProperty<> ("OutputWorkspace", "", Direction::Output), - "The name to use for the output workspace."); + "The name to use for the output workspace."); auto positiveInt = boost::make_shared >(); positiveInt->setLower(1); declareProperty("NumberOfWavelengthPoints", EMPTY_INT(), positiveInt, - "The number of wavelength points for which a simulation is atttempted (default: all points)"); - declareProperty("EventsPerPoint", 300, positiveInt, - "The number of \"neutron\" events to generate per simulated point"); + "The number of wavelength points for which a simulation is atttempted (default: all points)"); + declareProperty("EventsPerPoint", m_numberOfEvents, positiveInt, + "The number of \"neutron\" events to generate per simulated point"); declareProperty("SeedValue", 123456789, positiveInt, - "Seed the random number generator with this value"); + "Seed the random number generator with this value"); } - + /** * Execution code */ void MonteCarloAbsorption::exec() { retrieveInput(); - initCaches(); - + initCaches(); + + g_log.debug() << "Creating output workspace\n"; MatrixWorkspace_sptr correctionFactors = WorkspaceFactory::Instance().create(m_inputWS); correctionFactors->isDistribution(true); // The output of this is a distribution correctionFactors->setYUnit(""); // Need to explicitly set YUnit to nothing correctionFactors->setYUnitLabel("Attenuation factor"); - + const bool isHistogram = m_inputWS->isHistogramData(); const int numHists = static_cast(m_inputWS->getNumberHistograms()); const int numBins = static_cast(m_inputWS->blocksize()); - + // Compute the step size m_xStepSize = numBins/m_numberOfPoints; - std::ostringstream message; - message << "Simulation performed every " << m_xStepSize << " wavelength points" << std::endl; - g_log.information(message.str()); - message.str(""); - - Progress prog(this,0.0,1.0,numHists); + g_log.information() << "Simulation performed every " << m_xStepSize + << " wavelength points" << std::endl; + + Progress prog(this,0.0,1.0, numHists*numBins/m_xStepSize); + PARALLEL_FOR1(correctionFactors) for( int i = 0; i < numHists; ++i ) { + PARALLEL_START_INTERUPT_REGION // Copy over the X-values const MantidVec & xValues = m_inputWS->readX(i); @@ -132,16 +130,19 @@ namespace Mantid } catch(Kernel::Exception::NotFoundError&) { - continue; + // intel compiler hangs with continue statements inside a catch + // block that is within an omp loop... } + if(!detector) continue; MantidVec & yValues = correctionFactors->dataY(i); MantidVec & eValues = correctionFactors->dataE(i); // Simulation for each requested wavelength point for( int bin = 0; bin < numBins; bin += m_xStepSize ) { + prog.report("Computing corrections for bin " + boost::lexical_cast(bin)); const double lambda = isHistogram ? - (0.5 * (xValues[bin] + xValues[bin + 1]) ) : xValues[bin]; + (0.5 * (xValues[bin] + xValues[bin + 1]) ) : xValues[bin]; doSimulation(detector.get(), lambda, yValues[bin], eValues[bin]); // Ensure we have the last point for the interpolation if ( m_xStepSize > 1 && bin + m_xStepSize >= numBins && bin+1 != numBins) @@ -153,11 +154,13 @@ namespace Mantid // Interpolate through points not simulated if( m_xStepSize > 1 ) { + prog.report("Interpolating unsimulated points"); Kernel::VectorHelper::linearlyInterpolateY(xValues, yValues, m_xStepSize); } - prog.report(); - } + PARALLEL_END_INTERUPT_REGION + } + PARALLEL_CHECK_INTERUPT_REGION // Save the results setProperty("OutputWorkspace", correctionFactors); @@ -175,9 +178,9 @@ namespace Mantid double & attenFactor, double & error) { /** - Currently, assuming square beam profile to pick start position then randomly selecting + Currently, assuming square beam profile to pick start position then randomly selecting a point within the sample using it's bounding box. - This point defines the single scattering point and hence the attenuation path lengths and final + This point defines the single scattering point and hence the attenuation path lengths and final directional vector to the detector */ // Absolute detector position @@ -190,15 +193,12 @@ namespace Mantid { V3D startPos = sampleBeamProfile(); V3D scatterPoint = selectScatterPoint(); - try - { - attenFactor += attenuationFactor(startPos, scatterPoint, detectorPos, lambda); - } - catch(std::logic_error &) + double eventFactor(0.0); + if(attenuationFactor(startPos, scatterPoint, detectorPos, lambda, eventFactor)) { - continue; + attenFactor += eventFactor; + ++numDetected; } - ++numDetected; } // Attenuation factor is simply the average value @@ -218,26 +218,35 @@ namespace Mantid } /** - * Selects a random location within the sample + container environment. + * Selects a random location within the sample + container environment. The bounding box is + * used as an approximation to generate a point and this is then tested for its validity within + * the shape. * @returns Selected position as V3D object */ V3D MonteCarloAbsorption::selectScatterPoint() const { - // Generate 3 random numbers, use them to calculate a random location - // within the bounding box of the sample environment + sample - // and then check if this position is within the whole environment. - // If it is return it, if not try again. + // Randomly select a block from the subdivided set and then randomly select a point + // within that block and test if it inside the sample/container. If yes then accept, else + // keep trying. + boost::uniform_int uniIntDist(0, m_blocks.size() - 1); + boost::variate_generator> + uniInt(rgen(), uniIntDist); + boost::uniform_real<> uniRealDist(0, 1.0); + boost::variate_generator> + uniReal(rgen(), uniRealDist); + V3D scatterPoint; int nattempts(0); while( nattempts < MaxRandPointAttempts ) { - const double x = m_bbox_halflength*(2.0*m_randGen->nextValue() - 1.0); - const double y = m_bbox_halfwidth*(2.0*m_randGen->nextValue() - 1.0); - const double z = m_bbox_halfheight*(2.0*m_randGen->nextValue() - 1.0); + size_t index = uniInt(); + const auto & block = m_blocks[index]; + const double x = m_blkHalfX*(2.0*uniReal() - 1.0) + block.xMin(); + const double y = m_blkHalfY*(2.0*uniReal() - 1.0) + block.yMin(); + const double z = m_blkHalfZ*(2.0*uniReal() - 1.0) + block.zMin(); scatterPoint(x,y,z); ++nattempts; - if( m_sampleShape->isValid(scatterPoint) || - (m_container && m_container->isValid(scatterPoint)) ) + if( ptIntersectsSample(scatterPoint) ) { scatterPoint += m_samplePos; return scatterPoint; @@ -245,9 +254,8 @@ namespace Mantid } // If we got here then the shape is too strange for the bounding box to be of any use. g_log.error() << "Attempts to generate a random point with the sample/can " - << "have exceeded the allowed number of tries.\n"; + << "have exceeded the allowed number of tries.\n"; throw std::runtime_error("Attempts to produce random scatter point failed. Check sample shape."); - } /** @@ -256,25 +264,27 @@ namespace Mantid * @param scatterPoint :: The point of scatter * @param finalPos :: The end point of the track * @param lambda :: The wavelength of the neutron - * @returns The attenuation factor for this neutron's track + * @param factor :: Output parameter storing the attenuation factor + * @returns True if the track was valid, false otherwise */ - double + bool MonteCarloAbsorption::attenuationFactor(const V3D & startPos, const V3D & scatterPoint, - const V3D & finalPos, const double lambda) + const V3D & finalPos, const double lambda, + double & factor) { - double factor(1.0); - - // Define two tracks, before and after scatter, and trace check their + // Start at one + factor = 1.0; + // Define two tracks, before and after scatter, and trace check their // intersections with the the environment and sample Track beforeScatter(scatterPoint, (startPos - scatterPoint)); Track afterScatter(scatterPoint, (finalPos - scatterPoint)); // Theoretically this should never happen as there should always be an intersection // but do to precision limitations points very close to the surface give // zero intersection, so just reject - if( m_sampleShape->interceptSurface(beforeScatter) == 0 || + if( m_sampleShape->interceptSurface(beforeScatter) == 0 || m_sampleShape->interceptSurface(afterScatter) == 0 ) { - throw std::logic_error("Track has no surfaces intersections."); + return false; } double length = beforeScatter.begin()->distInsideObject; @@ -291,14 +301,12 @@ namespace Mantid citr != cend; ++citr) { length = citr->distInsideObject; - IObjComponent *objComp = dynamic_cast(citr->componentID); - Material_const_sptr mat = objComp->material(); - factor *= attenuation(length, *mat, lambda); + factor *= attenuation(length, citr->object->material(), lambda); } length = afterScatter.begin()->distInsideObject; factor *= attenuation(length, *m_sampleMaterial, lambda); - + afterScatter.clearIntersectionResults(); if( m_container ) { @@ -310,22 +318,20 @@ namespace Mantid citr != cend; ++citr) { length = citr->distInsideObject; - IObjComponent *objComp = dynamic_cast(citr->componentID); - Material_const_sptr mat = objComp->material(); - factor *= attenuation(length, *mat, lambda); + factor *= attenuation(length, citr->object->material(), lambda); } - - return factor; + + return true; } /** * Calculate the attenuation for a given length, material and wavelength * @param length :: Distance through the material - * @param material :: A reference to the Material + * @param material :: A reference to the Material * @param lambda :: The wavelength * @returns The attenuation factor */ - double + double MonteCarloAbsorption::attenuation(const double length, const Kernel::Material& material, const double lambda) const { @@ -344,24 +350,6 @@ namespace Mantid { m_inputWS = getProperty("InputWorkspace"); - // // Define a test sample material - // Material *vanadium = new Material("Vanadium", PhysicalConstants::getNeutronAtom(23,0), 0.072); - // m_inputWS->mutableSample().setMaterial(*vanadium); - - // // Define test environment - // std::ostringstream xml; - // xml << "" - // << "" - // << "" - // << ""; - - // Geometry::ShapeFactory shapeMaker; - // Object_sptr p = shapeMaker.createShape(xml.str()); - - // API::SampleEnvironment * kit = new API::SampleEnvironment("TestEnv"); - // kit->add(new ObjComponent("one", p, NULL, boost::shared_ptr(vanadium))); - // m_inputWS->mutableSample().setEnvironment(kit); - m_sampleShape = &(m_inputWS->sample().getShape()); m_sampleMaterial = &(m_inputWS->sample().getMaterial()); if( !m_sampleShape->hasValidShape() ) @@ -370,13 +358,13 @@ namespace Mantid << ", No. of surfaces: " << m_sampleShape->getSurfacePtr().size() << "\n"; throw std::invalid_argument("Input workspace has an invalid sample shape."); } - + if( m_sampleMaterial->totalScatterXSection(1.0) == 0.0 ) { g_log.warning() << "The sample material appears to have zero scattering cross section.\n" << "Result will most likely be nonsensical.\n"; } - + try { m_container = &(m_inputWS->sample().getEnvironment()); @@ -402,33 +390,152 @@ namespace Mantid } /** - * Initialise the caches used here including setting up the random + * Initialise the caches used here including setting up the random * number generator */ void MonteCarloAbsorption::initCaches() { - if( !m_randGen ) - { - const int seedValue = getProperty("SeedValue"); - m_randGen = new Kernel::MersenneTwister(seedValue); - } - + g_log.debug() << "Caching input\n"; + // Setup random number generators for parallel execution + initRNG(); + m_samplePos = m_inputWS->getInstrument()->getSample()->getPos(); m_sourcePos = m_inputWS->getInstrument()->getSource()->getPos(); BoundingBox box(m_sampleShape->getBoundingBox()); if( m_container ) { - BoundingBox envBox; - m_container->getBoundingBox(envBox); - box.grow(envBox); + box.grow(m_container->boundingBox()); } - //Save the dimensions for quicker calculations later - m_bbox_length = box.xMax() - box.xMin(); - m_bbox_halflength = 0.5 * m_bbox_length; - m_bbox_width = box.yMax() - box.yMin(); - m_bbox_halfwidth = 0.5 * m_bbox_width; - m_bbox_height = box.zMax() - box.zMin(); - m_bbox_halfheight = 0.5 * m_bbox_height; + + // Chop the bounding box up into a set of small boxes. This will be used + // as a first guess for generating a random scatter point + const double cubeSide = ELEMENT_SIZE*1e-3; + const double xLength = box.width().X(); + const double yLength = box.width().Y(); + const double zLength = box.width().Z(); + const int numXSlices = static_cast(xLength/cubeSide); + const int numYSlices = static_cast(yLength/cubeSide); + const int numZSlices = static_cast(zLength/cubeSide); + const double xThick = xLength/numXSlices; + const double yThick = yLength/numYSlices; + const double zThick = zLength/numZSlices; + m_blkHalfX = 0.5*xThick; + m_blkHalfY = 0.5*yThick; + m_blkHalfZ = 0.5*zThick; + + const size_t numPossibleVolElements = numXSlices*numYSlices*numZSlices; + g_log.debug() << "Attempting to divide sample + container into " << numPossibleVolElements << " blocks.\n"; + + try + { + m_blocks.clear(); + m_blocks.reserve(numPossibleVolElements/2); + } + catch (std::exception&) + { + // Typically get here if the number of volume elements is too large + // Provide a bit more information + g_log.error("Too many volume elements requested - try increasing the value of the ElementSize property."); + throw; + } + + const auto boxCentre = box.centrePoint(); + const double x0 = boxCentre.X() - 0.5*xLength; + const double y0 = boxCentre.Y() - 0.5*yLength; + const double z0 = boxCentre.Z() - 0.5*zLength; + // Store a chunk as a BoundingBox object. + // Only cache blocks that have some intersection with the + // sample or container. + for (int i = 0; i < numZSlices; ++i) + { + const double zmin = z0 + i*zThick; + const double zmax = zmin + zThick; + for (int j = 0; j < numYSlices; ++j) + { + const double ymin = y0 + j*yThick; + const double ymax = ymin + yThick; + for (int k = 0; k < numXSlices; ++k) + { + const double xmin = x0 + k*xThick; + const double xmax = xmin + xThick; + if(boxIntersectsSample(xmax, ymax, zmax, xmin, ymin, zmin)) + { +#if !(defined(__INTEL_COMPILER)) && !(defined(__clang__)) + m_blocks.emplace_back(xmax, ymax, zmax, xmin, ymin, zmin); +#else + m_blocks.push_back(BoundingBox(xmax, ymax, zmax, xmin, ymin, zmin)); +#endif + } + } + } + } + + m_numVolumeElements = m_blocks.size(); + g_log.debug() << "Sample + container divided into " << m_numVolumeElements << " blocks."; + if(m_numVolumeElements == numPossibleVolElements) g_log.debug("\n"); + else g_log.debug() << " Skipped " << (numPossibleVolElements-m_numVolumeElements) + << " blocks that do not intersect with the sample + container\n"; + } + + /** + */ + void MonteCarloAbsorption::initRNG() + { + const int baseSeed = getProperty("SeedValue"); + // For parallel execution use a vector of RNG, each with a seed one higher that the previous + m_rngs.resize(PARALLEL_GET_MAX_THREADS); + // Set the seeds + for(int i = 0; i < static_cast(m_rngs.size()); ++i) + { + m_rngs[i].seed(baseSeed + i); + } + } + + /** + * @return A reference to a boost::random::mt19937 object + */ + boost::mt19937 &MonteCarloAbsorption::rgen() const + { + // Const from point of view of caller + return const_cast(this)->m_rngs[PARALLEL_THREAD_NUMBER]; + } + + /** + * @param xmax max x-coordinate of cuboid point + * @param ymax max y-coordinate of cuboid point + * @param zmax max z-coordinate of cuboid point + * @param xmin min z-coordinate of cuboid point + * @param ymin min z-coordinate of cuboid point + * @param zmin min z-coordinate of cuboid point + * @return True if any of the vertices intersect the sample or container + */ + bool MonteCarloAbsorption::boxIntersectsSample(const double xmax, const double ymax, const double zmax, + const double xmin, const double ymin, const double zmin) const + { + // Check all 8 corners for intersection + if( ptIntersectsSample(V3D(xmax, ymin, zmin)) || // left-front-bottom + ptIntersectsSample(V3D(xmax, ymax, zmin)) || // left-front-top + ptIntersectsSample(V3D(xmin, ymax, zmin)) || // right-front-top + ptIntersectsSample(V3D(xmin, ymin, zmin)) || // right-front-bottom + ptIntersectsSample(V3D(xmax, ymin, zmax)) || // left-back-bottom + ptIntersectsSample(V3D(xmax, ymax, zmax)) || // left-back-top + ptIntersectsSample(V3D(xmin, ymax, zmax)) || // right-back-top + ptIntersectsSample(V3D(xmin, ymin, zmax)) ) // right-back-bottom + { + return true; + } + else return false; + } + + /** + * + * @param pt A V3D giving a point to test + * @return True if point is inside sample or container, false otherwise + */ + bool MonteCarloAbsorption::ptIntersectsSample(const V3D &pt) const + { + return m_sampleShape->isValid(pt) || + (m_container && m_container->isValid(pt)); } } diff --git a/Code/Mantid/Framework/Algorithms/src/MultipleScatteringCylinderAbsorption.cpp b/Code/Mantid/Framework/Algorithms/src/MultipleScatteringCylinderAbsorption.cpp index 7dcf1d1cf188..f776f68d60df 100644 --- a/Code/Mantid/Framework/Algorithms/src/MultipleScatteringCylinderAbsorption.cpp +++ b/Code/Mantid/Framework/Algorithms/src/MultipleScatteringCylinderAbsorption.cpp @@ -127,8 +127,9 @@ void MultipleScatteringCylinderAbsorption::exec() { NeutronAtom neutron(static_cast(EMPTY_DBL()), static_cast(0), 0.0, 0.0, coeff3, 0.0, coeff3, coeff1); - Material mat("SetInMultipleScattering", neutron, coeff2); - in_WS->mutableSample().setMaterial(mat); + Object shape = in_WS->sample().getShape(); // copy + shape.setMaterial(Material("SetInMultipleScattering", neutron, coeff2)); + in_WS->mutableSample().setShape(shape); } g_log.debug() << "radius=" << radius << " coeff1=" << coeff1 << " coeff2=" << coeff2 << " coeff3=" << coeff3 << "\n"; diff --git a/Code/Mantid/Framework/Algorithms/src/PDFFourierTransform.cpp b/Code/Mantid/Framework/Algorithms/src/PDFFourierTransform.cpp index 43f2e2432b18..25daf3594db6 100644 --- a/Code/Mantid/Framework/Algorithms/src/PDFFourierTransform.cpp +++ b/Code/Mantid/Framework/Algorithms/src/PDFFourierTransform.cpp @@ -134,7 +134,12 @@ namespace Mantid if (Qmax <= Qmin) result["Qmax"] = "Must be greater than Qmin"; + // check for null pointers - this is to protect against workspace groups API::MatrixWorkspace_const_sptr inputWS = getProperty("InputWorkspace"); + if (!inputWS) { + return result; + } + if (inputWS->getNumberHistograms() != 1) { result["InputWorkspace"] = "Input workspace must have only one spectrum"; diff --git a/Code/Mantid/Framework/Algorithms/src/RecordPythonScript.cpp b/Code/Mantid/Framework/Algorithms/src/RecordPythonScript.cpp index a8c168957215..8ba046e0677b 100644 --- a/Code/Mantid/Framework/Algorithms/src/RecordPythonScript.cpp +++ b/Code/Mantid/Framework/Algorithms/src/RecordPythonScript.cpp @@ -89,7 +89,13 @@ void RecordPythonScript::startingHandle(API::IAlgorithm_sptr alg) std::string algString; for(auto p = props.begin() ; p != props.end(); ++p) { - std::string paramString = (**p).name() + "='" + (**p).value() + "'"; + std::string opener = "='"; + if ((**p).value().find('\\') != std::string::npos ) + { + opener= "=r'"; + } + + std::string paramString = (**p).name() + opener + (**p).value() + "'"; // Miss out parameters that are empty. if(paramString.length() != 0) diff --git a/Code/Mantid/Framework/Algorithms/src/SofQW.cpp b/Code/Mantid/Framework/Algorithms/src/SofQW.cpp index c0b6ec3c0227..77b5368bb0e7 100644 --- a/Code/Mantid/Framework/Algorithms/src/SofQW.cpp +++ b/Code/Mantid/Framework/Algorithms/src/SofQW.cpp @@ -1,6 +1,8 @@ //---------------------------------------------------------------------- // Includes //---------------------------------------------------------------------- +#include + #include "MantidAlgorithms/SofQW.h" #include "MantidDataObjects/Histogram1D.h" #include "MantidAPI/BinEdgeAxis.h" @@ -127,7 +129,7 @@ void SofQW::exec() IDetector_const_sptr spectrumDet = inputWorkspace->getDetector(i); if( spectrumDet->isMonitor() ) continue; - const double efixed = m_EmodeProperties.getEFixed(spectrumDet); + const double efixed = m_EmodeProperties.getEFixed(spectrumDet); // For inelastic scattering the simple relationship q=4*pi*sinTheta/lambda does not hold. In order to // be completely general we must calculate the momentum transfer by calculating the incident and final @@ -142,6 +144,7 @@ void SofQW::exec() { detectors.push_back(spectrumDet); } + const size_t numDets = detectors.size(); const double numDets_d = static_cast(numDets); // cache to reduce number of static casts const MantidVec& Y = inputWorkspace->readY(i); @@ -185,8 +188,12 @@ void SofQW::exec() } } - const V3D ki = beamDir*sqrt(energyToK*ei); - const V3D kf = scatterDir*(sqrt(energyToK*(ef))); + + if(ei < 0) + throw std::runtime_error("Negative incident energy. Check binning."); + + const V3D ki = beamDir * sqrt(energyToK * ei); + const V3D kf = scatterDir * (sqrt(energyToK * (ef))); const double q = (ki - kf).norm(); // Test whether it's in range of the Q axis diff --git a/Code/Mantid/Framework/Algorithms/src/SphericalAbsorption.cpp b/Code/Mantid/Framework/Algorithms/src/SphericalAbsorption.cpp index 1c902cec5095..59b6187c4eac 100644 --- a/Code/Mantid/Framework/Algorithms/src/SphericalAbsorption.cpp +++ b/Code/Mantid/Framework/Algorithms/src/SphericalAbsorption.cpp @@ -104,8 +104,9 @@ void SphericalAbsorption::retrieveBaseProperties() { NeutronAtom neutron(static_cast(EMPTY_DBL()), static_cast(0), 0.0, 0.0, sigma_s, 0.0, sigma_s, sigma_atten); - Material mat("SetInSphericalAbsorption", neutron, rho); - m_inputWS->mutableSample().setMaterial(mat); + Object shape = m_inputWS->sample().getShape(); // copy + shape.setMaterial(Material("SetInSphericalAbsorption", neutron, rho)); + m_inputWS->mutableSample().setShape(shape); } m_refAtten = sigma_atten * rho; diff --git a/Code/Mantid/Framework/Algorithms/src/Stitch1DMany.cpp b/Code/Mantid/Framework/Algorithms/src/Stitch1DMany.cpp new file mode 100644 index 000000000000..f3f6130a4e4d --- /dev/null +++ b/Code/Mantid/Framework/Algorithms/src/Stitch1DMany.cpp @@ -0,0 +1,261 @@ +#include "MantidAlgorithms/Stitch1DMany.h" +#include "MantidAPI/AlgorithmManager.h" +#include "MantidAPI/WorkspaceProperty.h" +#include "MantidAPI/MatrixWorkspace.h" +#include "MantidAPI/WorkspaceValidators.h" +#include "MantidKernel/ArrayProperty.h" +#include "MantidKernel/RebinParamsValidator.h" +#include "MantidKernel/BoundedValidator.h" + +#include + +using namespace Mantid::Kernel; +using namespace Mantid::API; + +namespace Mantid +{ + namespace Algorithms + { + DECLARE_ALGORITHM(Stitch1DMany) + + /** Initialize the algorithm's properties. + */ + void Stitch1DMany::init() + { + + declareProperty(new ArrayProperty("InputWorkspaces", Direction::Input), + "Input Workspaces. List of histogram workspaces to stitch together."); + + declareProperty(new WorkspaceProperty("OutputWorkspace", "", Direction::Output), + "Output stitched workspace."); + + declareProperty(new ArrayProperty("Params", boost::make_shared(true), Direction::Input), + "Rebinning Parameters. See Rebin for format."); + + declareProperty(new ArrayProperty("StartOverlaps", Direction::Input), "Start overlaps for stitched workspaces."); + + declareProperty(new ArrayProperty("EndOverlaps", Direction::Input), "End overlaps for stitched workspaces."); + + declareProperty(new PropertyWithValue("ScaleRHSWorkspace", true, Direction::Input), + "Scaling either with respect to workspace 1 or workspace 2"); + + declareProperty(new PropertyWithValue("UseManualScaleFactor", false, Direction::Input), + "True to use a provided value for the scale factor."); + + auto manualScaleFactorValidator = boost::make_shared >(); + manualScaleFactorValidator->setLower(0); + manualScaleFactorValidator->setExclusive(true); + declareProperty(new PropertyWithValue("ManualScaleFactor", 1.0, manualScaleFactorValidator, Direction::Input), + "Provided value for the scale factor."); + + declareProperty(new ArrayProperty("OutScaleFactors", Direction::Output), + "The actual used values for the scaling factores at each stitch step."); + } + + /** Load and validate the algorithm's properties. + */ + std::map Stitch1DMany::validateInputs() + { + std::map errors; + + m_inputWorkspaces.clear(); + + const std::vector inputWorkspacesStr = this->getProperty("InputWorkspaces"); + if(inputWorkspacesStr.size() < 2) + errors["InputWorkspaces"] = "At least 2 input workspaces required."; + + for(auto ws = inputWorkspacesStr.begin(); ws != inputWorkspacesStr.end(); ++ws) + { + if(AnalysisDataService::Instance().doesExist(*ws)) + { + m_inputWorkspaces.push_back(AnalysisDataService::Instance().retrieveWS(*ws)); + } + else + { + errors["InputWorkspaces"] = *ws + " is not a valid workspace."; + break; + } + } + + //Check that all the workspaces are of the same type + if(m_inputWorkspaces.size() > 0) + { + const std::string id = m_inputWorkspaces[0]->id(); + for(auto it = m_inputWorkspaces.begin(); it != m_inputWorkspaces.end(); ++it) + { + if((*it)->id() != id) + { + errors["InputWorkspaces"] = "All workspaces must be the same type."; + break; + } + } + + //If our inputs are all group workspaces, check they're the same size + WorkspaceGroup_sptr firstGroup = boost::dynamic_pointer_cast(m_inputWorkspaces[0]); + if(firstGroup) + { + size_t groupSize = firstGroup->size(); + for(auto it = m_inputWorkspaces.begin(); it != m_inputWorkspaces.end(); ++it) + { + WorkspaceGroup_sptr group = boost::dynamic_pointer_cast(*it); + if(group->size() != groupSize) + { + errors["InputWorkspaces"] = "All group workspaces must be the same size."; + break; + } + } + } + } + else + { + errors["InputWorkspaces"] = "Input workspaces must be given"; + } + + m_numWorkspaces = m_inputWorkspaces.size(); + + m_startOverlaps = this->getProperty("StartOverlaps"); + m_endOverlaps = this->getProperty("EndOverlaps"); + + if(m_startOverlaps.size() > 0 && m_startOverlaps.size() != m_numWorkspaces - 1) + errors["StartOverlaps"] = "If given, StartOverlaps must have one fewer entries than the number of input workspaces."; + + if(m_startOverlaps.size() != m_endOverlaps.size()) + errors["EndOverlaps"] = "EndOverlaps must have the same number of entries as StartOverlaps."; + + + m_scaleRHSWorkspace = this->getProperty("ScaleRHSWorkspace"); + m_useManualScaleFactor = this->getProperty("UseManualScaleFactor"); + m_manualScaleFactor = this->getProperty("ManualScaleFactor"); + m_params = this->getProperty("Params"); + + if(m_params.size() < 1) + errors["Params"] = "At least one parameter must be given."; + + if(!m_scaleRHSWorkspace) + { + //Flip these around for processing + std::reverse(m_inputWorkspaces.begin(), m_inputWorkspaces.end()); + std::reverse(m_startOverlaps.begin(), m_startOverlaps.end()); + std::reverse(m_endOverlaps.begin(), m_endOverlaps.end()); + } + + m_scaleFactors.clear(); + m_outputWorkspace.reset(); + + return errors; + } + + /** Execute the algorithm. + */ + void Stitch1DMany::exec() + { + //Check we're not dealing with group workspaces + if(!boost::dynamic_pointer_cast(m_inputWorkspaces[0])) + { + MatrixWorkspace_sptr lhsWS = boost::dynamic_pointer_cast(m_inputWorkspaces[0]); + + for(size_t i = 1; i < m_numWorkspaces; ++i) + { + MatrixWorkspace_sptr rhsWS = boost::dynamic_pointer_cast(m_inputWorkspaces[i]); + + IAlgorithm_sptr stitchAlg = createChildAlgorithm("Stitch1D"); + stitchAlg->initialize(); + + stitchAlg->setProperty("LHSWorkspace", lhsWS); + stitchAlg->setProperty("RHSWorkspace", rhsWS); + if(m_startOverlaps.size() > i - 1) + { + stitchAlg->setProperty("StartOverlap", m_startOverlaps[i-1]); + stitchAlg->setProperty("EndOverlap", m_endOverlaps[i-1]); + } + stitchAlg->setProperty("Params", m_params); + stitchAlg->setProperty("ScaleRHSWorkspace", m_scaleRHSWorkspace); + stitchAlg->setProperty("UseManualScaleFactor", m_useManualScaleFactor); + if(m_useManualScaleFactor) + stitchAlg->setProperty("ManualScaleFactor", m_manualScaleFactor); + + stitchAlg->execute(); + + lhsWS = stitchAlg->getProperty("OutputWorkspace"); + m_scaleFactors.push_back(stitchAlg->getProperty("OutScaleFactor")); + } + + if(!isChild()) + { + //Copy each input workspace's history into our output workspace's history + for(auto inWS = m_inputWorkspaces.begin(); inWS != m_inputWorkspaces.end(); ++inWS) + lhsWS->history().addHistory((*inWS)->getHistory()); + } + //We're a child algorithm, but we're recording history anyway + else if(isRecordingHistoryForChild() && m_parentHistory) + { + m_parentHistory->addChildHistory(m_history); + } + + m_outputWorkspace = lhsWS; + } + //We're dealing with group workspaces + else + { + std::vector groupWorkspaces; + for(auto it = m_inputWorkspaces.begin(); it != m_inputWorkspaces.end(); ++it) + groupWorkspaces.push_back(boost::dynamic_pointer_cast(*it)); + + //List of workspaces to be grouped + std::vector toGroup; + + size_t numWSPerGroup = groupWorkspaces[0]->size(); + + for(size_t i = 0; i < numWSPerGroup; ++i) + { + //List of workspaces to stitch + std::vector toProcess; + //The name of the resulting workspace + std::string outName; + + for(size_t j = 0; j < groupWorkspaces.size(); ++j) + { + const std::string wsName = groupWorkspaces[j]->getItem(i)->name(); + toProcess.push_back(wsName); + outName += wsName; + } + + IAlgorithm_sptr stitchAlg = AlgorithmManager::Instance().create("Stitch1DMany"); + stitchAlg->initialize(); + stitchAlg->setProperty("InputWorkspaces", toProcess); + stitchAlg->setProperty("OutputWorkspace", outName); + stitchAlg->setProperty("StartOverlaps", m_startOverlaps); + stitchAlg->setProperty("EndOverlaps", m_endOverlaps); + stitchAlg->setProperty("Params", m_params); + stitchAlg->setProperty("ScaleRHSWorkspace", m_scaleRHSWorkspace); + stitchAlg->setProperty("UseManualScaleFactor", m_useManualScaleFactor); + if(m_useManualScaleFactor) + stitchAlg->setProperty("ManualScaleFactor", m_manualScaleFactor); + stitchAlg->execute(); + + //Add the resulting workspace to the list to be grouped together + toGroup.push_back(outName); + + //Add the scalefactors to the list so far + const std::vector scaleFactors = stitchAlg->getProperty("OutScaleFactors"); + m_scaleFactors.insert(m_scaleFactors.end(), scaleFactors.begin(), scaleFactors.end()); + } + + const std::string groupName = this->getProperty("OutputWorkspace"); + + IAlgorithm_sptr groupAlg = AlgorithmManager::Instance().create("GroupWorkspaces"); + groupAlg->initialize(); + groupAlg->setProperty("InputWorkspaces", toGroup); + groupAlg->setProperty("OutputWorkspace", groupName); + groupAlg->execute(); + + m_outputWorkspace = AnalysisDataService::Instance().retrieveWS(groupName); + } + + //Save output + this->setProperty("OutputWorkspace", m_outputWorkspace); + this->setProperty("OutScaleFactors", m_scaleFactors); + } + + } // namespace Algorithms +} // namespace Mantid diff --git a/Code/Mantid/Framework/Algorithms/src/SumEventsByLogValue.cpp b/Code/Mantid/Framework/Algorithms/src/SumEventsByLogValue.cpp index 21335f0bf8ec..284fcff0fae0 100644 --- a/Code/Mantid/Framework/Algorithms/src/SumEventsByLogValue.cpp +++ b/Code/Mantid/Framework/Algorithms/src/SumEventsByLogValue.cpp @@ -48,7 +48,11 @@ namespace Algorithms { std::map errors; + // check for null pointers - this is to protect against workspace groups m_inputWorkspace = getProperty("InputWorkspace"); + if (!m_inputWorkspace) { + return errors; + } // This only works for unweighted events // TODO: Either turn this check into a proper validator or amend the algorithm to work for weighted events diff --git a/Code/Mantid/Framework/Algorithms/src/WienerSmooth.cpp b/Code/Mantid/Framework/Algorithms/src/WienerSmooth.cpp new file mode 100644 index 000000000000..878d54287690 --- /dev/null +++ b/Code/Mantid/Framework/Algorithms/src/WienerSmooth.cpp @@ -0,0 +1,333 @@ +#include "MantidAlgorithms/WienerSmooth.h" +#include "MantidAPI/IFunction.h" +#include "MantidAPI/FunctionFactory.h" + +#include + +namespace Mantid +{ +namespace Algorithms +{ + + using Mantid::Kernel::Direction; + using Mantid::API::WorkspaceProperty; + + // Register the algorithm into the AlgorithmFactory + DECLARE_ALGORITHM(WienerSmooth) + + namespace + { + // Square values + struct PowerSpectrum + { + double operator()(double x) const {return x * x;} + }; + + // To be used when actual noise level cannot be estimated + const double guessSignalToNoiseRatio = 1e15; + } + + //---------------------------------------------------------------------------------------------- + /** Constructor + */ + WienerSmooth::WienerSmooth() + { + } + + //---------------------------------------------------------------------------------------------- + /** Destructor + */ + WienerSmooth::~WienerSmooth() + { + } + + + //---------------------------------------------------------------------------------------------- + + + /// Algorithm's version for identification. @see Algorithm::version + int WienerSmooth::version() const { return 1;}; + + /// Algorithm's category for identification. @see Algorithm::category + const std::string WienerSmooth::category() const { return "Arithmetic\\FFT;Transforms\\Smoothing";} + + /// Algorithm's summary for use in the GUI and help. @see Algorithm::summary + const std::string WienerSmooth::summary() const { return "Smooth spectrum using Wiener filter.";}; + + //---------------------------------------------------------------------------------------------- + /** Initialize the algorithm's properties. + */ + void WienerSmooth::init() + { + declareProperty(new WorkspaceProperty<>("InputWorkspace","",Direction::Input), "An input workspace."); + declareProperty("WorkspaceIndex",0,"A workspace index for the histogram to smooth."); + declareProperty(new WorkspaceProperty<>("OutputWorkspace","",Direction::Output), "An output workspace."); + } + + //---------------------------------------------------------------------------------------------- + /** Execute the algorithm. + */ + void WienerSmooth::exec() + { + // Get the data to smooth + API::MatrixWorkspace_sptr inputWS = getProperty("InputWorkspace"); + size_t wsIndex = static_cast( getProperty("WorkspaceIndex") ); + + size_t dataSize = inputWS->blocksize(); + + // it won't work for very small workspaces + if ( dataSize < 4 ) + { + g_log.debug() << "No smoothing, spectrum copied." << std::endl; + setProperty( "OutputWorkspace", copyInput(inputWS,wsIndex) ); + return; + } + + // Due to the way RealFFT works the input should be even-sized + const bool isOddSize = dataSize % 2 != 0; + if ( isOddSize ) + { + // add a fake value to the end to make size even + inputWS = copyInput(inputWS,wsIndex); + wsIndex = 0; + auto &X = inputWS->dataX(wsIndex); + auto &Y = inputWS->dataY(wsIndex); + auto &E = inputWS->dataE(wsIndex); + double dx = X[dataSize-1] - X[dataSize-2]; + X.push_back(X.back() + dx); + Y.push_back(Y.back()); + E.push_back(E.back()); + } + + // the input vectors + auto &X = inputWS->readX(wsIndex); + auto &Y = inputWS->readY(wsIndex); + auto &E = inputWS->readE(wsIndex); + + // Digital fourier transform works best for data oscillating around 0. + // Fit a spline with a small number of break points to the data. + // Make sure that the spline passes through the first and the last points + // of the data. + // The fitted spline will be subtracted from the data and the difference + // will be smoothed with the Wiener filter. After that the spline will be + // added to the smoothed data to produce the output. + + // number of spline break points, must be smaller than the data size but between 2 and 10 + size_t nbreak = 10; + if ( nbreak * 3 > dataSize ) nbreak = dataSize / 3; + + // NB. The spline mustn't fit too well to the data. If it does smoothing doesn't happen. + // TODO: it's possible that the spline is unnecessary and a simple linear function will + // do a better job. + + g_log.debug() << "Spline break points " << nbreak << std::endl; + + // define the spline + API::IFunction_sptr spline = API::FunctionFactory::Instance().createFunction("BSpline"); + auto xInterval = getStartEnd( X, inputWS->isHistogramData() ); + spline->setAttributeValue( "StartX", xInterval.first ); + spline->setAttributeValue( "EndX", xInterval.second ); + spline->setAttributeValue( "NBreak", static_cast(nbreak) ); + // fix the first and last parameters to the first and last data values + spline->setParameter(0, Y.front() ); + spline->fix(0); + size_t lastParamIndex = spline->nParams() - 1; + spline->setParameter(lastParamIndex, Y.back() ); + spline->fix(lastParamIndex); + + // fit the spline to the data + auto fit = createChildAlgorithm("Fit"); + fit->initialize(); + fit->setProperty( "Function", spline ); + fit->setProperty( "InputWorkspace", inputWS ); + fit->setProperty( "WorkspaceIndex", static_cast(wsIndex) ); + fit->setProperty( "CreateOutput", true ); + fit->execute(); + + // get the fit output workspace; spectrum 2 contains the difference that is to be smoothed + API::MatrixWorkspace_sptr fitOut = fit->getProperty("OutputWorkspace"); + + // Fourier transform the difference spectrum + auto fourier = createChildAlgorithm( "RealFFT" ); + fourier->initialize(); + fourier->setProperty( "InputWorkspace", fitOut ); + fourier->setProperty( "WorkspaceIndex", 2 ); + // we don't require bin linearity as we don't need the exact transform + fourier->setProperty( "IgnoreXBins", true ); + fourier->execute(); + + API::MatrixWorkspace_sptr fourierOut = fourier->getProperty("OutputWorkspace"); + + // spectrum 2 of the transformed workspace has the transform modulus which is a square + // root of the power spectrum + auto &powerSpec = fourierOut->dataY(2); + // convert the modulus to power spectrum wich is the base of the Wiener filter + std::transform( powerSpec.begin(), powerSpec.end(), powerSpec.begin(), PowerSpectrum() ); + + // estimate power spectrum's noise as the average of its high frequency half + size_t n2 = powerSpec.size(); + double noise = std::accumulate( powerSpec.begin() + n2/2, powerSpec.end(), 0.0 ); + noise /= static_cast(n2); + + // index of the maximum element in powerSpec + const size_t imax = static_cast(std::distance( powerSpec.begin(), std::max_element(powerSpec.begin(), powerSpec.end()) )); + + if ( noise == 0.0 ) + { + noise = powerSpec[imax] / guessSignalToNoiseRatio; + } + + g_log.debug() << "Maximum signal " << powerSpec[imax] << std::endl; + g_log.debug() << "Noise " << noise << std::endl; + + // storage for the Wiener filter, initialized with 0.0's + std::vector wf(n2); + + // The filter consists of two parts: + // 1) low frequency region, from 0 until the power spectrum falls to the noise level, filter is calculated + // from the power spectrum + // 2) high frequency noisy region, filter is a smooth function of frequency decreasing to 0 + + // the following code is an adaptation of a fortran routine + // noise starting index + size_t i0 = 0; + // intermediate variables + double xx = 0.0; + double xy = 0.0; + double ym = 0.0; + // low frequency filter values: the higher the power spectrum the closer the filter to 1.0 + for(size_t i = 0; i < n2; ++i) + { + double cd1 = powerSpec[i] / noise; + if ( cd1 < 1.0 && i > imax ) + { + i0 = i; + break; + } + double cd2 = log(cd1); + wf[i] = cd1 / (1.0 + cd1); + double j = static_cast(i+1); + xx += j * j; + xy += j * cd2; + ym += cd2; + } + + // i0 should always be > 0 but in case something goes wrong make a check + if ( i0 > 0 ) + { + g_log.debug() << "Noise start index " << i0 << std::endl; + + // high frequency filter values: smooth decreasing function + double ri0f = static_cast(i0 + 1); + double xm = (1.0 + ri0f)/2; + ym /= ri0f; + double a1 = (xy - ri0f*xm*ym)/(xx-ri0f*xm*xm); + double b1 = ym - a1*xm; + + g_log.debug() << "(a1,b1) = (" << a1 << ',' << b1 << ')' << std::endl; + + const double dblev = -20.0; + // cut-off index + double ri1 = floor( (dblev/4-b1)/a1 ); + if ( ri1 < static_cast(i0) ) + { + g_log.warning() << "Failed to build Wiener filter: no smoothing." << std::endl; + ri1 = static_cast(i0); + } + size_t i1 = static_cast(ri1); + if ( i1 > n2 ) i1 = n2; + for(size_t i = i0; i < i1; ++i) + { + double s = exp(a1*static_cast(i+1)+b1); + wf[i] = s / (1.0 + s); + } + // wf[i] for i1 <= i < n2 are 0.0 + + g_log.debug() << "Cut-off index " << i1 << std::endl; + } + else + { + g_log.warning() << "Power spectrum has an unexpected shape: no smoothing" << std::endl; + } + + // multiply the fourier transform by the filter + auto &re = fourierOut->dataY(0); + auto &im = fourierOut->dataY(1); + std::transform( re.begin(), re.end(), wf.begin(), re.begin(), std::multiplies() ); + std::transform( im.begin(), im.end(), wf.begin(), im.begin(), std::multiplies() ); + + // inverse fourier transform + fourier = createChildAlgorithm( "RealFFT" ); + fourier->initialize(); + fourier->setProperty( "InputWorkspace", fourierOut ); + fourier->setProperty( "IgnoreXBins", true ); + fourier->setPropertyValue( "Transform", "Backward" ); + fourier->execute(); + + API::MatrixWorkspace_sptr out = fourier->getProperty("OutputWorkspace"); + auto &background = fitOut->readY(1); + auto &y = out->dataY(0); + + // add the spline "background" to the smoothed data + std::transform( y.begin(), y.end(), background.begin(), y.begin(), std::plus() ); + + // copy the x-values and errors from the original spectrum + // remove the last values for odd-sized inputs + if ( isOddSize ) + { + out->dataX(0).assign( X.begin(), X.end() - 1 ); + out->dataE(0).assign( E.begin(), E.end() - 1 ); + out->dataY(0).resize( Y.size() - 1 ); + } + else + { + out->setX(0, X ); + out->dataE(0).assign(E.begin(),E.end()); + } + + // set the output + setProperty( "OutputWorkspace", out ); + } + + /** + * Get the start and end of the x-interval. + * @param X :: The x-vector of a spectrum. + * @param isHistogram :: Is the x-vector comming form a histogram? If it's true the bin + * centres are used. + * @return :: A pair of start x and end x. + */ + std::pair WienerSmooth::getStartEnd( const MantidVec& X, bool isHistogram ) const + { + const size_t n = X.size(); + if ( n < 3 ) + { + // 3 is the smallest number for this method to work without breaking + throw std::runtime_error("Number of bins/data points cannot be smaller than 3."); + } + if ( isHistogram ) + { + return std::make_pair( (X[0] + X[1])/2, (X[n-1] + X[n-2])/2 ); + } + // else + return std::make_pair( X.front(), X.back() ); + } + + /** + * Exctract the input spectrum into a separate workspace. + * @param inputWS :: The input workspace. + * @param wsIndex :: The index of the input spectrum. + * @return :: Workspace with the copied spectrum. + */ + API::MatrixWorkspace_sptr WienerSmooth::copyInput(API::MatrixWorkspace_sptr inputWS, size_t wsIndex) + { + auto alg = createChildAlgorithm("ExtractSingleSpectrum"); + alg->initialize(); + alg->setProperty("InputWorkspace", inputWS); + alg->setProperty("WorkspaceIndex", static_cast(wsIndex)); + alg->execute(); + API::MatrixWorkspace_sptr ws = alg->getProperty("OutputWorkspace"); + return ws; + } + +} // namespace Algorithms +} // namespace Mantid \ No newline at end of file diff --git a/Code/Mantid/Framework/Algorithms/test/AnnularRingAbsorptionTest.h b/Code/Mantid/Framework/Algorithms/test/AnnularRingAbsorptionTest.h new file mode 100644 index 000000000000..1772fd0a1257 --- /dev/null +++ b/Code/Mantid/Framework/Algorithms/test/AnnularRingAbsorptionTest.h @@ -0,0 +1,143 @@ +#ifndef MANTID_ALGORITHMS_ANNULARRINGABSORPTIONTEST_H_ +#define MANTID_ALGORITHMS_ANNULARRINGABSORPTIONTEST_H_ + +#include + +#include "MantidAlgorithms/AnnularRingAbsorption.h" +#include "MantidAPI/FrameworkManager.h" +#include "MantidAPI/Sample.h" +#include "MantidKernel/UnitFactory.h" + +#include "MantidTestHelpers/WorkspaceCreationHelper.h" + +using Mantid::Algorithms::AnnularRingAbsorption; + +class AnnularRingAbsorptionTest : 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 AnnularRingAbsorptionTest *createSuite() { return new AnnularRingAbsorptionTest(); } + static void destroySuite( AnnularRingAbsorptionTest *suite ) { delete suite; } + + void test_Init() + { + AnnularRingAbsorption alg; + TS_ASSERT_THROWS_NOTHING( alg.initialize() ) + TS_ASSERT( alg.isInitialized() ) + } + + //-------------------- Success cases -------------------------------- + + void test_Algorithm_Attaches_Sample_To_InputWorkspace_And_Produces_Correct_Result() + { + using namespace Mantid::API; + + auto alg = createAlgorithmForTestCan(); + auto inputWS = createInputWorkspace(); + + TS_ASSERT_THROWS_NOTHING( alg->setProperty("InputWorkspace", inputWS) ); + TS_ASSERT_THROWS_NOTHING( alg->setPropertyValue("OutputWorkspace", "UnusedForChild") ); + const int numOMPThreads = FrameworkManager::Instance().getNumOMPThreads(); + FrameworkManager::Instance().setNumOMPThreads(1); // To ensure reproducible results + TS_ASSERT_THROWS_NOTHING(alg->execute()); + FrameworkManager::Instance().setNumOMPThreads(numOMPThreads); + TS_ASSERT( alg->isExecuted() ); + + MatrixWorkspace_sptr outWS = alg->getProperty("OutputWorkspace"); + TS_ASSERT(outWS); + + const double delta(1e-08); + const size_t middle_index = 4; + TS_ASSERT_DELTA(outWS->readY(0).front(), 0.984770748517, delta); + TS_ASSERT_DELTA(outWS->readY(0)[middle_index], 0.896084505371, delta); + TS_ASSERT_DELTA(outWS->readY(0).back(), 0.807794634447, delta); + } + + //-------------------- Failure cases -------------------------------- + + void test_Workspace_With_No_Instrument_Is_Not_Accepted() + { + using Mantid::API::MatrixWorkspace_sptr; + + auto alg = createAlgorithm(); + // Create a simple test workspace that has no instrument + auto testWS = WorkspaceCreationHelper::Create2DWorkspace(10, 5); + + TS_ASSERT_THROWS(alg->setProperty("InputWorkspace", testWS), + std::invalid_argument); + } + + void test_Workspace_With_Units_Not_In_Wavelength_Is_Not_Accepted() + { + using Mantid::API::MatrixWorkspace_sptr; + + auto alg = createAlgorithm(); + // Create a simple test workspace that has no instrument + auto inputWS = WorkspaceCreationHelper::create2DWorkspaceWithFullInstrument(1, 5); + + TS_ASSERT_THROWS(alg->setProperty("InputWorkspace", inputWS), + std::invalid_argument); + } + + void test_Invalid_Sample_Material_Throws_Error() + { + using Mantid::API::MatrixWorkspace_sptr; + + auto alg = createAlgorithmForTestCan(); + auto inputWS = createInputWorkspace(); + + TS_ASSERT_THROWS_NOTHING( alg->setProperty("InputWorkspace", inputWS) ); + TS_ASSERT_THROWS_NOTHING( alg->setProperty("SampleChemicalFormula", "A-lO") ); + TS_ASSERT_THROWS(alg->execute(), std::invalid_argument ); + TS_ASSERT( !alg->isExecuted() ); + } + + //-------------------- Helpers -------------------------------------- + +private: + + Mantid::API::IAlgorithm_sptr createAlgorithmForTestCan() + { + auto alg = createAlgorithm(); + + TS_ASSERT_THROWS_NOTHING( alg->setPropertyValue("OutputWorkspace", "UnusedForChild") ); + + TS_ASSERT_THROWS_NOTHING( alg->setProperty("CanOuterRadius", 1.1) ); + TS_ASSERT_THROWS_NOTHING( alg->setProperty("CanInnerRadius", 0.92) ); + + TS_ASSERT_THROWS_NOTHING( alg->setProperty("SampleHeight", 3.8) ); + TS_ASSERT_THROWS_NOTHING( alg->setProperty("SampleThickness", 0.05) ); + TS_ASSERT_THROWS_NOTHING( alg->setProperty("SampleChemicalFormula", "Li2-Ir-O3") ); + TS_ASSERT_THROWS_NOTHING( alg->setProperty("SampleNumberDensity", 0.004813) ); + + TS_ASSERT_THROWS_NOTHING( alg->setProperty("NumberOfWavelengthPoints", 5000) ); + TS_ASSERT_THROWS_NOTHING( alg->setProperty("EventsPerPoint", 300) ); + + return alg; + } + + + Mantid::API::IAlgorithm_sptr createAlgorithm() + { + auto alg = boost::shared_ptr(new AnnularRingAbsorption()); + alg->initialize(); + alg->setChild(true); + alg->setRethrows(true); + return alg; + } + + Mantid::API::MatrixWorkspace_sptr createInputWorkspace() + { + const int nspectra(1), nbins(9); + auto inputWS = WorkspaceCreationHelper::create2DWorkspaceWithFullInstrument(nspectra, nbins); + // Needs to have units of wavelength + inputWS->getAxis(0)->unit() = Mantid::Kernel::UnitFactory::Instance().create("Wavelength"); + + return inputWS; + } + +}; + + +#endif /* MANTID_ALGORITHMS_ANNULARRINGABSORPTIONTEST_H_ */ diff --git a/Code/Mantid/Framework/Algorithms/test/CheckWorkspacesMatchTest.h b/Code/Mantid/Framework/Algorithms/test/CheckWorkspacesMatchTest.h index cc64c202e0ec..38c14708fdb1 100644 --- a/Code/Mantid/Framework/Algorithms/test/CheckWorkspacesMatchTest.h +++ b/Code/Mantid/Framework/Algorithms/test/CheckWorkspacesMatchTest.h @@ -688,7 +688,7 @@ class CheckWorkspacesMatchTest : public CxxTest::TestSuite TS_ASSERT_THROWS_NOTHING( checker.setProperty("Workspace2",ws3) ); TS_ASSERT( checker.execute() ); - TS_ASSERT_EQUALS( checker.getPropertyValue("Result"), "Log name mismatch" ); + TS_ASSERT_EQUALS( checker.getPropertyValue("Result"), "Log mismatch" ); Mantid::API::MatrixWorkspace_sptr ws4 = WorkspaceCreationHelper::Create2DWorkspace123(2,2); ws4->mutableRun().addLogData(new Mantid::Kernel::PropertyWithValue("Prop1",100)); @@ -697,7 +697,7 @@ class CheckWorkspacesMatchTest : public CxxTest::TestSuite TS_ASSERT_THROWS_NOTHING( checker.setProperty("Workspace2",ws4) ); TS_ASSERT( checker.execute() ); - TS_ASSERT_EQUALS( checker.getPropertyValue("Result"), "Log value mismatch" ); + TS_ASSERT_EQUALS( checker.getPropertyValue("Result"), "Log mismatch" ); } void test_Input_With_Two_Groups_That_Are_The_Same_Matches() diff --git a/Code/Mantid/Framework/Algorithms/test/ConvertMDHistoToMatrixWorkspaceTest.h b/Code/Mantid/Framework/Algorithms/test/ConvertMDHistoToMatrixWorkspaceTest.h index f55cb3de319e..5f2624525521 100644 --- a/Code/Mantid/Framework/Algorithms/test/ConvertMDHistoToMatrixWorkspaceTest.h +++ b/Code/Mantid/Framework/Algorithms/test/ConvertMDHistoToMatrixWorkspaceTest.h @@ -16,6 +16,8 @@ #include "MantidTestHelpers/MDEventsTestHelper.h" #include "MantidTestHelpers/WorkspaceCreationHelper.h" +#include + using namespace Mantid; using namespace Mantid::API; using namespace Mantid::Kernel; @@ -78,6 +80,151 @@ class ConvertMDHistoToMatrixWorkspaceTest : public CxxTest::TestSuite return out_ws; } + /** + * Test convesion of a MD workspace to a 2D MatrixWorkspace. + * + * @param ndims :: Number of dimensions in the input MDHistoWorkspace. ndims >= 2. + * @param nonIntegr :: Indices of the non-integrated dimensions. There must be 2 of them to pass the test. + */ + void do_test_2D_slice(size_t ndims, std::vector nonIntegr) + { + // prepare input workspace + + // create an MD histo workspace + size_t size = 1; + // property values for CreateMDHistoWorkspace + std::vector extents(ndims*2); + std::vector numberOfBins(ndims); + std::vector names(ndims); + std::vector units(ndims); + // property values for SliceMDHisto + std::vector start(ndims); + std::vector end(ndims); + for(size_t i = 0; i < ndims; ++i) + { + size_t nbins = 3 + i; + size *= nbins; + numberOfBins[i] = static_cast(nbins); + extents[2*i] = 0.0; + extents[2*i+1] = static_cast(nbins); + names[i] = "x_" + boost::lexical_cast(i); + if ( nonIntegr.end() != std::find( nonIntegr.begin(), nonIntegr.end(), i) ) + { + // if it's a non-integrated dimension - don't slice + end[i] = static_cast(nbins); + } + else + { + end[i] = 1; + } + } + std::vector data(size); + std::vector error(size); + + auto alg = AlgorithmManager::Instance().create("CreateMDHistoWorkspace"); + alg->initialize(); + alg->setRethrows(true); + alg->setChild(true); + alg->setProperty("SignalInput", data); + alg->setProperty("ErrorInput", error); + alg->setProperty("Dimensionality", static_cast(ndims)); + alg->setProperty("Extents", extents); + alg->setProperty("NumberOfBins", numberOfBins); + alg->setProperty("Names", names); + alg->setProperty("Units", units); + alg->setPropertyValue("OutputWorkspace", "_"); // Not really required for child algorithm + + try + { + alg->execute(); + } + catch(std::exception& e) + { + TS_FAIL(e.what()); + } + + // slice the md ws to make it acceptable by ConvertMDHistoToMatrixWorkspace + IMDHistoWorkspace_sptr ws = alg->getProperty("OutputWorkspace"); + TS_ASSERT( ws ); + + alg = AlgorithmManager::Instance().create("SliceMDHisto"); + alg->initialize(); + alg->setRethrows(true); + alg->setChild(true); + alg->setProperty("InputWorkspace", ws); + alg->setProperty("Start", start); + alg->setProperty("End", end); + alg->setPropertyValue("OutputWorkspace", "_1"); // Not really required for child algorithm + + try + { + alg->execute(); + } + catch(std::exception& e) + { + TS_FAIL(e.what()); + } + + IMDHistoWorkspace_sptr slice = alg->getProperty("OutputWorkspace"); + TS_ASSERT( slice ); + + // test ConvertMDHistoToMatrixWorkspace + + alg = AlgorithmManager::Instance().create("ConvertMDHistoToMatrixWorkspace"); + alg->initialize(); + alg->setRethrows(true); + alg->setChild(true); + alg->setProperty("InputWorkspace", slice); + alg->setPropertyValue("OutputWorkspace", "_2"); // Not really required for child algorithm + + if ( nonIntegr.size() > 2 || nonIntegr.empty() ) + { + TS_ASSERT_THROWS( alg->execute(), std::invalid_argument ); + } + else + { + try + { + alg->execute(); + } + catch(std::exception& e) + { + TS_FAIL(e.what()); + } + + + MatrixWorkspace_sptr matrix = alg->getProperty("OutputWorkspace"); + TS_ASSERT( matrix ); + + if ( nonIntegr.size() == 1 ) + { + TS_ASSERT_EQUALS( matrix->getNumberHistograms(), 1 ); + } + + if ( nonIntegr.size() >= 1 ) + { + auto xDim = slice->getDimension(nonIntegr[0]); + TS_ASSERT_EQUALS( xDim->getNBins(), matrix->blocksize() ); + for(size_t i = 0; i < matrix->getNumberHistograms(); ++i) + { + TS_ASSERT_EQUALS( matrix->readX(i).front(), xDim->getMinimum() ); + TS_ASSERT_EQUALS( matrix->readX(i).back(), xDim->getMaximum() ); + } + } + else if ( nonIntegr.size() == 2 ) + { + auto yDim = slice->getDimension(nonIntegr[1]); + TS_ASSERT_EQUALS( yDim->getNBins(), matrix->getNumberHistograms() ); + auto axis = matrix->getAxis(1); + TS_ASSERT_EQUALS( axis->getMin(), yDim->getMinimum() ); + TS_ASSERT_EQUALS( axis->getMax(), yDim->getMaximum() ); + } + + } + + AnalysisDataService::Instance().clear(); + } + public: ConvertMDHistoToMatrixWorkspaceTest() @@ -103,7 +250,7 @@ class ConvertMDHistoToMatrixWorkspaceTest : public CxxTest::TestSuite const size_t n_dims = 1; const double signal = 1; const double error_sq = 0; - size_t nbins[1] = {1}; + size_t nbins[1] = {2}; coord_t min[1] = {-1}; coord_t max[1] = {1}; @@ -130,6 +277,107 @@ class ConvertMDHistoToMatrixWorkspaceTest : public CxxTest::TestSuite } + void test_2D_slice_0() + { + // 4D sliced to 2D + std::vector nonIntegr(2); + nonIntegr[0] = 0; + nonIntegr[1] = 1; + do_test_2D_slice(4,nonIntegr); + } + + void test_2D_slice_1() + { + // 4D unsliced + do_test_2D_slice(4,std::vector()); + } + + void test_2D_slice_2() + { + // 4D sliced to 3D + std::vector nonIntegr(3); + nonIntegr[0] = 0; + nonIntegr[1] = 1; + nonIntegr[2] = 2; + do_test_2D_slice(4,nonIntegr); + } + + void test_2D_slice_3() + { + // 4D sliced to 2D + std::vector nonIntegr(2); + nonIntegr[0] = 0; + nonIntegr[1] = 2; + do_test_2D_slice(4,nonIntegr); + } + + void test_2D_slice_4() + { + // 4D sliced to 2D + std::vector nonIntegr(2); + nonIntegr[0] = 0; + nonIntegr[1] = 3; + do_test_2D_slice(4,nonIntegr); + } + + void test_2D_slice_5() + { + // 4D sliced to 2D + std::vector nonIntegr(2); + nonIntegr[0] = 1; + nonIntegr[1] = 3; + do_test_2D_slice(4,nonIntegr); + } + + void test_2D_slice_6() + { + // 3D sliced to 2D + std::vector nonIntegr(2); + nonIntegr[0] = 1; + nonIntegr[1] = 2; + do_test_2D_slice(3,nonIntegr); + } + + void test_2D_slice_7() + { + // 4D sliced to 1D + std::vector nonIntegr(1,0); + do_test_2D_slice(4,nonIntegr); + } + + void test_2D_slice_8() + { + // 4D sliced to 1D + std::vector nonIntegr(1,1); + do_test_2D_slice(4,nonIntegr); + } + + void test_2D_slice_9() + { + // 4D sliced to 1D + std::vector nonIntegr(1,2); + do_test_2D_slice(4,nonIntegr); + } + + void test_2D_slice_10() + { + // 4D sliced to 1D + std::vector nonIntegr(1,3); + do_test_2D_slice(4,nonIntegr); + } + + void test_2D_slice_11() + { + // 2D unsliced + do_test_2D_slice(2,std::vector()); + } + + void test_2D_slice_12() + { + // 1D unsliced + do_test_2D_slice(1,std::vector()); + } + }; diff --git a/Code/Mantid/Framework/Algorithms/test/CopySampleTest.h b/Code/Mantid/Framework/Algorithms/test/CopySampleTest.h index d3a0aad1fe26..3c5c3403f3de 100644 --- a/Code/Mantid/Framework/Algorithms/test/CopySampleTest.h +++ b/Code/Mantid/Framework/Algorithms/test/CopySampleTest.h @@ -3,7 +3,6 @@ #include #include "MantidKernel/Timer.h" -#include "MantidKernel/System.h" #include #include @@ -20,6 +19,7 @@ #include "MantidMDEvents/MDEvent.h" #include "MantidMDEvents/MDEventFactory.h" #include "MantidMDEvents/MDEventWorkspace.h" +#include "MantidTestHelpers/ComponentCreationHelper.h" using namespace Mantid; using namespace Mantid::Algorithms; @@ -33,7 +33,7 @@ class CopySampleTest : public CxxTest::TestSuite { public: - + void test_Init() { CopySample alg; @@ -41,38 +41,21 @@ class CopySampleTest : public CxxTest::TestSuite TS_ASSERT( alg.isInitialized() ) } - Object_sptr createCappedCylinder(double radius, double height, const V3D & baseCentre, const V3D & axis, const std::string & id) - { - std::ostringstream xml; - xml << "" - << "" - << "" - << "" - << "" << ""; - ShapeFactory shapeMaker; - return shapeMaker.createShape(xml.str()); - } - ObjComponent * createSingleObjectComponent() - { - Object_sptr pixelShape = createCappedCylinder(0.5, 1.5, V3D(0.0,0.0,0.0), V3D(0.,1.0,0.), "tube"); - return new ObjComponent("pixel", pixelShape); - } - Sample createsample() { Sample sample; sample.setName("test"); const std::string envName("TestKit"); SampleEnvironment *kit = new SampleEnvironment(envName); - kit->add(createSingleObjectComponent()); + auto shape = ComponentCreationHelper::createCappedCylinder(0.5, 1.5, V3D(0.0,0.0,0.0), V3D(0.,1.0,0.), "tube"); + kit->add(*shape); sample.setEnvironment(kit); OrientedLattice *latt = new OrientedLattice(1.0,2.0,3.0, 90, 90, 90); sample.setOrientedLattice(latt); delete latt; - Material vanBlock("vanBlock", Mantid::PhysicalConstants::getNeutronAtom(23, 0), 0.072); - sample.setMaterial(vanBlock); - Object_sptr shape_sptr = - createCappedCylinder(0.0127, 1.0, V3D(), V3D(0.0, 1.0, 0.0), "cyl"); + Object_sptr shape_sptr = \ + ComponentCreationHelper::createCappedCylinder(0.0127, 1.0, V3D(), V3D(0.0, 1.0, 0.0), "cyl"); + shape_sptr->setMaterial(Material("vanBlock", Mantid::PhysicalConstants::getNeutronAtom(23, 0), 0.072)); sample.setShape(*shape_sptr); return sample; } @@ -103,7 +86,7 @@ class CopySampleTest : public CxxTest::TestSuite TS_ASSERT_THROWS_NOTHING( alg.execute(); ); TS_ASSERT( alg.isExecuted() ); - + // Retrieve the workspace from data service. MatrixWorkspace_sptr ws; TS_ASSERT_THROWS_NOTHING( ws = AnalysisDataService::Instance().retrieveWS(outWSName) ); @@ -114,7 +97,7 @@ class CopySampleTest : public CxxTest::TestSuite Sample copy=ws->mutableSample(); TS_ASSERT_EQUALS(copy.getName(),"test" ); TS_ASSERT_EQUALS(copy.getOrientedLattice().c(), 3.0); - TS_ASSERT_EQUALS(copy.getEnvironment().getName(), "TestKit"); + TS_ASSERT_EQUALS(copy.getEnvironment().name(), "TestKit"); TS_ASSERT_EQUALS(copy.getEnvironment().nelements(), 1); TS_ASSERT_DELTA(copy.getMaterial().cohScatterXSection(2.1), 0.0184, 1e-02); TS_ASSERT_EQUALS(copy.getShape().getName(),s.getShape().getName()); @@ -123,7 +106,7 @@ class CopySampleTest : public CxxTest::TestSuite AnalysisDataService::Instance().remove(inWSName); AnalysisDataService::Instance().remove(outWSName); } - + void test_exec_some() { @@ -162,7 +145,7 @@ class CopySampleTest : public CxxTest::TestSuite Sample copy=ws->mutableSample(); TS_ASSERT_DIFFERS(copy.getName(),"test" ); TS_ASSERT(!copy.hasOrientedLattice()); - TS_ASSERT_EQUALS(copy.getEnvironment().getName(), "TestKit"); + TS_ASSERT_EQUALS(copy.getEnvironment().name(), "TestKit"); TS_ASSERT_EQUALS(copy.getEnvironment().nelements(), 1); TS_ASSERT_DELTA(copy.getMaterial().cohScatterXSection(2.1), 0.0184, 1e-02); TS_ASSERT_DIFFERS(copy.getShape().getName(),s.getShape().getName()); diff --git a/Code/Mantid/Framework/Algorithms/test/CorelliCrossCorrelateTest.h b/Code/Mantid/Framework/Algorithms/test/CorelliCrossCorrelateTest.h new file mode 100644 index 000000000000..b4c9bed5adb2 --- /dev/null +++ b/Code/Mantid/Framework/Algorithms/test/CorelliCrossCorrelateTest.h @@ -0,0 +1,103 @@ +#ifndef MANTID_ALGORITHMS_CORELLICROSSCORRELATETEST_H_ +#define MANTID_ALGORITHMS_CORELLICROSSCORRELATETEST_H_ + +#include + +#include "MantidAlgorithms/CorelliCrossCorrelate.h" +#include "MantidKernel/DateAndTime.h" +#include "MantidDataObjects/EventWorkspace.h" +#include "MantidKernel/TimeSeriesProperty.h" + +using Mantid::Algorithms::CorelliCrossCorrelate; +using namespace Mantid::API; +using namespace Mantid::DataObjects; +using namespace Mantid::Kernel; + +class CorelliCrossCorrelateTest : 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 CorelliCrossCorrelateTest *createSuite() { + return new CorelliCrossCorrelateTest(); + } + static void destroySuite(CorelliCrossCorrelateTest *suite) { delete suite; } + + void test_Init() { + CorelliCrossCorrelate alg; + TS_ASSERT_THROWS_NOTHING(alg.initialize()) + TS_ASSERT(alg.isInitialized()) + } + + void test_exec() { + // Name of the output workspace. + std::string outWSName("CorelliCrossCorrelateTest_OutputWS"); + + IAlgorithm_sptr lei = + AlgorithmFactory::Instance().create("LoadEmptyInstrument", 1); + lei->initialize(); + lei->setPropertyValue("Filename", "CORELLI_Definition.xml"); + lei->setPropertyValue("OutputWorkspace", + "CorelliCrossCorrelateTest_OutputWS"); + lei->setPropertyValue("MakeEventWorkspace", "1"); + lei->execute(); + + EventWorkspace_sptr ws; + ws = AnalysisDataService::Instance().retrieveWS( + "CorelliCrossCorrelateTest_OutputWS"); + + DateAndTime startTime("2007-11-30T16:17:00"); + EventList *evlist = ws->getEventListPtr(0); + + // Add some events to the workspace. + evlist->addEventQuickly(TofEvent(10.0, startTime + 0.007)); + evlist->addEventQuickly(TofEvent(100.0, startTime + 0.012)); + evlist->addEventQuickly(TofEvent(1000.0, startTime + 0.012)); + evlist->addEventQuickly(TofEvent(10000.0, startTime + 0.012)); + evlist->addEventQuickly(TofEvent(1222.0, startTime + 0.03)); + + ws->getAxis(0)->setUnit("TOF"); + + ws->sortAll(PULSETIME_SORT, NULL); + + // Add some chopper TDCs to the workspace. + double period = 1 / 293.383; + auto tdc = new TimeSeriesProperty("chopper4_TDC"); + for (int i = 0; i < 10; i++) { + double tdcTime = i * period; + tdc->addValue(startTime + tdcTime, 1); + } + ws->mutableRun().addLogData(tdc); + + CorelliCrossCorrelate alg; + TS_ASSERT_THROWS_NOTHING(alg.initialize()) + TS_ASSERT(alg.isInitialized()) + TS_ASSERT_THROWS_NOTHING(alg.setPropertyValue( + "InputWorkspace", "CorelliCrossCorrelateTest_OutputWS")); + TS_ASSERT_THROWS_NOTHING(alg.setPropertyValue( + "OutputWorkspace", "CorelliCrossCorrelateTest_OutputWS")); + TS_ASSERT_THROWS_NOTHING(alg.setPropertyValue("TimingOffset", "20000")); + TS_ASSERT_THROWS_NOTHING(alg.execute();); + TS_ASSERT(alg.isExecuted()); + + // Retrieve the workspace from data service. + TS_ASSERT_THROWS_NOTHING( + ws = AnalysisDataService::Instance().retrieveWS( + "CorelliCrossCorrelateTest_OutputWS")); + TS_ASSERT(ws); + if (!ws) + return; + + std::vector &events = evlist->getWeightedEvents(); + + TS_ASSERT_DELTA(events[0].weight(), -1.99392, 0.00001) + TS_ASSERT_DELTA(events[1].weight(), -1.99392, 0.00001) + TS_ASSERT_DELTA(events[2].weight(), 2.00612, 0.00001) + TS_ASSERT_DELTA(events[3].weight(), -1.99392, 0.00001) + TS_ASSERT_DELTA(events[4].weight(), 2.00612, 0.00001) + + // Remove workspace from the data service. + AnalysisDataService::Instance().remove(outWSName); + } +}; + +#endif /* MANTID_ALGORITHMS_CORELLICROSSCORRELATETEST_H_ */ diff --git a/Code/Mantid/Framework/Algorithms/test/CreateGroupingWorkspaceTest.h b/Code/Mantid/Framework/Algorithms/test/CreateGroupingWorkspaceTest.h index f66cf9a5994f..1c6da9d70818 100644 --- a/Code/Mantid/Framework/Algorithms/test/CreateGroupingWorkspaceTest.h +++ b/Code/Mantid/Framework/Algorithms/test/CreateGroupingWorkspaceTest.h @@ -28,7 +28,6 @@ class CreateGroupingWorkspaceTest : public CxxTest::TestSuite void doTest(std::string outWSName) { - // Retrieve the workspace from data service. GroupingWorkspace_sptr ws; TS_ASSERT_THROWS_NOTHING( ws = AnalysisDataService::Instance().retrieveWS(outWSName) ); @@ -83,7 +82,6 @@ class CreateGroupingWorkspaceTest : public CxxTest::TestSuite TS_ASSERT_EQUALS(static_cast(alg.getProperty("NumberGroupedSpectraResult")), 0); TS_ASSERT_EQUALS(static_cast(alg.getProperty("NumberGroupsResult")), 0); } - void test_exec_WithBankNames() @@ -149,6 +147,32 @@ class CreateGroupingWorkspaceTest : public CxxTest::TestSuite AnalysisDataService::Instance().remove(outWSName); } + void test_exec_WithFixedGroups() + { + // Name of the output workspace. + std::string outWSName("CreateGroupingWorkspaceTest_OutputWS"); + + CreateGroupingWorkspace alg; + TS_ASSERT_THROWS_NOTHING( alg.initialize() ) + TS_ASSERT( alg.isInitialized() ) + TS_ASSERT_THROWS_NOTHING( alg.setPropertyValue("InstrumentName", "IRIS") ); + TS_ASSERT_THROWS_NOTHING( alg.setProperty("FixedGroupCount", 10) ); + TS_ASSERT_THROWS_NOTHING( alg.setPropertyValue("ComponentName", "graphite") ); + TS_ASSERT_THROWS_NOTHING( alg.setPropertyValue("OutputWorkspace", outWSName) ); + TS_ASSERT_THROWS_NOTHING( alg.execute(); ); + TS_ASSERT( alg.isExecuted() ); + + // Retrieve the workspace from data service. + GroupingWorkspace_sptr ws; + TS_ASSERT_THROWS_NOTHING( ws = AnalysisDataService::Instance().retrieveWS(outWSName) ); + TS_ASSERT(ws); + if (!ws) return; + + TS_ASSERT_EQUALS(static_cast(alg.getProperty("NumberGroupedSpectraResult")), 50); + TS_ASSERT_EQUALS(static_cast(alg.getProperty("NumberGroupsResult")), 10); + + AnalysisDataService::Instance().remove(outWSName); + } }; diff --git a/Code/Mantid/Framework/Algorithms/test/ElasticWindowTest.h b/Code/Mantid/Framework/Algorithms/test/ElasticWindowTest.h new file mode 100644 index 000000000000..9c0104fb8b98 --- /dev/null +++ b/Code/Mantid/Framework/Algorithms/test/ElasticWindowTest.h @@ -0,0 +1,192 @@ +#ifndef MANTID_ALGORITHMS_ELASTICWINDOWTEST_H_ +#define MANTID_ALGORITHMS_ELASTICWINDOWTEST_H_ + +#include + +#include +#include + +#include "MantidKernel/System.h" + +#include "MantidAlgorithms/ConvertUnits.h" +#include "MantidAlgorithms/ConvertSpectrumAxis.h" +#include "MantidAlgorithms/CreateSampleWorkspace.h" +#include "MantidAlgorithms/ElasticWindow.h" +#include "MantidAlgorithms/Rebin.h" +#include "MantidAlgorithms/SetInstrumentParameter.h" + +using namespace Mantid; +using namespace Mantid::Algorithms; +using namespace Mantid::API; +using namespace Mantid::Kernel; +using namespace Mantid::Kernel::Units; + +class ElasticWindowTest : public CxxTest::TestSuite +{ +public: + + void setUp() + { + // Create a workspace and format it for the ElasticWindow algorithm + + CreateSampleWorkspace createAlg; + createAlg.initialize(); + createAlg.setProperty("Function", "User Defined"); + createAlg.setProperty("UserDefinedFunction", "name=Lorentzian,Amplitude=100,PeakCentre=12700,FWHM=20;name=LinearBackground,A0=0.01"); + createAlg.setProperty("XMin", 27000.0); + createAlg.setProperty("XMax", 28000.0); + createAlg.setProperty("BinWidth", 10.0); + createAlg.setProperty("NumBanks", 1); + createAlg.setProperty("OutputWorkspace", "__ElasticWindowTest_sample"); + createAlg.execute(); + + ConvertUnits convertUnitsAlg; + convertUnitsAlg.initialize(); + convertUnitsAlg.setProperty("InputWorkspace", "__ElasticWindowTest_sample"); + convertUnitsAlg.setProperty("Target", "DeltaE"); + convertUnitsAlg.setProperty("EMode", "Indirect"); + convertUnitsAlg.setProperty("Efixed", 1.555); + convertUnitsAlg.setProperty("OutputWorkspace", "__ElasticWindowTest_sample"); + convertUnitsAlg.execute(); + + Rebin rebinAlg; + rebinAlg.initialize(); + rebinAlg.setProperty("InputWorkspace", "__ElasticWindowTest_sample"); + rebinAlg.setProperty("Params", "-0.2,0.004,0.2"); + rebinAlg.setProperty("OutputWorkspace", "__ElasticWindowTest_sample"); + rebinAlg.execute(); + + SetInstrumentParameter setParamAlg; + setParamAlg.initialize(); + setParamAlg.setProperty("Workspace", "__ElasticWindowTest_sample"); + setParamAlg.setProperty("ParameterName", "Efixed"); + setParamAlg.setProperty("ParameterType", "Number"); + setParamAlg.setProperty("Value", "1.555"); + setParamAlg.execute(); + } + + /** + * Converts the generated sample workspace spectra axis to Q. + */ + void convertSampleWsToQ() + { + ConvertSpectrumAxis convQAlg; + convQAlg.initialize(); + + TS_ASSERT_THROWS_NOTHING( convQAlg.setProperty("InputWorkspace", "__ElasticWindowTest_sample") ); + TS_ASSERT_THROWS_NOTHING( convQAlg.setProperty("Target", "MomentumTransfer") ); + TS_ASSERT_THROWS_NOTHING( convQAlg.setProperty("EMode", "Indirect") ); + TS_ASSERT_THROWS_NOTHING( convQAlg.setProperty("OutputWorkspace", "__ElasticWindowTest_sample") ); + + TS_ASSERT_THROWS_NOTHING( convQAlg.execute() ); + TS_ASSERT( convQAlg.isExecuted() ); + } + + /** + * Test initialization of the algorithm is successful. + */ + void test_init() + { + ElasticWindow alg; + TS_ASSERT_THROWS_NOTHING(alg.initialize()); + TS_ASSERT(alg.isInitialized()); + } + + /** + * Test running ElasticWindow with just the peak range defined using reduced data. + */ + void test_redPeakOnly() + { + ElasticWindow elwinAlg; + elwinAlg.initialize(); + + TS_ASSERT_THROWS_NOTHING( elwinAlg.setProperty("InputWorkspace", "__ElasticWindowTest_sample") ); + TS_ASSERT_THROWS_NOTHING( elwinAlg.setProperty("Range1Start", -0.1) ); + TS_ASSERT_THROWS_NOTHING( elwinAlg.setProperty("Range1End", 0.1) ); + TS_ASSERT_THROWS_NOTHING( elwinAlg.setProperty("OutputInQ", "__ElasticWindowTest_outputQ") ); + TS_ASSERT_THROWS_NOTHING( elwinAlg.setProperty("OutputInQSquared", "__ElasticWindowTest_outputQsq") ); + + TS_ASSERT_THROWS_NOTHING( elwinAlg.execute() ); + TS_ASSERT( elwinAlg.isExecuted() ); + + MatrixWorkspace_sptr qWs = AnalysisDataService::Instance().retrieveWS("__ElasticWindowTest_outputQ"); + verifyQworkspace(qWs); + } + + /** + * Test running ElasticWindow with just the peak range defined using S(Q,w) data. + */ + void test_sqwPeakOnly() + { + // First convert the sample workspace from spectra number to elastic Q + convertSampleWsToQ(); + + ElasticWindow elwinAlg; + elwinAlg.initialize(); + + TS_ASSERT_THROWS_NOTHING( elwinAlg.setProperty("InputWorkspace", "__ElasticWindowTest_sample") ); + TS_ASSERT_THROWS_NOTHING( elwinAlg.setProperty("Range1Start", -0.1) ); + TS_ASSERT_THROWS_NOTHING( elwinAlg.setProperty("Range1End", 0.1) ); + TS_ASSERT_THROWS_NOTHING( elwinAlg.setProperty("OutputInQ", "__ElasticWindowTest_outputQ") ); + TS_ASSERT_THROWS_NOTHING( elwinAlg.setProperty("OutputInQSquared", "__ElasticWindowTest_outputQsq") ); + + TS_ASSERT_THROWS_NOTHING( elwinAlg.execute() ); + TS_ASSERT( elwinAlg.isExecuted() ); + + MatrixWorkspace_sptr qWs = AnalysisDataService::Instance().retrieveWS("__ElasticWindowTest_outputQ"); + verifyQworkspace(qWs); + } + + /** + * Test running ElasticWindow with both the peak and background ranges defined using reduced data. + */ + void test_redPeakAndBackground() + { + ElasticWindow elwinAlg; + elwinAlg.initialize(); + + TS_ASSERT_THROWS_NOTHING( elwinAlg.setProperty("InputWorkspace", "__ElasticWindowTest_sample") ); + TS_ASSERT_THROWS_NOTHING( elwinAlg.setProperty("Range1Start", -0.04) ); + TS_ASSERT_THROWS_NOTHING( elwinAlg.setProperty("Range1End", 0.04) ); + TS_ASSERT_THROWS_NOTHING( elwinAlg.setProperty("Range2Start", 0.05) ); + TS_ASSERT_THROWS_NOTHING( elwinAlg.setProperty("Range2End", 0.06) ); + TS_ASSERT_THROWS_NOTHING( elwinAlg.setProperty("OutputInQ", "__ElasticWindowTest_outputQ") ); + TS_ASSERT_THROWS_NOTHING( elwinAlg.setProperty("OutputInQSquared", "__ElasticWindowTest_outputQsq") ); + + TS_ASSERT_THROWS_NOTHING( elwinAlg.execute() ); + TS_ASSERT( elwinAlg.isExecuted() ); + + MatrixWorkspace_sptr qWs = AnalysisDataService::Instance().retrieveWS("__ElasticWindowTest_outputQ"); + verifyQworkspace(qWs); + + MatrixWorkspace_sptr q2Ws = AnalysisDataService::Instance().retrieveWS("__ElasticWindowTest_outputQsq"); + verifyQ2workspace(q2Ws); + } + +private: + + /** + * Ensures that a workspace is valid output in Q. + * + * @param ws Workspace to test + */ + void verifyQworkspace(MatrixWorkspace_sptr ws) + { + std::string unitID = ws->getAxis(0)->unit()->unitID(); + TS_ASSERT_EQUALS(unitID, "MomentumTransfer"); + } + + /** + * Ensures that a workspace is valid output in Q^2. + * + * @param ws Workspace to test + */ + void verifyQ2workspace(MatrixWorkspace_sptr ws) + { + std::string unitID = ws->getAxis(0)->unit()->unitID(); + TS_ASSERT_EQUALS(unitID, "QSquared"); + } + +}; + +#endif /* MANTID_ALGORITHMS_ELASTICWINDOWTEST_H_ */ diff --git a/Code/Mantid/Framework/Algorithms/test/ExponentialTest.h b/Code/Mantid/Framework/Algorithms/test/ExponentialTest.h index f2d4e18b547a..985ff4628d14 100644 --- a/Code/Mantid/Framework/Algorithms/test/ExponentialTest.h +++ b/Code/Mantid/Framework/Algorithms/test/ExponentialTest.h @@ -1,4 +1,4 @@ -#ifndef EXPONENTAILTEST_H_ +#ifndef EXPONENTIALTEST_H_ #define EXPONENTIALTEST_H_ #include diff --git a/Code/Mantid/Framework/Algorithms/test/IntegrationTest.h b/Code/Mantid/Framework/Algorithms/test/IntegrationTest.h index ab4498a01145..d3e1809ecb16 100644 --- a/Code/Mantid/Framework/Algorithms/test/IntegrationTest.h +++ b/Code/Mantid/Framework/Algorithms/test/IntegrationTest.h @@ -354,6 +354,102 @@ class IntegrationTest : public CxxTest::TestSuite doTestRebinned("-1.5", "1.75", 0, 3, true, 4, truth); } + void makeRealBinBoundariesWorkspace(const std::string inWsName) + { + const unsigned int lenX = 11, lenY = 10, lenE = lenY; + + Workspace_sptr wsAsWs = WorkspaceFactory::Instance().create("Workspace2D", 1, lenX, lenY); + Workspace2D_sptr ws = boost::dynamic_pointer_cast(wsAsWs); + + double x[lenX] = {-1, -0.8, -0.6, -0.4, -0.2, -2.22045e-16, 0.2, 0.4, 0.6, 0.8, 1}; + for (unsigned int i = 0; i < lenX; i++) + { + ws->dataX(0)[i] = x[i]; + // Generate some rounding errors. Note: if you increase errors by making this more complicated, + // you'll eventually make Integration "fail". + // Q is: how much tolerance should it have to inprecise numbers? For example, replace the 13.3 + // multiplier/divisor by 13, and you'll get a -0.199999... sufficiently different from the + // initial -0.2 that Integration will fail to catch one bin and because of that some tests will fail. + ws->dataX(0)[i] /= 2.5671; + ws->dataX(0)[i] *= 13.3; + ws->dataX(0)[i] /= 13.3; + ws->dataX(0)[i] *= 2.5671; + } + double y[lenY] = {0, 0, 0, 2, 2, 2, 2, 0 , 0, 0}; + for (unsigned int i = 0; i < lenY; i++) + { + ws->dataY(0)[i] = y[i]; + } + double e[lenE] = {0, 0, 0, 0, 0, 0, 0, 0 , 0, 0}; + for (unsigned int i = 0; i < lenE; i++) + { + ws->dataE(0)[i] = e[i]; + } + AnalysisDataService::Instance().add(inWsName, ws); + } + + void doTestRealBinBoundaries(const std::string inWsName, + const std::string rangeLower, + const std::string rangeUpper, + const double expectedVal, + const bool checkRanges = false, + const bool IncPartialBins = false) + { + Workspace_sptr auxWs; + TS_ASSERT_THROWS_NOTHING(auxWs = AnalysisDataService::Instance().retrieve(inWsName)); + Workspace2D_sptr inWs = boost::dynamic_pointer_cast(auxWs); + + std::string outWsName = "out_real_boundaries_ws"; + + Integration integ; + integ.initialize(); + integ.setPropertyValue("InputWorkspace", inWs->getName()); + integ.setPropertyValue("OutputWorkspace", outWsName); + integ.setPropertyValue("RangeLower", rangeLower); + integ.setPropertyValue("RangeUpper", rangeUpper); + integ.setProperty("IncludePartialBins", IncPartialBins); + integ.execute(); + + // should have created output work space + TS_ASSERT_THROWS_NOTHING(auxWs = AnalysisDataService::Instance().retrieve(outWsName)); + Workspace2D_sptr outWs = boost::dynamic_pointer_cast(auxWs); + TS_ASSERT_EQUALS(inWs->getNumberHistograms(), outWs->getNumberHistograms()); + + if (checkRanges) + { + TS_ASSERT_LESS_THAN_EQUALS(atof(rangeLower.c_str()), outWs->dataX(0).front()); + TS_ASSERT_LESS_THAN_EQUALS(outWs->dataX(0).back(), atof(rangeUpper.c_str())); + } + // At last, check numerical results + TS_ASSERT_DELTA(outWs->dataY(0)[0], expectedVal, 1e-8 ); + } + + void testProperHandlingOfIntegrationBoundaries() + { + std::string inWsName = "in_real_boundaries_ws"; + makeRealBinBoundariesWorkspace(inWsName); + + doTestRealBinBoundaries(inWsName, "-0.4", "-0.2", 2, true); + doTestRealBinBoundaries(inWsName, "-0.2", "-0.0", 2, true); + doTestRealBinBoundaries(inWsName, "-0.2", "0.2", 4, true); + doTestRealBinBoundaries(inWsName, "-0.2", "0.4", 6, true); + doTestRealBinBoundaries(inWsName, "-0.4", "0.2", 6, true); + doTestRealBinBoundaries(inWsName, "-0.4", "0.4", 8, true); + doTestRealBinBoundaries(inWsName, "-1", "1", 8, true); + doTestRealBinBoundaries(inWsName, "-1.8", "1.2", 8, true); + + doTestRealBinBoundaries(inWsName, "-0.4", "-0.200001", 0, true); + doTestRealBinBoundaries(inWsName, "-0.399999", "-0.2", 0, true); + doTestRealBinBoundaries(inWsName, "-0.399999", "-0.200001", 0, true); + doTestRealBinBoundaries(inWsName, "-0.3999", "-0.2", 0, true); + + doTestRealBinBoundaries(inWsName, "0.6", "6.5", 0, true); + doTestRealBinBoundaries(inWsName, "-1", "-0.8", 0, true); + doTestRealBinBoundaries(inWsName, "2.2", "3.03", 0); + doTestRealBinBoundaries(inWsName, "-42.2", "-3.03", 0); + + } + private: Integration alg; // Test with range limits Integration alg2; // Test without limits diff --git a/Code/Mantid/Framework/Algorithms/test/LorentzCorrectionTest.h b/Code/Mantid/Framework/Algorithms/test/LorentzCorrectionTest.h new file mode 100644 index 000000000000..bd553d7cea50 --- /dev/null +++ b/Code/Mantid/Framework/Algorithms/test/LorentzCorrectionTest.h @@ -0,0 +1,164 @@ +#ifndef MANTID_ALGORITHMS_LORENTZCORRECTIONTEST_H_ +#define MANTID_ALGORITHMS_LORENTZCORRECTIONTEST_H_ + +#include + +#include "MantidAlgorithms/LorentzCorrection.h" +#include "MantidTestHelpers/WorkspaceCreationHelper.h" +#include "MantidDataObjects/Workspace2D.h" +#include "MantidKernel/V3D.h" +#include "MantidGeometry/Instrument.h" +#include "MantidGeometry/Instrument/ReferenceFrame.h" +#include "MantidGeometry/Instrument/Detector.h" +#include "MantidGeometry/Instrument/ObjComponent.h" +#include + +using Mantid::Algorithms::LorentzCorrection; +using namespace Mantid::Kernel; +using namespace Mantid::API; +using namespace Mantid::Geometry; +using namespace WorkspaceCreationHelper; + +class LorentzCorrectionTest: public CxxTest::TestSuite +{ + +private: + + /* + * Calculate what the weight should be. + */ + double calculate_weight_at(MatrixWorkspace_sptr& ws, const int bin_index) + { + const Mantid::MantidVec& xData = ws->readX(0); + + auto detector = ws->getDetector(0); + double twotheta = ws->detectorTwoTheta(detector); + double lam = (xData[bin_index] + xData[bin_index + 1]) / 2; + double weight = std::sin(twotheta / 2); + weight = weight * weight; + weight = weight / (lam * lam * lam * lam); + return weight; + } + + /** + Create a workspace in wavelength with a simple instrument defined with a single detector. + */ + MatrixWorkspace_sptr create_workspace(const int nBins) + { + Instrument_sptr instrument = boost::make_shared(); + instrument->setReferenceFrame(boost::make_shared(Y, X, Left, "0,0,0")); + + ObjComponent *source = new ObjComponent("source"); + source->setPos(V3D(0, 0, 0)); + instrument->add(source); + instrument->markAsSource(source); + + ObjComponent *sample = new ObjComponent("some-surface-holder"); + source->setPos(V3D(15, 0, 0)); + instrument->add(sample); + instrument->markAsSamplePos(sample); + + Detector* det = new Detector("my-detector", 1, NULL); + det->setPos(20, (20 - sample->getPos().X()), 0); + instrument->add(det); + instrument->markAsDetector(det); + + const int nSpectra = 1; + const double deltaX = 10; + const double startX = 0; + auto workspace = Create2DWorkspaceBinned(nSpectra, nBins, startX, deltaX); // Creates histogram data + + auto & ydata = workspace->dataY(0); + auto & edata = workspace->dataE(0); + for (size_t i = 0; i < ydata.size(); ++i) + { + ydata[i] = 1; + edata[i] = 1; + } + + workspace->getAxis(0)->setUnit("Wavelength"); + workspace->setYUnit("Counts"); + workspace->setInstrument(instrument); + workspace->getSpectrum(0)->addDetectorID(det->getID()); + return workspace; + } + +public: + // This pair of boilerplate methods prevent the suite being created statically + // This means the constructor isn't called when running other tests + static LorentzCorrectionTest *createSuite() + { + return new LorentzCorrectionTest(); + } + static void destroySuite(LorentzCorrectionTest *suite) + { + delete suite; + } + + void test_init() + { + LorentzCorrection alg; + TS_ASSERT_THROWS_NOTHING( alg.initialize()) + TS_ASSERT( alg.isInitialized()) + } + + void test_check_input_units() + { + const int nHisto = 1; + const int nBins = 1; + auto ws_tof = create2DWorkspaceWithFullInstrument(nHisto, nBins); + + LorentzCorrection alg; + alg.setChild(true); + alg.initialize(); + TSM_ASSERT_THROWS("Workspace must be in units of wavelength", + alg.setProperty("InputWorkspace", ws_tof), std::invalid_argument&); + } + + void test_throws_if_wavelength_zero() + { + auto ws_lam = this->create_workspace(2 /*nBins*/); + ws_lam->dataX(0)[0] = 0; // Make wavelength zero + ws_lam->dataX(0)[1] = 0; // Make wavelength zero + LorentzCorrection alg; + alg.setChild(true); + alg.setRethrows(true); + alg.initialize(); + alg.setProperty("InputWorkspace", ws_lam); + alg.setPropertyValue("OutputWorkspace", "temp"); + TSM_ASSERT_THROWS("Should throw with zero wavelength values.", alg.execute(), std::runtime_error&); + } + + void test_execute() + { + auto ws_lam = this->create_workspace(2 /*nBins*/); + + LorentzCorrection alg; + alg.initialize(); + alg.setChild(true); + alg.setProperty("InputWorkspace", ws_lam); + alg.setPropertyValue("OutputWorkspace", "temp"); + alg.execute(); + MatrixWorkspace_sptr out_ws = alg.getProperty("OutputWorkspace"); + TS_ASSERT(out_ws != NULL); + + const std::string unitID = out_ws->getAxis(0)->unit()->unitID(); + TS_ASSERT_EQUALS(unitID, "Wavelength"); + + const Mantid::MantidVec& yData = out_ws->readY(0); + const Mantid::MantidVec& eData = out_ws->readE(0); + + int index = 0; + double weight = calculate_weight_at(out_ws, index /*y index*/); + TS_ASSERT_EQUALS(yData[index], weight); + TS_ASSERT_EQUALS(eData[index], weight); + + index++; // go to 1 + weight = calculate_weight_at(out_ws, index /*y index*/); + TS_ASSERT_EQUALS(yData[index], weight); + TS_ASSERT_EQUALS(eData[index], weight); + } + +}; + +#endif /* MANTID_ALGORITHMS_LORENTZCORRECTIONTEST_H_ */ diff --git a/Code/Mantid/Framework/Algorithms/test/MonteCarloAbsorptionTest.h b/Code/Mantid/Framework/Algorithms/test/MonteCarloAbsorptionTest.h index 317d9a15efba..9347e30699b7 100644 --- a/Code/Mantid/Framework/Algorithms/test/MonteCarloAbsorptionTest.h +++ b/Code/Mantid/Framework/Algorithms/test/MonteCarloAbsorptionTest.h @@ -2,68 +2,68 @@ #define MONTECARLOABSORPTIONTEST_H_ #include "MantidAlgorithms/MonteCarloAbsorption.h" +#include "MantidAPI/FrameworkManager.h" #include "MantidAPI/SampleEnvironment.h" #include "MantidGeometry/Objects/ShapeFactory.h" -#include "MantidKernel/UnitFactory.h" #include "MantidKernel/PhysicalConstants.h" +#include "MantidKernel/UnitFactory.h" + #include -#include "MantidTestHelpers/WorkspaceCreationHelper.h" #include "MantidTestHelpers/ComponentCreationHelper.h" - -using namespace Mantid; -using namespace Mantid::API; -using namespace Mantid::Geometry; -using namespace Mantid::Kernel; - -using Mantid::Algorithms::MonteCarloAbsorption; -using Mantid::DataObjects::Workspace2D_sptr; -using Mantid::Geometry::ShapeFactory; -using Mantid::Kernel::V3D; +#include "MantidTestHelpers/WorkspaceCreationHelper.h" class MonteCarloAbsorptionTest : public CxxTest::TestSuite { public: - + void test_That_Workspace_With_No_Instrument_Is_Not_Accepted() { - IAlgorithm_sptr mcAbsorb = createAlgorithm(); + using namespace Mantid::API; + + auto mcAbsorb = createAlgorithm(); // Create a simple test workspace that has no instrument - Workspace2D_sptr testWS = WorkspaceCreationHelper::Create2DWorkspace(10, 5); - - TS_ASSERT_THROWS(mcAbsorb->setProperty("InputWorkspace", testWS), - std::invalid_argument); + auto testWS = WorkspaceCreationHelper::Create2DWorkspace(10, 5); + + TS_ASSERT_THROWS(mcAbsorb->setProperty("InputWorkspace", testWS), + std::invalid_argument); } - void test_That_Workspace_With_An_Invalid_Sample_Shape_Is_Not_Accepted() - { - Workspace2D_sptr testWS = WorkspaceCreationHelper::create2DWorkspaceWithFullInstrument(9, 10); - // Needs to have units of wavelength - testWS->getAxis(0)->unit() = Mantid::Kernel::UnitFactory::Instance().create("Wavelength"); - - IAlgorithm_sptr mcAbsorb = createAlgorithm(); - TS_ASSERT_THROWS_NOTHING(mcAbsorb->setProperty("InputWorkspace", testWS)); - const std::string outputName("mctest-workspace"); - TS_ASSERT_THROWS_NOTHING(mcAbsorb->setPropertyValue("OutputWorkspace",outputName)); - TS_ASSERT_THROWS(mcAbsorb->execute(), std::invalid_argument); - } + void test_That_Workspace_With_An_Invalid_Sample_Shape_Is_Not_Accepted() + { + using namespace Mantid::API; + + auto testWS = WorkspaceCreationHelper::create2DWorkspaceWithFullInstrument(9, 10); + // Needs to have units of wavelength + testWS->getAxis(0)->unit() = Mantid::Kernel::UnitFactory::Instance().create("Wavelength"); + + auto mcAbsorb = createAlgorithm(); + TS_ASSERT_THROWS_NOTHING(mcAbsorb->setProperty("InputWorkspace", testWS)); + const std::string outputName("mctest-workspace"); + TS_ASSERT_THROWS_NOTHING(mcAbsorb->setPropertyValue("OutputWorkspace",outputName)); + TS_ASSERT_THROWS(mcAbsorb->execute(), std::invalid_argument); + } void test_That_Workspace_With_A_Correctly_Defined_Sample_Shape_And_Material_Succeeds() { + using namespace Mantid::API; + const std::string inputName("mcabsorb-input"); setUpWS(inputName); // Run the algorithm - IAlgorithm_sptr mcAbsorb = createAlgorithm(); + auto mcAbsorb = createAlgorithm(); TS_ASSERT_THROWS_NOTHING(mcAbsorb->setPropertyValue("InputWorkspace", inputName)); const std::string outputName("mcabsorb-factors"); TS_ASSERT_THROWS_NOTHING(mcAbsorb->setPropertyValue("OutputWorkspace",outputName)); - mcAbsorb->execute(); + const int numOMPThreads = FrameworkManager::Instance().getNumOMPThreads(); + FrameworkManager::Instance().setNumOMPThreads(1); // To ensure reproducible results TS_ASSERT_THROWS_NOTHING(mcAbsorb->execute()); + FrameworkManager::Instance().setNumOMPThreads(numOMPThreads); AnalysisDataServiceImpl & dataStore = AnalysisDataService::Instance(); - MatrixWorkspace_sptr factorWS = - boost::dynamic_pointer_cast(dataStore.retrieve(outputName)); + MatrixWorkspace_sptr factorWS = + boost::dynamic_pointer_cast(dataStore.retrieve(outputName)); TS_ASSERT(factorWS); if( !factorWS ) TS_FAIL("Cannot retrieve output workspace"); @@ -73,18 +73,18 @@ class MonteCarloAbsorptionTest : public CxxTest::TestSuite // Pick out some random values const double delta(1e-08); const size_t middle_index = (nbins/2) - 1; - TS_ASSERT_DELTA(factorWS->readY(0).front(), 0.00477768, delta); - TS_ASSERT_DELTA(factorWS->readY(0)[middle_index], 0.000134089, delta); - TS_ASSERT_DELTA(factorWS->readY(0).back(), 1.18e-7, delta); - + TS_ASSERT_DELTA(factorWS->readY(0).front(), 0.005869405757, delta); + TS_ASSERT_DELTA(factorWS->readY(0)[middle_index], 0.000104368636, delta); + TS_ASSERT_DELTA(factorWS->readY(0).back(), 0.000004337609, delta); + // Different spectra - TS_ASSERT_DELTA(factorWS->readY(4).front(), 0.00868274, delta); - TS_ASSERT_DELTA(factorWS->readY(4)[middle_index], 0.000177871, delta); - TS_ASSERT_DELTA(factorWS->readY(4).back(), 0.000131046, delta); + TS_ASSERT_DELTA(factorWS->readY(2).front(), 0.007355971026, delta); + TS_ASSERT_DELTA(factorWS->readY(2)[middle_index], 0.000092901957, delta); + TS_ASSERT_DELTA(factorWS->readY(2).back(), 0.000003265731, delta); - TS_ASSERT_DELTA(factorWS->readY(8).front(), 0.00654336, delta); - TS_ASSERT_DELTA(factorWS->readY(8)[middle_index], 0.000224293, delta); - TS_ASSERT_DELTA(factorWS->readY(8).back(), 1.14231e-5, delta); + TS_ASSERT_DELTA(factorWS->readY(4).front(), 0.004037809093, delta); + TS_ASSERT_DELTA(factorWS->readY(4)[middle_index], 0.000190782521, delta); + TS_ASSERT_DELTA(factorWS->readY(4).back(), 0.000019473169, delta); dataStore.remove(inputName); dataStore.remove(outputName); @@ -92,21 +92,20 @@ class MonteCarloAbsorptionTest : public CxxTest::TestSuite void test_That_Workspace_With_A_Defined_Sample_Shape_And_Container_Succeeds() { + using namespace Mantid::API; + AnalysisDataServiceImpl & dataStore = AnalysisDataService::Instance(); const std::string inputName("mcabsorb-input"); setUpWS(inputName, 1, 10, true); // Run the algorithm - IAlgorithm_sptr mcAbsorb = createAlgorithm(); + auto mcAbsorb = createAlgorithm(); TS_ASSERT_THROWS_NOTHING(mcAbsorb->setPropertyValue("InputWorkspace", inputName)); const std::string outputName("mcabsorb-factors"); TS_ASSERT_THROWS_NOTHING(mcAbsorb->setPropertyValue("OutputWorkspace",outputName)); - mcAbsorb->execute(); TS_ASSERT_THROWS_NOTHING(mcAbsorb->execute()); - - MatrixWorkspace_sptr factorWS = - boost::dynamic_pointer_cast(dataStore.retrieve(outputName)); + auto factorWS = boost::dynamic_pointer_cast(dataStore.retrieve(outputName)); TS_ASSERT(factorWS); if( !factorWS ) TS_FAIL("Cannot retrieve output workspace"); @@ -116,9 +115,9 @@ class MonteCarloAbsorptionTest : public CxxTest::TestSuite // Pick out some random values const double delta(1e-08); const size_t middle_index = (nbins/2) - 1; - TS_ASSERT_DELTA(factorWS->readY(0).front(), 1.9588e-05, delta); - TS_ASSERT_DELTA(factorWS->readY(0)[middle_index], 6.56478e-09, 1e-9); - TS_ASSERT_DELTA(factorWS->readY(0).back(), 2.3604e-11, 1e-12); + TS_ASSERT_DELTA(factorWS->readY(0).front(), 0.005122949, delta); + TS_ASSERT_DELTA(factorWS->readY(0)[middle_index], 0.000238143162, delta); + TS_ASSERT_DELTA(factorWS->readY(0).back(), 0.000003069996, delta); dataStore.remove(inputName); dataStore.remove(outputName); @@ -126,43 +125,47 @@ class MonteCarloAbsorptionTest : public CxxTest::TestSuite private: - - void setUpWS(const std::string & name, const int nspectra = 9, const int nbins = 10, - bool addContainer = false) + + void setUpWS(const std::string & name, const int nspectra = 5, const int nbins = 10, + bool addContainer = false) { - Workspace2D_sptr space = WorkspaceCreationHelper::create2DWorkspaceWithFullInstrument(nspectra, nbins); + using namespace Mantid::API; + using namespace Mantid::Geometry; + using namespace Mantid::Kernel; + namespace PhysicalConstants = Mantid::PhysicalConstants; + + auto space = WorkspaceCreationHelper::create2DWorkspaceWithFullInstrument(nspectra, nbins); // Needs to have units of wavelength - space->getAxis(0)->unit() = Mantid::Kernel::UnitFactory::Instance().create("Wavelength"); - + space->getAxis(0)->unit() = UnitFactory::Instance().create("Wavelength"); + // Define a sample shape Object_sptr sampleShape = ComponentCreationHelper::createSphere(0.1, V3D(), "sample-sphere"); - space->mutableSample().setShape(*sampleShape); // And a material - Material vanadium("Vanadium", PhysicalConstants::getNeutronAtom(23,0), 0.072); - space->mutableSample().setMaterial(vanadium); + sampleShape->setMaterial(Material("Vanadium", PhysicalConstants::getNeutronAtom(23,0), 0.072)); + space->mutableSample().setShape(*sampleShape); if( addContainer ) { const std::string id("container"); - const double radius(0.25); - const double height(0.4); - const V3D baseCentre(0.0, -height/2.0,0.0); + const double radius(0.11); + const double height(0.03); + const V3D baseCentre(0.0, -height/2.0, 0.0); const V3D axis(0.0, 1.0,0.0); - + // Define a container shape. Use a simple cylinder std::ostringstream xml; - xml << "" - << "" - << "" - << "" - << "" - << ""; - + xml << "" + << "" + << "" + << "" + << "" + << ""; + ShapeFactory shapeMaker; Object_sptr containerShape = shapeMaker.createShape(xml.str()); - Material_sptr canMaterial(new Material("CanMaterial", PhysicalConstants::getNeutronAtom(26, 0), 0.01)); + containerShape->setMaterial(Material("CanMaterial", PhysicalConstants::getNeutronAtom(26, 0), 0.01)); SampleEnvironment *can = new SampleEnvironment("can"); - can->add(new ObjComponent("1", containerShape, NULL, canMaterial)); + can->add(*containerShape); space->mutableSample().setEnvironment(can); } @@ -170,9 +173,9 @@ class MonteCarloAbsorptionTest : public CxxTest::TestSuite AnalysisDataService::Instance().add(name, space); } - IAlgorithm_sptr createAlgorithm() + Mantid::API::IAlgorithm_sptr createAlgorithm() { - IAlgorithm_sptr mcAbsorb = boost::shared_ptr(new MonteCarloAbsorption()); + auto mcAbsorb = boost::shared_ptr(new Mantid::Algorithms::MonteCarloAbsorption()); TS_ASSERT_THROWS_NOTHING(mcAbsorb->initialize()); TS_ASSERT_EQUALS(mcAbsorb->isInitialized(), true); mcAbsorb->setRethrows(true); diff --git a/Code/Mantid/Framework/Algorithms/test/MultiplyDivideTest.in.h b/Code/Mantid/Framework/Algorithms/test/MultiplyDivideTest.in.h index aad652c34b8d..9a52eac541b7 100644 --- a/Code/Mantid/Framework/Algorithms/test/MultiplyDivideTest.in.h +++ b/Code/Mantid/Framework/Algorithms/test/MultiplyDivideTest.in.h @@ -1,4 +1,4 @@ -#ifndef @MULTIPLYDIVIDETEST_CLASS@_H +#ifndef @MULTIPLYDIVIDETEST_CLASS@_H_ #define @MULTIPLYDIVIDETEST_CLASS@_H_ #include @@ -980,4 +980,4 @@ class @MULTIPLYDIVIDETEST_CLASS@ : public CxxTest::TestSuite }; -#endif /*MULTIPLYTEST_H_ or DIVIDETEST_H*/ +#endif /*MULTIPLYTEST_H_ or DIVIDETEST_H_*/ diff --git a/Code/Mantid/Framework/Algorithms/test/WienerSmoothTest.h b/Code/Mantid/Framework/Algorithms/test/WienerSmoothTest.h new file mode 100644 index 000000000000..7539290556b6 --- /dev/null +++ b/Code/Mantid/Framework/Algorithms/test/WienerSmoothTest.h @@ -0,0 +1,178 @@ +#ifndef MANTID_ALGORITHMS_WIENERSMOOTHTEST_H_ +#define MANTID_ALGORITHMS_WIENERSMOOTHTEST_H_ + +#include + +#include "MantidAlgorithms/WienerSmooth.h" +#include "MantidAPI/WorkspaceFactory.h" + +#include + +using Mantid::Algorithms::WienerSmooth; +using namespace Mantid::API; + +class WienerSmoothTest : 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 WienerSmoothTest *createSuite() { return new WienerSmoothTest(); } + static void destroySuite( WienerSmoothTest *suite ) { delete suite; } + + + void test_Init() + { + WienerSmooth alg; + TS_ASSERT_THROWS_NOTHING( alg.initialize() ) + TS_ASSERT( alg.isInitialized() ) + } + + void test_data_points_odd() + { + double x[] = {2.27988, 2.5079, 2.73593, 2.96398, 3.19203, 3.4201, 3.64818, 3.87627, 4.10439, 4.33251, 4.56066, 4.78882, 5.017, 5.2452, 5.47342, 5.70167, 5.92994, 6.15823, 6.38654, 6.61488, 6.84325, 7.07164, 7.30006, 7.52851, 7.75699, 7.9855, 8.21405, 8.44262, 8.67123, 8.89988, 9.12856, 9.35727, 9.58603, 9.81482, 10.0437, 10.2725, 10.5014, 10.7304, 10.9594, 11.1884, 11.4175, 11.6466, 11.8758, 12.1051, 12.3343, 12.5637, 12.793, 13.0225, 13.2519, 13.4815, 13.7111, 13.9407, 14.1704, 14.4001, 14.63, 14.8598, 15.0898, 15.3198, 15.5498, 15.7799, 16.0101, 16.2404, 16.4707, 16.7011, 16.9315, 17.162, 17.3926, 17.6233, 17.854, 18.0848, 18.3157, 18.5467, 18.7777, 19.0088, 19.24, 19.4712, 19.7026, 19.934, 20.1655, 20.3971, 20.6288, 20.8605, 21.0924, 21.3243, 21.5563, 21.7885, 22.0207, 22.2529, 22.4853, 22.7178, 22.9504, 23.1831, 23.4158, 23.6487, 23.8817, 24.1147, 24.3479, 24.5812, 24.8145, 25.048, 25.2816, 25.5153, 25.7491, 25.983, 26.217, 26.4511, 26.6854, 26.9197, 27.1542, 27.3888, 27.6235, 27.8583, 28.0932, 28.3283, 28.5635, 28.7988, 29.0342, 29.2698, 29.5054, 29.7413, 29.9772, 30.2133, 30.4495, 30.6858, 30.9223, 31.1589, 31.3956, 31.6325, 31.8695, 32.1066, 32.3439, 32.5814, 32.8189, 33.0567, 33.2945, 33.5326, 33.7707, 34.009, 34.2475, 34.4861, 34.7249, 34.9639, 35.2029, 35.4422, 35.6816, 35.9212, 36.1609, 36.4008, 36.6409, 36.8811, 37.1215, 37.3621, 37.6028, 37.8437, 38.0848, 38.326, 38.5675, 38.8091, 39.0509, 39.2929, 39.535, 39.7774, 40.0199, 40.2626, 40.5055, 40.7486, 40.9919, 41.2353, 41.479, 41.7229, 41.9669, 42.2112, 42.4557, 42.7003, 42.9452, 43.1903, 43.4356, 43.6811, 43.9268, 44.1727, 44.4188, 44.6652, 44.9118, 45.1585, 45.4056, 45.6528, 45.9002, 46.1479, 46.3958, 46.644, 46.8923, 47.141, 47.3898, 47.6389, 47.8882, 48.1378, 48.3876, 48.6376, 48.8879, 49.1384, 49.3892, 49.6403, 49.8916, 50.1431, 50.395, 50.647, 50.8994, 51.152, 51.4048, 51.658, 51.9114, 52.1651, 52.419, 52.6733, 52.9278, 53.1826, 53.4377, 53.693, 53.9487, 54.2046, 54.4609, 54.7174, 54.9743, 55.2314, 55.4888, 55.7466, 56.0046, 56.263, 56.5216, 56.7806, 57.0399, 57.2995, 57.5595, 57.8197, 58.0803, 58.3412, 58.6025, 58.8641, 59.126, 59.3883, 59.6509}; + double y[] = {0.1189, 0.14286, 0.15511, 0.20033, 0.24087, 0.2996, 0.3667, 0.45925, 0.54581, 0.64787, 0.72139, 0.75917, 0.7592, 0.70437, 0.66543, 0.61568, 0.57946, 0.56725, 0.54555, 0.54935, 0.55913, 0.57079, 0.59763, 0.62659, 0.65637, 0.70992, 0.76924, 0.84962, 0.90275, 0.96503, 1.0212, 1.04499, 1.02727, 0.98586, 0.94215, 0.89535, 0.85004, 0.82062, 0.77311, 0.75757, 0.72619, 0.70849, 0.68867, 0.68672, 0.68862, 0.69738, 0.68253, 0.66519, 0.68893, 0.69585, 0.7261, 0.76552, 0.82647, 0.91327, 0.9998, 1.12527, 1.22703, 1.37864, 1.50838, 1.64859, 1.7446, 1.82841, 1.82272, 1.81786, 1.7517, 1.64564, 1.53517, 1.43061, 1.30539, 1.20773, 1.13472, 1.05424, 0.97878, 0.89599, 0.85828, 0.79429, 0.73088, 0.70002, 0.67398, 0.65064, 0.59312, 0.61832, 0.60326, 0.59493, 0.61048, 0.62192, 0.65194, 0.67122, 0.68651, 0.72684, 0.75618, 0.78981, 0.84201, 0.89634, 0.91493, 0.94592, 0.99613, 1.02684, 1.0639, 1.09255, 1.13058, 1.14893, 1.1503, 1.18634, 1.18879, 1.20033, 1.20279, 1.20045, 1.18814, 1.17842, 1.16808, 1.15407, 1.12928, 1.11879, 1.1023, 1.07958, 1.05638, 1.0462, 1.04083, 1.03085, 1.03033, 1.02903, 1.02619, 1.02792, 1.03886, 1.04313, 1.05231, 1.04534, 1.06358, 1.05425, 1.05435, 1.0434, 1.02563, 1.01394, 0.98787, 0.96556, 0.94457, 0.9051, 0.88604, 0.86141, 0.84185, 0.84891, 0.83551, 0.81485, 0.84004, 0.83454, 0.8117, 0.83888, 0.84998, 0.874, 0.87528, 0.88786, 0.92081, 0.93851, 0.95443, 0.97785, 0.99923, 1.02937, 1.04029, 1.05765, 1.07661, 1.08395, 1.09994, 1.11099, 1.12797, 1.13621, 1.14869, 1.15218, 1.15627, 1.15252, 1.1553, 1.14769, 1.13809, 1.11836, 1.116, 1.1029, 1.08102, 1.06264, 1.04897, 1.02698, 1.00413, 0.98735, 0.97338, 0.9704, 0.96175, 0.93567, 0.93158, 0.92161, 0.91366, 0.91242, 0.91492, 0.91012, 0.91363, 0.91386, 0.91193, 0.92262, 0.92101, 0.92347, 0.92783, 0.92892, 0.93323, 0.9285, 0.94434, 0.94073, 0.95938, 0.95013, 0.9697, 0.96185, 0.97768, 0.99063, 1.00007, 1.00453, 1.01804, 1.02646, 1.02738, 1.03621, 1.04134, 1.06078, 1.06342, 1.06341, 1.0653, 1.0678, 1.06715, 1.07105, 1.0638, 1.06224, 1.06376, 1.06679, 1.06187, 1.06411, 1.05411, 1.04652, 1.04076, 1.03172, 1.0255, 1.02284, 1.01324, 1.00444, 1.00077, 0.99847, 0.98269}; + double e[] = {0.04306, 0.05999, 0.04333, 0.04134, 0.04024, 0.04153, 0.04734, 0.05491, 0.04546, 0.04019, 0.03919, 0.03947, 0.05077, 0.05629, 0.04336, 0.04067, 0.04076, 0.04336, 0.05906, 0.03617, 0.03875, 0.02772, 0.02843, 0.03264, 0.03888, 0.03328, 0.02734, 0.02536, 0.02707, 0.03122, 0.0303, 0.02557, 0.02234, 0.02146, 0.02234, 0.02462, 0.02666, 0.02109, 0.01672, 0.01538, 0.01634, 0.01944, 0.02216, 0.01792, 0.01708, 0.01789, 0.01926, 0.02449, 0.02792, 0.02203, 0.02044, 0.01906, 0.01968, 0.02428, 0.02771, 0.02898, 0.0256, 0.02432, 0.02239, 0.02456, 0.02836, 0.02819, 0.0222, 0.02531, 0.02621, 0.02977, 0.03856, 0.0322, 0.0313, 0.02681, 0.02502, 0.02521, 0.04617, 0.04736, 0.04408, 0.03813, 0.03342, 0.03071, 0.03107, 0.0337, 0.03596, 0.043, 0.03307, 0.0304, 0.02416, 0.03019, 0.02611, 0.02916, 0.0353, 0.03024, 0.02706, 0.02964, 0.03262, 0.03533, 0.04161, 0.03895, 0.03374, 0.0291, 0.03359, 0.03053, 0.03269, 0.02773, 0.03506, 0.02503, 0.0229, 0.02088, 0.01967, 0.01941, 0.02053, 0.02489, 0.02607, 0.02021, 0.02098, 0.01894, 0.01798, 0.01767, 0.01715, 0.0206, 0.02024, 0.02458, 0.02048, 0.02021, 0.0202, 0.0179, 0.01829, 0.01982, 0.01909, 0.01999, 0.02195, 0.02019, 0.02036, 0.02057, 0.02009, 0.02106, 0.02476, 0.02473, 0.02957, 0.03164, 0.03068, 0.02894, 0.02685, 0.02684, 0.02714, 0.029, 0.03087, 0.03901, 0.03279, 0.02733, 0.02219, 0.02775, 0.02265, 0.02202, 0.022, 0.02211, 0.02168, 0.02739, 0.03042, 0.02999, 0.02711, 0.03, 0.02325, 0.02459, 0.02342, 0.02207, 0.02149, 0.02135, 0.01932, 0.01802, 0.01806, 0.01805, 0.01814, 0.01895, 0.01899, 0.01936, 0.02054, 0.02212, 0.02178, 0.01983, 0.02211, 0.02087, 0.02193, 0.02155, 0.02467, 0.02282, 0.02405, 0.01853, 0.01814, 0.01842, 0.01839, 0.02002, 0.02071, 0.02061, 0.02047, 0.02057, 0.02164, 0.02491, 0.02371, 0.02035, 0.02759, 0.02022, 0.03238, 0.03274, 0.02986, 0.02708, 0.02428, 0.03229, 0.02994, 0.02933, 0.02563, 0.02142, 0.02133, 0.02193, 0.02093, 0.02061, 0.01954, 0.02149, 0.02398, 0.024, 0.02216, 0.01969, 0.01981, 0.01982, 0.0202, 0.02001, 0.02083, 0.02022, 0.02228, 0.01919, 0.01454, 0.01797, 0.02072, 0.02082, 0.01926, 0.02009, 0.0186, 0.01869, 0.01973, 0.02004, 0.01693, 0.01896, 0.01926}; + double ysmooth[] = { 0.10759, 0.143251, 0.171589, 0.199732, 0.236917, 0.291331, 0.366582, 0.459241, 0.558691, 0.649694, 0.717026, 0.750456, 0.748111, 0.716828, 0.669429, 0.620179, 0.580393, 0.555871, 0.546833, 0.549841, 0.560536, 0.575983, 0.59587, 0.622382, 0.65895, 0.708318, 0.770491, 0.841309, 0.912356, 0.973826, 1.01656, 1.03354, 1.02365, 0.991779, 0.946698, 0.897704, 0.85169, 0.811872, 0.778457, 0.750452, 0.72728, 0.709251, 0.696869, 0.689744, 0.686162, 0.683859, 0.681506, 0.68013, 0.683295, 0.696084, 0.723202, 0.767506, 0.829628, 0.908752, 1.00389, 1.11443, 1.2395, 1.37496, 1.51285, 1.64188, 1.74784, 1.81689, 1.83964, 1.81408, 1.74634, 1.64871, 1.53592, 1.42116, 1.31322, 1.2158, 1.12859, 1.04948, 0.976509, 0.908902, 0.847008, 0.791577, 0.743056, 0.701415, 0.666452, 0.638279, 0.617469, 0.604722, 0.600189, 0.603033, 0.611557, 0.625455, 0.643837, 0.666154, 0.692705, 0.723941, 0.759658, 0.798676, 0.839181, 0.879467, 0.918593, 0.956462, 0.993336, 1.02919, 1.06336, 1.0947, 1.12219, 1.14538, 1.16443, 1.17971, 1.19127, 1.19868, 1.20127, 1.19871, 1.19132, 1.18014, 1.16646, 1.15141, 1.13508, 1.1169, 1.0977, 1.07879, 1.06169, 1.04779, 1.03777, 1.03156, 1.02847, 1.02774, 1.02886, 1.03169, 1.03621, 1.0421, 1.04849, 1.054, 1.05713, 1.05668, 1.052, 1.04293, 1.02955, 1.01192, 0.990232, 0.96504, 0.937653, 0.91009, 0.884635, 0.863576, 0.848612, 0.838996, 0.833117, 0.829432, 0.827287, 0.82711, 0.829988, 0.836869, 0.847928, 0.86244, 0.879208, 0.897206, 0.916011, 0.935771, 0.956769, 0.978891, 1.00138, 1.023, 1.04258, 1.0595, 1.07397, 1.08688, 1.09928, 1.11191, 1.12485, 1.13748, 1.14775, 1.15429, 1.1568, 1.15554, 1.15118, 1.1445, 1.13609, 1.12611, 1.11428, 1.10015, 1.08346, 1.06456, 1.04448, 1.02473, 1.00668, 0.991032, 0.977582, 0.965464, 0.953779, 0.942234, 0.931349, 0.922173, 0.915673, 0.912145, 0.911036, 0.911148, 0.912427, 0.914533, 0.91682, 0.919042, 0.921206, 0.923422, 0.925845, 0.92866, 0.932023, 0.935995, 0.9405, 0.945371, 0.950503, 0.956003, 0.96222, 0.96957, 0.978253, 0.988023, 0.998173, 1.00783, 1.01636, 1.02371, 1.03041, 1.03733, 1.04518, 1.05362, 1.06071, 1.06583, 1.06859, 1.06904, 1.06785, 1.06607, 1.06475, 1.06439, 1.06473, 1.06483, 1.06359, 1.06028, 1.05491, 1.0481, 1.04066, 1.03315, 1.02581, 1.01875, 1.01226, 1.0068, 1.00236, 0.997817, 0.990511}; + + size_t nx = sizeof(x) / sizeof(double); + size_t ny = sizeof(y) / sizeof(double); + TS_ASSERT_EQUALS( nx, ny ); + + do_test(nx,x,ny,y,e,ysmooth); + + } + + void test_data_points_even() + { + double x[] = {2.27988, 2.5079, 2.73593, 2.96398, 3.19203, 3.4201, 3.64818, 3.87627, 4.10439, 4.33251, 4.56066, 4.78882, 5.017, 5.2452, 5.47342, 5.70167, 5.92994, 6.15823, 6.38654, 6.61488, 6.84325, 7.07164, 7.30006, 7.52851, 7.75699, 7.9855, 8.21405, 8.44262, 8.67123, 8.89988, 9.12856, 9.35727, 9.58603, 9.81482, 10.0437, 10.2725, 10.5014, 10.7304, 10.9594, 11.1884, 11.4175, 11.6466, 11.8758, 12.1051, 12.3343, 12.5637, 12.793, 13.0225, 13.2519, 13.4815, 13.7111, 13.9407, 14.1704, 14.4001, 14.63, 14.8598, 15.0898, 15.3198, 15.5498, 15.7799, 16.0101, 16.2404, 16.4707, 16.7011, 16.9315, 17.162, 17.3926, 17.6233, 17.854, 18.0848, 18.3157, 18.5467, 18.7777, 19.0088, 19.24, 19.4712, 19.7026, 19.934, 20.1655, 20.3971, 20.6288, 20.8605, 21.0924, 21.3243, 21.5563, 21.7885, 22.0207, 22.2529, 22.4853, 22.7178, 22.9504, 23.1831, 23.4158, 23.6487, 23.8817, 24.1147, 24.3479, 24.5812, 24.8145, 25.048, 25.2816, 25.5153, 25.7491, 25.983, 26.217, 26.4511, 26.6854, 26.9197, 27.1542, 27.3888, 27.6235, 27.8583, 28.0932, 28.3283, 28.5635, 28.7988, 29.0342, 29.2698, 29.5054, 29.7413, 29.9772, 30.2133, 30.4495, 30.6858, 30.9223, 31.1589, 31.3956, 31.6325, 31.8695, 32.1066, 32.3439, 32.5814, 32.8189, 33.0567, 33.2945, 33.5326, 33.7707, 34.009, 34.2475, 34.4861, 34.7249, 34.9639, 35.2029, 35.4422, 35.6816, 35.9212, 36.1609, 36.4008, 36.6409, 36.8811, 37.1215, 37.3621, 37.6028, 37.8437, 38.0848, 38.326, 38.5675, 38.8091, 39.0509, 39.2929, 39.535, 39.7774, 40.0199, 40.2626, 40.5055, 40.7486, 40.9919, 41.2353, 41.479, 41.7229, 41.9669, 42.2112, 42.4557, 42.7003, 42.9452, 43.1903, 43.4356, 43.6811, 43.9268, 44.1727, 44.4188, 44.6652, 44.9118, 45.1585, 45.4056, 45.6528, 45.9002, 46.1479, 46.3958, 46.644, 46.8923, 47.141, 47.3898, 47.6389, 47.8882, 48.1378, 48.3876, 48.6376, 48.8879, 49.1384, 49.3892, 49.6403, 49.8916, 50.1431, 50.395, 50.647, 50.8994, 51.152, 51.4048, 51.658, 51.9114, 52.1651, 52.419, 52.6733, 52.9278, 53.1826, 53.4377, 53.693, 53.9487, 54.2046, 54.4609, 54.7174, 54.9743, 55.2314, 55.4888, 55.7466, 56.0046, 56.263, 56.5216, 56.7806, 57.0399, 57.2995, 57.5595, 57.8197, 58.0803, 58.3412, 58.6025, 58.8641, 59.126, 59.3883}; + double y[] = {0.1189, 0.14286, 0.15511, 0.20033, 0.24087, 0.2996, 0.3667, 0.45925, 0.54581, 0.64787, 0.72139, 0.75917, 0.7592, 0.70437, 0.66543, 0.61568, 0.57946, 0.56725, 0.54555, 0.54935, 0.55913, 0.57079, 0.59763, 0.62659, 0.65637, 0.70992, 0.76924, 0.84962, 0.90275, 0.96503, 1.0212, 1.04499, 1.02727, 0.98586, 0.94215, 0.89535, 0.85004, 0.82062, 0.77311, 0.75757, 0.72619, 0.70849, 0.68867, 0.68672, 0.68862, 0.69738, 0.68253, 0.66519, 0.68893, 0.69585, 0.7261, 0.76552, 0.82647, 0.91327, 0.9998, 1.12527, 1.22703, 1.37864, 1.50838, 1.64859, 1.7446, 1.82841, 1.82272, 1.81786, 1.7517, 1.64564, 1.53517, 1.43061, 1.30539, 1.20773, 1.13472, 1.05424, 0.97878, 0.89599, 0.85828, 0.79429, 0.73088, 0.70002, 0.67398, 0.65064, 0.59312, 0.61832, 0.60326, 0.59493, 0.61048, 0.62192, 0.65194, 0.67122, 0.68651, 0.72684, 0.75618, 0.78981, 0.84201, 0.89634, 0.91493, 0.94592, 0.99613, 1.02684, 1.0639, 1.09255, 1.13058, 1.14893, 1.1503, 1.18634, 1.18879, 1.20033, 1.20279, 1.20045, 1.18814, 1.17842, 1.16808, 1.15407, 1.12928, 1.11879, 1.1023, 1.07958, 1.05638, 1.0462, 1.04083, 1.03085, 1.03033, 1.02903, 1.02619, 1.02792, 1.03886, 1.04313, 1.05231, 1.04534, 1.06358, 1.05425, 1.05435, 1.0434, 1.02563, 1.01394, 0.98787, 0.96556, 0.94457, 0.9051, 0.88604, 0.86141, 0.84185, 0.84891, 0.83551, 0.81485, 0.84004, 0.83454, 0.8117, 0.83888, 0.84998, 0.874, 0.87528, 0.88786, 0.92081, 0.93851, 0.95443, 0.97785, 0.99923, 1.02937, 1.04029, 1.05765, 1.07661, 1.08395, 1.09994, 1.11099, 1.12797, 1.13621, 1.14869, 1.15218, 1.15627, 1.15252, 1.1553, 1.14769, 1.13809, 1.11836, 1.116, 1.1029, 1.08102, 1.06264, 1.04897, 1.02698, 1.00413, 0.98735, 0.97338, 0.9704, 0.96175, 0.93567, 0.93158, 0.92161, 0.91366, 0.91242, 0.91492, 0.91012, 0.91363, 0.91386, 0.91193, 0.92262, 0.92101, 0.92347, 0.92783, 0.92892, 0.93323, 0.9285, 0.94434, 0.94073, 0.95938, 0.95013, 0.9697, 0.96185, 0.97768, 0.99063, 1.00007, 1.00453, 1.01804, 1.02646, 1.02738, 1.03621, 1.04134, 1.06078, 1.06342, 1.06341, 1.0653, 1.0678, 1.06715, 1.07105, 1.0638, 1.06224, 1.06376, 1.06679, 1.06187, 1.06411, 1.05411, 1.04652, 1.04076, 1.03172, 1.0255, 1.02284, 1.01324, 1.00444, 1.00077, 0.99847}; + double e[] = {0.04306, 0.05999, 0.04333, 0.04134, 0.04024, 0.04153, 0.04734, 0.05491, 0.04546, 0.04019, 0.03919, 0.03947, 0.05077, 0.05629, 0.04336, 0.04067, 0.04076, 0.04336, 0.05906, 0.03617, 0.03875, 0.02772, 0.02843, 0.03264, 0.03888, 0.03328, 0.02734, 0.02536, 0.02707, 0.03122, 0.0303, 0.02557, 0.02234, 0.02146, 0.02234, 0.02462, 0.02666, 0.02109, 0.01672, 0.01538, 0.01634, 0.01944, 0.02216, 0.01792, 0.01708, 0.01789, 0.01926, 0.02449, 0.02792, 0.02203, 0.02044, 0.01906, 0.01968, 0.02428, 0.02771, 0.02898, 0.0256, 0.02432, 0.02239, 0.02456, 0.02836, 0.02819, 0.0222, 0.02531, 0.02621, 0.02977, 0.03856, 0.0322, 0.0313, 0.02681, 0.02502, 0.02521, 0.04617, 0.04736, 0.04408, 0.03813, 0.03342, 0.03071, 0.03107, 0.0337, 0.03596, 0.043, 0.03307, 0.0304, 0.02416, 0.03019, 0.02611, 0.02916, 0.0353, 0.03024, 0.02706, 0.02964, 0.03262, 0.03533, 0.04161, 0.03895, 0.03374, 0.0291, 0.03359, 0.03053, 0.03269, 0.02773, 0.03506, 0.02503, 0.0229, 0.02088, 0.01967, 0.01941, 0.02053, 0.02489, 0.02607, 0.02021, 0.02098, 0.01894, 0.01798, 0.01767, 0.01715, 0.0206, 0.02024, 0.02458, 0.02048, 0.02021, 0.0202, 0.0179, 0.01829, 0.01982, 0.01909, 0.01999, 0.02195, 0.02019, 0.02036, 0.02057, 0.02009, 0.02106, 0.02476, 0.02473, 0.02957, 0.03164, 0.03068, 0.02894, 0.02685, 0.02684, 0.02714, 0.029, 0.03087, 0.03901, 0.03279, 0.02733, 0.02219, 0.02775, 0.02265, 0.02202, 0.022, 0.02211, 0.02168, 0.02739, 0.03042, 0.02999, 0.02711, 0.03, 0.02325, 0.02459, 0.02342, 0.02207, 0.02149, 0.02135, 0.01932, 0.01802, 0.01806, 0.01805, 0.01814, 0.01895, 0.01899, 0.01936, 0.02054, 0.02212, 0.02178, 0.01983, 0.02211, 0.02087, 0.02193, 0.02155, 0.02467, 0.02282, 0.02405, 0.01853, 0.01814, 0.01842, 0.01839, 0.02002, 0.02071, 0.02061, 0.02047, 0.02057, 0.02164, 0.02491, 0.02371, 0.02035, 0.02759, 0.02022, 0.03238, 0.03274, 0.02986, 0.02708, 0.02428, 0.03229, 0.02994, 0.02933, 0.02563, 0.02142, 0.02133, 0.02193, 0.02093, 0.02061, 0.01954, 0.02149, 0.02398, 0.024, 0.02216, 0.01969, 0.01981, 0.01982, 0.0202, 0.02001, 0.02083, 0.02022, 0.02228, 0.01919, 0.01454, 0.01797, 0.02072, 0.02082, 0.01926, 0.02009, 0.0186, 0.01869, 0.01973, 0.02004, 0.01693, 0.01896}; + double ysmooth[] = {0.10571,0.14113,0.170422,0.200497,0.239198,0.293392,0.366697,0.457178,0.556025,0.648596,0.718482,0.753394,0.750224,0.716433,0.666845,0.617474,0.57971,0.557712,0.549671,0.551374,0.559535,0.573258,0.593607,0.622393,0.661243,0.711095,0.771562,0.839774,0.909265,0.971962,1.01731,1.03628,1.02621,0.992143,0.944593,0.894828,0.850347,0.813122,0.781275,0.752565,0.727006,0.706837,0.694262,0.689009,0.687835,0.686556,0.683059,0.679327,0.680829,0.693973,0.723165,0.769591,0.832162,0.909674,1.00243,1.11185,1.23795,1.37532,1.51508,1.64431,1.74854,1.81526,1.83691,1.81237,1.74696,1.65114,1.53824,1.42157,1.31148,1.21335,1.12741,1.05048,0.978865,0.910745,0.846919,0.789678,0.740859,0.700616,0.667622,0.640477,0.619021,0.604505,0.598366,0.600683,0.610957,0.627116,0.646201,0.667321,0.691793,0.72171,0.757878,0.798734,0.841012,0.88164,0.919466,0.955461,0.991354,1.02781,1.06358,1.0962,1.12366,1.14564,1.16334,1.17823,1.19063,1.19938,1.20271,1.19967,1.19099,1.17879,1.16542,1.15147,1.1357,1.11789,1.09839,1.07867,1.06088,1.04693,1.03753,1.03208,1.02932,1.02826,1.02866,1.03092,1.03541,1.04178,1.04881,1.05473,1.05783,1.05695,1.05171,1.04225,1.02885,1.01163,0.990588,0.965894,0.938441,0.909963,0.883834,0.86308,0.848462,0.839233,0.833626,0.829895,0.827354,0.826657,0.829251,0.836315,0.847938,0.863033,0.880003,0.897678,0.915863,0.935151,0.956155,0.97874,1.00179,1.02362,1.0429,1.05922,1.07326,1.08624,1.09925,1.11277,1.12627,1.13771,1.14663,1.15282,1.15604,1.15598,1.15242,1.14559,1.13622,1.12526,1.11323,1.0998,1.08412,1.06567,1.04509,1.02428,1.00551,0.990114,0.977699,0.966525,0.954864,0.942373,0.930385,0.920947,0.915278,0.912759,0.912023,0.91237,0.912668,0.913178,0.914857,0.918109,0.922192,0.925704,0.927744,0.92875,0.930251,0.933724,0.939431,0.946216,0.952447,0.95739,0.961909,0.967867,0.976659,0.98799,0.999852,1.00986,1.01694,1.02214,1.02797,1.03633,1.04593,1.05531,1.06259,1.06658,1.06761,1.06711,1.06649,1.06632,1.06626,1.06578,1.06471,1.06335,1.06193,1.06,1.05648,1.05032,1.04148,1.03143,1.0226,1.01698,1.0146,1.01285,1.00723,0.993213}; + + size_t nx = sizeof(x) / sizeof(double); + size_t ny = sizeof(y) / sizeof(double); + TS_ASSERT_EQUALS( nx, ny ); + + do_test(nx,x,ny,y,e,ysmooth); + + } + + void test_histogram_odd() + { + double x[] = {2.27988, 2.5079, 2.73593, 2.96398, 3.19203, 3.4201, 3.64818, 3.87627, 4.10439, 4.33251, 4.56066, 4.78882, 5.017, 5.2452, 5.47342, 5.70167, 5.92994, 6.15823, 6.38654, 6.61488, 6.84325, 7.07164, 7.30006, 7.52851, 7.75699, 7.9855, 8.21405, 8.44262, 8.67123, 8.89988, 9.12856, 9.35727, 9.58603, 9.81482, 10.0437, 10.2725, 10.5014, 10.7304, 10.9594, 11.1884, 11.4175, 11.6466, 11.8758, 12.1051, 12.3343, 12.5637, 12.793, 13.0225, 13.2519, 13.4815, 13.7111, 13.9407, 14.1704, 14.4001, 14.63, 14.8598, 15.0898, 15.3198, 15.5498, 15.7799, 16.0101, 16.2404, 16.4707, 16.7011, 16.9315, 17.162, 17.3926, 17.6233, 17.854, 18.0848, 18.3157, 18.5467, 18.7777, 19.0088, 19.24, 19.4712, 19.7026, 19.934, 20.1655, 20.3971, 20.6288, 20.8605, 21.0924, 21.3243, 21.5563, 21.7885, 22.0207, 22.2529, 22.4853, 22.7178, 22.9504, 23.1831, 23.4158, 23.6487, 23.8817, 24.1147, 24.3479, 24.5812, 24.8145, 25.048, 25.2816, 25.5153, 25.7491, 25.983, 26.217, 26.4511, 26.6854, 26.9197, 27.1542, 27.3888, 27.6235, 27.8583, 28.0932, 28.3283, 28.5635, 28.7988, 29.0342, 29.2698, 29.5054, 29.7413, 29.9772, 30.2133, 30.4495, 30.6858, 30.9223, 31.1589, 31.3956, 31.6325, 31.8695, 32.1066, 32.3439, 32.5814, 32.8189, 33.0567, 33.2945, 33.5326, 33.7707, 34.009, 34.2475, 34.4861, 34.7249, 34.9639, 35.2029, 35.4422, 35.6816, 35.9212, 36.1609, 36.4008, 36.6409, 36.8811, 37.1215, 37.3621, 37.6028, 37.8437, 38.0848, 38.326, 38.5675, 38.8091, 39.0509, 39.2929, 39.535, 39.7774, 40.0199, 40.2626, 40.5055, 40.7486, 40.9919, 41.2353, 41.479, 41.7229, 41.9669, 42.2112, 42.4557, 42.7003, 42.9452, 43.1903, 43.4356, 43.6811, 43.9268, 44.1727, 44.4188, 44.6652, 44.9118, 45.1585, 45.4056, 45.6528, 45.9002, 46.1479, 46.3958, 46.644, 46.8923, 47.141, 47.3898, 47.6389, 47.8882, 48.1378, 48.3876, 48.6376, 48.8879, 49.1384, 49.3892, 49.6403, 49.8916, 50.1431, 50.395, 50.647, 50.8994, 51.152, 51.4048, 51.658, 51.9114, 52.1651, 52.419, 52.6733, 52.9278, 53.1826, 53.4377, 53.693, 53.9487, 54.2046, 54.4609, 54.7174, 54.9743, 55.2314, 55.4888, 55.7466, 56.0046, 56.263, 56.5216, 56.7806, 57.0399, 57.2995, 57.5595, 57.8197, 58.0803, 58.3412, 58.6025, 58.8641, 59.126, 59.3883, 59.6509}; + double y[] = {0.1189, 0.14286, 0.15511, 0.20033, 0.24087, 0.2996, 0.3667, 0.45925, 0.54581, 0.64787, 0.72139, 0.75917, 0.7592, 0.70437, 0.66543, 0.61568, 0.57946, 0.56725, 0.54555, 0.54935, 0.55913, 0.57079, 0.59763, 0.62659, 0.65637, 0.70992, 0.76924, 0.84962, 0.90275, 0.96503, 1.0212, 1.04499, 1.02727, 0.98586, 0.94215, 0.89535, 0.85004, 0.82062, 0.77311, 0.75757, 0.72619, 0.70849, 0.68867, 0.68672, 0.68862, 0.69738, 0.68253, 0.66519, 0.68893, 0.69585, 0.7261, 0.76552, 0.82647, 0.91327, 0.9998, 1.12527, 1.22703, 1.37864, 1.50838, 1.64859, 1.7446, 1.82841, 1.82272, 1.81786, 1.7517, 1.64564, 1.53517, 1.43061, 1.30539, 1.20773, 1.13472, 1.05424, 0.97878, 0.89599, 0.85828, 0.79429, 0.73088, 0.70002, 0.67398, 0.65064, 0.59312, 0.61832, 0.60326, 0.59493, 0.61048, 0.62192, 0.65194, 0.67122, 0.68651, 0.72684, 0.75618, 0.78981, 0.84201, 0.89634, 0.91493, 0.94592, 0.99613, 1.02684, 1.0639, 1.09255, 1.13058, 1.14893, 1.1503, 1.18634, 1.18879, 1.20033, 1.20279, 1.20045, 1.18814, 1.17842, 1.16808, 1.15407, 1.12928, 1.11879, 1.1023, 1.07958, 1.05638, 1.0462, 1.04083, 1.03085, 1.03033, 1.02903, 1.02619, 1.02792, 1.03886, 1.04313, 1.05231, 1.04534, 1.06358, 1.05425, 1.05435, 1.0434, 1.02563, 1.01394, 0.98787, 0.96556, 0.94457, 0.9051, 0.88604, 0.86141, 0.84185, 0.84891, 0.83551, 0.81485, 0.84004, 0.83454, 0.8117, 0.83888, 0.84998, 0.874, 0.87528, 0.88786, 0.92081, 0.93851, 0.95443, 0.97785, 0.99923, 1.02937, 1.04029, 1.05765, 1.07661, 1.08395, 1.09994, 1.11099, 1.12797, 1.13621, 1.14869, 1.15218, 1.15627, 1.15252, 1.1553, 1.14769, 1.13809, 1.11836, 1.116, 1.1029, 1.08102, 1.06264, 1.04897, 1.02698, 1.00413, 0.98735, 0.97338, 0.9704, 0.96175, 0.93567, 0.93158, 0.92161, 0.91366, 0.91242, 0.91492, 0.91012, 0.91363, 0.91386, 0.91193, 0.92262, 0.92101, 0.92347, 0.92783, 0.92892, 0.93323, 0.9285, 0.94434, 0.94073, 0.95938, 0.95013, 0.9697, 0.96185, 0.97768, 0.99063, 1.00007, 1.00453, 1.01804, 1.02646, 1.02738, 1.03621, 1.04134, 1.06078, 1.06342, 1.06341, 1.0653, 1.0678, 1.06715, 1.07105, 1.0638, 1.06224, 1.06376, 1.06679, 1.06187, 1.06411, 1.05411, 1.04652, 1.04076, 1.03172, 1.0255, 1.02284, 1.01324, 1.00444, 1.00077, 0.99847}; + double e[] = {0.04306, 0.05999, 0.04333, 0.04134, 0.04024, 0.04153, 0.04734, 0.05491, 0.04546, 0.04019, 0.03919, 0.03947, 0.05077, 0.05629, 0.04336, 0.04067, 0.04076, 0.04336, 0.05906, 0.03617, 0.03875, 0.02772, 0.02843, 0.03264, 0.03888, 0.03328, 0.02734, 0.02536, 0.02707, 0.03122, 0.0303, 0.02557, 0.02234, 0.02146, 0.02234, 0.02462, 0.02666, 0.02109, 0.01672, 0.01538, 0.01634, 0.01944, 0.02216, 0.01792, 0.01708, 0.01789, 0.01926, 0.02449, 0.02792, 0.02203, 0.02044, 0.01906, 0.01968, 0.02428, 0.02771, 0.02898, 0.0256, 0.02432, 0.02239, 0.02456, 0.02836, 0.02819, 0.0222, 0.02531, 0.02621, 0.02977, 0.03856, 0.0322, 0.0313, 0.02681, 0.02502, 0.02521, 0.04617, 0.04736, 0.04408, 0.03813, 0.03342, 0.03071, 0.03107, 0.0337, 0.03596, 0.043, 0.03307, 0.0304, 0.02416, 0.03019, 0.02611, 0.02916, 0.0353, 0.03024, 0.02706, 0.02964, 0.03262, 0.03533, 0.04161, 0.03895, 0.03374, 0.0291, 0.03359, 0.03053, 0.03269, 0.02773, 0.03506, 0.02503, 0.0229, 0.02088, 0.01967, 0.01941, 0.02053, 0.02489, 0.02607, 0.02021, 0.02098, 0.01894, 0.01798, 0.01767, 0.01715, 0.0206, 0.02024, 0.02458, 0.02048, 0.02021, 0.0202, 0.0179, 0.01829, 0.01982, 0.01909, 0.01999, 0.02195, 0.02019, 0.02036, 0.02057, 0.02009, 0.02106, 0.02476, 0.02473, 0.02957, 0.03164, 0.03068, 0.02894, 0.02685, 0.02684, 0.02714, 0.029, 0.03087, 0.03901, 0.03279, 0.02733, 0.02219, 0.02775, 0.02265, 0.02202, 0.022, 0.02211, 0.02168, 0.02739, 0.03042, 0.02999, 0.02711, 0.03, 0.02325, 0.02459, 0.02342, 0.02207, 0.02149, 0.02135, 0.01932, 0.01802, 0.01806, 0.01805, 0.01814, 0.01895, 0.01899, 0.01936, 0.02054, 0.02212, 0.02178, 0.01983, 0.02211, 0.02087, 0.02193, 0.02155, 0.02467, 0.02282, 0.02405, 0.01853, 0.01814, 0.01842, 0.01839, 0.02002, 0.02071, 0.02061, 0.02047, 0.02057, 0.02164, 0.02491, 0.02371, 0.02035, 0.02759, 0.02022, 0.03238, 0.03274, 0.02986, 0.02708, 0.02428, 0.03229, 0.02994, 0.02933, 0.02563, 0.02142, 0.02133, 0.02193, 0.02093, 0.02061, 0.01954, 0.02149, 0.02398, 0.024, 0.02216, 0.01969, 0.01981, 0.01982, 0.0202, 0.02001, 0.02083, 0.02022, 0.02228, 0.01919, 0.01454, 0.01797, 0.02072, 0.02082, 0.01926, 0.02009, 0.0186, 0.01869, 0.01973, 0.02004, 0.01693, 0.01896}; + double ysmooth[] = {0.105725,0.141127,0.170416,0.200494,0.239199,0.293395,0.366699,0.457179,0.556023,0.648595,0.718481,0.753394,0.750224,0.716434,0.666845,0.617474,0.57971,0.557711,0.549671,0.551373,0.559534,0.573259,0.593609,0.622395,0.661243,0.711093,0.771558,0.839774,0.909271,0.971963,1.0173,1.03627,1.02621,0.992143,0.944593,0.894828,0.850347,0.813123,0.781275,0.752565,0.727005,0.706836,0.694262,0.689006,0.687838,0.686555,0.683062,0.679325,0.68083,0.693972,0.723162,0.76959,0.832161,0.909682,1.00243,1.11185,1.23795,1.37532,1.51509,1.64432,1.74854,1.81525,1.8369,1.81237,1.74696,1.65114,1.53824,1.42157,1.31148,1.21335,1.12741,1.05048,0.978866,0.910744,0.846918,0.789675,0.74086,0.700618,0.667625,0.640476,0.619019,0.604495,0.598366,0.6007,0.610954,0.62711,0.6462,0.66732,0.691794,0.721711,0.757878,0.798735,0.84101,0.881639,0.919467,0.955461,0.991354,1.02781,1.06358,1.0962,1.12366,1.14564,1.16334,1.17823,1.19063,1.19938,1.20271,1.19967,1.19099,1.17879,1.1654,1.15147,1.13571,1.1179,1.09839,1.07866,1.06088,1.04693,1.03753,1.03208,1.02932,1.02825,1.02865,1.03092,1.03541,1.04178,1.04882,1.05473,1.05782,1.05695,1.05171,1.04225,1.02885,1.01164,0.990583,0.96589,0.938439,0.909974,0.883834,0.863075,0.848458,0.839235,0.833627,0.829897,0.827354,0.826656,0.82925,0.836315,0.84794,0.863035,0.880003,0.897676,0.915862,0.93515,0.956156,0.978743,1.00179,1.02362,1.0429,1.05922,1.07326,1.08624,1.09925,1.11277,1.12627,1.13771,1.14663,1.15282,1.15604,1.15598,1.15242,1.14559,1.13622,1.12526,1.11322,1.0998,1.08412,1.06568,1.04509,1.02428,1.0055,0.990111,0.9777,0.966526,0.954868,0.942376,0.930383,0.920943,0.915273,0.912768,0.912022,0.912369,0.912666,0.913179,0.914858,0.91811,0.922192,0.925703,0.927744,0.928751,0.930253,0.933725,0.939431,0.946214,0.952445,0.95739,0.96191,0.967868,0.976661,0.987989,0.999851,1.00986,1.01694,1.02215,1.02797,1.03633,1.04593,1.05532,1.06259,1.06658,1.06761,1.06711,1.06649,1.06632,1.06626,1.06578,1.06471,1.06335,1.06193,1.06,1.05648,1.05032,1.04148,1.03143,1.0226,1.01698,1.0146,1.01285,1.00722,0.993211}; + + size_t nx = sizeof(x) / sizeof(double); + size_t ny = sizeof(y) / sizeof(double); + + TS_ASSERT_EQUALS( nx, ny + 1 ); + + do_test(nx,x,ny,y,e,ysmooth); + + } + + void test_small_dataset_odd() + { + double x[] = {2.27988, 2.5079, 2.73593, 2.96398, 3.19203, 3.4201, 3.64818, 3.87627, 4.10439, 4.33251, 4.56066, 4.78882, 5.017, 5.2452, 5.47342, 5.70167, 5.92994, 6.15823, 6.38654, 6.61488, 6.84325}; + double y[] = {0.1189, 0.14286, 0.15511, 0.20033, 0.24087, 0.2996, 0.3667, 0.45925, 0.54581, 0.64787, 0.72139, 0.75917, 0.7592, 0.70437, 0.66543, 0.61568, 0.57946, 0.56725, 0.54555, 0.54935, 0.55913}; + double e[] = {0.04306, 0.05999, 0.04333, 0.04134, 0.04024, 0.04153,0.04734, 0.05491, 0.04546, 0.04019, 0.03919, 0.03947, 0.05077, 0.05629, 0.04336, 0.04067, 0.04076, 0.04336, 0.05906, 0.03617, 0.03875}; + double ysmooth[] = {0.119953,0.138392,0.158673,0.197465,0.242644,0.300178,0.369039,0.456804,0.550945,0.646607,0.721446,0.760649,0.755715,0.712672,0.664265,0.616398,0.583482,0.563747,0.548997,0.548158,0.555918}; + + size_t nx = sizeof(x) / sizeof(double); + size_t ny = sizeof(y) / sizeof(double); + + do_test(nx,x,ny,y,e,ysmooth); + + } + + void test_small_dataset_even() + { + double x[] = {2.27988, 2.5079, 2.73593, 2.96398, 3.19203, 3.4201, 3.64818, 3.87627, 4.10439, 4.33251, 4.56066, 4.78882, 5.017, 5.2452, 5.47342, 5.70167, 5.92994, 6.15823, 6.38654, 6.61488}; + double y[] = {0.1189, 0.14286, 0.15511, 0.20033, 0.24087, 0.2996, 0.3667, 0.45925, 0.54581, 0.64787, 0.72139, 0.75917, 0.7592, 0.70437, 0.66543, 0.61568, 0.57946, 0.56725, 0.54555, 0.54935}; + double e[] = {0.04306, 0.05999, 0.04333, 0.04134, 0.04024, 0.04153,0.04734, 0.05491, 0.04546, 0.04019, 0.03919, 0.03947, 0.05077, 0.05629, 0.04336, 0.04067, 0.04076, 0.04336, 0.05906, 0.03617}; + double ysmooth[] = {0.116583,0.136542,0.161394,0.195961,0.240597,0.300037,0.371905,0.453996,0.552692,0.645688,0.721389,0.761067,0.751442,0.709996,0.661161,0.616885,0.581682,0.561372,0.547726,0.549986}; + + size_t nx = sizeof(x) / sizeof(double); + size_t ny = sizeof(y) / sizeof(double); + + do_test(nx,x,ny,y,e,ysmooth); + + } + + void test_very_small_dataset() + { + double x[] = {2.27988, 2.5079, 2.73593}; + double y[] = {0.1189, 0.14286, 0.15511}; + double e[] = {0.04306, 0.05999, 0.04333}; + double ysmooth[] = {0.1189, 0.14286, 0.15511}; + + size_t nx = sizeof(x) / sizeof(double); + size_t ny = sizeof(y) / sizeof(double); + + do_test(nx,x,ny,y,e,ysmooth); + + } + + void do_test(size_t nx, double* x, size_t ny, double* y, double* e, double* ysmooth) + { + + auto dataWS = WorkspaceFactory::Instance().create( "Workspace2D", 1, nx, ny ); + auto &X = dataWS->dataX(0); + auto &Y = dataWS->dataY(0); + auto &E = dataWS->dataE(0); + X.assign( x, x + nx ); + Y.assign( y, y + ny ); + E.assign( e, e + ny ); + + auto outputWs = runWienerSmooth( dataWS, 0 ); + + auto &outY = outputWs->readY(0); + + for(size_t i = 0; i < outY.size(); ++i) + { + TS_ASSERT_DELTA( outY[i], ysmooth[i], 1e-5 ); + //std::cerr << outY[i] << std::endl; + } + + AnalysisDataService::Instance().clear(); + } + + MatrixWorkspace_sptr runWienerSmooth(MatrixWorkspace_sptr inputWS, size_t wsIndex) + { + // Name of the output workspace. + std::string outWSName("WienerSmoothTest_OutputWS"); + + WienerSmooth alg; + alg.setRethrows( true ); + TS_ASSERT_THROWS_NOTHING( alg.initialize() ) + TS_ASSERT( alg.isInitialized() ) + TS_ASSERT_THROWS_NOTHING( alg.setProperty("InputWorkspace", inputWS) ); + TS_ASSERT_THROWS_NOTHING( alg.setProperty("WorkspaceIndex", static_cast(wsIndex)) ); + TS_ASSERT_THROWS_NOTHING( alg.setPropertyValue("OutputWorkspace", outWSName) ); + TS_ASSERT_THROWS_NOTHING( alg.execute(); ); + TS_ASSERT( alg.isExecuted() ); + + // Retrieve the workspace from data service. + MatrixWorkspace_sptr ws; + TS_ASSERT_THROWS_NOTHING( ws = AnalysisDataService::Instance().retrieveWS(outWSName) ); + TS_ASSERT(ws); + + auto &inX = inputWS->readX(wsIndex); + auto &inE = inputWS->readE(wsIndex); + + auto outX = ws->readX(0); + auto outE = ws->readE(0); + + TS_ASSERT_EQUALS( inputWS->readY(wsIndex).size(), ws->readY(0).size() ); + TS_ASSERT( std::equal( outX.begin(), outX.end(), inX.begin() ) ); + TS_ASSERT( std::equal( outE.begin(), outE.end(), inE.begin() ) ); + + return ws; + } + +}; + + +#endif /* MANTID_ALGORITHMS_WIENERSMOOTHTEST_H_ */ \ No newline at end of file diff --git a/Code/Mantid/Framework/CMakeLists.txt b/Code/Mantid/Framework/CMakeLists.txt index 6fedd798384e..1d0bd009642e 100644 --- a/Code/Mantid/Framework/CMakeLists.txt +++ b/Code/Mantid/Framework/CMakeLists.txt @@ -22,6 +22,7 @@ if ( NOT COMMONSETUP_DONE ) include ( CommonSetup ) endif () +option(BUILD_MATLAB_DEPENDENCIES "Build Mantid-Matlab interface in the case of Matlab was found" OFF) ########################################################################### # Look for dependencies - bail out if any necessary ones not found ########################################################################### @@ -81,11 +82,13 @@ add_subdirectory (API) set ( MANTIDLIBS ${MANTIDLIBS} API ) add_subdirectory (PythonInterface) - -find_package ( Matlab ) -if( MATLAB_FOUND ) - add_subdirectory (MatlabAPI) -endif () +# +if (BUILD_MATLAB_DEPENDENCIES) + find_package ( Matlab ) + if( MATLAB_FOUND ) + add_subdirectory (MatlabAPI) + endif () +endif() include_directories (DataObjects/inc) add_subdirectory (DataObjects) diff --git a/Code/Mantid/Framework/Crystal/src/AnvredCorrection.cpp b/Code/Mantid/Framework/Crystal/src/AnvredCorrection.cpp index 54189edf4ea6..488afbdf9e3a 100644 --- a/Code/Mantid/Framework/Crystal/src/AnvredCorrection.cpp +++ b/Code/Mantid/Framework/Crystal/src/AnvredCorrection.cpp @@ -395,9 +395,10 @@ void AnvredCorrection::retrieveBaseProperties() else //Save input in Sample with wrong atomic number and name { NeutronAtom neutron(static_cast(EMPTY_DBL()), static_cast(0), - 0.0, 0.0, smu, 0.0, smu, amu); - Material mat("SetInAnvredCorrection", neutron, 1.0); - m_inputWS->mutableSample().setMaterial(mat); + 0.0, 0.0, smu, 0.0, smu, amu); + Object shape = m_inputWS->sample().getShape(); // copy + shape.setMaterial(Material("SetInAnvredCorrection", neutron, 1.0)); + m_inputWS->mutableSample().setShape(shape); } if (smu != EMPTY_DBL() && amu != EMPTY_DBL()) g_log.notice() << "LinearScatteringCoef = " << smu << " 1/cm\n" diff --git a/Code/Mantid/Framework/Crystal/src/LoadHKL.cpp b/Code/Mantid/Framework/Crystal/src/LoadHKL.cpp index 82cfb1317096..d4022c3f509b 100644 --- a/Code/Mantid/Framework/Crystal/src/LoadHKL.cpp +++ b/Code/Mantid/Framework/Crystal/src/LoadHKL.cpp @@ -161,9 +161,11 @@ namespace Crystal API::Run & mrun = ws->mutableRun(); mrun.addProperty("Radius", radius, true); NeutronAtom neutron(static_cast(EMPTY_DBL()), static_cast(0), - 0.0, 0.0, smu, 0.0, smu, amu); - Material mat("SetInLoadHKL", neutron, 1.0); - ws->mutableSample().setMaterial(mat); + 0.0, 0.0, smu, 0.0, smu, amu); + Object shape = ws->sample().getShape(); // copy + shape.setMaterial(Material("SetInLoadHKL", neutron, 1.0)); + ws->mutableSample().setShape(shape); + setProperty("OutputWorkspace", boost::dynamic_pointer_cast(ws)); diff --git a/Code/Mantid/Framework/Crystal/src/SaveHKL.cpp b/Code/Mantid/Framework/Crystal/src/SaveHKL.cpp index 1eacba2ab53f..0962a6b6b8af 100644 --- a/Code/Mantid/Framework/Crystal/src/SaveHKL.cpp +++ b/Code/Mantid/Framework/Crystal/src/SaveHKL.cpp @@ -196,9 +196,11 @@ namespace Crystal else if (smu != EMPTY_DBL() && amu != EMPTY_DBL()) //Save input in Sample with wrong atomic number and name { NeutronAtom neutron(static_cast(EMPTY_DBL()), static_cast(0), - 0.0, 0.0, smu, 0.0, smu, amu); - Material mat("SetInAnvredCorrection", neutron, 1.0); - ws->mutableSample().setMaterial(mat); + 0.0, 0.0, smu, 0.0, smu, amu); + Object shape = ws->sample().getShape(); // copy + shape.setMaterial(Material("SetInSaveHKL", neutron, 1.0)); + ws->mutableSample().setShape(shape); + } if (smu != EMPTY_DBL() && amu != EMPTY_DBL()) g_log.notice() << "LinearScatteringCoef = " << smu << " 1/cm\n" diff --git a/Code/Mantid/Framework/Crystal/test/FindUBUsingMinMaxDTest.h b/Code/Mantid/Framework/Crystal/test/FindUBUsingMinMaxDTest.h index a872f62bb855..48271d258974 100644 --- a/Code/Mantid/Framework/Crystal/test/FindUBUsingMinMaxDTest.h +++ b/Code/Mantid/Framework/Crystal/test/FindUBUsingMinMaxDTest.h @@ -1,5 +1,5 @@ #ifndef MANTID_CRYSTAL_FIND_UB_USING_MIN_MAX_D_TEST_H_ -#define MANTID_CRYSTAL_FIND_UB_USING_MIN_MAX_TEST_H_ +#define MANTID_CRYSTAL_FIND_UB_USING_MIN_MAX_D_TEST_H_ #include #include "MantidKernel/Timer.h" diff --git a/Code/Mantid/Framework/Crystal/test/LoadHKLTest.h b/Code/Mantid/Framework/Crystal/test/LoadHKLTest.h index 7c84e690f646..cf250a4730fc 100644 --- a/Code/Mantid/Framework/Crystal/test/LoadHKLTest.h +++ b/Code/Mantid/Framework/Crystal/test/LoadHKLTest.h @@ -42,9 +42,11 @@ class LoadHKLTest : public CxxTest::TestSuite double smu = 0.357; double amu = 0.011; NeutronAtom neutron(static_cast(EMPTY_DBL()), static_cast(0), - 0.0, 0.0, smu, 0.0, smu, amu); - Material mat("SetInAnvredCorrection", neutron, 1.0); - ws->mutableSample().setMaterial(mat); + 0.0, 0.0, smu, 0.0, smu, amu); + Object sampleShape; + sampleShape.setMaterial(Material("SetInAnvredCorrection", neutron, 1.0)); + ws->mutableSample().setShape(sampleShape); + API::Run & mrun = ws->mutableRun(); mrun.addProperty("Radius", 0.1, true); diff --git a/Code/Mantid/Framework/Crystal/test/SaveHKLTest.h b/Code/Mantid/Framework/Crystal/test/SaveHKLTest.h index 61c3c4156921..317d53b7bc74 100644 --- a/Code/Mantid/Framework/Crystal/test/SaveHKLTest.h +++ b/Code/Mantid/Framework/Crystal/test/SaveHKLTest.h @@ -41,9 +41,11 @@ class SaveHKLTest : public CxxTest::TestSuite double smu = 0.357; double amu = 0.011; NeutronAtom neutron(static_cast(EMPTY_DBL()), static_cast(0), - 0.0, 0.0, smu, 0.0, smu, amu); - Material mat("SetInSaveHKLTest", neutron, 1.0); - ws->mutableSample().setMaterial(mat); + 0.0, 0.0, smu, 0.0, smu, amu); + Object sampleShape; + sampleShape.setMaterial(Material("SetInSaveHKLTest", neutron, 1.0)); + ws->mutableSample().setShape(sampleShape); + API::Run & mrun = ws->mutableRun(); mrun.addProperty("Radius", 0.1, true); diff --git a/Code/Mantid/Framework/Crystal/test/SortHKLTest.h b/Code/Mantid/Framework/Crystal/test/SortHKLTest.h index 5a0791f26999..4fb1ae8f5d3d 100644 --- a/Code/Mantid/Framework/Crystal/test/SortHKLTest.h +++ b/Code/Mantid/Framework/Crystal/test/SortHKLTest.h @@ -42,9 +42,11 @@ class SortHKLTest : public CxxTest::TestSuite double smu = 0.357; double amu = 0.011; NeutronAtom neutron(static_cast(EMPTY_DBL()), static_cast(0), - 0.0, 0.0, smu, 0.0, smu, amu); - Material mat("SetInSaveHKLTest", neutron, 1.0); - ws->mutableSample().setMaterial(mat); + 0.0, 0.0, smu, 0.0, smu, amu); + Object sampleShape; + sampleShape.setMaterial(Material("SetInSaveHKLTest", neutron, 1.0)); + ws->mutableSample().setShape(sampleShape); + API::Run & mrun = ws->mutableRun(); mrun.addProperty("Radius", 0.1, true); diff --git a/Code/Mantid/Framework/CurveFitting/CMakeLists.txt b/Code/Mantid/Framework/CurveFitting/CMakeLists.txt index c0906757d86a..25c639f653aa 100644 --- a/Code/Mantid/Framework/CurveFitting/CMakeLists.txt +++ b/Code/Mantid/Framework/CurveFitting/CMakeLists.txt @@ -12,6 +12,7 @@ set ( SRC_FILES src/Bk2BkExpConvPV.cpp src/BoundaryConstraint.cpp src/CalculateGammaBackground.cpp + src/CalculateMSVesuvio.cpp src/Chebyshev.cpp src/ComptonPeakProfile.cpp src/ComptonProfile.cpp @@ -32,6 +33,7 @@ set ( SRC_FILES src/ExpDecay.cpp src/ExpDecayMuon.cpp src/ExpDecayOsc.cpp + src/FABADAMinimizer.cpp src/FRConjugateGradientMinimizer.cpp src/Fit.cpp src/Fit1D.cpp @@ -56,6 +58,7 @@ set ( SRC_FILES src/LogNormal.cpp src/Lorentzian.cpp src/Lorentzian1D.cpp + src/MSVesuvioHelpers.cpp src/MultiDomainCreator.cpp src/MuonFInteraction.cpp src/NeutronBk2BkExpConvPVoigt.cpp @@ -96,14 +99,11 @@ set ( SRC_FILES src/UserFunction1D.cpp src/VesuvioResolution.cpp src/Voigt.cpp - src/FakeMinimizer.cpp - ) - + set ( SRC_UNITY_IGNORE_FILES src/Fit1D.cpp src/GSLFunctions.cpp ) set ( INC_FILES - inc/MantidCurveFitting/FakeMinimizer.h # inc/MantidCurveFitting/CostFuncIgnorePosPeaks.h # inc/MantidCurveFitting/SCDPanelErrors.h # inc/MantidCurveFitting/ChebyshevPolynomialBackground.h @@ -117,6 +117,7 @@ set ( INC_FILES inc/MantidCurveFitting/Bk2BkExpConvPV.h inc/MantidCurveFitting/BoundaryConstraint.h inc/MantidCurveFitting/CalculateGammaBackground.h + inc/MantidCurveFitting/CalculateMSVesuvio.h inc/MantidCurveFitting/Chebyshev.h inc/MantidCurveFitting/ComptonPeakProfile.h inc/MantidCurveFitting/ComptonProfile.h @@ -131,13 +132,14 @@ set ( INC_FILES inc/MantidCurveFitting/DampingMinimizer.h inc/MantidCurveFitting/DeltaFunction.h inc/MantidCurveFitting/DerivMinimizer.h - inc/MantidCurveFitting/DiffSphere.h inc/MantidCurveFitting/DiffRotDiscreteCircle.h + inc/MantidCurveFitting/DiffSphere.h inc/MantidCurveFitting/DllConfig.h inc/MantidCurveFitting/EndErfc.h inc/MantidCurveFitting/ExpDecay.h inc/MantidCurveFitting/ExpDecayMuon.h inc/MantidCurveFitting/ExpDecayOsc.h + inc/MantidCurveFitting/FABADAMinimizer.h inc/MantidCurveFitting/FRConjugateGradientMinimizer.h inc/MantidCurveFitting/Fit.h inc/MantidCurveFitting/Fit1D.h @@ -165,6 +167,7 @@ set ( INC_FILES inc/MantidCurveFitting/LogNormal.h inc/MantidCurveFitting/Lorentzian.h inc/MantidCurveFitting/Lorentzian1D.h + inc/MantidCurveFitting/MSVesuvioHelpers.h inc/MantidCurveFitting/MultiDomainCreator.h inc/MantidCurveFitting/MuonFInteraction.h inc/MantidCurveFitting/NeutronBk2BkExpConvPVoigt.h @@ -206,7 +209,7 @@ set ( INC_FILES inc/MantidCurveFitting/VesuvioResolution.h inc/MantidCurveFitting/Voigt.h ) - + set ( TEST_FILES # ChebyshevPolynomialBackgroundTest.h # RefinePowderInstrumentParametersTest.h @@ -220,6 +223,7 @@ set ( TEST_FILES Bk2BkExpConvPVTest.h BoundaryConstraintTest.h CalculateGammaBackgroundTest.h + CalculateMSVesuvioTest.h ChebyshevTest.h CompositeFunctionTest.h ComptonPeakProfileTest.h @@ -237,6 +241,7 @@ set ( TEST_FILES ExpDecayMuonTest.h ExpDecayOscTest.h ExpDecayTest.h + FABADAMinimizerTest.h FRConjugateGradientTest.h FitMWTest.h FitTest.h diff --git a/Code/Mantid/Framework/CurveFitting/inc/MantidCurveFitting/CalculateMSVesuvio.h b/Code/Mantid/Framework/CurveFitting/inc/MantidCurveFitting/CalculateMSVesuvio.h new file mode 100644 index 000000000000..0938057d47fe --- /dev/null +++ b/Code/Mantid/Framework/CurveFitting/inc/MantidCurveFitting/CalculateMSVesuvio.h @@ -0,0 +1,148 @@ +#ifndef MANTID_CURVEFITTING_CALCULATEMSVESUVIO_H_ +#define MANTID_CURVEFITTING_CALCULATEMSVESUVIO_H_ +//----------------------------------------------------------------------------- +// Includes +//----------------------------------------------------------------------------- +#include "MantidAPI/Algorithm.h" +#include "MantidGeometry/Instrument/ReferenceFrame.h" +#include "MantidKernel/V3D.h" + +namespace Mantid +{ + namespace CurveFitting + { + //----------------------------------------------------------------------------- + // CurveFitting forward declarations + //----------------------------------------------------------------------------- + struct DetectorParams; + struct ResolutionParams; + namespace MSVesuvioHelper + { + class RandomNumberGenerator; + struct Simulation; + struct SimulationWithErrors; + } + + /** + Calculates the multiple scattering & total scattering contributions + for a flat-plate or cylindrical sample. + + Copyright © 2014 ISIS Rutherford Appleton Laboratory & + NScD Oak Ridge National Laboratory + + This file is part of Mantid. + + Mantid is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + Mantid is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + + File change history is stored at: + Code Documentation is available at: + */ + class DLLExport CalculateMSVesuvio : public API::Algorithm + { + private: + // Holds date on the compton scattering properties of an atom + struct ComptonNeutronAtom + { + ComptonNeutronAtom() + : mass(-1.0), sclength(-1.0), profile(-1.0) {} + double mass; // in amu + double sclength; // 4pi/xsec + double profile; // s.d of J(y) + }; + // Holds data about sample as a whole. + struct SampleComptonProperties + { + SampleComptonProperties(const int nprops) + : atoms(nprops), density(-1.0), totalxsec(-1.0), + mu(-1.0) {} + + std::vector atoms; + double density; // g/cm^3 + double totalxsec; // total free-scattering cross section + double mu; // attenuation factor (1/m) + }; + + public: + CalculateMSVesuvio(); + ~CalculateMSVesuvio(); + + /// @copydoc Algorithm::name + virtual const std::string name() const { return "CalculateMSVesuvio"; } + /// @copydoc Algorithm::version + virtual int version() const { return 1; } + /// @copydoc Algorithm::category + virtual const std::string category() const { return "ISIS"; } + /// @copydoc Algorithm::summary + virtual const std::string summary() const + { + return "Calculates the contributions of multiple scattering " + "on a flat plate sample for VESUVIO"; + } + + private: + void init(); + void exec(); + + void cacheInputs(); + void calculateMS(const size_t wsIndex, API::ISpectrum & totalsc, + API::ISpectrum & multsc) const; + void simulate(const DetectorParams & detpar, + const ResolutionParams &respar, + MSVesuvioHelper::Simulation & simulCounts) const; + void assignToOutput(const MSVesuvioHelper::SimulationWithErrors & avgCounts, + API::ISpectrum & totalsc, API::ISpectrum & multsc) const; + double calculateCounts(const DetectorParams & detpar, + const ResolutionParams &respar, + MSVesuvioHelper::Simulation & simulation) const; + + // single-event helpers + Kernel::V3D generateSrcPos(const double l1) const; + double generateE0(const double l1, const double t2, double &weight) const; + double generateTOF(const double gaussTOF, const double dtof, const double dl1) const; + bool generateScatter(const Kernel::V3D &startPos, const Kernel::V3D &direc, double &weight, + Kernel::V3D &scatterPt) const; + std::pair calculateE1Range(const double theta, const double en0) const; + double partialDiffXSec(const double en0, const double en1, const double theta) const; + Kernel::V3D generateDetectorPos(const Kernel::V3D & nominalPos, const double energy, + const Kernel::V3D &scatterPt, + const Kernel::V3D & direcBeforeSc, + double &scang, double &distToExit) const; + double generateE1(const double angle, const double e1nom, const double e1res) const; + + // Member Variables + MSVesuvioHelper::RandomNumberGenerator *m_randgen; // random number generator + + size_t m_acrossIdx, m_upIdx, m_beamIdx; // indices of each direction + Kernel::V3D m_beamDir; // Directional vector for beam + double m_srcR2; // beam penumbra radius (m) + double m_halfSampleHeight, m_halfSampleWidth, m_halfSampleThick; // (m) + double m_maxWidthSampleFrame; // Maximum width in sample frame (m) + Geometry::Object const *m_sampleShape; // sample shape + SampleComptonProperties *m_sampleProps; // description of sample properties + double m_detHeight, m_detWidth, m_detThick; // (m) + double m_tmin, m_tmax, m_delt; // min, max & dt TOF value + double m_foilRes; // resolution in energy of foil + + size_t m_nscatters; // highest order of scattering to generate + size_t m_nruns; // number of runs per spectrum + size_t m_nevents; // number of single events per run + + API::Progress *m_progress; + API::MatrixWorkspace_sptr m_inputWS; + }; + + } // namespace CurveFitting +} // namespace Mantid + +#endif /* MANTID_CURVEFITTING_CALCULATEMSVESUVIO_H_ */ diff --git a/Code/Mantid/Framework/CurveFitting/inc/MantidCurveFitting/ConvertToYSpace.h b/Code/Mantid/Framework/CurveFitting/inc/MantidCurveFitting/ConvertToYSpace.h index 3bbbfeaa2292..caadecb04434 100644 --- a/Code/Mantid/Framework/CurveFitting/inc/MantidCurveFitting/ConvertToYSpace.h +++ b/Code/Mantid/Framework/CurveFitting/inc/MantidCurveFitting/ConvertToYSpace.h @@ -14,6 +14,7 @@ namespace CurveFitting { double l1; ///< source-sample distance in metres double l2; ///< sample-detector distance in metres + Kernel::V3D pos; ///< Full 3D position double theta; ///< scattering angle in radians double t0; ///< time delay in seconds double efixed; ///< final energy diff --git a/Code/Mantid/Framework/CurveFitting/inc/MantidCurveFitting/FABADAMinimizer.h b/Code/Mantid/Framework/CurveFitting/inc/MantidCurveFitting/FABADAMinimizer.h new file mode 100644 index 000000000000..b2c12fddc4e8 --- /dev/null +++ b/Code/Mantid/Framework/CurveFitting/inc/MantidCurveFitting/FABADAMinimizer.h @@ -0,0 +1,95 @@ +#ifndef MANTID_CURVEFITTING_FABADAMINIMIZER_H_ +#define MANTID_CURVEFITTING_FABADAMINIMIZER_H_ + +#include "MantidKernel/System.h" +#include "MantidAPI/IFuncMinimizer.h" +#include "MantidCurveFitting/GSLVector.h" +#include "MantidCurveFitting/GSLMatrix.h" +#include +#include + + +namespace Mantid +{ +namespace CurveFitting +{ +class CostFuncLeastSquares; + + /** FABADA : TODO: DESCRIPTION + + Copyright © 2014 ISIS Rutherford Appleton Laboratory & NScD Oak Ridge National Laboratory + + This file is part of Mantid. + + Mantid is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + Mantid is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + + File change history is stored at: + Code Documentation is available at: + */ + class DLLExport FABADAMinimizer : public API::IFuncMinimizer + { + 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. + virtual void initialize(API::ICostFunction_sptr function, size_t maxIterations); + /// Do one iteration. + virtual bool iterate(size_t iter); + /// Return current value of the cost function + virtual double costFunctionVal(); + + private: + /// Pointer to the cost function. Must be the least squares. + /// Intentar encontrar una manera de sacar aqui el numero de parametros que no sea necesaria la cost function + boost::shared_ptr m_leastSquares; + /// The number of iterations done. + size_t m_counter; + /// + size_t m_numberIterations; + /// The number of changes done in each parameter. + std::vector m_changes; + /// The jump for each parameter + std::vector m_jump; + /// Parameters. + GSLVector m_parameters; + /// Markov chain. + std::vector> m_chain; + /// The chi square result of previous iteration; + double m_chi2; + /// Boolean that indicates if converged + bool m_converged; + /// The point when convergence starts + size_t m_conv_point; + /// Convergence of each parameter + std::vector m_par_converged; + ///Lower bound for each parameter + std::vector m_lower; + ///Upper bound for each parameter + std::vector m_upper; + /// Bool that indicates if there is any boundary constraint + std::vector m_bound; + /// Convergence criteria for each parameter + std::vector m_criteria; + }; + + +} // namespace CurveFitting +} // namespace Mantid + +#endif /* MANTID_CURVEFITTING_FABADAMINIMIZER_H_ */ diff --git a/Code/Mantid/Framework/CurveFitting/inc/MantidCurveFitting/FakeMinimizer.h b/Code/Mantid/Framework/CurveFitting/inc/MantidCurveFitting/FakeMinimizer.h deleted file mode 100644 index 65ed977845bb..000000000000 --- a/Code/Mantid/Framework/CurveFitting/inc/MantidCurveFitting/FakeMinimizer.h +++ /dev/null @@ -1,65 +0,0 @@ -#ifndef MANTID_CURVEFITTING_FAKEMINIMIZER_H_ -#define MANTID_CURVEFITTING_FAKEMINIMIZER_H_ - -//---------------------------------------------------------------------- -// Includes -//---------------------------------------------------------------------- -#include "MantidAPI/IFuncMinimizer.h" - -namespace Mantid -{ -namespace CurveFitting -{ -/** Fake minimizer for testing output workspace properties. - Must be deleted before closing ticket #10008. - - Copyright © 2009 ISIS Rutherford Appleton Laboratory & NScD Oak Ridge National Laboratory - - This file is part of Mantid. - - Mantid is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - Mantid is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . - - File change history is stored at: . - Code Documentation is available at: -*/ -class DLLExport FakeMinimizer : public API::IFuncMinimizer -{ -public: - /// Constructor setting a value for the relative error acceptance (default=0.01) - FakeMinimizer(); - /// Destructor - ~FakeMinimizer(); - - /// Overloading base class methods - std::string name()const{return "Fake";} - /// Do one iteration - bool iterate(size_t); - /// Return current value of the cost function - double costFunctionVal(); - /// Initialize minimizer, i.e. pass a function to minimize. - virtual void initialize(API::ICostFunction_sptr function, size_t maxIterations = 0); - -private: - size_t m_maxIters; - std::vector m_data; - int m_someInt; - double m_someDouble; - std::string m_someString; -}; - - -} // namespace CurveFitting -} // namespace Mantid - -#endif /*MANTID_CURVEFITTING_FAKEMINIMIZER_H_*/ diff --git a/Code/Mantid/Framework/CurveFitting/inc/MantidCurveFitting/MSVesuvioHelpers.h b/Code/Mantid/Framework/CurveFitting/inc/MantidCurveFitting/MSVesuvioHelpers.h new file mode 100644 index 000000000000..9084339ea9eb --- /dev/null +++ b/Code/Mantid/Framework/CurveFitting/inc/MantidCurveFitting/MSVesuvioHelpers.h @@ -0,0 +1,75 @@ +#ifndef MANTID_CURVEFITTING_MSVESUVIOHELPERS_H +#define MANTID_CURVEFITTING_MSVESUVIOHELPERS_H + +#include + +#include +#include +#include + +namespace Mantid { namespace CurveFitting +{ + namespace MSVesuvioHelper + { + // Absorption energy for double-difference gold foil + double finalEnergyAuDD(const double randv); + // Absorption energy for gold foil YAP + double finalEnergyAuYap(const double randv); + // Absorption energy for uranium + double finalEnergyUranium(const double randv); + + // Ties together random numbers with various probability distributions + // @todo: Should move to Kernel + class RandomNumberGenerator + { + typedef boost::uniform_real uniform_double; + typedef boost::normal_distribution gaussian_double; + public: + RandomNumberGenerator(const int seed); + /// Returns a flat random number between 0.0 & 1.0 + double flat(); + /// Returns a random number distributed by a normal distribution + double gaussian(const double mean, const double sigma); + + private: + RandomNumberGenerator(); + boost::mt19937 m_generator; + }; + + // Stores counts for each scatter order + // for a "run" of a given number of events + struct Simulation + { + Simulation(const size_t order, const size_t ntimes); + + std::vector> counts; + size_t maxorder; + }; + // Stores counts for each scatter order with errors + struct SimulationWithErrors + { + SimulationWithErrors(const size_t order, const size_t ntimes) : + sim(order, ntimes), errors(order, std::vector(ntimes)) {} + + void normalise(); + Simulation sim; + std::vector> errors; + }; + + // Accumulates and averages the results of a set of simulations + struct SimulationAggregator + { + SimulationAggregator(const size_t nruns); + + // Creates a placeholder for a new simulation + Simulation & newSimulation(const size_t order, + const size_t ntimes); + SimulationWithErrors average() const; + + std::vector results; + }; + + } +}} + +#endif // MANTID_CURVEFITTING_MSVESUVIOHELPERS_H diff --git a/Code/Mantid/Framework/CurveFitting/inc/MantidCurveFitting/TabulatedFunction.h b/Code/Mantid/Framework/CurveFitting/inc/MantidCurveFitting/TabulatedFunction.h index 3cdbcc69a14b..191d01e45117 100644 --- a/Code/Mantid/Framework/CurveFitting/inc/MantidCurveFitting/TabulatedFunction.h +++ b/Code/Mantid/Framework/CurveFitting/inc/MantidCurveFitting/TabulatedFunction.h @@ -37,7 +37,7 @@ of real numbers separated by spaces. The first column are the x-values and the s If a nexus file is used its first spectrum provides the data for the function. The same is true for a workspace which must be a MatrixWorkspace. -The function has a signle parameter - a scaling factor "Scaling". +The function has two parameters - a scaling factor "Scaling" and a shift factor along the abscissas 'Shift' @author Roman Tolchenov, Tessella plc @date 4/09/2012 @@ -96,7 +96,7 @@ class DLLExport TabulatedFunction : public API::ParamFunction, public API::IFunc void clear() const; /// Evaluate the function for a list of arguments and given scaling factor - void eval(double scaling, double* out, const double* xValues, const size_t nData)const; + void eval(double scaling, double shift, double* out, const double* xValues, const size_t nData)const; /// Fill in the x and y value containers (m_xData and m_yData) void setupData() const; diff --git a/Code/Mantid/Framework/CurveFitting/inc/MantidCurveFitting/VesuvioResolution.h b/Code/Mantid/Framework/CurveFitting/inc/MantidCurveFitting/VesuvioResolution.h index f03970f60223..543363c119e9 100644 --- a/Code/Mantid/Framework/CurveFitting/inc/MantidCurveFitting/VesuvioResolution.h +++ b/Code/Mantid/Framework/CurveFitting/inc/MantidCurveFitting/VesuvioResolution.h @@ -20,11 +20,12 @@ namespace CurveFitting /// It avoids some functions taking a huge number of arguments struct ResolutionParams { - double dl1; ///< spread in source-sample distance - double dl2; ///< spread in sample-detector distance - double dthe; ///< spread in scattering angle - double dEnLorentz; ///< lorentz width in energy - double dEnGauss; ///< gaussian width in energy + double dl1; ///< spread in source-sample distance (m) + double dl2; ///< spread in sample-detector distance (m) + double dtof; ///< spread in tof measurement (us) + double dthe; ///< spread in scattering angle (radians) + double dEnLorentz; ///< lorentz width in energy (meV) + double dEnGauss; ///< gaussian width in energy (meV }; /** @@ -54,6 +55,11 @@ namespace CurveFitting class MANTID_CURVEFITTING_DLL VesuvioResolution : public virtual API::ParamFunction, public virtual API::IFunction1D { public: + + /// Creates a POD struct containing the required resolution parameters for this spectrum + static ResolutionParams getResolutionParameters(const API::MatrixWorkspace_const_sptr & ws, + const size_t index); + /// Default constructor required for factory VesuvioResolution(); diff --git a/Code/Mantid/Framework/CurveFitting/src/CalculateGammaBackground.cpp b/Code/Mantid/Framework/CurveFitting/src/CalculateGammaBackground.cpp index e3027dc59b89..a408a931f7f4 100644 --- a/Code/Mantid/Framework/CurveFitting/src/CalculateGammaBackground.cpp +++ b/Code/Mantid/Framework/CurveFitting/src/CalculateGammaBackground.cpp @@ -1,6 +1,7 @@ #include "MantidCurveFitting/CalculateGammaBackground.h" #include "MantidCurveFitting/ComptonProfile.h" #include "MantidCurveFitting/ConvertToYSpace.h" +#include "MantidCurveFitting/VesuvioResolution.h" #include "MantidAPI/CompositeFunction.h" #include "MantidAPI/FunctionProperty.h" @@ -231,24 +232,9 @@ namespace Mantid */ void CalculateGammaBackground::calculateSpectrumFromDetector(const size_t inputIndex, const size_t outputIndex) { - auto det = m_inputWS->getDetector(inputIndex); - const auto & pmap = m_inputWS->constInstrumentParameters(); - auto detPos = det->getPos(); - // -- Setup detector & resolution parameters -- - DetectorParams detPar; - detPar.l1 = m_l1; - detPar.l2 = m_samplePos.distance(detPos); - detPar.theta = m_inputWS->detectorTwoTheta(det); //radians - detPar.t0 = ConvertToYSpace::getComponentParameter(det, pmap, "t0")*1e-6; // seconds - detPar.efixed = ConvertToYSpace::getComponentParameter(det, pmap,"efixed"); - - ResolutionParams detRes; - detRes.dl1 = ConvertToYSpace::getComponentParameter(det, pmap, "sigma_l1"); // DL0 - detRes.dl2 = ConvertToYSpace::getComponentParameter(det, pmap, "sigma_l2"); // DL1 - detRes.dthe = ConvertToYSpace::getComponentParameter(det, pmap, "sigma_theta"); //DTH in radians - detRes.dEnGauss = ConvertToYSpace::getComponentParameter(det, pmap, "sigma_gauss"); - detRes.dEnLorentz = ConvertToYSpace::getComponentParameter(det, pmap, "hwhm_lorentz"); + DetectorParams detPar = ConvertToYSpace::getDetectorParameters(m_inputWS, inputIndex); + ResolutionParams detRes = VesuvioResolution::getResolutionParameters(m_inputWS, inputIndex); // Compute a time of flight spectrum convolved with a Voigt resolution function for each mass // at the detector point & sum to a single spectrum @@ -269,24 +255,9 @@ namespace Mantid */ void CalculateGammaBackground::calculateBackgroundFromFoils(const size_t inputIndex, const size_t outputIndex) { - auto det = m_inputWS->getDetector(inputIndex); - const auto & pmap = m_inputWS->constInstrumentParameters(); - auto detPos = det->getPos(); - // -- Setup detector & resolution parameters -- - DetectorParams detPar; - detPar.l1 = m_l1; - detPar.l2 = m_samplePos.distance(detPos); - detPar.theta = m_inputWS->detectorTwoTheta(det); //radians - detPar.t0 = ConvertToYSpace::getComponentParameter(det, pmap, "t0")*1e-6; // seconds - detPar.efixed = ConvertToYSpace::getComponentParameter(det, pmap,"efixed"); - - ResolutionParams detRes; - detRes.dl1 = ConvertToYSpace::getComponentParameter(det, pmap, "sigma_l1"); // DL0 - detRes.dl2 = ConvertToYSpace::getComponentParameter(det, pmap, "sigma_l2"); // DL1 - detRes.dthe = ConvertToYSpace::getComponentParameter(det, pmap, "sigma_theta"); //DTH in radians - detRes.dEnGauss = ConvertToYSpace::getComponentParameter(det, pmap, "sigma_gauss"); - detRes.dEnLorentz = ConvertToYSpace::getComponentParameter(det, pmap, "hwhm_lorentz"); + DetectorParams detPar = ConvertToYSpace::getDetectorParameters(m_inputWS, inputIndex); + ResolutionParams detRes = VesuvioResolution::getResolutionParameters(m_inputWS, inputIndex); const size_t nxvalues = m_backgroundWS->blocksize(); std::vector foilSpectrum(nxvalues); @@ -297,13 +268,13 @@ namespace Mantid for(size_t i = 0; i < m_foils0.size(); ++i) { foilSpectrum.assign(nxvalues,0.0); - calculateBackgroundSingleFoil(foilSpectrum, outputIndex,m_foils1[i], detPos, detPar, detRes); + calculateBackgroundSingleFoil(foilSpectrum, outputIndex,m_foils1[i], detPar.pos, detPar, detRes); // sum spectrum values from first position std::transform(ctfoil.begin(), ctfoil.end(), foilSpectrum.begin(), ctfoil.begin(), std::plus()); foilSpectrum.assign(nxvalues,0.0); - calculateBackgroundSingleFoil(foilSpectrum, outputIndex,m_foils0[i], detPos, detPar, detRes); + calculateBackgroundSingleFoil(foilSpectrum, outputIndex,m_foils0[i], detPar.pos, detPar, detRes); // subtract spectrum values from zeroth position std::transform(ctfoil.begin(), ctfoil.end(), foilSpectrum.begin(), ctfoil.begin(), std::minus()); @@ -472,14 +443,14 @@ namespace Mantid { for(size_t i = 0; i < m_inputWS->getNumberHistograms(); ++i) { - m_indices[i] = i; // 1-to-1 + m_indices.insert(std::make_pair(i,i)); // 1-to-1 } } else { for(size_t i = 0; i < requestedIndices.size(); ++i) { - m_indices[i] = static_cast(requestedIndices[i]); //user-requested->increasing on output + m_indices.insert(std::make_pair(i, static_cast(requestedIndices[i]))); //user-requested->increasing on output } } diff --git a/Code/Mantid/Framework/CurveFitting/src/CalculateMSVesuvio.cpp b/Code/Mantid/Framework/CurveFitting/src/CalculateMSVesuvio.cpp new file mode 100644 index 000000000000..532e4dab4e5d --- /dev/null +++ b/Code/Mantid/Framework/CurveFitting/src/CalculateMSVesuvio.cpp @@ -0,0 +1,788 @@ +//----------------------------------------------------------------------------- +// Includes +//----------------------------------------------------------------------------- +#include "MantidCurveFitting/CalculateMSVesuvio.h" +// Use helpers for storing detector/resolution parameters +#include "MantidCurveFitting/ConvertToYSpace.h" +#include "MantidCurveFitting/MSVesuvioHelpers.h" +#include "MantidCurveFitting/VesuvioResolution.h" + +#include "MantidAPI/SampleShapeValidator.h" +#include "MantidAPI/WorkspaceValidators.h" + +#include "MantidGeometry/Instrument/ParameterMap.h" +#include "MantidGeometry/Objects/Track.h" + +#include "MantidKernel/ArrayLengthValidator.h" +#include "MantidKernel/ArrayProperty.h" +#include "MantidKernel/BoundedValidator.h" +#include "MantidKernel/CompositeValidator.h" +#include "MantidKernel/MersenneTwister.h" +#include "MantidKernel/VectorHelper.h" + +#include + +namespace Mantid +{ + namespace CurveFitting + { + using namespace API; + using namespace Kernel; + using Geometry::Link; + using Geometry::ParameterMap; + using Geometry::Track; + + namespace + { + const size_t MAX_SCATTER_PT_TRIES = 25; + /// Conversion constant + const double MASS_TO_MEV = 0.5*PhysicalConstants::NeutronMass/PhysicalConstants::meV; + } // end anonymous namespace + + //------------------------------------------------------------------------- + // Member functions + //------------------------------------------------------------------------- + + // Register the algorithm into the AlgorithmFactory + DECLARE_ALGORITHM(CalculateMSVesuvio) + + /// Constructor + CalculateMSVesuvio::CalculateMSVesuvio() : Algorithm(), + m_randgen(NULL), + m_acrossIdx(0), m_upIdx(1), m_beamIdx(3), m_beamDir(), m_srcR2(0.0), + m_halfSampleHeight(0.0), m_halfSampleWidth(0.0), m_halfSampleThick(0.0), + m_maxWidthSampleFrame(0.0), m_sampleShape(NULL), m_sampleProps(NULL), + m_detHeight(-1.0), m_detWidth(-1.0), m_detThick(-1.0), + m_tmin(-1.0), m_tmax(-1.0), m_delt(-1.0), m_foilRes(-1.0), + m_nscatters(0), m_nruns(0), m_nevents(0), + m_progress(NULL), m_inputWS() + { + } + + /// Destructor + CalculateMSVesuvio::~CalculateMSVesuvio() + { + delete m_randgen; + delete m_progress; + delete m_sampleProps; + } + + /** + * Initialize the algorithm's properties. + */ + void CalculateMSVesuvio::init() + { + // Inputs + auto inputWSValidator = boost::make_shared(); + inputWSValidator->add("TOF"); + inputWSValidator->add(); + declareProperty(new WorkspaceProperty<>("InputWorkspace","", + Direction::Input, inputWSValidator), + "Input workspace to be corrected, in units of TOF."); + + // -- Sample -- + auto positiveInt = boost::make_shared>(); + positiveInt->setLower(1); + declareProperty("NoOfMasses", -1, positiveInt, + "The number of masses contained within the sample"); + + auto positiveNonZero = boost::make_shared>(); + positiveNonZero->setLower(0.0); + positiveNonZero->setLowerExclusive(true); + declareProperty("SampleDensity", -1.0, positiveNonZero, + "The density of the sample in gm/cm^3"); + + auto nonEmptyArray = boost::make_shared>(); + nonEmptyArray->setLengthMin(3); + declareProperty(new ArrayProperty("AtomicProperties", nonEmptyArray), + "Atomic properties of masses within the sample. " + "The expected format is 3 consecutive values per mass: " + "mass(amu), cross-section (barns) & s.d of Compton profile."); + setPropertyGroup("NoOfMasses", "Sample"); + setPropertyGroup("SampleDensity", "Sample"); + setPropertyGroup("AtomicProperties", "Sample"); + + // -- Beam -- + declareProperty("BeamRadius", -1.0, positiveNonZero, + "Radius, in cm, of beam"); + + // -- Algorithm -- + declareProperty("Seed", 123456789, positiveInt, + "Seed the random number generator with this value"); + declareProperty("NumScatters", 3, positiveInt, + "Number of scattering orders to calculate"); + declareProperty("NumRuns", 10, positiveInt, + "Number of simulated runs per spectrum"); + declareProperty("NumEventsPerRun", 50000, positiveInt, + "Number of events per run"); + setPropertyGroup("Seed", "Algorithm"); + setPropertyGroup("NumScatters", "Algorithm"); + setPropertyGroup("NumRuns", "Algorithm"); + setPropertyGroup("NumEventsPerRun", "Algorithm"); + + // Outputs + declareProperty(new WorkspaceProperty<>("TotalScatteringWS","", Direction::Output), + "Workspace to store the calculated total scattering counts"); + declareProperty(new WorkspaceProperty<>("MultipleScatteringWS","", Direction::Output), + "Workspace to store the calculated total scattering counts"); + } + + /** + * Execute the algorithm. + */ + void CalculateMSVesuvio::exec() + { + m_inputWS = getProperty("InputWorkspace"); + cacheInputs(); + + // Create new workspaces + MatrixWorkspace_sptr totalsc = WorkspaceFactory::Instance().create(m_inputWS); + MatrixWorkspace_sptr multsc = WorkspaceFactory::Instance().create(m_inputWS); + + // Initialize random number generator + m_randgen = new MSVesuvioHelper::RandomNumberGenerator(getProperty("Seed")); + + // Setup progress + const size_t nhist = m_inputWS->getNumberHistograms(); + m_progress = new API::Progress(this, 0.0, 1.0, nhist*m_nruns*2); + for(size_t i = 0; i < nhist; ++i) + { + + // Copy over the X-values + const MantidVec & xValues = m_inputWS->readX(i); + totalsc->dataX(i) = xValues; + multsc->dataX(i) = xValues; + + // Final detector position + Geometry::IDetector_const_sptr detector; + try + { + detector = m_inputWS->getDetector(i); + } + catch(Kernel::Exception::NotFoundError&) + { + // intel compiler doesn't like continue in a catch inside an OMP loop + } + if(!detector) + { + std::ostringstream os; + os << "No valid detector object found for spectrum at workspace index '" << i << "'. No correction calculated."; + g_log.information(os.str()); + continue; + } + + // the output spectrum objects have references to where the data will be stored + calculateMS(i, *totalsc->getSpectrum(i), *multsc->getSpectrum(i)); + } + + setProperty("TotalScatteringWS", totalsc); + setProperty("MultipleScatteringWS", multsc); + } + + /** + * Caches inputs insuitable form for speed in later calculations + */ + void CalculateMSVesuvio::cacheInputs() + { + // Algorithm + int nscatters = getProperty("NumScatters"); + m_nscatters = static_cast(nscatters); + int nruns = getProperty("NumRuns"); + m_nruns = static_cast(nruns); + int nevents = getProperty("NumEventsPerRun"); + m_nevents = static_cast(nevents); + + // -- Geometry -- + const auto instrument = m_inputWS->getInstrument(); + m_beamDir = instrument->getSample()->getPos() - instrument->getSource()->getPos(); + m_beamDir.normalize(); + + const auto rframe = instrument->getReferenceFrame(); + m_acrossIdx = rframe->pointingHorizontal(); + m_upIdx = rframe->pointingUp(); + m_beamIdx = rframe->pointingAlongBeam(); + + m_srcR2 = getProperty("BeamRadius"); + // Convert to metres + m_srcR2 /= 100.0; + + // Sample shape + m_sampleShape = &(m_inputWS->sample().getShape()); + // We know the shape is valid from the property validator + // Use the bounding box as an approximation to determine the extents + // as this will match in both height and width for a cuboid & cylinder + // sample shape + Geometry::BoundingBox bounds = m_sampleShape->getBoundingBox(); + V3D boxWidth = bounds.width(); + // Use half-width/height for easier calculation later + m_halfSampleWidth = 0.5*boxWidth[m_acrossIdx]; + m_halfSampleHeight = 0.5*boxWidth[m_upIdx]; + m_halfSampleThick = 0.5*boxWidth[m_beamIdx]; + + // -- Workspace -- + const auto & inX = m_inputWS->readX(0); + m_tmin = inX.front()*1e-06; + m_tmax = inX.back()*1e-06; + m_delt = (inX[1] - inX.front()); + + // -- Sample -- + int nmasses = getProperty("NoOfMasses"); + std::vector sampleInfo = getProperty("AtomicProperties"); + const int nInputAtomProps = static_cast(sampleInfo.size()); + const int nExptdAtomProp(3); + if(nInputAtomProps != nExptdAtomProp*nmasses) + { + std::ostringstream os; + os << "Inconsistent AtomicProperties list defined. Expected " << nExptdAtomProp*nmasses + << " values, however, only " << sampleInfo.size() << " have been given."; + throw std::invalid_argument(os.str()); + } + const int natoms = nInputAtomProps/3; + m_sampleProps = new SampleComptonProperties(natoms); + m_sampleProps->density = getProperty("SampleDensity"); + + double totalMass(0.0); // total mass in grams + m_sampleProps->totalxsec = 0.0; + for(int i = 0; i < natoms; ++i) + { + auto & comptonAtom = m_sampleProps->atoms[i]; + comptonAtom.mass = sampleInfo[nExptdAtomProp*i]; + totalMass += comptonAtom.mass*PhysicalConstants::AtomicMassUnit*1000; + + const double xsec = sampleInfo[nExptdAtomProp*i + 1]; + comptonAtom.sclength = sqrt(xsec/(4.0*M_PI)); + const double factor = 1.0 + (PhysicalConstants::NeutronMassAMU/comptonAtom.mass); + m_sampleProps->totalxsec += (xsec/(factor*factor)); + + comptonAtom.profile = sampleInfo[nExptdAtomProp*i + 2]; + } + const double numberDensity = m_sampleProps->density*1e6/totalMass; // formula units/m^3 + m_sampleProps->mu = numberDensity*m_sampleProps->totalxsec*1e-28; + + // -- Detector geometry -- choose first detector that is not a monitor + Geometry::IDetector_const_sptr detPixel; + for(size_t i = 0; i < m_inputWS->getNumberHistograms(); ++i) + { + try + { + detPixel = m_inputWS->getDetector(i); + } + catch(Exception::NotFoundError &) + { + continue; + } + if(!detPixel->isMonitor()) break; + } + // Bounding box in detector frame + Geometry::Object_const_sptr pixelShape = detPixel->shape(); + if(!pixelShape || !pixelShape->hasValidShape()) + { + throw std::invalid_argument("Detector pixel has no defined shape!"); + } + Geometry::BoundingBox detBounds = pixelShape->getBoundingBox(); + V3D detBoxWidth = detBounds.width(); + m_detWidth = detBoxWidth[m_acrossIdx]; + m_detHeight = detBoxWidth[m_upIdx]; + m_detThick = detBoxWidth[m_beamIdx]; + + // Foil resolution + auto foil = instrument->getComponentByName("foil-pos0"); + if(!foil) + { + throw std::runtime_error("Workspace has no gold foil component defined."); + } + auto param = m_inputWS->instrumentParameters().get(foil.get(), "hwhm_lorentz"); + if(!param) + { + throw std::runtime_error("Foil component has no hwhm_lorentz parameter defined."); + } + m_foilRes = param->value(); + } + + /** + * Calculate the total scattering and contributions from higher-order scattering for given + * spectrum + * @param wsIndex The index on the input workspace for the chosen spectrum + * @param totalsc A non-const reference to the spectrum that will contain the total scattering calculation + * @param multsc A non-const reference to the spectrum that will contain the multiple scattering contribution + */ + void CalculateMSVesuvio::calculateMS(const size_t wsIndex, API::ISpectrum & totalsc, + API::ISpectrum & multsc) const + { + // Detector information + DetectorParams detpar = ConvertToYSpace::getDetectorParameters(m_inputWS, wsIndex); + detpar.t0 *= 1e6; // t0 in microseconds here + ResolutionParams respar = VesuvioResolution::getResolutionParameters(m_inputWS, wsIndex); + + // Final counts averaged over all simulations + MSVesuvioHelper::SimulationAggregator accumulator(m_nruns); + for(size_t i = 0; i < m_nruns; ++i) + { + m_progress->report("MS calculation: idx=" + boost::lexical_cast(wsIndex) + + ", run=" + boost::lexical_cast(i)); + + simulate(detpar, respar, + accumulator.newSimulation(m_nscatters, m_inputWS->blocksize())); + + m_progress->report("MS calculation: idx=" + boost::lexical_cast(wsIndex) + + ", run=" + boost::lexical_cast(i)); + } + + // Average over all runs and assign to output workspaces + MSVesuvioHelper::SimulationWithErrors avgCounts = accumulator.average(); + avgCounts.normalise(); + assignToOutput(avgCounts, totalsc, multsc); + } + + /** + * Perform a single simulation of a given number of events for up to a maximum number of + * scatterings on a chosen detector + * @param detpar Detector information describing the final detector position + * @param respar Resolution information on the intrument as a whole + * @param simulCounts Simulation object used to storing the calculated number of counts + */ + void CalculateMSVesuvio::simulate(const DetectorParams & detpar, + const ResolutionParams &respar, + MSVesuvioHelper::Simulation & simulCounts) const + { + for(size_t i = 0; i < m_nevents; ++i) + { + calculateCounts(detpar, respar, simulCounts); + } + } + + /** + * Assign the averaged counts to the correct workspaces + * @param avgCounts Counts & errors separated for each scattering order + * @param totalsc A non-const reference to the spectrum for the total scattering calculation + * @param multsc A non-const reference to the spectrum for the multiple scattering contribution + */ + void + CalculateMSVesuvio::assignToOutput(const MSVesuvioHelper::SimulationWithErrors &avgCounts, + API::ISpectrum & totalsc, API::ISpectrum & multsc) const + { + // Sum up all multiple scatter events + auto & msscatY = multsc.dataY(); + auto & msscatE = multsc.dataE(); + for(size_t i = 1; i < m_nscatters; ++i) //(i >= 1 for multiple scatters) + { + const auto & counts = avgCounts.sim.counts[i]; + // equivalent to msscatY[j] += counts[j] + std::transform(counts.begin(), counts.end(), msscatY.begin(), msscatY.begin(), + std::plus()); + const auto & scerrors = avgCounts.errors[i]; + // sum errors in quadrature + std::transform(scerrors.begin(), scerrors.end(), msscatE.begin(), msscatE.begin(), + VectorHelper::SumGaussError()); + } + // for total scattering add on single-scatter events + auto & totalscY = totalsc.dataY(); + auto & totalscE = totalsc.dataE(); + const auto & counts0 = avgCounts.sim.counts.front(); + std::transform(counts0.begin(), counts0.end(), msscatY.begin(), totalscY.begin(), + std::plus()); + const auto & errors0 = avgCounts.errors.front(); + std::transform(errors0.begin(), errors0.end(), msscatE.begin(), totalscE.begin(), + VectorHelper::SumGaussError()); + } + + /** + * @param detpar Detector information describing the final detector position + * @param respar Resolution information on the intrument as a whole + * @param simulation [Output] Store the calculated counts here + * @return The sum of the weights for all scatters + */ + double CalculateMSVesuvio::calculateCounts(const DetectorParams &detpar, + const ResolutionParams &respar, + MSVesuvioHelper::Simulation &simulation) const + { + double weightSum(0.0); + + // moderator coord in lab frame + V3D srcPos = generateSrcPos(detpar.l1); + if(fabs(srcPos[m_acrossIdx]) > m_halfSampleWidth || + fabs(srcPos[m_upIdx]) > m_halfSampleHeight) + { + return 0.0; // misses sample + } + + // track various variables during calculation + std::vector weights(m_nscatters, 1.0), // start at 1.0 + tofs(m_nscatters, 0.0), // tof accumulates for each piece of the calculation + en1(m_nscatters, 0.0); + + const double vel2 = sqrt(detpar.efixed/MASS_TO_MEV); + const double t2 = detpar.l2/vel2; + en1[0] = generateE0(detpar.l1, t2, weights[0]); + tofs[0] = generateTOF(en1[0], respar.dtof, respar.dl1); // correction for resolution in l1 + + // Neutron path + std::vector scatterPts(m_nscatters), // track origin of each scatter + neutronDirs(m_nscatters); // neutron directions + V3D startPos(srcPos); + neutronDirs[0] = m_beamDir; + + generateScatter(startPos, neutronDirs[0], weights[0], scatterPts[0]); + double distFromStart = startPos.distance(scatterPts[0]); + // Compute TOF for first scatter event + const double vel0 = sqrt(en1[0]/MASS_TO_MEV); + tofs[0] += (distFromStart*1e6/vel0); + + // multiple scatter events within sample, i.e not including zeroth + for(size_t i = 1; i < m_nscatters; ++i) + { + weights[i] = weights[i-1]; + tofs[i] = tofs[i-1]; + + // Generate a new direction of travel + const V3D & prevSc = scatterPts[i-1]; + V3D & curSc = scatterPts[i]; + const V3D & oldDir = neutronDirs[i-1]; + V3D & newDir = neutronDirs[i]; + size_t ntries(0); + do + { + const double randth = acos(2.0*m_randgen->flat() - 1.0); + const double randphi = 2.0*M_PI*m_randgen->flat(); + newDir.azimuth_polar_SNS(1.0, randphi, randth); + + // Update weight + const double wgt = weights[i]; + if(generateScatter(prevSc, newDir, weights[i], curSc)) + break; + else + { + weights[i] = wgt; // put it back to what it was + ++ntries; + } + } + while(ntries < MAX_SCATTER_PT_TRIES); + if(ntries == MAX_SCATTER_PT_TRIES) + { + throw std::runtime_error("Unable to generate scatter point in sample. Check sample shape."); + } + + const double scang = newDir.angle(oldDir); + auto e1range = calculateE1Range(scang, en1[i-1]); + en1[i] = e1range.first + m_randgen->flat()*(e1range.second - e1range.first); + const double d2sig = partialDiffXSec(en1[i-1], en1[i], scang); + double weight = d2sig*4.0*M_PI*(e1range.second - e1range.first)/m_sampleProps->totalxsec; + // accumulate total weight + weightSum += weight; + weights[i] *= weight; // account for this scatter on top of previous + + // Increment time of flight... + const double veli = sqrt(en1[i]/MASS_TO_MEV); + tofs[i] += (curSc.distance(prevSc)*1e6/veli); + } + + // force all orders in to current detector + const auto & inX = m_inputWS->readX(0); + for(size_t i = 0; i < m_nscatters; ++i) + { + double scang(0.0), distToExit(0.0); + V3D detPos = generateDetectorPos(detpar.pos, en1[i], scatterPts[i], neutronDirs[i], + scang, distToExit); + // Weight by probability neutron leaves sample + double & curWgt = weights[i]; + curWgt *= exp(-m_sampleProps->mu*distToExit); + // Weight by cross-section for the final energy + const double efinal = generateE1(detpar.theta, detpar.efixed, m_foilRes); + curWgt *= partialDiffXSec(en1[i], efinal, scang)/m_sampleProps->totalxsec; + // final TOF + const double veli = sqrt(efinal/MASS_TO_MEV); + tofs[i] += detpar.t0 + (scatterPts[i].distance(detPos)*1e6)/veli; + // "Bin" weight into appropriate place + std::vector &counts = simulation.counts[i]; + const double finalTOF = tofs[i]; + + for (size_t it = 0; it < inX.size(); ++it) + { + if (inX[it] - 0.5*m_delt < finalTOF && finalTOF < inX[it] + 0.5*m_delt) + { + counts[it] += curWgt; + break; + } + } + } + + return weightSum; + } + + /** + * Sample from the moderator assuming it can be seen + * as a cylindrical ring with inner and outer radius + * @param l1 Src-sample distance (m) + * @returns Position on the moderator of the generated point + */ + V3D CalculateMSVesuvio::generateSrcPos(const double l1) const + { + double radius(-1.0), widthPos(0.0), heightPos(0.0); + do + { + widthPos = -m_srcR2 + 2.0*m_srcR2*m_randgen->flat(); + heightPos = -m_srcR2 + 2.0*m_srcR2*m_randgen->flat(); + using std::sqrt; + radius = sqrt(widthPos*widthPos + heightPos*heightPos); + } + while(radius > m_srcR2); + // assign to output + V3D srcPos; + srcPos[m_acrossIdx] = widthPos; + srcPos[m_upIdx] = heightPos; + srcPos[m_beamIdx] = -l1; + + return srcPos; + } + + /** + * Generate an incident energy based on a randomly-selected TOF value + * It is assigned a weight = (2.0*E0/(T-t2))/E0^0.9. + * @param l1 Distance from src to sample (metres) + * @param t2 Nominal time from sample to detector (seconds) + * @param weight [Out] Weight factor to modify for the generated energy value + * @return + */ + double CalculateMSVesuvio::generateE0(const double l1, const double t2, double &weight) const + { + const double tof = m_tmin + (m_tmax - m_tmin)*m_randgen->flat(); + const double t1 = (tof - t2); + const double vel0 = l1/t1; + const double en0 = MASS_TO_MEV*vel0*vel0; + + weight = 2.0*en0/t1/pow(en0, 0.9); + weight *= 1e-4; // Reduce weight to ~1 + + return en0; + } + + /** + * Generate an initial tof from this distribution: + * 1-(0.5*X**2/T0**2+X/T0+1)*EXP(-X/T0), where x is the time and t0 + * is the src-sample time. + * @param dtof Error in time resolution (us) + * @param en0 Value of the incident energy + * @param dl1 S.d of moderator to sample distance + * @return tof Guass TOF modified for asymmetric pulse + */ + double CalculateMSVesuvio::generateTOF(const double en0, const double dtof, + const double dl1) const + { + const double vel1 = sqrt(en0/MASS_TO_MEV); + const double dt1 = (dl1/vel1)*1e6; + const double xmin(0.0), xmax(15.0*dt1); + double dx = 0.5*(xmax - xmin); + // Generate a random y position in th distribution + const double yv = m_randgen->flat(); + + double xt(xmin); + double tof = m_randgen->gaussian(0.0, dtof); + while(true) + { + xt += dx; + //Y=1-(0.5*X**2/T0**2+X/T0+1)*EXP(-X/T0) + double y = 1.0 - (0.5*xt*xt/(dt1*dt1) + xt/dt1 + 1)*exp(-xt/dt1); + if(fabs(y - yv) < 1e-4) + { + tof += xt - 3*dt1; + break; + } + if(y > yv) + { + dx = -fabs(0.5*dx); + } + else + { + dx = fabs(0.5*dx); + } + } + return tof; + } + + /** + * Generate a scatter event and update the weight according to the + * amount the beam would be attenuted by the sample + * @param startPos Starting position + * @param direc Direction of travel for the neutron + * @param weight [InOut] Multiply the incoming weight by the attenuation factor + * @param scatterPt [Out] Generated scattering point + * @return True if the scatter event was generated, false otherwise + */ + bool CalculateMSVesuvio::generateScatter(const Kernel::V3D &startPos, const Kernel::V3D &direc, + double &weight, V3D &scatterPt) const + { + Track particleTrack(startPos, direc); + if(m_sampleShape->interceptSurface(particleTrack) != 1) + { + return false; + } + // Find distance inside object and compute probability of scattering + const auto & link = particleTrack.begin(); + double totalObjectDist = link->distInsideObject; + const double scatterProb = 1.0 - exp(-m_sampleProps->mu*totalObjectDist); + // Select a random point on the track that is the actual scatter point + // from the scattering probability distribution + const double dist = -log(1.0 - m_randgen->flat()*scatterProb)/m_sampleProps->mu; + const double fraction = dist/totalObjectDist; + // Scatter point is then entry point + fraction of width in each direction + scatterPt = link->entryPoint; + V3D edgeDistances = (link->exitPoint - link->entryPoint); + scatterPt += edgeDistances*fraction; + // Update weight + weight *= scatterProb; + return true; + } + + /** + * @param theta Neutron scattering angle (radians) + * @param en0 Computed incident energy + * @return The range of allowed final energies for the neutron + */ + std::pair CalculateMSVesuvio::calculateE1Range(const double theta, const double en0) const + { + const double k0 = sqrt(en0/PhysicalConstants::E_mev_toNeutronWavenumberSq); + const double sth(sin(theta)), cth(cos(theta)); + + double e1min(1e10), e1max(-1e10); // large so that anything else is smaller + const auto & atoms = m_sampleProps->atoms; + for(size_t i = 0; i < atoms.size(); ++i) + { + const double mass = atoms[i].mass; + + const double fraction = (cth + sqrt(mass*mass - sth*sth))/(1.0 + mass); + const double k1 = fraction*k0; + const double en1 = PhysicalConstants::E_mev_toNeutronWavenumberSq*k1*k1; + const double qr = sqrt(k0*k0 + k1*k1 - 2.0*k0*k1*cth); + const double wr = en0 - en1; + const double width = PhysicalConstants::E_mev_toNeutronWavenumberSq*atoms[i].profile*qr/mass; + const double e1a = en0 - wr - 10.0*width; + const double e1b = en0 - wr + 10.0*width; + if(e1a < e1min) e1min = e1a; + if(e1b > e1max) e1max = e1b; + } + if(e1min < 0.0) e1min = 0.0; + return std::make_pair(e1min, e1max); + } + + /** + * Compute the partial differential cross section for this energy and theta. + * @param en0 Initial energy (meV) + * @param en1 Final energy (meV) + * @param theta Scattering angle + * @return Value of differential cross section + */ + double CalculateMSVesuvio::partialDiffXSec(const double en0, const double en1, const double theta) const + { + const double rt2pi = sqrt(2.0*M_PI); + + const double k0 = sqrt(en0/PhysicalConstants::E_mev_toNeutronWavenumberSq); + const double k1 = sqrt(en1/PhysicalConstants::E_mev_toNeutronWavenumberSq); + const double q = sqrt(k0*k0 + k1*k1 - 2.0*k0*k1*cos(theta)); + const double w = en0 - en1; + + double pdcs(0.0); + const auto & atoms = m_sampleProps->atoms; + if(q > 0.0) // avoid continuous checking in loop + { + for(size_t i = 0; i < atoms.size(); ++i) + { + const double jstddev = atoms[i].profile; + const double mass = atoms[i].mass; + const double y = mass*w/(4.18036*q) - 0.5*q; + const double jy = exp(-0.5*y*y/(jstddev*jstddev))/(jstddev*rt2pi); + const double sqw = mass*jy/(4.18036*q); + + const double sclength = atoms[i].sclength; + pdcs += sclength*sclength*(k1/k0)*sqw; + } + } + else + { + for(size_t i = 0; i < atoms.size(); ++i) + { + const double sclength = atoms[i].sclength; + pdcs += sclength*sclength; + } + } + + return pdcs; + } + + /** + * Generate a random position within the final detector in the lab frame + * @param nominalPos The poisiton of the centre point of the detector + * @param energy The final energy of the neutron + * @param scatterPt The position of the scatter event that lead to this detector + * @param direcBeforeSc Directional vector that lead to scatter point that hit this detector + * @param scang [Output] The value of the scattering angle for the generated point + * @param distToExit [Output] The distance covered within the object from scatter to exit + * @return A new position in the detector + */ + V3D CalculateMSVesuvio::generateDetectorPos(const V3D &nominalPos, const double energy, + const V3D &scatterPt, const V3D &direcBeforeSc, + double &scang, double &distToExit) const + { + const double mu = 7430.0/sqrt(energy); // Inverse attenuation length (m-1) for vesuvio det. + const double ps = 1.0 - exp(-mu*m_detThick); // Probability of detection in path thickness. + V3D detPos; + scang = 0.0; distToExit = 0.0; + size_t ntries(0); + do + { + // Beam direction by moving to front of "box"define by detector dimensions and then + // computing expected distance travelled based on probability + detPos[m_beamIdx] = (nominalPos[m_beamIdx] - 0.5*m_detThick) - \ + (log(1.0 - m_randgen->flat()*ps)/mu); + // perturb away from nominal position + detPos[m_acrossIdx] = nominalPos[m_acrossIdx] + (m_randgen->flat() - 0.5)*m_detWidth; + detPos[m_upIdx] = nominalPos[m_upIdx] + (m_randgen->flat() - 0.5)*m_detHeight; + + // Distance to exit the sample for this order + V3D scToDet = detPos - scatterPt; + scToDet.normalize(); + Geometry::Track scatterToDet(scatterPt, scToDet); + if(m_sampleShape->interceptSurface(scatterToDet) > 0) + { + scang = direcBeforeSc.angle(scToDet); + const auto & link = scatterToDet.begin(); + distToExit = link->distInsideObject; + break; + } + // if point is very close surface then there may be no valid intercept so try again + ++ntries; + } + while(ntries < MAX_SCATTER_PT_TRIES); + if(ntries == MAX_SCATTER_PT_TRIES) + { + throw std::runtime_error("Unable to create track from sample to detector. " + "Detector shape may be too small."); + } + return detPos; + } + + /** + * Generate the final energy of the analyser + * @param angle Detector angle from sample + * @param e1nom The nominal final energy of the analyzer + * @param e1res The resoltion in energy of the analyser + * @return A value for the final energy of the neutron + */ + double CalculateMSVesuvio::generateE1(const double angle, const double e1nom, + const double e1res) const + { + if(e1res == 0.0) return e1nom; + + const double randv = m_randgen->flat(); + if(e1nom < 5000.0) + { + if(angle > 90.0) return MSVesuvioHelper::finalEnergyAuDD(randv); + else return MSVesuvioHelper::finalEnergyAuYap(randv); + } + else + { + return MSVesuvioHelper::finalEnergyUranium(randv); + } + } + + } // namespace Algorithms +} // namespace Mantid diff --git a/Code/Mantid/Framework/CurveFitting/src/ConvertToYSpace.cpp b/Code/Mantid/Framework/CurveFitting/src/ConvertToYSpace.cpp index 0c615888a88a..9d36aa11d099 100644 --- a/Code/Mantid/Framework/CurveFitting/src/ConvertToYSpace.cpp +++ b/Code/Mantid/Framework/CurveFitting/src/ConvertToYSpace.cpp @@ -34,10 +34,10 @@ namespace Mantid //---------------------------------------------------------------------------------------------- /// Algorithm's name for identification. @see Algorithm::name - const std::string ConvertToYSpace::name() const { return "ConvertToYSpace";}; + const std::string ConvertToYSpace::name() const { return "ConvertToYSpace";} /// Algorithm's version for identification. @see Algorithm::version - int ConvertToYSpace::version() const { return 1;}; + int ConvertToYSpace::version() const { return 1;} /// Algorithm's category for identification. @see Algorithm::category const std::string ConvertToYSpace::category() const { return "Transforms\\Units";} @@ -75,6 +75,7 @@ namespace Mantid const auto & pmap = ws->constInstrumentParameters(); detpar.l1 = sample->getDistance(*source); detpar.l2 = det->getDistance(*sample); + detpar.pos = det->getPos(); detpar.theta = ws->detectorTwoTheta(det); detpar.t0 = ConvertToYSpace::getComponentParameter(det, pmap, "t0")*1e-6; // Convert to seconds detpar.efixed = ConvertToYSpace::getComponentParameter(det, pmap, "efixed"); @@ -215,18 +216,7 @@ namespace Mantid { try { - - auto det = m_inputWS->getDetector(index); - const auto & pmap = m_inputWS->constInstrumentParameters(); - auto detPos = det->getPos(); - - // -- Setup detector & resolution parameters -- - DetectorParams detPar; - detPar.l1 = m_l1; - detPar.l2 = m_samplePos.distance(detPos); - detPar.theta = m_inputWS->detectorTwoTheta(det); //radians - detPar.t0 = getComponentParameter(det, pmap, "t0")*1e-06; // seconds - detPar.efixed = getComponentParameter(det, pmap,"efixed"); + DetectorParams detPar = getDetectorParameters(m_inputWS, index); const double v1 = std::sqrt(detPar.efixed/MASS_TO_MEV); const double k1 = std::sqrt(detPar.efixed/PhysicalConstants::E_mev_toNeutronWavenumberSq); diff --git a/Code/Mantid/Framework/CurveFitting/src/EndErfc.cpp b/Code/Mantid/Framework/CurveFitting/src/EndErfc.cpp index 88cf79ec5e94..4fb78bff2bf2 100644 --- a/Code/Mantid/Framework/CurveFitting/src/EndErfc.cpp +++ b/Code/Mantid/Framework/CurveFitting/src/EndErfc.cpp @@ -19,10 +19,10 @@ namespace Mantid void EndErfc::init() { - declareParameter("A", 2000.0); - declareParameter("B", 50.0); - declareParameter("C", 6.0); - declareParameter("D", 0.0); + declareParameter("A", 2000.0,"Half value at minus infinity minus half value at plus infinity"); + declareParameter("B", 50.0,"Mid x value"); + declareParameter("C", 6.0,"Width parameter"); + declareParameter("D", 0.0,"Minimum value - must not be negative"); } diff --git a/Code/Mantid/Framework/CurveFitting/src/FABADAMinimizer.cpp b/Code/Mantid/Framework/CurveFitting/src/FABADAMinimizer.cpp new file mode 100644 index 000000000000..45f3477eb1fb --- /dev/null +++ b/Code/Mantid/Framework/CurveFitting/src/FABADAMinimizer.cpp @@ -0,0 +1,559 @@ +#include "MantidCurveFitting/FABADAMinimizer.h" +#include "MantidCurveFitting/CostFuncLeastSquares.h" +#include "MantidCurveFitting/BoundaryConstraint.h" + +#include +#include +#include + +#include "MantidAPI/CostFunctionFactory.h" +#include "MantidAPI/FuncMinimizerFactory.h" +#include "MantidAPI/IFunction.h" +#include "MantidAPI/WorkspaceFactory.h" +#include "MantidAPI/MatrixWorkspace.h" +#include "MantidAPI/WorkspaceProperty.h" +#include "MantidAPI/AnalysisDataService.h" +#include "MantidAPI/ITableWorkspace.h" +#include "MantidAPI/TableRow.h" +#include "MantidKernel/MersenneTwister.h" +#include "MantidKernel/PseudoRandomNumberGenerator.h" + +#include "MantidKernel/Logger.h" + +#include +#include +#include +#include +#include + +#include +#include + + +namespace Mantid +{ +namespace CurveFitting +{ + +namespace +{ + // static logger object + 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; +} + + +DECLARE_FUNCMINIMIZER(FABADAMinimizer, FABADA) + + + //---------------------------------------------------------------------------------------------- +/// Constructor +FABADAMinimizer::FABADAMinimizer():API::IFuncMinimizer(),m_conv_point(0) + { + declareProperty("ChainLength",static_cast(10000),"Length of the converged chain."); + 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",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("ChiSquareTable","chi2",Kernel::Direction::Output), + "The name to give the output workspace"); + declareProperty( + new API::WorkspaceProperty("PdfError","pdfE",Kernel::Direction::Output), + "The name to give the output workspace"); + + + } + + //---------------------------------------------------------------------------------------------- +/// Destructor +FABADAMinimizer::~FABADAMinimizer() + { + } + +/// Initialize minimizer. Set initial values for all private members. + void FABADAMinimizer::initialize(API::ICostFunction_sptr function, size_t maxIterations) + { + + m_leastSquares = boost::dynamic_pointer_cast(function); + if ( !m_leastSquares ) + { + throw std::invalid_argument("FABADA works only with least squares. Different function was given."); + } + + m_counter = 0; + m_leastSquares->getParameters(m_parameters); + API::IFunction_sptr fun = m_leastSquares->getFittingFunction(); + + if ( fun->nParams() == 0 ) + { + throw std::invalid_argument("Function has 0 fitting parameters."); + } + + size_t n = getProperty("ChainLength"); + m_numberIterations = n / fun->nParams(); + + if ( m_numberIterations > maxIterations ) + { + g_log.warning() << "MaxIterations property reduces the required number of iterations (" << m_numberIterations << ")." << std::endl; + m_numberIterations = maxIterations; + } + + for (size_t i=0 ; inParams(); ++i) + { + double p = m_parameters.get(i); + m_bound.push_back(false); + API::IConstraint *iconstr = fun->getConstraint(i); + if ( iconstr ) + { + BoundaryConstraint *bcon = dynamic_cast(iconstr); + if ( bcon ) + { + m_bound[i] = true; + if ( bcon -> hasLower()) { + m_lower.push_back(bcon->lower()); + } + else { + m_lower.push_back(-10e100); + } + if ( bcon -> hasUpper()){ + m_upper.push_back(bcon -> upper()); + } + else { + m_upper.push_back(10e100); + } + if (pm_upper[i]) { + p = m_upper[i]; + m_parameters.set(i,p); + } + + } + + } + std::vector v; + v.push_back(p); + m_chain.push_back(v); + m_changes.push_back(0); + m_par_converged.push_back(false); + m_criteria.push_back(getProperty("ConvergenceCriteria")); + if (p != 0.0) { + m_jump.push_back(std::abs(p/10)); + } + else { + m_jump.push_back(0.01); + } + } + m_chi2 = m_leastSquares -> val(); + std::vector v; + v.push_back(m_chi2); + m_chain.push_back(v); + m_converged = false; + } + + + +/// Do one iteration. Returns true if iterations to be continued, false if they must stop. + bool FABADAMinimizer::iterate(size_t) + { + + if ( !m_leastSquares ) + { + throw std::runtime_error("Cost function isn't set up."); + } + + size_t n = m_leastSquares->nParams(); + size_t m = n; + + // Just for the last iteration. For doing exactly the indicated number of iterations. + if(m_converged && m_counter == (m_numberIterations)){ + size_t t = getProperty("ChainLength"); + m = t % n; + } + + // Do one iteration of FABADA's algorithm for each parameter. + for(size_t i = 0; i distr(0.0,std::abs(m_jump[i])); + boost::variate_generator> 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< m_upper[i]) { + new_value = m_upper[i] - (new_value-m_upper[i])/2; + } + } + + // Set the new value in order to calculate the new Chi square value + if ( boost::math::isnan(new_value) ) + { + throw std::runtime_error("Parameter value is NaN."); + } + new_parameters.set(i,new_value); + 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 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 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; + + // Update the jump once each jumpCheckingRate iterations + if (m_counter % jumpCheckingRate == 150) + { + double jnew; + // All this is just a temporal test... + std::vector::const_iterator first = m_chain[n].end()-41; + std::vector::const_iterator last = m_chain[n].end(); + std::vector test(first, last); + int c = 0; + for(int j=0;j<39;++j) { + if (test[j] == test[j+1]) { + c += 1; + } + } + 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])getFittingFunction(); + throw std::runtime_error("Wrong convergence for parameter " + fun -> parameterName(i) +". Try to set a proper initial value this parameter" ); + } + } + + // 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 + { + if (chi2_new != m_chi2) { + double chi2_quotient = std::abs(chi2_new-m_chi2)/m_chi2; + if (chi2_quotient < m_criteria[i]){ + m_par_converged[i] = true; + } + } + } + } + + m_counter += 1; // Update the counter, after finishing the iteration for each parameter + + // 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; igetFittingFunction(); + std::string failed = ""; + for(size_t i=0; i parameterName(i) + ", "; + } + } + failed.replace(failed.end()-2,failed.end(),"."); + throw std::runtime_error("Convegence NOT reached after " + boost::lexical_cast(m_counter) + + " iterations.\n Try to set better initial values for parameters: " + failed); + } + } + else + { + // If convergence has been reached, continue untill complete the chain length. + 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::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( std::distance( m_chain[n].begin(), pos_min) ); + + std::vector par_def(n); + API::IFunction_sptr fun = m_leastSquares->getFittingFunction(); + + // 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::const_iterator first = m_chain[j].begin()+m_conv_point; + std::vector::const_iterator last = m_chain[j].end(); + std::vector conv_chain(first, last); + size_t conv_length = conv_chain.size(); + std::sort(conv_chain.begin(),conv_chain.end()); + std::vector::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::const_iterator pos_left = conv_chain.begin(); + if ( sigma < static_cast(std::distance(pos_left,pos_par)) ) + { + pos_left = pos_par - sigma; + } + // make sure the iterator is valid in any case + std::vector::const_iterator pos_right = conv_chain.end() - 1; + if ( sigma < static_cast(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 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(i)*bin; + X[i] = bin_end; + while(step::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 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]; + } + } + + // 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::const_iterator first = m_chain[j].begin()+m_conv_point; + std::vector::const_iterator last = m_chain[j].end(); + std::vector 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]; + } + } + + // Set and name the workspace for the converged part of the chain. + setProperty("OutputWorkspaceConverged",wsConv); + } + + // 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 setParameter(j,par_def[j]); + } + + // 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 = *pos_min/(double(data_number-n)); // For de minimum value. + double Chi2MP_red = Chi2MP/(double(data_number-n)); // For the most probable. + + // 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); + + + return false; + } + } + + return true; + } + double FABADAMinimizer::costFunctionVal() { + return m_chi2; + } + + +} // namespace CurveFitting +} // namespace Mantid diff --git a/Code/Mantid/Framework/CurveFitting/src/FakeMinimizer.cpp b/Code/Mantid/Framework/CurveFitting/src/FakeMinimizer.cpp deleted file mode 100644 index 5bc526756330..000000000000 --- a/Code/Mantid/Framework/CurveFitting/src/FakeMinimizer.cpp +++ /dev/null @@ -1,96 +0,0 @@ -//---------------------------------------------------------------------- -// Includes -//---------------------------------------------------------------------- -#include "MantidCurveFitting/FakeMinimizer.h" -#include "MantidCurveFitting/CostFuncFitting.h" - -#include "MantidAPI/FuncMinimizerFactory.h" -#include "MantidAPI/WorkspaceProperty.h" -#include "MantidAPI/MatrixWorkspace.h" -#include "MantidAPI/WorkspaceFactory.h" -#include "MantidKernel/UnitFactory.h" -#include "MantidKernel/Unit.h" - -#include "MantidKernel/Logger.h" - -namespace Mantid -{ -namespace CurveFitting -{ - namespace - { - /// static logger - Kernel::Logger g_log("FakeMinimizer"); - } - -DECLARE_FUNCMINIMIZER(FakeMinimizer,Fake) - - -FakeMinimizer::FakeMinimizer() -{ - declareProperty(new API::WorkspaceProperty("SomeOutput","abc",Kernel::Direction::Output), - "Name of the output Workspace holding some output."); - declareProperty("SomeInt",0,"Some integer value"); - declareProperty("SomeDouble",0.0,"Some double value"); - declareProperty("SomeString","Some units","Some string value"); -} - -FakeMinimizer::~FakeMinimizer() -{ -} - -void FakeMinimizer::initialize(API::ICostFunction_sptr, size_t maxIters) -{ - m_maxIters = maxIters; - m_data.resize(m_maxIters); - m_someInt = getProperty("SomeInt"); - m_someDouble = getProperty("SomeDouble"); - m_someString = getPropertyValue("SomeString"); -} - -/** - * Do one iteration. - * @param iter :: Current iteration number. - * @return :: true if iterations to be continued, false if they can stop - */ -bool FakeMinimizer::iterate(size_t iter) -{ - m_data[iter] = static_cast(iter) / static_cast(m_maxIters - 1); - - if ( iter >= m_maxIters - 1 ) - { - API::MatrixWorkspace_sptr ws = API::WorkspaceFactory::Instance().create("Workspace2D",1,m_maxIters,m_maxIters); - auto & X = ws->dataX(0); - for(size_t i = 0; i < X.size(); ++i) - { - X[i] = static_cast(i + 1); - } - auto & Y = ws->dataY(0); - Y.assign( m_data.begin(), m_data.end() ); - - auto &E = ws->dataE(0); - if ( m_maxIters > 0 ) - E[0] = static_cast( m_someInt ); - if ( m_maxIters > 1 ) - E[1] = m_someDouble; - - auto ilabel = Kernel::UnitFactory::Instance().create("Label"); - auto label = boost::dynamic_pointer_cast(ilabel); - label->setLabel( m_someString ); - auto axis = ws->getAxis(0); - axis->unit() = ilabel; - - setProperty("SomeOutput",ws); - return false; - } - - return true; -} - -double FakeMinimizer::costFunctionVal() -{ - return 0.0; -} - -} // namespace CurveFitting -} // namespace Mantid diff --git a/Code/Mantid/Framework/CurveFitting/src/Fit.cpp b/Code/Mantid/Framework/CurveFitting/src/Fit.cpp index 63d424221d45..19634cb1f99c 100644 --- a/Code/Mantid/Framework/CurveFitting/src/Fit.cpp +++ b/Code/Mantid/Framework/CurveFitting/src/Fit.cpp @@ -118,7 +118,7 @@ namespace CurveFitting auto &properties = minimizer.getProperties(); for(auto prop = properties.begin(); prop != properties.end(); ++prop) { - if ( (**prop).direction() == Kernel::Direction::Output ) + if ( (**prop).direction() == Kernel::Direction::Output && (**prop).isValid() == "" ) { Kernel::Property* property = (**prop).clone(); declareProperty( property ); @@ -335,7 +335,7 @@ namespace CurveFitting declareProperty("Minimizer","Levenberg-Marquardt", Kernel::IValidator_sptr(new Kernel::StartsWithValidator(minimizerOptions)), - "Minimizer to use for fitting. Minimizers available are \"Levenberg-Marquardt\", \"Simplex\", \"Conjugate gradient (Fletcher-Reeves imp.)\", \"Conjugate gradient (Polak-Ribiere imp.)\", \"BFGS\", and \"Levenberg-MarquardtMD\""); + "Minimizer to use for fitting. Minimizers available are \"Levenberg-Marquardt\", \"Simplex\", \"FABADA\", \"Conjugate gradient (Fletcher-Reeves imp.)\", \"Conjugate gradient (Polak-Ribiere imp.)\", \"BFGS\", and \"Levenberg-MarquardtMD\""); std::vector costFuncOptions = API::CostFunctionFactory::Instance().getKeys(); // select only CostFuncFitting variety diff --git a/Code/Mantid/Framework/CurveFitting/src/MSVesuvioHelpers.cpp b/Code/Mantid/Framework/CurveFitting/src/MSVesuvioHelpers.cpp new file mode 100644 index 000000000000..7b6aef7d6365 --- /dev/null +++ b/Code/Mantid/Framework/CurveFitting/src/MSVesuvioHelpers.cpp @@ -0,0 +1,419 @@ +//----------------------------------------------------------------------------- +// Includes +//----------------------------------------------------------------------------- +#include "MantidCurveFitting/MSVesuvioHelpers.h" + +#include +#include + +#include + +namespace Mantid { namespace CurveFitting +{ + namespace MSVesuvioHelper + { + + /** + * Generate the final energy of a neutron for gold foil analyser at 293K + * in double-difference mode: + * - THIN FOIL NUMBER DENSITY = 1.456E20 ATOMS/SQ CM. + * - THICK FOIL NUMBER DENSITY = 3.0* 1.456E20 ATOMS/SQ CM. + * @param randv A random number between 0.0 & 1.0, sample from a flat distribution + * @return A value to use for the final energy + */ + double finalEnergyAuDD(const double randv) + { + // Tabulated values of absoprtion energies from S.F. Mughabghab, Neutron Cross Sections, Academic + // Press, Orlando, Florida, 1984. + static const double ENERGIES[300] = {\ + 2000.0, 2020.7, 2041.5, 2062.2, 2082.9, 2103.7, 2124.4, 2145.2, 2165.9, 2186.6, 2207.4, 2228.1, + 2248.8, 2269.6, 2290.3, 2311.0, 2331.8, 2352.5, 2373.2, 2394.0, 2414.7, 2435.5, 2456.2, 2476.9, + 2497.7, 2518.4, 2539.1, 2559.9, 2580.6, 2601.3, 2622.1, 2642.8, 2663.5, 2684.3, 2705.0, 2725.8, + 2746.5, 2767.2, 2788.0, 2808.7, 2829.4, 2850.2, 2870.9, 2891.6, 2912.4, 2933.1, 2953.8, 2974.6, + 2995.3, 3016.1, 3036.8, 3057.5, 3078.3, 3099.0, 3119.7, 3140.5, 3161.2, 3181.9, 3202.7, 3223.4, + 3244.1, 3264.9, 3285.6, 3306.4, 3327.1, 3347.8, 3368.6, 3389.3, 3410.0, 3430.8, 3451.5, 3472.2, + 3493.0, 3513.7, 3534.4, 3555.2, 3575.9, 3596.7, 3617.4, 3638.1, 3658.9, 3679.6, 3700.3, 3721.1, + 3741.8, 3762.5, 3783.3, 3804.0, 3824.7, 3845.5, 3866.2, 3887.0, 3907.7, 3928.4, 3949.2, 3969.9, + 3990.6, 4011.4, 4032.1, 4052.8, 4073.6, 4094.3, 4115.1, 4135.8, 4156.5, 4177.3, 4198.0, 4218.7, + 4239.5, 4260.2, 4280.9, 4301.7, 4322.4, 4343.1, 4363.9, 4384.6, 4405.4, 4426.1, 4446.8, 4467.6, + 4488.3, 4509.0, 4529.8, 4550.5, 4571.2, 4592.0, 4612.7, 4633.4, 4654.2, 4674.9, 4695.7, 4716.4, + 4737.1, 4757.9, 4778.6, 4799.3, 4820.1, 4840.8, 4861.5, 4882.3, 4903.0, 4923.7, 4944.5, 4965.2, + 4986.0, 5006.7, 5027.4, 5048.2, 5068.9, 5089.6, 5110.4, 5131.1, 5151.8, 5172.6, 5193.3, 5214.0, + 5234.8, 5255.5, 5276.3, 5297.0, 5317.7, 5338.5, 5359.2, 5379.9, 5400.7, 5421.4, 5442.1, 5462.9, + 5483.6, 5504.3, 5525.1, 5545.8, 5566.6, 5587.3, 5608.0, 5628.8, 5649.5, 5670.2, 5691.0, 5711.7, + 5732.4, 5753.2, 5773.9, 5794.6, 5815.4, 5836.1, 5856.9, 5877.6, 5898.3, 5919.1, 5939.8, 5960.5, + 5981.3, 6002.0, 6022.7, 6043.5, 6064.2, 6085.0, 6105.7, 6126.4, 6147.2, 6167.9, 6188.6, 6209.4, + 6230.1, 6250.8, 6271.6, 6292.3, 6313.0, 6333.8, 6354.5, 6375.3, 6396.0, 6416.7, 6437.5, 6458.2, + 6478.9, 6499.7, 6520.4, 6541.1, 6561.9, 6582.6, 6603.3, 6624.1, 6644.8, 6665.6, 6686.3, 6707.0, + 6727.8, 6748.5, 6769.2, 6790.0, 6810.7, 6831.4, 6852.2, 6872.9, 6893.6, 6914.4, 6935.1, 6955.9, + 6976.6, 6997.3, 7018.1, 7038.8, 7059.5, 7080.3, 7101.0, 7121.7, 7142.5, 7163.2, 7183.9, 7204.7, + 7225.4, 7246.2, 7266.9, 7287.6, 7308.4, 7329.1, 7349.8, 7370.6, 7391.3, 7412.0, 7432.8, 7453.5, + 7474.2, 7495.0, 7515.7, 7536.5, 7557.2, 7577.9, 7598.7, 7619.4, 7640.1, 7660.9, 7681.6, 7702.3, + 7723.1, 7743.8, 7764.5, 7785.3, 7806.0, 7826.8, 7847.5, 7868.2, 7889.0, 7909.7, 7930.4, 7951.2, + 7971.9, 7992.6, 8013.4, 8034.1, 8054.8, 8075.6, 8096.3, 8117.1, 8137.8, 8158.5, 8179.3, 8200.0 + }; + static const double XVALUES[300] = {\ + 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, + 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, + 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00010, 0.00010, + 0.00010, 0.00010, 0.00010, 0.00010, 0.00010, 0.00010, 0.00010, 0.00010, 0.00010, 0.00010, 0.00010, 0.00010, + 0.00010, 0.00010, 0.00010, 0.00010, 0.00010, 0.00010, 0.00010, 0.00010, 0.00010, 0.00010, 0.00010, 0.00010, + 0.00010, 0.00010, 0.00010, 0.00010, 0.00010, 0.00010, 0.00020, 0.00020, 0.00020, 0.00020, 0.00020, 0.00020, + 0.00020, 0.00020, 0.00020, 0.00020, 0.00020, 0.00020, 0.00030, 0.00030, 0.00030, 0.00030, 0.00030, 0.00030, + 0.00030, 0.00030, 0.00040, 0.00040, 0.00040, 0.00040, 0.00040, 0.00050, 0.00050, 0.00050, 0.00050, 0.00060, + 0.00060, 0.00070, 0.00070, 0.00070, 0.00080, 0.00090, 0.00090, 0.00100, 0.00110, 0.00110, 0.00120, 0.00130, + 0.00150, 0.00160, 0.00170, 0.00190, 0.00210, 0.00230, 0.00260, 0.00290, 0.00320, 0.00360, 0.00410, 0.00470, + 0.00540, 0.00620, 0.00720, 0.00840, 0.00990, 0.01180, 0.01420, 0.01740, 0.02140, 0.02680, 0.03410, 0.04400, + 0.05770, 0.07680, 0.10360, 0.14050, 0.18960, 0.25110, 0.32310, 0.40240, 0.48540, 0.56870, 0.64930, 0.72370, + 0.78850, 0.84150, 0.88240, 0.91260, 0.93440, 0.95000, 0.96130, 0.96960, 0.97570, 0.98030, 0.98380, 0.98650, + 0.98870, 0.99040, 0.99180, 0.99290, 0.99380, 0.99460, 0.99520, 0.99580, 0.99620, 0.99660, 0.99700, 0.99730, + 0.99750, 0.99770, 0.99790, 0.99810, 0.99830, 0.99840, 0.99850, 0.99860, 0.99870, 0.99880, 0.99890, 0.99900, + 0.99900, 0.99910, 0.99910, 0.99920, 0.99920, 0.99930, 0.99930, 0.99940, 0.99940, 0.99940, 0.99940, 0.99950, + 0.99950, 0.99950, 0.99950, 0.99960, 0.99960, 0.99960, 0.99960, 0.99960, 0.99960, 0.99970, 0.99970, 0.99970, + 0.99970, 0.99970, 0.99970, 0.99970, 0.99970, 0.99970, 0.99980, 0.99980, 0.99980, 0.99980, 0.99980, 0.99980, + 0.99980, 0.99980, 0.99980, 0.99980, 0.99980, 0.99980, 0.99980, 0.99980, 0.99980, 0.99980, 0.99990, 0.99990, + 0.99990, 0.99990, 0.99990, 0.99990, 0.99990, 0.99990, 0.99990, 0.99990, 0.99990, 0.99990, 0.99990, 0.99990, + 0.99990, 0.99990, 0.99990, 0.99990, 0.99990, 0.99990, 0.99990, 0.99990, 0.99990, 0.99990, 0.99990, 0.99990, + 0.99990, 0.99990, 0.99990, 0.99990, 0.99990, 0.99990, 0.99990, 0.99990, 0.99990, 0.99990, 0.99990, 0.99990, + 0.99990, 0.99990, 0.99990, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, + 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, + 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000 + }; + + const double *xp1 = std::lower_bound(XVALUES, XVALUES+300, randv); + if(xp1 == XVALUES+300) return 0.0; + const double *xm1 = xp1 - 1; + const double *ep1 = ENERGIES + (xp1 - XVALUES); + const double *em1 = ep1 - 1; + const double ef = (*em1) + (randv - *xm1)*(*ep1 - *em1)/(*xp1 - *xm1); + if( ef < 100.0 ) return 0.0; + else return ef; + } + + /** + * Generate the final energy of a neutron for gold foil analyser at 293K + * with number density of 7.35E19 atoms/cm^2 in yap difference mode. + * @param randv A random number between 0.0 & 1.0, sample from a flat distribution + * @return A value to use for the final energy + */ + double finalEnergyAuYap(const double randv) + { + // Tabulated values of absoprtion energies from S.F. Mughabghab, Neutron Cross Sections, Academic + // Press, Orlando, Florida, 1984. + static const double ENERGIES[600] = {\ + 4000.0, 4003.3, 4006.7, 4010.0, 4013.4, 4016.7, 4020.0, 4023.4, 4026.7, 4030.1, 4033.4, 4036.7, + 4040.1, 4043.4, 4046.7, 4050.1, 4053.4, 4056.8, 4060.1, 4063.4, 4066.8, 4070.1, 4073.5, 4076.8, + 4080.1, 4083.5, 4086.8, 4090.2, 4093.5, 4096.8, 4100.2, 4103.5, 4106.8, 4110.2, 4113.5, 4116.9, + 4120.2, 4123.5, 4126.9, 4130.2, 4133.6, 4136.9, 4140.2, 4143.6, 4146.9, 4150.3, 4153.6, 4156.9, + 4160.3, 4163.6, 4166.9, 4170.3, 4173.6, 4177.0, 4180.3, 4183.6, 4187.0, 4190.3, 4193.7, 4197.0, + 4200.3, 4203.7, 4207.0, 4210.4, 4213.7, 4217.0, 4220.4, 4223.7, 4227.0, 4230.4, 4233.7, 4237.1, + 4240.4, 4243.7, 4247.1, 4250.4, 4253.8, 4257.1, 4260.4, 4263.8, 4267.1, 4270.5, 4273.8, 4277.1, + 4280.5, 4283.8, 4287.1, 4290.5, 4293.8, 4297.2, 4300.5, 4303.8, 4307.2, 4310.5, 4313.9, 4317.2, + 4320.5, 4323.9, 4327.2, 4330.6, 4333.9, 4337.2, 4340.6, 4343.9, 4347.2, 4350.6, 4353.9, 4357.3, + 4360.6, 4363.9, 4367.3, 4370.6, 4374.0, 4377.3, 4380.6, 4384.0, 4387.3, 4390.7, 4394.0, 4397.3, + 4400.7, 4404.0, 4407.3, 4410.7, 4414.0, 4417.4, 4420.7, 4424.0, 4427.4, 4430.7, 4434.1, 4437.4, + 4440.7, 4444.1, 4447.4, 4450.8, 4454.1, 4457.4, 4460.8, 4464.1, 4467.4, 4470.8, 4474.1, 4477.5, + 4480.8, 4484.1, 4487.5, 4490.8, 4494.2, 4497.5, 4500.8, 4504.2, 4507.5, 4510.9, 4514.2, 4517.5, + 4520.9, 4524.2, 4527.5, 4530.9, 4534.2, 4537.6, 4540.9, 4544.2, 4547.6, 4550.9, 4554.3, 4557.6, + 4560.9, 4564.3, 4567.6, 4571.0, 4574.3, 4577.6, 4581.0, 4584.3, 4587.6, 4591.0, 4594.3, 4597.7, + 4601.0, 4604.3, 4607.7, 4611.0, 4614.4, 4617.7, 4621.0, 4624.4, 4627.7, 4631.1, 4634.4, 4637.7, + 4641.1, 4644.4, 4647.7, 4651.1, 4654.4, 4657.8, 4661.1, 4664.4, 4667.8, 4671.1, 4674.5, 4677.8, + 4681.1, 4684.5, 4687.8, 4691.2, 4694.5, 4697.8, 4701.2, 4704.5, 4707.8, 4711.2, 4714.5, 4717.9, + 4721.2, 4724.5, 4727.9, 4731.2, 4734.6, 4737.9, 4741.2, 4744.6, 4747.9, 4751.3, 4754.6, 4757.9, + 4761.3, 4764.6, 4767.9, 4771.3, 4774.6, 4778.0, 4781.3, 4784.6, 4788.0, 4791.3, 4794.7, 4798.0, + 4801.3, 4804.7, 4808.0, 4811.4, 4814.7, 4818.0, 4821.4, 4824.7, 4828.0, 4831.4, 4834.7, 4838.1, + 4841.4, 4844.7, 4848.1, 4851.4, 4854.8, 4858.1, 4861.4, 4864.8, 4868.1, 4871.5, 4874.8, 4878.1, + 4881.5, 4884.8, 4888.1, 4891.5, 4894.8, 4898.2, 4901.5, 4904.8, 4908.2, 4911.5, 4914.9, 4918.2, + 4921.5, 4924.9, 4928.2, 4931.6, 4934.9, 4938.2, 4941.6, 4944.9, 4948.2, 4951.6, 4954.9, 4958.3, + 4961.6, 4964.9, 4968.3, 4971.6, 4975.0, 4978.3, 4981.6, 4985.0, 4988.3, 4991.7, 4995.0, 4998.3, + 5001.7, 5005.0, 5008.3, 5011.7, 5015.0, 5018.4, 5021.7, 5025.0, 5028.4, 5031.7, 5035.1, 5038.4, + 5041.7, 5045.1, 5048.4, 5051.8, 5055.1, 5058.4, 5061.8, 5065.1, 5068.4, 5071.8, 5075.1, 5078.5, + 5081.8, 5085.1, 5088.5, 5091.8, 5095.2, 5098.5, 5101.8, 5105.2, 5108.5, 5111.9, 5115.2, 5118.5, + 5121.9, 5125.2, 5128.5, 5131.9, 5135.2, 5138.6, 5141.9, 5145.2, 5148.6, 5151.9, 5155.3, 5158.6, + 5161.9, 5165.3, 5168.6, 5172.0, 5175.3, 5178.6, 5182.0, 5185.3, 5188.6, 5192.0, 5195.3, 5198.7, + 5202.0, 5205.3, 5208.7, 5212.0, 5215.4, 5218.7, 5222.0, 5225.4, 5228.7, 5232.1, 5235.4, 5238.7, + 5242.1, 5245.4, 5248.7, 5252.1, 5255.4, 5258.8, 5262.1, 5265.4, 5268.8, 5272.1, 5275.5, 5278.8, + 5282.1, 5285.5, 5288.8, 5292.2, 5295.5, 5298.8, 5302.2, 5305.5, 5308.8, 5312.2, 5315.5, 5318.9, + 5322.2, 5325.5, 5328.9, 5332.2, 5335.6, 5338.9, 5342.2, 5345.6, 5348.9, 5352.3, 5355.6, 5358.9, + 5362.3, 5365.6, 5368.9, 5372.3, 5375.6, 5379.0, 5382.3, 5385.6, 5389.0, 5392.3, 5395.7, 5399.0, + 5402.3, 5405.7, 5409.0, 5412.4, 5415.7, 5419.0, 5422.4, 5425.7, 5429.0, 5432.4, 5435.7, 5439.1, + 5442.4, 5445.7, 5449.1, 5452.4, 5455.8, 5459.1, 5462.4, 5465.8, 5469.1, 5472.5, 5475.8, 5479.1, + 5482.5, 5485.8, 5489.1, 5492.5, 5495.8, 5499.2, 5502.5, 5505.8, 5509.2, 5512.5, 5515.9, 5519.2, + 5522.5, 5525.9, 5529.2, 5532.6, 5535.9, 5539.2, 5542.6, 5545.9, 5549.2, 5552.6, 5555.9, 5559.3, + 5562.6, 5565.9, 5569.3, 5572.6, 5576.0, 5579.3, 5582.6, 5586.0, 5589.3, 5592.7, 5596.0, 5599.3, + 5602.7, 5606.0, 5609.3, 5612.7, 5616.0, 5619.4, 5622.7, 5626.0, 5629.4, 5632.7, 5636.1, 5639.4, + 5642.7, 5646.1, 5649.4, 5652.8, 5656.1, 5659.4, 5662.8, 5666.1, 5669.4, 5672.8, 5676.1, 5679.5, + 5682.8, 5686.1, 5689.5, 5692.8, 5696.2, 5699.5, 5702.8, 5706.2, 5709.5, 5712.9, 5716.2, 5719.5, + 5722.9, 5726.2, 5729.5, 5732.9, 5736.2, 5739.6, 5742.9, 5746.2, 5749.6, 5752.9, 5756.3, 5759.6, + 5762.9, 5766.3, 5769.6, 5773.0, 5776.3, 5779.6, 5783.0, 5786.3, 5789.6, 5793.0, 5796.3, 5799.7, + 5803.0, 5806.3, 5809.7, 5813.0, 5816.4, 5819.7, 5823.0, 5826.4, 5829.7, 5833.1, 5836.4, 5839.7, + 5843.1, 5846.4, 5849.7, 5853.1, 5856.4, 5859.8, 5863.1, 5866.4, 5869.8, 5873.1, 5876.5, 5879.8, + 5883.1, 5886.5, 5889.8, 5893.2, 5896.5, 5899.8, 5903.2, 5906.5, 5909.8, 5913.2, 5916.5, 5919.9, + 5923.2, 5926.5, 5929.9, 5933.2, 5936.6, 5939.9, 5943.2, 5946.6, 5949.9, 5953.3, 5956.6, 5959.9, + 5963.3, 5966.6, 5970.0, 5973.3, 5976.6, 5980.0, 5983.3, 5986.6, 5990.0, 5993.3, 5996.7, 6000.0 + }; + static const double XVALUES[600] = {\ + 0.00000, 0.00000, 0.00000, 0.00002, 0.00003, 0.00003, 0.00004, 0.00005, 0.00005, 0.00006, 0.00007, 0.00007, + 0.00008, 0.00009, 0.00010, 0.00010, 0.00011, 0.00012, 0.00013, 0.00014, 0.00015, 0.00015, 0.00016, 0.00017, + 0.00018, 0.00019, 0.00020, 0.00021, 0.00022, 0.00023, 0.00024, 0.00025, 0.00026, 0.00027, 0.00028, 0.00029, + 0.00030, 0.00031, 0.00032, 0.00033, 0.00034, 0.00035, 0.00037, 0.00038, 0.00039, 0.00040, 0.00041, 0.00043, + 0.00044, 0.00045, 0.00047, 0.00048, 0.00049, 0.00051, 0.00052, 0.00054, 0.00055, 0.00057, 0.00058, 0.00060, + 0.00061, 0.00063, 0.00065, 0.00066, 0.00068, 0.00070, 0.00072, 0.00074, 0.00075, 0.00077, 0.00079, 0.00081, + 0.00083, 0.00085, 0.00087, 0.00089, 0.00092, 0.00094, 0.00096, 0.00098, 0.00101, 0.00103, 0.00106, 0.00108, + 0.00111, 0.00113, 0.00116, 0.00118, 0.00121, 0.00124, 0.00127, 0.00130, 0.00133, 0.00136, 0.00139, 0.00142, + 0.00146, 0.00149, 0.00152, 0.00156, 0.00159, 0.00163, 0.00167, 0.00171, 0.00174, 0.00178, 0.00182, 0.00187, + 0.00191, 0.00195, 0.00200, 0.00204, 0.00209, 0.00214, 0.00219, 0.00224, 0.00229, 0.00235, 0.00240, 0.00246, + 0.00251, 0.00257, 0.00263, 0.00269, 0.00276, 0.00282, 0.00289, 0.00296, 0.00303, 0.00310, 0.00318, 0.00325, + 0.00333, 0.00341, 0.00349, 0.00358, 0.00367, 0.00376, 0.00385, 0.00394, 0.00404, 0.00414, 0.00425, 0.00435, + 0.00446, 0.00458, 0.00469, 0.00481, 0.00494, 0.00507, 0.00520, 0.00533, 0.00548, 0.00562, 0.00577, 0.00592, + 0.00608, 0.00625, 0.00642, 0.00659, 0.00677, 0.00696, 0.00716, 0.00736, 0.00757, 0.00778, 0.00800, 0.00823, + 0.00847, 0.00872, 0.00898, 0.00924, 0.00952, 0.00980, 0.01010, 0.01041, 0.01073, 0.01106, 0.01141, 0.01177, + 0.01214, 0.01253, 0.01293, 0.01335, 0.01379, 0.01425, 0.01472, 0.01522, 0.01573, 0.01627, 0.01683, 0.01742, + 0.01803, 0.01867, 0.01934, 0.02004, 0.02077, 0.02154, 0.02234, 0.02317, 0.02405, 0.02497, 0.02594, 0.02695, + 0.02801, 0.02913, 0.03030, 0.03153, 0.03282, 0.03419, 0.03561, 0.03712, 0.03871, 0.04037, 0.04213, 0.04398, + 0.04594, 0.04799, 0.05017, 0.05246, 0.05488, 0.05743, 0.06013, 0.06297, 0.06598, 0.06915, 0.07251, 0.07605, + 0.07979, 0.08374, 0.08791, 0.09230, 0.09694, 0.10183, 0.10698, 0.11241, 0.11812, 0.12411, 0.13041, 0.13703, + 0.14395, 0.15119, 0.15877, 0.16667, 0.17490, 0.18347, 0.19237, 0.20159, 0.21114, 0.22100, 0.23117, 0.24164, + 0.25240, 0.26344, 0.27473, 0.28628, 0.29807, 0.31007, 0.32228, 0.33468, 0.34725, 0.35999, 0.37286, 0.38586, + 0.39898, 0.41219, 0.42549, 0.43886, 0.45228, 0.46575, 0.47925, 0.49277, 0.50628, 0.51980, 0.53329, 0.54674, + 0.56016, 0.57350, 0.58677, 0.59996, 0.61304, 0.62600, 0.63883, 0.65152, 0.66403, 0.67638, 0.68853, 0.70048, + 0.71220, 0.72369, 0.73492, 0.74590, 0.75659, 0.76700, 0.77711, 0.78691, 0.79640, 0.80557, 0.81442, 0.82294, + 0.83113, 0.83900, 0.84654, 0.85376, 0.86067, 0.86726, 0.87355, 0.87954, 0.88525, 0.89067, 0.89583, 0.90073, + 0.90537, 0.90979, 0.91398, 0.91794, 0.92170, 0.92527, 0.92865, 0.93185, 0.93489, 0.93776, 0.94049, 0.94307, + 0.94552, 0.94784, 0.95005, 0.95213, 0.95412, 0.95600, 0.95779, 0.95949, 0.96110, 0.96264, 0.96410, 0.96549, + 0.96681, 0.96807, 0.96927, 0.97041, 0.97150, 0.97254, 0.97353, 0.97447, 0.97538, 0.97624, 0.97706, 0.97785, + 0.97860, 0.97933, 0.98002, 0.98068, 0.98131, 0.98192, 0.98250, 0.98306, 0.98359, 0.98411, 0.98460, 0.98507, + 0.98553, 0.98596, 0.98638, 0.98679, 0.98718, 0.98755, 0.98791, 0.98826, 0.98859, 0.98892, 0.98923, 0.98953, + 0.98981, 0.99009, 0.99036, 0.99062, 0.99087, 0.99111, 0.99135, 0.99158, 0.99179, 0.99201, 0.99221, 0.99241, + 0.99260, 0.99279, 0.99296, 0.99314, 0.99331, 0.99347, 0.99363, 0.99378, 0.99393, 0.99408, 0.99422, 0.99435, + 0.99448, 0.99461, 0.99473, 0.99486, 0.99497, 0.99509, 0.99520, 0.99530, 0.99541, 0.99551, 0.99561, 0.99571, + 0.99580, 0.99589, 0.99598, 0.99607, 0.99615, 0.99623, 0.99631, 0.99639, 0.99647, 0.99654, 0.99661, 0.99668, + 0.99675, 0.99682, 0.99688, 0.99694, 0.99701, 0.99707, 0.99713, 0.99718, 0.99724, 0.99729, 0.99735, 0.99740, + 0.99745, 0.99750, 0.99755, 0.99760, 0.99764, 0.99769, 0.99773, 0.99778, 0.99782, 0.99786, 0.99790, 0.99794, + 0.99798, 0.99802, 0.99806, 0.99809, 0.99813, 0.99816, 0.99820, 0.99823, 0.99827, 0.99830, 0.99833, 0.99836, + 0.99839, 0.99842, 0.99845, 0.99848, 0.99850, 0.99853, 0.99856, 0.99859, 0.99861, 0.99864, 0.99866, 0.99869, + 0.99871, 0.99873, 0.99876, 0.99878, 0.99880, 0.99882, 0.99884, 0.99886, 0.99889, 0.99891, 0.99893, 0.99895, + 0.99896, 0.99898, 0.99900, 0.99902, 0.99904, 0.99906, 0.99907, 0.99909, 0.99911, 0.99912, 0.99914, 0.99915, + 0.99917, 0.99919, 0.99920, 0.99922, 0.99923, 0.99924, 0.99926, 0.99927, 0.99929, 0.99930, 0.99931, 0.99933, + 0.99934, 0.99935, 0.99936, 0.99938, 0.99939, 0.99940, 0.99941, 0.99942, 0.99943, 0.99944, 0.99946, 0.99947, + 0.99948, 0.99949, 0.99950, 0.99951, 0.99952, 0.99953, 0.99954, 0.99955, 0.99956, 0.99956, 0.99957, 0.99958, + 0.99959, 0.99960, 0.99961, 0.99962, 0.99963, 0.99963, 0.99964, 0.99965, 0.99966, 0.99967, 0.99967, 0.99968, + 0.99969, 0.99970, 0.99970, 0.99971, 0.99972, 0.99973, 0.99973, 0.99974, 0.99975, 0.99975, 0.99976, 0.99977, + 0.99977, 0.99978, 0.99979, 0.99979, 0.99980, 0.99980, 0.99981, 0.99982, 0.99982, 0.99983, 0.99983, 0.99984, + 0.99984, 0.99985, 0.99985, 0.99986, 0.99986, 0.99987, 0.99988, 0.99988, 0.99989, 0.99989, 0.99990, 0.99990, + 0.99990, 0.99991, 0.99991, 0.99992, 0.99992, 0.99993, 0.99993, 0.99994, 0.99994, 0.99994, 0.99995, 0.99995, + 0.99996, 0.99996, 0.99997, 0.99997, 0.99997, 0.99998, 0.99998, 0.99998, 0.99999, 0.99999, 1.00000, 1.00000 + }; + + const double *xp1 = std::lower_bound(XVALUES, XVALUES+600, randv); + if(xp1 == XVALUES+600) return 0.0; + const double *xm1 = xp1 - 1; + const double *ep1 = ENERGIES + (xp1 - XVALUES); + const double *em1 = ep1 - 1; + return (*em1) + (randv - *xm1)*(*ep1 - *em1)/(*xp1 - *xm1); + } + + /** + * Generate the final energy of a neutron for uranium foil analyser at 293K + * with number density of 1.456E20 atoms/cm^2 in double-difference mode. + * @param randv A random number between 0.0 & 1.0, sample from a flat distribution + * @return A value to use for the final energy + */ + double finalEnergyUranium(const double randv) + { + static const double ENERGIES[201] = {\ + 5959.0, 5967.7, 5976.4, 5985.1, 5993.8, 6002.5, 6011.2, 6019.9, 6028.6, 6037.3, 6046.0, 6054.8, + 6063.5, 6072.2, 6080.9, 6089.6, 6098.3, 6107.0, 6115.7, 6124.4, 6133.1, 6141.8, 6150.5, 6159.2, + 6167.9, 6176.6, 6185.3, 6194.0, 6202.7, 6211.4, 6220.1, 6228.9, 6237.6, 6246.3, 6255.0, 6263.7, + 6272.4, 6281.1, 6289.8, 6298.5, 6307.2, 6315.9, 6324.6, 6333.3, 6342.0, 6350.7, 6359.4, 6368.1, + 6376.8, 6385.5, 6394.3, 6403.0, 6411.7, 6420.4, 6429.1, 6437.8, 6446.5, 6455.2, 6463.9, 6472.6, + 6481.3, 6490.0, 6498.7, 6507.4, 6516.1, 6524.8, 6533.5, 6542.2, 6550.9, 6559.6, 6568.4, 6577.1, + 6585.8, 6594.5, 6603.2, 6611.9, 6620.6, 6629.3, 6638.0, 6646.7, 6655.4, 6664.1, 6672.8, 6681.5, + 6690.2, 6698.9, 6707.6, 6716.3, 6725.0, 6733.7, 6742.5, 6751.2, 6759.9, 6768.6, 6777.3, 6786.0, + 6794.7, 6803.4, 6812.1, 6820.8, 6829.5, 6838.2, 6846.9, 6855.6, 6864.3, 6873.0, 6881.7, 6890.4, + 6899.1, 6907.8, 6916.5, 6925.3, 6934.0, 6942.7, 6951.4, 6960.1, 6968.8, 6977.5, 6986.2, 6994.9, + 7003.6, 7012.3, 7021.0, 7029.7, 7038.4, 7047.1, 7055.8, 7064.5, 7073.2, 7081.9, 7090.6, 7099.4, + 7108.1, 7116.8, 7125.5, 7134.2, 7142.9, 7151.6, 7160.3, 7169.0, 7177.7, 7186.4, 7195.1, 7203.8, + 7212.5, 7221.2, 7229.9, 7238.6, 7247.3, 7256.0, 7264.8, 7273.5, 7282.2, 7290.9, 7299.6, 7308.3, + 7317.0, 7325.7, 7334.4, 7343.1, 7351.8, 7360.5, 7369.2, 7377.9, 7386.6, 7395.3, 7404.0, 7412.7, + 7421.4, 7430.1, 7438.9, 7447.6, 7456.3, 7465.0, 7473.7, 7482.4, 7491.1, 7499.8, 7508.5, 7517.2, + 7525.9, 7534.6, 7543.3, 7552.0, 7560.7, 7569.4, 7578.1, 7586.8, 7595.5, 7604.2, 7613.0, 7621.7, + 7630.4, 7639.1, 7647.8, 7656.5, 7665.2, 7673.9, 7682.6, 7691.3, 7700.0 + }; + static const double XVALUES[201] = {\ + 0.00000, 0.00000, 0.00000, 0.00020, 0.00030, 0.00040, 0.00050, 0.00060, 0.00070, 0.00080, 0.00090, 0.00110, + 0.00120, 0.00140, 0.00150, 0.00170, 0.00190, 0.00210, 0.00230, 0.00250, 0.00270, 0.00290, 0.00310, 0.00340, + 0.00360, 0.00390, 0.00410, 0.00440, 0.00470, 0.00500, 0.00530, 0.00560, 0.00590, 0.00620, 0.00650, 0.00690, + 0.00720, 0.00760, 0.00800, 0.00840, 0.00880, 0.00920, 0.00960, 0.01010, 0.01050, 0.01100, 0.01150, 0.01210, + 0.01270, 0.01330, 0.01390, 0.01460, 0.01530, 0.01610, 0.01690, 0.01780, 0.01870, 0.01970, 0.02090, 0.02210, + 0.02350, 0.02500, 0.02660, 0.02850, 0.03070, 0.03320, 0.03620, 0.03990, 0.04440, 0.05020, 0.05780, 0.06790, + 0.08120, 0.09880, 0.12150, 0.15020, 0.18520, 0.22640, 0.27340, 0.32510, 0.38050, 0.43830, 0.49720, 0.55580, + 0.61290, 0.66710, 0.71740, 0.76250, 0.80190, 0.83510, 0.86220, 0.88380, 0.90050, 0.91340, 0.92340, 0.93100, + 0.93710, 0.94200, 0.94600, 0.94940, 0.95230, 0.95490, 0.95710, 0.95920, 0.96100, 0.96270, 0.96430, 0.96580, + 0.96710, 0.96840, 0.96950, 0.97060, 0.97170, 0.97270, 0.97360, 0.97450, 0.97540, 0.97620, 0.97700, 0.97770, + 0.97840, 0.97910, 0.97980, 0.98040, 0.98100, 0.98160, 0.98220, 0.98280, 0.98330, 0.98390, 0.98440, 0.98490, + 0.98540, 0.98590, 0.98630, 0.98680, 0.98720, 0.98770, 0.98810, 0.98850, 0.98890, 0.98930, 0.98970, 0.99010, + 0.99050, 0.99090, 0.99130, 0.99160, 0.99200, 0.99230, 0.99270, 0.99300, 0.99330, 0.99360, 0.99400, 0.99430, + 0.99460, 0.99480, 0.99510, 0.99540, 0.99560, 0.99590, 0.99610, 0.99640, 0.99660, 0.99680, 0.99710, 0.99730, + 0.99750, 0.99770, 0.99780, 0.99800, 0.99820, 0.99840, 0.99850, 0.99870, 0.99880, 0.99890, 0.99910, 0.99920, + 0.99930, 0.99940, 0.99950, 0.99960, 0.99960, 0.99970, 0.99980, 0.99980, 0.99990, 0.99990, 0.99990, 1.00000, + 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000 + }; + + const double *xp1 = std::lower_bound(XVALUES, XVALUES+201, randv); + if(xp1 == XVALUES+201) return 0.0; + const double *xm1 = xp1 - 1; + const double *ep1 = ENERGIES + (xp1 - XVALUES); + const double *em1 = ep1 - 1; + return (*em1) + (randv - *xm1)*(*ep1 - *em1)/(*xp1 - *xm1); + } + + //------------------------------------------------------------------------- + // RandomNumberGenerator + //------------------------------------------------------------------------- + /** + * Produces random numbers with various probability distributions + */ + RandomNumberGenerator::RandomNumberGenerator(const int seed) : m_generator() + { + m_generator.seed(static_cast(seed)); + } + /// Returns a flat random number between 0.0 & 1.0 + double RandomNumberGenerator::flat() + { + typedef boost::variate_generator uniform_generator; + return uniform_generator(m_generator, + uniform_double(0.0, 1.0))(); + } + /// Returns a random number distributed by a normal distribution + double RandomNumberGenerator::gaussian(const double mean, const double sigma) + { + typedef boost::variate_generator gauss_generator; + return gauss_generator(m_generator, + gaussian_double(mean, sigma))(); + } + + //------------------------------------------------------------------------- + // Simulation + //------------------------------------------------------------------------- + /** + * Stores counts for each scatter order + * for a "run" of a given number of events + */ + Simulation::Simulation(const size_t order, const size_t ntimes) : + counts(order, std::vector(ntimes)), + maxorder(order) + {} + + //------------------------------------------------------------------------- + // SimulationAggreator + //------------------------------------------------------------------------- + /** + * Accumulates and averages the results + * of each simulation + * @param nruns The number of runs that will be computed + */ + SimulationAggregator::SimulationAggregator(const size_t nruns) + { + results.reserve(nruns); + } + + /** + * @param order The number of requested scatterings + * @param ntimes The number of times on input workspace + * @return A reference to a new Simulation object + */ + Simulation & SimulationAggregator::newSimulation(const size_t order, const size_t ntimes) + { + results.push_back(Simulation(order, ntimes)); + return results.back(); + } + + /** + * @return The mean and standard deviation of the current set of simulations + */ + SimulationWithErrors + SimulationAggregator::average() const + { + const size_t maxorder(results[0].maxorder), ntimes(results[0].counts[0].size()), + nruns(results.size()); + SimulationWithErrors retval(maxorder, ntimes); + + for(size_t i = 0; i < maxorder; ++i) + { + auto & orderCounts = retval.sim.counts[i]; + auto & orderErrors = retval.errors[i]; + for(size_t j = 0; j < ntimes; ++j) + { + double mean(0.0); + size_t npoints(0); + for(size_t k = 0; k < nruns; ++k) + { + const double val = results[k].counts[i][j]; + if(val > 0.0) + { + mean += val; + npoints +=1; + } + } + if(npoints < 2) + { + orderCounts[j] = 0.0; + orderErrors[j] = 0.0; + } + else + { + const double dblPts = static_cast(npoints); + orderCounts[j] = mean/dblPts; + // error is std dev + double sumsq(0.0); + for(size_t k = 0; k < nruns; ++k) + { + const double val = results[k].counts[i][j]; + if(val > 0.0) + { + const double diff = (val - mean); + sumsq += diff*diff; + } + } + orderErrors[j] = sqrt(sumsq/(dblPts*(dblPts-1))); + } + } + } + + return retval; + } + //------------------------------------------------------------------------- + // SimulationWithErrors + //------------------------------------------------------------------------- + /** + * Normalise the counts so that the integral over the single-scatter + * events is 1. + */ + void SimulationWithErrors::normalise() + { + const double sumSingle = std::accumulate(sim.counts.front().begin(), + sim.counts.front().end(), 0.0); + if(sumSingle > 0.0) + { + const double invSum = 1.0/sumSingle; // multiply is faster + // Divide everything by the sum + const size_t nscatters = sim.counts.size(); + for(size_t i = 0; i < nscatters; ++i) + { + auto & counts = sim.counts[i]; + auto & scerrors = this->errors[i]; + for(auto cit = counts.begin(), eit = scerrors.begin(); cit != counts.end(); + ++cit, ++eit) + { + (*cit) *= invSum; + (*eit) *= invSum; + } + } + } + } + + } // namespace MSVesuvioHelper +}} diff --git a/Code/Mantid/Framework/CurveFitting/src/TabulatedFunction.cpp b/Code/Mantid/Framework/CurveFitting/src/TabulatedFunction.cpp index c0bbcaaefd39..eeafa2206365 100644 --- a/Code/Mantid/Framework/CurveFitting/src/TabulatedFunction.cpp +++ b/Code/Mantid/Framework/CurveFitting/src/TabulatedFunction.cpp @@ -36,13 +36,14 @@ TabulatedFunction::TabulatedFunction(): m_setupFinished(false) { declareParameter("Scaling",1.0,"A scaling factor"); + declareParameter("Shift", 0.0, "Shift in the abscissa"); declareAttribute("FileName", Attribute("", true)); declareAttribute("Workspace", Attribute("")); declareAttribute("WorkspaceIndex", Attribute(defaultIndexValue)); } /// Evaluate the function for a list of arguments and given scaling factor -void TabulatedFunction::eval(double scaling, double* out, const double* xValues, const size_t nData)const +void TabulatedFunction::eval(double scaling, double xshift, double* out, const double* xValues, const size_t nData)const { if (nData == 0) return; @@ -50,8 +51,15 @@ void TabulatedFunction::eval(double scaling, double* out, const double* xValues, if (size() == 0) return; - const double xStart = m_xData.front(); - const double xEnd = m_xData.back(); + //shift the domain over which the function is defined + std::vector xData(m_xData); + for(std::vector::iterator it = xData.begin(); it != xData.end(); ++it) + { + *it += xshift; + } + + const double xStart = xData.front(); + const double xEnd = xData.back(); if (xStart >= xValues[nData-1] || xEnd <= xValues[0]) return; @@ -71,8 +79,8 @@ void TabulatedFunction::eval(double scaling, double* out, const double* xValues, else { double xi = xValues[i]; - while(j < size()-1 && xi > m_xData[j]) j++; - if (xi == m_xData[j]) + while(j < size()-1 && xi > xData[j]) j++; + if (xi == xData[j]) { out[i] = m_yData[j] * scaling; } @@ -82,8 +90,8 @@ void TabulatedFunction::eval(double scaling, double* out, const double* xValues, } else if (j > 0) { - double x0 = m_xData[j-1]; - double x1 = m_xData[j]; + double x0 = xData[j-1]; + double x1 = xData[j]; double y0 = m_yData[j-1]; double y1 = m_yData[j]; out[i] = y0 + (y1 - y0)*(xi - x0)/(x1 - x0); @@ -105,8 +113,9 @@ void TabulatedFunction::eval(double scaling, double* out, const double* xValues, */ void TabulatedFunction::function1D(double* out, const double* xValues, const size_t nData)const { - const double scaling = getParameter(0); - eval(scaling, out, xValues, nData); + const double scaling = getParameter("Scaling"); + const double xshift = getParameter("Shift"); + eval(scaling, xshift, out, xValues, nData); } /** @@ -117,12 +126,27 @@ void TabulatedFunction::function1D(double* out, const double* xValues, const siz */ void TabulatedFunction::functionDeriv1D(API::Jacobian* out, const double* xValues, const size_t nData) { + const double scaling = getParameter("Scaling"); + const double xshift = getParameter("Shift"); std::vector tmp( nData ); - eval(1.0, tmp.data(), xValues, nData); + // derivative with respect to Scaling parameter + eval(1.0, xshift, tmp.data(), xValues, nData); for(size_t i = 0; i < nData; ++i) { out->set( i, 0, tmp[i] ); } + + // There is no unique definition for the partial derivative with respect + // to the Shift parameter. Here we take the central difference, + const double dx = (xValues[nData-1]-xValues[0])/static_cast(nData); + std::vector tmpplus( nData ); + eval(scaling, xshift+dx, tmpplus.data(), xValues, nData); + std::vector tmpminus( nData ); + eval(scaling, xshift-dx, tmpminus.data(), xValues, nData); + for(size_t i = 0; i < nData; ++i) + { + out->set( i, 1, (tmpplus[i]-tmpminus[i])/(2*dx) ); + } } diff --git a/Code/Mantid/Framework/CurveFitting/src/VesuvioResolution.cpp b/Code/Mantid/Framework/CurveFitting/src/VesuvioResolution.cpp index c0adfc1b6a56..6bcf01387e11 100644 --- a/Code/Mantid/Framework/CurveFitting/src/VesuvioResolution.cpp +++ b/Code/Mantid/Framework/CurveFitting/src/VesuvioResolution.cpp @@ -22,8 +22,44 @@ namespace CurveFitting // Register into factory DECLARE_FUNCTION(VesuvioResolution); + //--------------------------------------------------------------------------- + // Static functions + //--------------------------------------------------------------------------- + /** - */ + * @param ws The workspace with attached instrument + * @param index Index of the spectrum + * @return DetectorParams structure containing the relevant parameters + */ + ResolutionParams VesuvioResolution::getResolutionParameters(const API::MatrixWorkspace_const_sptr & ws, + const size_t index) + { + Geometry::IDetector_const_sptr detector; + try + { + detector = ws->getDetector(index); + } + catch (Kernel::Exception::NotFoundError &) + { + throw std::invalid_argument("VesuvioResolution - Workspace has no detector attached to histogram at index " + \ + boost::lexical_cast(index)); + } + + ResolutionParams respar; + const auto & pmap = ws->constInstrumentParameters(); + respar.dl1 = ConvertToYSpace::getComponentParameter(detector, pmap, "sigma_l1"); + respar.dl2 = ConvertToYSpace::getComponentParameter(detector, pmap, "sigma_l2"); + respar.dtof = ConvertToYSpace::getComponentParameter(detector, pmap, "sigma_tof"); + respar.dthe = ConvertToYSpace::getComponentParameter(detector, pmap, "sigma_theta"); //radians + respar.dEnLorentz = ConvertToYSpace::getComponentParameter(detector, pmap, "hwhm_lorentz"); + respar.dEnGauss = ConvertToYSpace::getComponentParameter(detector, pmap, "sigma_gauss"); + return respar; + } + + //--------------------------------------------------------------------------- + // Member functions + //--------------------------------------------------------------------------- + VesuvioResolution::VesuvioResolution() : API::ParamFunction(), API::IFunction1D(), m_log("VesuvioResolution"), m_wsIndex(0), m_mass(0.0), m_voigt(), @@ -63,34 +99,9 @@ namespace CurveFitting UNUSED_ARG(startX); UNUSED_ARG(endX); - auto inst = workspace->getInstrument(); - auto sample = inst->getSample(); - auto source = inst->getSource(); - if(!sample || !source) - { - throw std::invalid_argument("VesuvioResolution - Workspace has no source/sample."); - } m_wsIndex = wsIndex; - Geometry::IDetector_const_sptr det; - try - { - det = workspace->getDetector(m_wsIndex); - } - catch (Kernel::Exception::NotFoundError &) - { - throw std::invalid_argument("VesuvioResolution - Workspace has no detector attached to histogram at index " + boost::lexical_cast(m_wsIndex)); - } - DetectorParams detpar = ConvertToYSpace::getDetectorParameters(workspace, m_wsIndex); - const auto & pmap = workspace->constInstrumentParameters(); - - ResolutionParams respar; - respar.dl1 = ConvertToYSpace::getComponentParameter(det, pmap, "sigma_l1"); - respar.dl2 = ConvertToYSpace::getComponentParameter(det, pmap, "sigma_l2"); - respar.dthe = ConvertToYSpace::getComponentParameter(det, pmap, "sigma_theta"); //radians - respar.dEnLorentz = ConvertToYSpace::getComponentParameter(det, pmap, "hwhm_lorentz"); - respar.dEnGauss = ConvertToYSpace::getComponentParameter(det, pmap, "sigma_gauss"); - + ResolutionParams respar = getResolutionParameters(workspace, m_wsIndex); this->cacheResolutionComponents(detpar, respar); } @@ -156,7 +167,7 @@ namespace CurveFitting double wl2 = 2.0*STDDEV_TO_HWHM*std::abs((std::pow(k0y0,3)/(k1*qy0*detpar.l1))*common)*respar.dl2; m_resolutionSigma = std::sqrt(std::pow(wgauss,2) + std::pow(wtheta,2) + std::pow(wl1,2) + std::pow(wl2,2)); - + m_log.notice() << "--------------------- Mass=" << m_mass << " -----------------------" << std::endl; m_log.notice() << "w_l1 (FWHM)=" << wl2 << std::endl; m_log.notice() << "w_l0 (FWHM)=" << wl1 << std::endl; @@ -203,7 +214,7 @@ namespace CurveFitting { voigtApprox(voigt, xValues, lorentzPos, lorentzAmp, m_lorentzFWHM, m_resolutionSigma); } - + /** * Transforms the input y coordinates using the Voigt function approximation. The area is normalized to lorentzAmp * @param voigt [Out] Output values (vector is expected to be of the correct size diff --git a/Code/Mantid/Framework/CurveFitting/test/CalculateMSVesuvioTest.h b/Code/Mantid/Framework/CurveFitting/test/CalculateMSVesuvioTest.h new file mode 100644 index 000000000000..1c58cb8e71c6 --- /dev/null +++ b/Code/Mantid/Framework/CurveFitting/test/CalculateMSVesuvioTest.h @@ -0,0 +1,212 @@ +#ifndef MANTID_CURVEFITTING_CALCULATEMSVESUIVIOTEST_H_ +#define MANTID_CURVEFITTING_CALCULATEMSVESUIVIOTEST_H_ + +#include + +#include "MantidCurveFitting/CalculateMSVesuvio.h" +#include "MantidGeometry/Instrument/Goniometer.h" +#include "MantidGeometry/Objects/ShapeFactory.h" + +#include "MantidTestHelpers/ComponentCreationHelper.h" +#include "MantidTestHelpers/WorkspaceCreationHelper.h" + +#include "ComptonProfileTestHelpers.h" + +using Mantid::CurveFitting::CalculateMSVesuvio; + +class CalculateMSVesuvioTest : 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 CalculateMSVesuvioTest *createSuite() { return new CalculateMSVesuvioTest(); } + static void destroySuite( CalculateMSVesuvioTest *suite ) { delete suite; } + + // ------------------------ Success Cases ----------------------------------------- + + void test_init() + { + CalculateMSVesuvio alg; + TS_ASSERT_THROWS_NOTHING(alg.initialize()); + TS_ASSERT(alg.isInitialized()); + } + + void test_exec_with_flat_plate_sample() + { + auto alg = createTestAlgorithm(createFlatPlateSampleWS()); + TS_ASSERT_THROWS_NOTHING(alg->execute()); + TS_ASSERT(alg->isExecuted()); + + checkOutputValuesAsExpected(alg, 0.0099824991, 0.0020558473); + } + + // ------------------------ Failure Cases ----------------------------------------- + + void test_setting_input_workspace_not_in_tof_throws_invalid_argument() + { + CalculateMSVesuvio alg; + alg.initialize(); + + auto testWS = WorkspaceCreationHelper::Create2DWorkspace(1, 1); + TS_ASSERT_THROWS(alg.setProperty("InputWorkspace", testWS), std::invalid_argument); + } + + void test_setting_workspace_with_no_sample_shape_throws_invalid_argument() + { + CalculateMSVesuvio alg; + alg.initialize(); + + auto testWS = WorkspaceCreationHelper::Create2DWorkspace(1, 1); + testWS->getAxis(0)->setUnit("TOF"); + TS_ASSERT_THROWS(alg.setProperty("InputWorkspace", testWS), std::invalid_argument); + } + + void test_setting_nmasses_zero_or_negative_throws_invalid_argument() + { + CalculateMSVesuvio alg; + alg.initialize(); + + TS_ASSERT_THROWS(alg.setProperty("NoOfMasses", -1), std::invalid_argument); + TS_ASSERT_THROWS(alg.setProperty("NoOfMasses", 0), std::invalid_argument); + } + + void test_setting_sampledensity_zero_or_negative_throws_invalid_argument() + { + CalculateMSVesuvio alg; + alg.initialize(); + + TS_ASSERT_THROWS(alg.setProperty("SampleDensity", -1), std::invalid_argument); + TS_ASSERT_THROWS(alg.setProperty("SampleDensity", 0), std::invalid_argument); + } + + void test_setting_atomic_properties_not_length_three_times_nmasses_throws_invalid_argument_on_execute() + { + auto alg = createTestAlgorithm(createFlatPlateSampleWS()); + + alg->setProperty("NoOfMasses", 2); + const double sampleProps[5] = {1.007900, 0.9272392, 5.003738, 16.00000, 3.2587662E-02}; + alg->setProperty("AtomicProperties", std::vector(sampleProps, sampleProps + 5)); + + TS_ASSERT_THROWS(alg->execute(), std::invalid_argument); + } + + void test_setting_zero_or_negative_beam_radius_values_throws_invalid_argument() + { + CalculateMSVesuvio alg; + alg.initialize(); + + TS_ASSERT_THROWS(alg.setProperty("BeamRadius", -1.5), std::invalid_argument); + TS_ASSERT_THROWS(alg.setProperty("BeamRadius", 0.0), std::invalid_argument); + } + + void test_input_workspace_with_detector_that_has_no_shape_throws_exception() + { + auto alg = createTestAlgorithm(createFlatPlateSampleWS(false)); + + TS_ASSERT_THROWS(alg->execute(), std::invalid_argument); + } + +private: + + Mantid::API::IAlgorithm_sptr createTestAlgorithm(const Mantid::API::MatrixWorkspace_sptr & inputWS) + { + Mantid::API::IAlgorithm_sptr alg = boost::shared_ptr(new CalculateMSVesuvio); + alg->initialize(); + alg->setRethrows(true); + alg->setChild(true); + // inputs + alg->setProperty("InputWorkspace", inputWS); + alg->setProperty("NoOfMasses", 3); + alg->setProperty("SampleDensity", 241.0); + const double sampleProps[9] = {1.007900, 0.9272392, 5.003738, 16.00000, 3.2587662E-02, 13.92299, + 27.50000, 4.0172841E-02, 15.07701}; + alg->setProperty("AtomicProperties", std::vector(sampleProps, sampleProps + 9)); + alg->setProperty("BeamRadius", 2.5); + // reduce number of events for test purposes + alg->setProperty("NumEventsPerRun", 10000); + + // outputs + alg->setPropertyValue("TotalScatteringWS", "__unused_for_child"); + alg->setPropertyValue("MultipleScatteringWS", "__unused_for_child"); + + return alg; + } + + Mantid::API::MatrixWorkspace_sptr createFlatPlateSampleWS(const bool detShape = true) + { + auto testWS = createTestWorkspace(detShape); + // Sample shape + const double halfHeight(0.05), halfWidth(0.05), halfThick(0.0025); + std::ostringstream sampleShapeXML; + sampleShapeXML << " " + << " " + << " " + << " " + << " " + << ""; + auto sampleShape = Mantid::Geometry::ShapeFactory().createShape(sampleShapeXML.str()); + testWS->mutableSample().setShape(*sampleShape); + + return testWS; + } + + + Mantid::API::MatrixWorkspace_sptr createTestWorkspace(const bool detShape = true) + { + using namespace Mantid::Geometry; + using namespace Mantid::Kernel; + + const int nhist(1); + const double x0(50.0), x1(562.0), dx(1.0); + const bool singleMassSpec(false), foilChanger(true); + auto ws2d = ComptonProfileTestHelpers::createTestWorkspace(nhist, x0, x1, dx, + singleMassSpec, foilChanger); + + if(detShape) + { + // replace instrument with one that has a detector with a shape + const std::string shapeXML = \ + "" + "" + "" + "" + "" + "" + ""; + const auto pos = ws2d->getDetector(0)->getPos(); + auto instrument = ComptonProfileTestHelpers::createTestInstrumentWithFoilChanger(1, pos, shapeXML); + ws2d->setInstrument(instrument); + ComptonProfileTestHelpers::addResolutionParameters(ws2d, 1); + ComptonProfileTestHelpers::addFoilResolution(ws2d, "foil-pos0"); + } + + return ws2d; + } + + void checkOutputValuesAsExpected(const Mantid::API::IAlgorithm_sptr & alg, + const double expectedTotal, const double expectedMS) + { + using Mantid::API::MatrixWorkspace_sptr; + const size_t checkIdx = 100; + const double tolerance(1e-8); + + // Values for total scattering + MatrixWorkspace_sptr totScatter = alg->getProperty("TotalScatteringWS"); + TS_ASSERT(totScatter); + const auto & totY = totScatter->readY(0); + TS_ASSERT_DELTA(expectedTotal, totY[checkIdx], tolerance); + const auto & totX = totScatter->readX(0); + TS_ASSERT_DELTA(150.0, totX[checkIdx], tolerance); // based on workspace setup + + // Values for multiple scatters + MatrixWorkspace_sptr multScatter = alg->getProperty("MultipleScatteringWS"); + TS_ASSERT(multScatter); + const auto & msY = multScatter->readY(0); + TS_ASSERT_DELTA(expectedMS, msY[checkIdx], tolerance); + const auto & msX = multScatter->readX(0); + TS_ASSERT_DELTA(150.0, msX[checkIdx], tolerance); // based on workspace setup + } +}; + + +#endif /* MANTID_CURVEFITTING_CALCULATEMSVESUIVIOTEST_H_ */ diff --git a/Code/Mantid/Framework/CurveFitting/test/ComptonProfileTestHelpers.h b/Code/Mantid/Framework/CurveFitting/test/ComptonProfileTestHelpers.h index 199fabefdd64..83c29bd6fb0c 100644 --- a/Code/Mantid/Framework/CurveFitting/test/ComptonProfileTestHelpers.h +++ b/Code/Mantid/Framework/CurveFitting/test/ComptonProfileTestHelpers.h @@ -2,6 +2,7 @@ #define COMPTONPROFILETESTHELPERS_H_ #include "MantidGeometry/Instrument/Detector.h" +#include "MantidGeometry/Objects/ShapeFactory.h" #include "MantidKernel/MersenneTwister.h" #include "MantidTestHelpers/ComponentCreationHelper.h" @@ -14,9 +15,12 @@ namespace ComptonProfileTestHelpers static Mantid::API::MatrixWorkspace_sptr createTestWorkspace(const size_t nhist,const double x0, const double x1, const double dx, const bool singleMassSpectrum = false, const bool addFoilChanger = false); - static Mantid::Geometry::Instrument_sptr createTestInstrumentWithFoilChanger(const Mantid::detid_t id,const Mantid::Kernel::V3D &); + static Mantid::Geometry::Instrument_sptr createTestInstrumentWithFoilChanger(const Mantid::detid_t id, + const Mantid::Kernel::V3D &, + const std::string &detShapeXML = ""); static Mantid::Geometry::Instrument_sptr createTestInstrumentWithNoFoilChanger(const Mantid::detid_t id, - const Mantid::Kernel::V3D &); + const Mantid::Kernel::V3D &, + const std::string & detShape = ""); static void addResolutionParameters(const Mantid::API::MatrixWorkspace_sptr & ws, const Mantid::detid_t detID); static void addFoilResolution(const Mantid::API::MatrixWorkspace_sptr & ws, @@ -60,14 +64,14 @@ namespace ComptonProfileTestHelpers { double r(0.553), theta(66.5993), phi(138.6); Mantid::Kernel::V3D detPos; - detPos.spherical(r, theta, phi); + detPos.spherical_rad(r, theta*M_PI/180.0, phi*M_PI/180.0); ws2d->setInstrument(createTestInstrumentWithFoilChanger(id,detPos)); } else { double r(0.55), theta(66.5993), phi(0.0); Mantid::Kernel::V3D detPos; - detPos.spherical(r, theta, phi); + detPos.spherical_rad(r, theta*M_PI/180.0, phi*M_PI/180.0); ws2d->setInstrument(createTestInstrumentWithNoFoilChanger(id,detPos)); } @@ -90,15 +94,19 @@ namespace ComptonProfileTestHelpers return ws2d; } - static Mantid::Geometry::Instrument_sptr createTestInstrumentWithFoilChanger(const Mantid::detid_t id, - const Mantid::Kernel::V3D & detPos) + static Mantid::Geometry::Instrument_sptr + createTestInstrumentWithFoilChanger(const Mantid::detid_t id, + const Mantid::Kernel::V3D & detPos, + const std::string &detShapeXML) { using Mantid::Kernel::V3D; using namespace Mantid::Geometry; - auto inst = createTestInstrumentWithNoFoilChanger(id, detPos); + auto inst = createTestInstrumentWithNoFoilChanger(id, detPos, detShapeXML); // add changer - auto changerShape = ComponentCreationHelper::createCappedCylinder(0.05,0.4,V3D(0.0,-0.2,0.0),V3D(0.0,1,0.0), "cylinder"); + auto changerShape = \ + ComponentCreationHelper::createCappedCylinder(0.05, 0.4, V3D(0.0,-0.2,0.0), + V3D(0.0,1,0.0), "cylinder"); auto *changer = new ObjComponent("foil-changer",changerShape); changer->setPos(V3D(0.0,0.0,0.0)); inst->add(changer); @@ -120,8 +128,10 @@ namespace ComptonProfileTestHelpers return inst; } - static Mantid::Geometry::Instrument_sptr createTestInstrumentWithNoFoilChanger(const Mantid::detid_t id, - const Mantid::Kernel::V3D & detPos) + static Mantid::Geometry::Instrument_sptr + createTestInstrumentWithNoFoilChanger(const Mantid::detid_t id, + const Mantid::Kernel::V3D & detPos, + const std::string &detShapeXML) { using Mantid::Kernel::V3D; using namespace Mantid::Geometry; @@ -140,7 +150,16 @@ namespace ComptonProfileTestHelpers inst->markAsSamplePos(sampleHolder); //Just give it a single detector - auto *det0 = new Detector("det0",id,NULL); + Detector *det0(NULL); + if(!detShapeXML.empty()) + { + auto shape = ShapeFactory().createShape(detShapeXML); + det0 = new Detector("det0", id, shape, NULL); + } + else + { + det0 = new Detector("det0", id, NULL); + } det0->setPos(detPos); inst->add(det0); inst->markAsDetector(det0); @@ -163,6 +182,7 @@ namespace ComptonProfileTestHelpers pmap.addDouble(compID, "t0", -0.32); pmap.addDouble(compID, "hwhm_lorentz", 24); pmap.addDouble(compID, "sigma_gauss", 73); + pmap.addDouble(compID, "sigma_tof", 0.3); } static void addFoilResolution(const Mantid::API::MatrixWorkspace_sptr & ws, diff --git a/Code/Mantid/Framework/CurveFitting/test/FABADAMinimizerTest.h b/Code/Mantid/Framework/CurveFitting/test/FABADAMinimizerTest.h new file mode 100644 index 000000000000..a8f1857f0f06 --- /dev/null +++ b/Code/Mantid/Framework/CurveFitting/test/FABADAMinimizerTest.h @@ -0,0 +1,183 @@ +#ifndef MANTID_CURVEFITTING_FABADAMINIMIZERTEST_H_ +#define MANTID_CURVEFITTING_FABADAMINIMIZERTEST_H_ + +#include + +#include "MantidCurveFitting/FABADAMinimizer.h" + +#include "MantidCurveFitting/Fit.h" +#include "MantidAPI/AlgorithmManager.h" + +#include "MantidCurveFitting/ExpDecay.h" +#include "MantidKernel/PropertyManager.h" +#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 +{ +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; } + + + void test_expDecay() + { + const bool histogram(false); + auto ws2 = createTestWorkspace(histogram); + + API::IFunction_sptr fun(new ExpDecay); + 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"); + + 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_EQUALS(fit.getPropertyValue("OutputStatus"), "success"); + + size_t n = fun -> nParams(); + + TS_ASSERT( AnalysisDataService::Instance().doesExist("pdf") ); + MatrixWorkspace_sptr wsPDF = boost::dynamic_pointer_cast( + 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( + 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") ); + MatrixWorkspace_sptr wsConv = boost::dynamic_pointer_cast( + API::AnalysisDataService::Instance().retrieve("conv")); + TS_ASSERT(wsConv); + 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); + + TS_ASSERT( AnalysisDataService::Instance().doesExist("chain") ); + MatrixWorkspace_sptr wsChain = boost::dynamic_pointer_cast( + API::AnalysisDataService::Instance().retrieve("chain")); + TS_ASSERT(wsChain); + TS_ASSERT_EQUALS(wsChain->getNumberHistograms(),n+1); + + const Mantid::MantidVec& Xchain = wsChain->dataX(0); + TS_ASSERT_EQUALS(Xchain.size(), 6881); + 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( + 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")); + + } + + void test_low_MaxIterations() + { + const bool histogram(false); + auto ws2 = createTestWorkspace(histogram); + + API::IFunction_sptr fun(new ExpDecay); + 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 ); + + TS_ASSERT( !fit.isExecuted() ); + + } +private: + + API::MatrixWorkspace_sptr createTestWorkspace(const bool histogram) + { + 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) + { + x[i] = 0.1 * double(i); + 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/IkedaCarpenterPVTest.h b/Code/Mantid/Framework/CurveFitting/test/IkedaCarpenterPVTest.h index 8781aa2642cb..bcda9753e4b2 100644 --- a/Code/Mantid/Framework/CurveFitting/test/IkedaCarpenterPVTest.h +++ b/Code/Mantid/Framework/CurveFitting/test/IkedaCarpenterPVTest.h @@ -108,7 +108,7 @@ class IkedaCarpenterPVTest : public CxxTest::TestSuite * Changing compiler on OS X has yet again caused this (and only this) test to fail. * Switch it off until it is clear why the other Fit tests are okay on OS X using Intel */ -#if !(defined __APPLE__ && defined __INTEL_COMPILER) +#if !(defined __APPLE__) // create mock data to test against std::string wsName = "IkedaCarpenterPV1D_GaussMockData"; @@ -174,7 +174,7 @@ class IkedaCarpenterPVTest : public CxxTest::TestSuite using namespace Mantid::CurveFitting; -#if !(defined __APPLE__ && defined __INTEL_COMPILER) +#if !(defined __APPLE__) // create mock data to test against std::string wsName = "IkedaCarpenterPV1D_GaussMockData_DeltaE"; diff --git a/Code/Mantid/Framework/CurveFitting/test/TabulatedFunctionTest.h b/Code/Mantid/Framework/CurveFitting/test/TabulatedFunctionTest.h index ccc3d05fbd7e..7006f66712b0 100644 --- a/Code/Mantid/Framework/CurveFitting/test/TabulatedFunctionTest.h +++ b/Code/Mantid/Framework/CurveFitting/test/TabulatedFunctionTest.h @@ -160,6 +160,7 @@ class TabulatedFunctionTest : public CxxTest::TestSuite fun.setAttributeValue("Workspace","TABULATEDFUNCTIONTEST_WS"); fun.setAttributeValue("WorkspaceIndex",2); TS_ASSERT_EQUALS( fun.getParameter( "Scaling" ), 1.0 ); + TS_ASSERT_EQUALS( fun.getParameter( "Shift" ), 0.0 ); FunctionDomain1DVector x(-5.0, 5.0, 83); FunctionValues y( x ); fun.function( x, y ); @@ -202,12 +203,14 @@ class TabulatedFunctionTest : public CxxTest::TestSuite fun.setAttributeValue("Workspace","TABULATEDFUNCTIONTEST_WS"); fun.setParameter( "Scaling", 3.3 ); TS_ASSERT_EQUALS( fun.getParameter( "Scaling" ), 3.3 ); + fun.setParameter( "Shift", 0.0 ); + TS_ASSERT_EQUALS( fun.getParameter( "Shift" ), 0.0 ); FunctionDomain1DVector x(-5.0, 5.0, 83); FunctionValues y( x ); fun.function( x, y ); - Mantid::CurveFitting::Jacobian jac(x.size(),1); + Mantid::CurveFitting::Jacobian jac(x.size(),2); fun.functionDeriv(x, jac); for(size_t i = 0; i < x.size(); ++i) @@ -236,26 +239,28 @@ class TabulatedFunctionTest : public CxxTest::TestSuite void test_factory_create_from_file() { - std::string inif = "name=TabulatedFunction,FileName=\"" + m_nexusFileName + "\",WorkspaceIndex=17,Scaling=2"; + std::string inif = "name=TabulatedFunction,FileName=\"" + m_nexusFileName + "\",WorkspaceIndex=17,Scaling=2,Shift=0.02"; auto funf = Mantid::API::FunctionFactory::Instance().createInitialized(inif); TS_ASSERT( funf ); TS_ASSERT_EQUALS( funf->getAttribute("Workspace").asString(), ""); TS_ASSERT_EQUALS( funf->getAttribute("WorkspaceIndex").asInt(), 17); TS_ASSERT_EQUALS( funf->getAttribute("FileName").asUnquotedString(), m_nexusFileName); TS_ASSERT_EQUALS( funf->getParameter("Scaling"), 2.0); + TS_ASSERT_EQUALS( funf->getParameter("Shift"), 0.02); } void test_factory_create_from_workspace() { auto ws = WorkspaceCreationHelper::Create2DWorkspaceFromFunction(Fun(),1,-5.0,5.0,0.1,false); AnalysisDataService::Instance().add( "TABULATEDFUNCTIONTEST_WS", ws ); - std::string inif = "name=TabulatedFunction,Workspace=TABULATEDFUNCTIONTEST_WS,WorkspaceIndex=71,Scaling=3.14"; + std::string inif = "name=TabulatedFunction,Workspace=TABULATEDFUNCTIONTEST_WS,WorkspaceIndex=71,Scaling=3.14,Shift=0.02"; auto funf = Mantid::API::FunctionFactory::Instance().createInitialized(inif); TS_ASSERT( funf ); TS_ASSERT_EQUALS( funf->getAttribute("Workspace").asString(), "TABULATEDFUNCTIONTEST_WS"); TS_ASSERT_EQUALS( funf->getAttribute("WorkspaceIndex").asInt(), 71); TS_ASSERT_EQUALS( funf->getAttribute("FileName").asUnquotedString(), ""); TS_ASSERT_EQUALS( funf->getParameter("Scaling"), 3.14); + TS_ASSERT_EQUALS( funf->getParameter("Shift"), 0.02); AnalysisDataService::Instance().clear(); } diff --git a/Code/Mantid/Framework/DataHandling/CMakeLists.txt b/Code/Mantid/Framework/DataHandling/CMakeLists.txt index 3351dfa21f25..5df27be94a93 100644 --- a/Code/Mantid/Framework/DataHandling/CMakeLists.txt +++ b/Code/Mantid/Framework/DataHandling/CMakeLists.txt @@ -20,11 +20,11 @@ set ( SRC_FILES src/ISISDataArchive.cpp src/ISISRunLogs.cpp src/Load.cpp + src/LoadANSTOHelper.cpp src/LoadAscii.cpp src/LoadAscii2.cpp - src/LoadBBY.cpp + src/LoadBBY.cpp src/LoadCalFile.cpp - src/LoadVulcanCalFile.cpp src/LoadCanSAS1D.cpp src/LoadCanSAS1D2.cpp src/LoadDaveGrp.cpp @@ -35,6 +35,7 @@ set ( SRC_FILES src/LoadEventNexus.cpp src/LoadEventPreNexus.cpp src/LoadEventPreNexus2.cpp + src/LoadFITS.cpp src/LoadFullprofResolution.cpp src/LoadGSASInstrumentFile.cpp src/LoadGSS.cpp @@ -92,6 +93,7 @@ set ( SRC_FILES src/LoadSpec.cpp src/LoadSpice2D.cpp src/LoadTOFRawNexus.cpp + src/LoadVulcanCalFile.cpp src/MaskDetectors.cpp src/MaskDetectorsInShape.cpp src/MergeLogs.cpp @@ -105,7 +107,6 @@ set ( SRC_FILES src/RenameLog.cpp src/RotateInstrumentComponent.cpp src/SNSDataArchive.cpp - src/SNSDataArchiveICAT2.cpp src/SaveANSTOAscii.cpp src/SaveAscii.cpp src/SaveAscii2.cpp @@ -127,9 +128,12 @@ set ( SRC_FILES src/SaveNXSPE.cpp src/SaveNexus.cpp src/SaveNexusProcessed.cpp + src/SaveNXTomo.cpp src/SaveParameterFile.cpp src/SavePAR.cpp + src/SavePDFGui.cpp src/SavePHX.cpp + src/SaveParameterFile.cpp src/SaveRKH.cpp src/SaveReflTBL.cpp src/SaveSPE.cpp @@ -162,11 +166,11 @@ set ( INC_FILES inc/MantidDataHandling/ISISDataArchive.h inc/MantidDataHandling/ISISRunLogs.h inc/MantidDataHandling/Load.h + inc/MantidDataHandling/LoadANSTOHelper.h inc/MantidDataHandling/LoadAscii.h inc/MantidDataHandling/LoadAscii2.h - inc/MantidDataHandling/LoadBBY.h + inc/MantidDataHandling/LoadBBY.h inc/MantidDataHandling/LoadCalFile.h - inc/MantidDataHandling/LoadVulcanCalFile.h inc/MantidDataHandling/LoadCanSAS1D.h inc/MantidDataHandling/LoadCanSAS1D2.h inc/MantidDataHandling/LoadDaveGrp.h @@ -177,6 +181,7 @@ set ( INC_FILES inc/MantidDataHandling/LoadEventNexus.h inc/MantidDataHandling/LoadEventPreNexus.h inc/MantidDataHandling/LoadEventPreNexus2.h + inc/MantidDataHandling/LoadFITS.h inc/MantidDataHandling/LoadFullprofResolution.h inc/MantidDataHandling/LoadGSASInstrumentFile.h inc/MantidDataHandling/LoadGSS.h @@ -229,6 +234,7 @@ set ( INC_FILES inc/MantidDataHandling/LoadSpec.h inc/MantidDataHandling/LoadSpice2D.h inc/MantidDataHandling/LoadTOFRawNexus.h + inc/MantidDataHandling/LoadVulcanCalFile.h inc/MantidDataHandling/MaskDetectors.h inc/MantidDataHandling/MaskDetectorsInShape.h inc/MantidDataHandling/MergeLogs.h @@ -242,7 +248,6 @@ set ( INC_FILES inc/MantidDataHandling/RenameLog.h inc/MantidDataHandling/RotateInstrumentComponent.h inc/MantidDataHandling/SNSDataArchive.h - inc/MantidDataHandling/SNSDataArchiveICAT2.h inc/MantidDataHandling/SaveANSTOAscii.h inc/MantidDataHandling/SaveAscii.h inc/MantidDataHandling/SaveAscii2.h @@ -264,9 +269,12 @@ set ( INC_FILES inc/MantidDataHandling/SaveNXSPE.h inc/MantidDataHandling/SaveNexus.h inc/MantidDataHandling/SaveNexusProcessed.h + inc/MantidDataHandling/SaveNXTomo.h inc/MantidDataHandling/SaveParameterFile.h inc/MantidDataHandling/SavePAR.h + inc/MantidDataHandling/SavePDFGui.h inc/MantidDataHandling/SavePHX.h + inc/MantidDataHandling/SaveParameterFile.h inc/MantidDataHandling/SaveRKH.h inc/MantidDataHandling/SaveReflTBL.h inc/MantidDataHandling/SaveSPE.h @@ -306,7 +314,6 @@ set ( TEST_FILES LoadAsciiTest.h LoadBBYTest.h LoadCalFileTest.h - LoadVulcanCalFileTest.h LoadCanSAS1dTest.h LoadDaveGrpTest.h LoadDetectorInfoTest.h @@ -316,6 +323,7 @@ set ( TEST_FILES LoadEventNexusTest.h LoadEventPreNexus2Test.h LoadEventPreNexusTest.h + LoadFITSTest.h LoadFullprofResolutionTest.h LoadGSASInstrumentFileTest.h LoadGSSTest.h @@ -363,6 +371,7 @@ set ( TEST_FILES LoadSpice2dTest.h LoadTOFRawNexusTest.h LoadTest.h + LoadVulcanCalFileTest.h MaskDetectorsInShapeTest.h MaskDetectorsTest.h MergeLogsTest.h @@ -375,7 +384,6 @@ set ( TEST_FILES RemoveLogsTest.h RenameLogTest.h RotateInstrumentComponentTest.h - SNSDataArchiveICAT2Test.h SNSDataArchiveTest.h SaveANSTOAsciiTest.h SaveAscii2Test.h @@ -397,9 +405,10 @@ set ( TEST_FILES SaveNXSPETest.h SaveNexusProcessedTest.h SaveNexusTest.h - SaveParameterFileTest.h SavePARTest.h + SavePDFGuiTest.h SavePHXTest.h + SaveParameterFileTest.h SaveRKHTest.h SaveReflTBLTest.h SaveSPETest.h @@ -407,7 +416,7 @@ set ( TEST_FILES SetSampleMaterialTest.h SetScalingPSDTest.h UpdateInstrumentFromFileTest.h - XMLlogfileTest.h + XMLInstrumentParameterTest.h ) diff --git a/Code/Mantid/Framework/DataHandling/inc/MantidDataHandling/GroupDetectors2.h b/Code/Mantid/Framework/DataHandling/inc/MantidDataHandling/GroupDetectors2.h index 1ccf563bae57..e590e68f84c7 100644 --- a/Code/Mantid/Framework/DataHandling/inc/MantidDataHandling/GroupDetectors2.h +++ b/Code/Mantid/Framework/DataHandling/inc/MantidDataHandling/GroupDetectors2.h @@ -9,10 +9,8 @@ #include #include "MantidDataObjects/EventWorkspace.h" #include "MantidDataObjects/GroupingWorkspace.h" + #include -#ifdef HAS_UNORDERED_MAP_H -#include -#endif #include @@ -109,8 +107,8 @@ class DLLExport GroupDetectors2 : public API::Algorithm /// Algorithm's name for identification overriding a virtual method virtual const std::string name() const { return "GroupDetectors"; }; - ///Summary of algorithms purpose - virtual const std::string summary() const {return "Sums spectra bin-by-bin, equivalent to grouping the data from a set of detectors. Individual groups can be specified by passing the algorithm a list of spectrum numbers, detector IDs or workspace indices. Many spectra groups can be created in one execution via an input file.";} + ///Summary of algorithms purpose + virtual const std::string summary() const {return "Sums spectra bin-by-bin, equivalent to grouping the data from a set of detectors. Individual groups can be specified by passing the algorithm a list of spectrum numbers, detector IDs or workspace indices. Many spectra groups can be created in one execution via an input file.";} /// Algorithm's version for identification overriding a virtual method virtual int version() const { return 2; }; @@ -133,13 +131,8 @@ class DLLExport GroupDetectors2 : public API::Algorithm }; }; - -#ifndef HAS_UNORDERED_MAP_H -/// used to store the lists of WORKSPACE INDICES that will be grouped, the keys are not used -typedef std::map > storage_map; -#else -typedef std::tr1::unordered_map > storage_map; -#endif + /// used to store the lists of WORKSPACE INDICES that will be grouped, the keys are not used + typedef std::map > storage_map; /// An estimate of the percentage of the algorithm runtimes that has been completed double m_FracCompl; diff --git a/Code/Mantid/Framework/DataHandling/inc/MantidDataHandling/Load.h b/Code/Mantid/Framework/DataHandling/inc/MantidDataHandling/Load.h index 5b5e6087eeb9..3e00a95603c2 100644 --- a/Code/Mantid/Framework/DataHandling/inc/MantidDataHandling/Load.h +++ b/Code/Mantid/Framework/DataHandling/inc/MantidDataHandling/Load.h @@ -43,8 +43,8 @@ namespace Mantid Load(); /// Algorithm's name for identification overriding a virtual method virtual const std::string name() const { return "Load"; } - ///Summary of algorithms purpose - virtual const std::string summary() const {return "Attempts to load a given file by finding an appropriate Load algorithm.";} + ///Summary of algorithms purpose + virtual const std::string summary() const {return "Attempts to load a given file by finding an appropriate Load algorithm.";} /// Algorithm's version for identification overriding a virtual method virtual int version() const { return 1; } diff --git a/Code/Mantid/Framework/DataHandling/inc/MantidDataHandling/LoadANSTOHelper.h b/Code/Mantid/Framework/DataHandling/inc/MantidDataHandling/LoadANSTOHelper.h new file mode 100644 index 000000000000..2858c5a931c4 --- /dev/null +++ b/Code/Mantid/Framework/DataHandling/inc/MantidDataHandling/LoadANSTOHelper.h @@ -0,0 +1,195 @@ +#ifndef DATAHANDING_ANSTO_H_ +#define DATAHANDING_ANSTO_H_ + +//--------------------------------------------------- +// Includes +//--------------------------------------------------- + +#include "MantidAPI/IFileLoader.h" +#include "MantidGeometry/Instrument.h" +#include "MantidDataObjects/EventWorkspace.h" +#include "MantidNexus/NexusClasses.h" + +#define TarTypeFlag_NormalFile '0' +#define TarTypeFlag_HardLink '1' +#define TarTypeFlag_SymbolicLink '2' +#define TarTypeFlag_CharacterSpecial '3' +#define TarTypeFlag_BlockSpecial '4' +#define TarTypeFlag_Directory '5' +#define TarTypeFlag_FIFO '6' +#define TarTypeFlag_ContiguousFile '7' + +namespace Mantid +{ + namespace DataHandling + { + namespace ANSTO + { + /// pointer to the vector of events + typedef std::vector *EventVector_pt; + + /// helper class to keep track of progress + class ProgressTracker { + private: + // fields + const std::string m_msg; + size_t m_count; + int64_t m_step; + int64_t m_next; + // matntid + API::Progress &m_progBar; + + public: + // construction + ProgressTracker(API::Progress &progBar, const char *msg, int64_t target, size_t count); + ~ProgressTracker(); + + // methods + void update(int64_t position); + void complete(); + }; + + class EventCounter { + private: + // fields + std::vector &m_eventCounts; + const std::vector &m_mask; + double m_tofMin; + double m_tofMax; + + public: + // construction + EventCounter(std::vector &eventCounts, const std::vector &mask); + + // properties + double tofMin() const; + double tofMax() const; + + // methods + void addEvent(size_t s, double tof); + }; + + class EventAssigner { + private: + // fields + std::vector &m_eventVectors; + const std::vector &m_mask; + + public: + // construction + EventAssigner(std::vector &eventVectors, const std::vector &mask); + + // methods + void addEvent(size_t s, double tof); + }; + + class FastReadOnlyFile { + private: +#ifdef WIN32 + HANDLE m_handle; +#else + FILE *m_handle; +#endif + public: + // construction + FastReadOnlyFile(const char *filename); + ~FastReadOnlyFile(); + + // properties + void* handle() const; + + // methods + bool read(void *buffer, uint32_t size); + bool seek(int64_t offset, int whence, int64_t *newPosition = NULL); + }; + + namespace Tar + { + struct EntryHeader { + // cppcheck-suppress unusedStructMember + char FileName[100]; + // cppcheck-suppress unusedStructMember + char FileMode[8]; + // cppcheck-suppress unusedStructMember + char OwnerUserID[8]; + // cppcheck-suppress unusedStructMember + char OwnerGroupID[8]; + // cppcheck-suppress unusedStructMember + char FileSize[12]; // in bytes (octal base) + // cppcheck-suppress unusedStructMember + char LastModification[12]; // time in numeric Unix time format (octal) + // cppcheck-suppress unusedStructMember + char Checksum[8]; + // cppcheck-suppress unusedStructMember + char TypeFlag; + // cppcheck-suppress unusedStructMember + char LinkedFileName[100]; + // cppcheck-suppress unusedStructMember + char UStar[8]; + // cppcheck-suppress unusedStructMember + char OwnerUserName[32]; + // cppcheck-suppress unusedStructMember + char OwnerGroupName[32]; + // cppcheck-suppress unusedStructMember + char DeviceMajorNumber[8]; + // cppcheck-suppress unusedStructMember + char DeviceMinorNumber[8]; + // cppcheck-suppress unusedStructMember + char FilenamePrefix[155]; + }; + + template + int64_t octalToInt(char (&str)[N]); + + class File { + + static const auto BUFFER_SIZE = 4096; + + struct FileInfo { + int64_t Offset; + int64_t Size; + }; + + private: + // fields + bool m_good; + FastReadOnlyFile m_file; + std::vector m_fileNames; + std::vector m_fileInfos; + // selected file + size_t m_selected; // index + int64_t m_position; + int64_t m_size; + // buffer + uint8_t m_buffer[BUFFER_SIZE]; + size_t m_bufferPosition; + size_t m_bufferAvailable; + + // not supported + File(const File&); + File& operator =(const File&); + + public: + // construction + File(const std::string &path); + + // properties + bool good() const; + const std::vector& files() const; + // from selected file + const std::string& selected_name() const; + int64_t selected_position() const; + int64_t selected_size() const; + + // methods + bool select(const char *file); + bool skip(uint64_t offset); + size_t read(void *dst, size_t size); + int read_byte(); + }; + + } + } + } +} +#endif //DATAHANDING_ANSTO_H_ \ No newline at end of file diff --git a/Code/Mantid/Framework/DataHandling/inc/MantidDataHandling/LoadBBY.h b/Code/Mantid/Framework/DataHandling/inc/MantidDataHandling/LoadBBY.h index 80ad924d4c83..a5df89e1036b 100644 --- a/Code/Mantid/Framework/DataHandling/inc/MantidDataHandling/LoadBBY.h +++ b/Code/Mantid/Framework/DataHandling/inc/MantidDataHandling/LoadBBY.h @@ -9,6 +9,7 @@ #include "MantidGeometry/Instrument.h" #include "MantidDataObjects/EventWorkspace.h" #include "MantidNexus/NexusClasses.h" +#include "LoadANSTOHelper.h" namespace Mantid { @@ -42,10 +43,6 @@ namespace Mantid Code Documentation is available at: */ - namespace BbyTar { - class File; - } - class DLLExport LoadBBY : public API::IFileLoader { public: // construction @@ -69,14 +66,16 @@ namespace Mantid private: // instrument creation - Geometry::Instrument_sptr createInstrument(BbyTar::File &tarFile); + Geometry::Instrument_sptr createInstrument(ANSTO::Tar::File &tarFile); - // to micro seconds - static double ToMicroSeconds(double fileTime); + // load nx dataset + template + static bool loadNXDataSet(T &value, NeXus::NXEntry &entry, const std::string &path); // binary file access template - void loadEvents(API::Progress &prog, const char *progMsg, BbyTar::File &file, const double tofMinBoundary, const double tofMaxBoundary, Counter &counter); + static void loadEvents(API::Progress &prog, const char *progMsg, ANSTO::Tar::File &file, const double tofMinBoundary, const double tofMaxBoundary, Counter &counter); + static std::vector createMaskVector(const std::string &maskFilename, bool &maskFileLoaded); }; } } diff --git a/Code/Mantid/Framework/DataHandling/inc/MantidDataHandling/LoadEventNexus.h b/Code/Mantid/Framework/DataHandling/inc/MantidDataHandling/LoadEventNexus.h index 1fb267994473..47e29736657b 100644 --- a/Code/Mantid/Framework/DataHandling/inc/MantidDataHandling/LoadEventNexus.h +++ b/Code/Mantid/Framework/DataHandling/inc/MantidDataHandling/LoadEventNexus.h @@ -129,6 +129,9 @@ namespace DataHandling static void loadSampleDataISIScompatibility(::NeXus::File& file, Mantid::API::MatrixWorkspace_sptr WS); + /// method used to return instrument name for some old ISIS files where it is not written properly within the instrument + static std::string readInstrumentFromISIS_VMSCompat(::NeXus::File &hFile); + public: /// The name and path of the input file @@ -142,6 +145,13 @@ namespace DataHandling /// Filter by a maximum time-of-flight double filter_tof_max; + /// Spectra list to load + std::vector m_specList; + /// Minimum spectrum to load + int32_t m_specMin; + /// Maximum spectrum to load + int32_t m_specMax; + /// Filter by start time Kernel::DateAndTime filter_time_start; /// Filter by stop time @@ -158,6 +168,9 @@ namespace DataHandling /// Was the instrument loaded? bool instrument_loaded_correctly; + /// Mutex protecting tof limits + Poco::FastMutex m_tofMutex; + /// Limits found to tof double longest_tof; /// Limits found to tof @@ -245,6 +258,9 @@ namespace DataHandling void filterDuringPause(API::MatrixWorkspace_sptr workspace); + // Validate the optional spectra input properties and initialize m_specList + void createSpectraList(int32_t min, int32_t max); + public: /// name of top level NXentry to use std::string m_top_entry_name; diff --git a/Code/Mantid/Framework/DataHandling/inc/MantidDataHandling/LoadFITS.h b/Code/Mantid/Framework/DataHandling/inc/MantidDataHandling/LoadFITS.h new file mode 100644 index 000000000000..dcfc964b646f --- /dev/null +++ b/Code/Mantid/Framework/DataHandling/inc/MantidDataHandling/LoadFITS.h @@ -0,0 +1,117 @@ +#ifndef MANTID_DATAHANDLING_LOADFITS_H_ +#define MANTID_DATAHANDLING_LOADFITS_H_ + +//--------------------------------------------------- +// Includes +//--------------------------------------------------- +#include "MantidAPI/IFileLoader.h" +#include +#include +#include +#include + +using namespace std; + +struct FITSInfo { + vector headerItems; + map headerKeys; + int bitsPerPixel; + int numberOfAxis; + vector axisPixelLengths; + double tof; + double timeBin; + long int countsInImage; + long int numberOfTriggers; + string extension; + string filePath; +}; + +namespace Mantid +{ +namespace DataHandling +{ + /** + LoadFITS : Load a number of FITS files into a histogram Workspace + + File format is described here: http://www.fileformat.info/format/fits/egff.htm + This loader doesn't support the full specification, caveats are: + Support for unsigned 8, 16, 32 bit values only + Support only for 2 data axis + No support for format extensions + + Loader is designed to work with multiple files, loading into a single workspace. + At points there are assumptions that all files in a batch use the same number of bits per pixel, + and that the number of spectra in each file are the same. + + @author John R Hill, RAL + @date 29/08/2014 + + Copyright © 2014 ISIS Rutherford Appleton Laboratory & NScD Oak Ridge National Laboratory + + This file is part of Mantid. + + Mantid is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + Mantid is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + + File change history is stored at: + Code Documentation is available at: + */ + + class DLLExport LoadFITS : public API::IFileLoader + { + public: + LoadFITS() {} + virtual ~LoadFITS() {} + + /// Algorithm's name for identification overriding a virtual method + virtual const std::string name() const { return "LoadFITS" ;} + + ///Summary of algorithms purpose + virtual const std::string summary() const {return "Load data from FITS files.";} + + /// Algorithm's version for identification overriding a virtual method + virtual int version() const { return 1 ;} + + /// Algorithm's category for identification overriding a virtual method + virtual const std::string category() const { return "DataHandling";} + + /// Returns a confidence value that this algorithm can load a file + virtual int confidence(Kernel::FileDescriptor & descriptor) const; + + /// Returns a value indicating whether or not loader wants to load multiple files into a single workspace + virtual bool loadMutipleAsOne() { return true; } + + private: + /// Initialisation code + void init(); + /// Execution code + void exec(); + /// Parses the header values for the FITS file + bool parseHeader(FITSInfo &headerInfo); + /// Load data from a number of files into the workspace + void loadChunkOfBinsFromFile(Mantid::API::MatrixWorkspace_sptr &workspace, vector > &yVals, vector > &eVals, void *&bufferAny, MantidVecPtr &x, size_t spetraCount, int bitsPerPixel, size_t binChunkStartIndex); + /// Initialises a workspace with IDF and fills it with data + API::MatrixWorkspace_sptr initAndPopulateHistogramWorkspace(); + /// Creates a comma separated string of rotations from a file + std::string ReadRotations(std::string rotFilePath, size_t fileCount); + + vector m_allHeaderInfo; + size_t m_binChunkSize; + static const int FIXED_HEADER_SIZE = 2880; + }; + + +} // namespace DataHandling +} // namespace Mantid + +#endif // MANTID_DATAHANDLING_LOADFITS_H_ diff --git a/Code/Mantid/Framework/DataHandling/inc/MantidDataHandling/LoadFullprofResolution.h b/Code/Mantid/Framework/DataHandling/inc/MantidDataHandling/LoadFullprofResolution.h index 989812493da5..3ea47f5d2c50 100644 --- a/Code/Mantid/Framework/DataHandling/inc/MantidDataHandling/LoadFullprofResolution.h +++ b/Code/Mantid/Framework/DataHandling/inc/MantidDataHandling/LoadFullprofResolution.h @@ -55,6 +55,42 @@ namespace Mantid virtual const std::string summary() const {return "Load Fullprof's resolution (.irf) file to one or multiple TableWorkspace(s) and/or where this is supported." " See description section, translate fullprof resolution fitting parameter into Mantid equivalent fitting parameters.";} + /// Get row numbers of the parameters in the table workspace + static void getTableRowNumbers(const API::ITableWorkspace_sptr & tablews, std::map& parammap); + + /// Put parameters into a matrix workspace + static void putParametersIntoWorkspace( const API::Column_const_sptr, API::MatrixWorkspace_sptr ws, int profNumber, std::string & parameterXMLString); + + /// Add an Ikeda-Carpenter PV ALFBE parameter + static void addALFBEParameter(const API::Column_const_sptr, Poco::XML::Document* mDoc, Poco::XML::Element* parent, const std::string& paramName); + + /// Add set of Ikeda-Carpenter PV Sigma parameters + static void addSigmaParameters(const API::Column_const_sptr, Poco::XML::Document* mDoc, Poco::XML::Element* parent ); + + /// Add set of Ikeda-Carpenter PV Gamma parameters + static void addGammaParameters(const API::Column_const_sptr, Poco::XML::Document* mDoc, Poco::XML::Element* parent ); + + /// Add set of BackToBackExponential S parameters + static void addBBX_S_Parameters(const API::Column_const_sptr, Poco::XML::Document* mDoc, Poco::XML::Element* parent ); + + /// Add set of BackToBackExponential A parameters + static void addBBX_A_Parameters(const API::Column_const_sptr, Poco::XML::Document* mDoc, Poco::XML::Element* parent ); + + /// Add set of BackToBackExponential B parameters + static void addBBX_B_Parameters(const API::Column_const_sptr, Poco::XML::Document* mDoc, Poco::XML::Element* parent ); + + /// Get value for XML eq attribute for parameter + static std::string getXMLEqValue( const API::Column_const_sptr, const std::string& name ); + + /// Get value for XML eq attribute for squared parameter + static std::string getXMLSquaredEqValue( const API::Column_const_sptr column, const std::string& name ); + + // Translate a parameter name from as it appears in the table workspace to its name in the XML file + static std::string getXMLParameterName( const std::string& name ); + + /// Place to store the row numbers + static std::map m_rowNumbers; + private: /// Implement abstract Algorithm methods void init(); @@ -94,42 +130,6 @@ namespace Mantid /// Create Bank to Workspace Correspondence void createBankToWorkspaceMap ( const std::vector& banks, const std::vector& workspaces, std::map< int, size_t>& WorkpsaceOfBank ); - /// Put parameters into a matrix workspace - void putParametersIntoWorkspace( const API::Column_const_sptr, API::MatrixWorkspace_sptr ws, int profNumber); - - /// Add an Ikeda-Carpenter PV ALFBE parameter - void addALFBEParameter(const API::Column_const_sptr, Poco::XML::Document* mDoc, Poco::XML::Element* parent, const std::string& paramName); - - /// Add set of Ikeda-Carpenter PV Sigma parameters - void addSigmaParameters(const API::Column_const_sptr, Poco::XML::Document* mDoc, Poco::XML::Element* parent ); - - /// Add set of Ikeda-Carpenter PV Gamma parameters - void addGammaParameters(const API::Column_const_sptr, Poco::XML::Document* mDoc, Poco::XML::Element* parent ); - - /// Add set of BackToBackExponential S parameters - void addBBX_S_Parameters(const API::Column_const_sptr, Poco::XML::Document* mDoc, Poco::XML::Element* parent ); - - /// Add set of BackToBackExponential A parameters - void addBBX_A_Parameters(const API::Column_const_sptr, Poco::XML::Document* mDoc, Poco::XML::Element* parent ); - - /// Add set of BackToBackExponential B parameters - void addBBX_B_Parameters(const API::Column_const_sptr, Poco::XML::Document* mDoc, Poco::XML::Element* parent ); - - /// Get value for XML eq attribute for parameter - std::string getXMLEqValue( const API::Column_const_sptr, const std::string& name ); - - /// Get value for XML eq attribute for squared parameter - std::string getXMLSquaredEqValue( const API::Column_const_sptr column, const std::string& name ); - - // Translate a parameter name from as it appears in the table workspace to its name in the XML file - std::string getXMLParameterName( const std::string& name ); - - /// Get row numbers of the parameters in the table workspace - void getTableRowNumbers(const API::ITableWorkspace_sptr & tablews, std::map& parammap); - - /// Place to store the row numbers - std::map m_rowNumbers; - }; diff --git a/Code/Mantid/Framework/DataHandling/inc/MantidDataHandling/LoadIDFFromNexus.h b/Code/Mantid/Framework/DataHandling/inc/MantidDataHandling/LoadIDFFromNexus.h index 4ee11d3a8e4a..268b479d3233 100644 --- a/Code/Mantid/Framework/DataHandling/inc/MantidDataHandling/LoadIDFFromNexus.h +++ b/Code/Mantid/Framework/DataHandling/inc/MantidDataHandling/LoadIDFFromNexus.h @@ -1,4 +1,4 @@ -#ifndef MANTID_DATAHANDLING_LOADIDFROMNEXUS_H_ +#ifndef MANTID_DATAHANDLING_LOADIDFFROMNEXUS_H_ #define MANTID_DATAHANDLING_LOADIDFFROMNEXUS_H_ //---------------------------------------------------------------------- diff --git a/Code/Mantid/Framework/DataHandling/inc/MantidDataHandling/LoadISISNexus2.h b/Code/Mantid/Framework/DataHandling/inc/MantidDataHandling/LoadISISNexus2.h index 9181a2be9b27..fe9acf88471f 100644 --- a/Code/Mantid/Framework/DataHandling/inc/MantidDataHandling/LoadISISNexus2.h +++ b/Code/Mantid/Framework/DataHandling/inc/MantidDataHandling/LoadISISNexus2.h @@ -91,42 +91,70 @@ namespace Mantid struct SpectraBlock { /// Constructor - initialize the block - SpectraBlock(int64_t f,int64_t l,bool m):first(f),last(l),isMonitor(m){} + SpectraBlock(int64_t f,int64_t l,bool is_mon,const std::string &monname): + first(f),last(l),isMonitor(is_mon),monName(monname){} + int64_t first; ///< first spectrum number of the block int64_t last; ///< last spectrum number of the block bool isMonitor; ///< is the data in a monitor group + std::string monName; }; + + /// The structure describes parameters of a single time-block written in the nexus file + struct DataBlock + { + // The number of data periods + int numberOfPeriods; + // The number of time channels per spectrum (N histogram bins -1) + std::size_t numberOfChannels; + // The number of spectra + size_t numberOfSpectra; + // minimal spectra Id (by default 1, undefined -- max_value) + int64_t spectraID_min; + // maximal spectra Id (by default 1, undefined -- 0) + int64_t spectraID_max; + + DataBlock():numberOfPeriods(0),numberOfChannels(0),numberOfSpectra(0),spectraID_min(std::numeric_limits::max()),spectraID_max(0){} + + DataBlock(const NeXus::NXInt &data): + numberOfPeriods(data.dim0()), + numberOfChannels(data.dim2()), + numberOfSpectra (data.dim1()), + spectraID_min(std::numeric_limits::max()), + spectraID_max(0) + {}; + }; private: /// Overwrites Algorithm method. void init(); /// Overwrites Algorithm method void exec(); // Validate the optional input properties - void checkOptionalProperties(); + void checkOptionalProperties(const std::map &ExcludedMonitors); /// Prepare a vector of SpectraBlock structures to simplify loading - size_t prepareSpectraBlocks(); + size_t prepareSpectraBlocks(std::map &monitors, const std::map &specInd2specNum_map,const DataBlock &LoadBlock); /// Run LoadInstrument as a ChildAlgorithm - void runLoadInstrument(DataObjects::Workspace2D_sptr); + void runLoadInstrument(DataObjects::Workspace2D_sptr &); /// Load in details about the run - void loadRunDetails(DataObjects::Workspace2D_sptr local_workspace, Mantid::NeXus::NXEntry & entry); + void loadRunDetails(DataObjects::Workspace2D_sptr &local_workspace, Mantid::NeXus::NXEntry & entry); /// Parse an ISO formatted date-time string into separate date and time strings void parseISODateTime(const std::string & datetime_iso, std::string & date, std::string & time) const; /// Load in details about the sample - void loadSampleData(DataObjects::Workspace2D_sptr, Mantid::NeXus::NXEntry & entry); + void loadSampleData(DataObjects::Workspace2D_sptr &, Mantid::NeXus::NXEntry & entry); /// Load log data from the nexus file - void loadLogs(DataObjects::Workspace2D_sptr ws, Mantid::NeXus::NXEntry & entry); + void loadLogs(DataObjects::Workspace2D_sptr &ws, 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); + void loadPeriodData(int64_t period, Mantid::NeXus::NXEntry & entry, DataObjects::Workspace2D_sptr &local_workspace); // Load a data block void loadBlock(Mantid::NeXus::NXDataSetTyped & data, int64_t blocksize, int64_t period, int64_t start, - int64_t &hist, int64_t& spec_num, DataObjects::Workspace2D_sptr localWorkspace); + int64_t &hist, int64_t& spec_num, DataObjects::Workspace2D_sptr &localWorkspace); // Create period logs - void createPeriodLogs(int64_t period, DataObjects::Workspace2D_sptr local_workspace); + void createPeriodLogs(int64_t period, DataObjects::Workspace2D_sptr &local_workspace); // Validate multi-period logs - void validateMultiPeriodLogs(Mantid::API::MatrixWorkspace_sptr); + void validateMultiPeriodLogs(Mantid::API::MatrixWorkspace_sptr ); // build the list of spectra numbers to load and include in the spectra list - void buildSpectraInd2SpectraNumMap(const std::vector &spec_list); + void buildSpectraInd2SpectraNumMap(bool range_supplied,int64_t range_min,int64_t range_max,const std::vector &spec_list,const std::map &ExcludedMonitors); /// The name and path of the input file @@ -136,28 +164,19 @@ namespace Mantid /// The sample name read from Nexus std::string m_samplename; - /// The number of spectra - std::size_t m_numberOfSpectra; - /// The number of spectra in the raw file - std::size_t m_numberOfSpectraInFile; - /// The number of periods - int m_numberOfPeriods; - /// The number of periods in the raw file - int m_numberOfPeriodsInFile; - /// The number of time channels per spectrum - std::size_t m_numberOfChannels; - /// The number of time channels per spectrum in the raw file - std::size_t m_numberOfChannelsInFile; + // the description of the data block in the file to load. + // the description of single time-range data block, obtained from detectors + DataBlock m_detBlockInfo; + // the description of single time-range data block, obtained from monitors + DataBlock m_monBlockInfo; + // description of the block to be loaded may include monitors and detectors with the same time binning if the detectors and monitors are loaded together + // in single workspace or equal to the detectorBlock if monitors are excluded + // or monBlockInfo if only monitors are loaded. + DataBlock m_loadBlockInfo; + /// Is there a detector block bool m_have_detector; - - /// Have the spectrum_min/max properties been set? - bool m_range_supplied; - /// The value of the SpectrumMin property - int64_t m_spec_min; - /// The value of the SpectrumMax property - int64_t m_spec_max; /// if true, a spectra list or range of spectra is supplied bool m_load_selected_spectra; /// map of spectra Index to spectra Number (spectraID) @@ -192,8 +211,10 @@ namespace Mantid static double dblSqrt(double in); // C++ interface to the NXS file - ::NeXus::File * m_cppFile; + boost::scoped_ptr< ::NeXus::File> m_cppFile; + bool findSpectraDetRangeInFile(NeXus::NXEntry &entry,boost::shared_array &spectrum_index,int64_t ndets,int64_t n_vms_compat_spectra, + std::map &monitors,bool excludeMonitors,bool separateMonitors,std::map &ExcludedMonitors); }; } // namespace DataHandling diff --git a/Code/Mantid/Framework/DataHandling/inc/MantidDataHandling/LoadInstrument.h b/Code/Mantid/Framework/DataHandling/inc/MantidDataHandling/LoadInstrument.h index 499babea9a34..5e8201bca7d1 100644 --- a/Code/Mantid/Framework/DataHandling/inc/MantidDataHandling/LoadInstrument.h +++ b/Code/Mantid/Framework/DataHandling/inc/MantidDataHandling/LoadInstrument.h @@ -87,15 +87,13 @@ namespace Mantid /// Algorithm's name for identification overriding a virtual method virtual const std::string name() const { return "LoadInstrument";}; ///Summary of algorithms purpose - virtual const std::string summary() const {return "Loads an Instrument Definition File (IDF) into a workspace. After the IDF has been read this algorithm will attempt to run the Child Algorithm LoadParameterFile; where if IDF filename is of the form IDENTIFIER_Definition.xml then the instrument parameters in the file named IDENTIFIER_Parameters.xml would be loaded (in the directory specified by the parameterDefinition.directory Mantid property).";} + virtual const std::string summary() const {return "Loads an Instrument Definition File (IDF) into a workspace. After the IDF has been read this algorithm will attempt to run the Child Algorithm LoadParameterFile; where if IDF filename is of the form IDENTIFIER_Definition.xml then the instrument parameters in the file named IDENTIFIER_Parameters.xml would be loaded.";} /// Algorithm's version for identification overriding a virtual method virtual int version() const { return 1;}; /// Algorithm's category for identification overriding a virtual method virtual const std::string category() const { return "DataHandling\\Instrument";} - void execManually(); - private: void init(); void exec(); diff --git a/Code/Mantid/Framework/DataHandling/inc/MantidDataHandling/LoadNXSPE.h b/Code/Mantid/Framework/DataHandling/inc/MantidDataHandling/LoadNXSPE.h index 73c12b72f787..2145b9733d06 100644 --- a/Code/Mantid/Framework/DataHandling/inc/MantidDataHandling/LoadNXSPE.h +++ b/Code/Mantid/Framework/DataHandling/inc/MantidDataHandling/LoadNXSPE.h @@ -57,6 +57,9 @@ namespace DataHandling /// Returns a confidence value that this algorithm can load a file virtual int confidence(Kernel::NexusDescriptor & descriptor) const; + /// Confidence in identifier. + static int identiferConfidence(const std::string& value); + private: /// Initialise the properties diff --git a/Code/Mantid/Framework/DataHandling/inc/MantidDataHandling/LoadParameterFile.h b/Code/Mantid/Framework/DataHandling/inc/MantidDataHandling/LoadParameterFile.h index 7e1d800517cd..608c6bd145f7 100644 --- a/Code/Mantid/Framework/DataHandling/inc/MantidDataHandling/LoadParameterFile.h +++ b/Code/Mantid/Framework/DataHandling/inc/MantidDataHandling/LoadParameterFile.h @@ -87,8 +87,6 @@ namespace Mantid /// Algorithm's category for identification overriding a virtual method virtual const std::string category() const { return "DataHandling\\Instrument";} - static void execManually(bool useString, std::string filename, std::string parameterString, Mantid::API::ExperimentInfo_sptr localWorkspace); - private: void init(); diff --git a/Code/Mantid/Framework/DataHandling/inc/MantidDataHandling/LoadRaw3.h b/Code/Mantid/Framework/DataHandling/inc/MantidDataHandling/LoadRaw3.h index 1203d8d98bfd..326f4830d43e 100644 --- a/Code/Mantid/Framework/DataHandling/inc/MantidDataHandling/LoadRaw3.h +++ b/Code/Mantid/Framework/DataHandling/inc/MantidDataHandling/LoadRaw3.h @@ -21,7 +21,7 @@ namespace Mantid Loads an file in ISIS RAW format and stores it in a 2D workspace (Workspace2D class). LoadRaw is an algorithm and LoadRawHelper class and - overrides the init() & exec() methods. + overrides the init() & exec() methods. LoadRaw3 uses less memory by only loading up the datablocks as required. Copyright © 2007-9 ISIS Rutherford Appleton Laboratory & NScD Oak Ridge National Laboratory @@ -71,12 +71,6 @@ namespace Mantid /// returns true if the given spectrum is a monitor bool isMonitor(const std::vector& monitorIndexes,specid_t spectrumNum); - /// returns true if the Exclude Monitor option(property) selected - bool isExcludeMonitors(const std::string &monitorOption); - /// returns true if the Separate Monitor Option selected - bool isSeparateMonitors(const std::string &monitorOption); - /// returns true if the Include Monitor Option selected - bool isIncludeMonitors(const std::string &monitorOption); /// validate workspace sizes void validateWorkspaceSizes( bool bexcludeMonitors ,bool bseparateMonitors, diff --git a/Code/Mantid/Framework/DataHandling/inc/MantidDataHandling/LoadRawHelper.h b/Code/Mantid/Framework/DataHandling/inc/MantidDataHandling/LoadRawHelper.h index 70178fc433c2..96fd62201711 100644 --- a/Code/Mantid/Framework/DataHandling/inc/MantidDataHandling/LoadRawHelper.h +++ b/Code/Mantid/Framework/DataHandling/inc/MantidDataHandling/LoadRawHelper.h @@ -27,32 +27,32 @@ namespace Mantid { /** @class LoadRawHelper DataHandling/LoadRawHelper.h - Helper class for LoadRaw algorithms. + Helper class for LoadRaw algorithms. - @author Sofia Antony, ISIS,RAL - @date 14/04/2010 + @author Sofia Antony, ISIS,RAL + @date 14/04/2010 - Copyright © 2007-9 ISIS Rutherford Appleton Laboratory & NScD Oak Ridge National Laboratory + Copyright © 2007-9 ISIS Rutherford Appleton Laboratory & NScD Oak Ridge National Laboratory - This file is part of Mantid. + 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 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. + 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 . + You should have received a copy of the GNU General Public License + along with this program. If not, see . - File change history is stored at: . - Code Documentation is available at: - */ + File change history is stored at: . + Code Documentation is available at: + */ class DLLExport LoadRawHelper: public API::IFileLoader { public: @@ -74,6 +74,37 @@ namespace Mantid /// Returns a confidence value that this algorithm can load a file virtual int confidence(Kernel::FileDescriptor & descriptor) const; + /// returns true if the Exclude Monitor option(property) selected + static bool isExcludeMonitors(const std::string &monitorOption); + /// returns true if the Separate Monitor Option selected + static bool isSeparateMonitors(const std::string &monitorOption); + /// returns true if the Include Monitor Option selected + static bool isIncludeMonitors(const std::string &monitorOption); + + + static void ProcessLoadMonitorOptions(bool &bincludeMonitors,bool &bseparateMonitors,bool &bexcludeMonitors,API::Algorithm *const pAlgo); + ///creates monitor workspace + static void createMonitorWorkspace(DataObjects::Workspace2D_sptr& monws_sptr, + DataObjects::Workspace2D_sptr& ws_sptr,API::WorkspaceGroup_sptr& mongrp_sptr, + const int64_t mwsSpecs,const int64_t nwsSpecs,const int64_t numberOfPeriods,const int64_t lenthIn,std::string title,API::Algorithm *const pAlg); + /// creates shared pointer to group workspace + static API::WorkspaceGroup_sptr createGroupWorkspace(); + + ///creates shared pointer to workspace from parent workspace + static DataObjects::Workspace2D_sptr createWorkspace(DataObjects::Workspace2D_sptr ws_sptr, + int64_t nVectors=-1,int64_t xLengthIn=-1,int64_t yLengthIn=-1); + + /// overloaded method to create shared pointer to workspace + static DataObjects::Workspace2D_sptr createWorkspace(int64_t nVectors,int64_t xlengthIn,int64_t ylengthIn,const std::string& title); + + /// sets the workspace property + static void setWorkspaceProperty(const std::string & propertyName,const std::string& title, + API::WorkspaceGroup_sptr grpws_sptr,DataObjects::Workspace2D_sptr ws_sptr,int64_t numberOfPeriods,bool bMonitor,API::Algorithm * const pAlg); + + /// overloaded method to set the workspace property + static void setWorkspaceProperty(DataObjects::Workspace2D_sptr ws_sptr,API::WorkspaceGroup_sptr grpws_sptr,const int64_t period,bool bmonitors,API::Algorithm *const pAlg); + + protected: /// Overwrites Algorithm method. void init(); @@ -95,19 +126,6 @@ namespace Mantid bool readData(FILE* file,int histToRead); bool readData(FILE* file,int64_t histToRead); - ///creates shared pointer to workspace from parent workspace - DataObjects::Workspace2D_sptr createWorkspace(DataObjects::Workspace2D_sptr ws_sptr, - int64_t nVectors=-1,int64_t xLengthIn=-1,int64_t yLengthIn=-1); - - /// overloaded method to create shared pointer to workspace - DataObjects::Workspace2D_sptr createWorkspace(int64_t nVectors,int64_t xlengthIn,int64_t ylengthIn,const std::string& title); - ///creates monitor workspace - void createMonitorWorkspace(DataObjects::Workspace2D_sptr& monws_sptr, - DataObjects::Workspace2D_sptr& ws_sptr,API::WorkspaceGroup_sptr& mongrp_sptr, - const int64_t mwsSpecs,const int64_t nwsSpecs,const int64_t numberOfPeriods,const int64_t lenthIn,std::string title); - - /// creates shared pointer to group workspace - API::WorkspaceGroup_sptr createGroupWorkspace(); //Constructs the time channel (X) vector(s) std::vector > getTimeChannels(const int64_t& regimes, const int64_t& lengthIn); @@ -126,16 +144,10 @@ namespace Mantid ///gets the monitor spectrum list from the workspace std::vector getmonitorSpectrumList(const API::SpectrumDetectorMapping& mapping); - /// sets the workspace property - void setWorkspaceProperty(const std::string & propertyName,const std::string& title, - API::WorkspaceGroup_sptr grpws_sptr,DataObjects::Workspace2D_sptr ws_sptr,int64_t numberOfPeriods,bool bMonitor); - - /// overloaded method to set the workspace property - void setWorkspaceProperty(DataObjects::Workspace2D_sptr ws_sptr,API::WorkspaceGroup_sptr grpws_sptr,const int64_t period,bool bmonitors); /// This method sets the raw file data to workspace vectors void setWorkspaceData(DataObjects::Workspace2D_sptr newWorkspace,const std::vector >& - timeChannelsVec,int64_t wsIndex,specid_t nspecNum,int64_t noTimeRegimes,int64_t lengthIn,int64_t binStart); + timeChannelsVec,int64_t wsIndex,specid_t nspecNum,int64_t noTimeRegimes,int64_t lengthIn,int64_t binStart); /// ISISRAW class instance which does raw file reading. Shared pointer to prevent memory leak when an exception is thrown. @@ -161,10 +173,10 @@ namespace Mantid specid_t calculateWorkspaceSize(); /// calculate workspace sizes if separate or exclude monitors are selected void calculateWorkspacesizes(const std::vector& monitorSpecList, - specid_t& normalwsSpecs, specid_t& monitorwsSpecs); - /// load the specra + specid_t& normalwsSpecs, specid_t& monitorwsSpecs); + /// load the spectra void loadSpectra(FILE* file,const int& period, const int& m_total_specs, - DataObjects::Workspace2D_sptr ws_sptr,std::vector >); + DataObjects::Workspace2D_sptr ws_sptr,std::vector >); /// Has the spectrum_list property been set? bool m_list; diff --git a/Code/Mantid/Framework/DataHandling/inc/MantidDataHandling/MaskDetectors.h b/Code/Mantid/Framework/DataHandling/inc/MantidDataHandling/MaskDetectors.h index a5d19e74870f..9a0dd7814e0c 100644 --- a/Code/Mantid/Framework/DataHandling/inc/MantidDataHandling/MaskDetectors.h +++ b/Code/Mantid/Framework/DataHandling/inc/MantidDataHandling/MaskDetectors.h @@ -7,6 +7,7 @@ #include "MantidAPI/Algorithm.h" #include "MantidDataObjects/EventWorkspace.h" #include "MantidDataObjects/MaskWorkspace.h" +#include "MantidDataObjects/PeaksWorkspace.h" namespace Mantid { @@ -70,6 +71,7 @@ class DLLExport MaskDetectors : public API::Algorithm // Implement abstract Algorithm methods void init(); void exec(); + void execPeaks(DataObjects::PeaksWorkspace_sptr WS); void fillIndexListFromSpectra(std::vector& indexList, const std::vector& spectraList, const API::MatrixWorkspace_sptr WS); void appendToIndexListFromWS(std::vector& indexList, const API::MatrixWorkspace_sptr maskedWorkspace); diff --git a/Code/Mantid/Framework/DataHandling/inc/MantidDataHandling/SNSDataArchiveICAT2.h b/Code/Mantid/Framework/DataHandling/inc/MantidDataHandling/SNSDataArchiveICAT2.h deleted file mode 100644 index a1976b1f84e9..000000000000 --- a/Code/Mantid/Framework/DataHandling/inc/MantidDataHandling/SNSDataArchiveICAT2.h +++ /dev/null @@ -1,57 +0,0 @@ -#ifndef MANTID_DATAHANDLING_SNSDATAARCHIVEICAT2_H_ -#define MANTID_DATAHANDLING_SNSDATAARCHIVEICAT2_H_ - -//---------------------------------------------------------------------- -// Includes -//---------------------------------------------------------------------- -#include "MantidKernel/System.h" -#include "MantidAPI/IArchiveSearch.h" - -#include - - -namespace Mantid -{ - -namespace DataHandling -{ -/** - This class is for searching the SNS data archive - - @date 02/22/2012 - - Copyright © 2010 ISIS Rutherford Appleton Laboratory & NScD Oak Ridge National Laboratory - - This file is part of Mantid. - - Mantid is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - Mantid is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . - - File change history is stored at: . - Code Documentation is available at: - */ - -class DLLExport SNSDataArchiveICAT2: public API::IArchiveSearch -{ -public: - /// Find the archive location of a set of files. - std::string getArchivePath(const std::set& filenames, const std::vector& exts) const; -private: - /// Call web service to get full path. - std::string getPath(const std::string& fName) const; -}; - -} -} - -#endif /* MANTID_DATAHANDLING_SNSDATAARCHIVEICAT2_H_ */ diff --git a/Code/Mantid/Framework/DataHandling/inc/MantidDataHandling/SaveAscii2.h b/Code/Mantid/Framework/DataHandling/inc/MantidDataHandling/SaveAscii2.h index dfacc3d56224..4e0dc838f1f5 100644 --- a/Code/Mantid/Framework/DataHandling/inc/MantidDataHandling/SaveAscii2.h +++ b/Code/Mantid/Framework/DataHandling/inc/MantidDataHandling/SaveAscii2.h @@ -57,9 +57,8 @@ namespace Mantid ~SaveAscii2() {} /// Algorithm's name for identification overriding a virtual method virtual const std::string name() const { return "SaveAscii"; } - ///Summary of algorithms purpose - virtual const std::string summary() const {return "Saves a 2D workspace to a ascii file.";} - + ///Summary of algorithms purpose + virtual const std::string summary() const {return "Saves a 2D workspace to a ascii file.";} /// Algorithm's version for identification overriding a virtual method virtual int version() const { return 2; } /// Algorithm's category for identification overriding a virtual method @@ -90,6 +89,7 @@ namespace Mantid bool m_writeDX; bool m_writeID; bool m_isHistogram; + bool m_isCommonBins; API::MatrixWorkspace_const_sptr m_ws; }; } // namespace DataHandling diff --git a/Code/Mantid/Framework/DataHandling/inc/MantidDataHandling/SaveNXTomo.h b/Code/Mantid/Framework/DataHandling/inc/MantidDataHandling/SaveNXTomo.h new file mode 100644 index 000000000000..cf83e7184b31 --- /dev/null +++ b/Code/Mantid/Framework/DataHandling/inc/MantidDataHandling/SaveNXTomo.h @@ -0,0 +1,106 @@ +#ifndef MANTID_DATAHANDLING_SAVENXTOMO_H_ +#define MANTID_DATAHANDLING_SAVENXTOMO_H_ + +//--------------------------------------------------- +// Includes +//--------------------------------------------------- +#include "vector" +#include "MantidGeometry/Instrument/RectangularDetector.h" + +namespace Mantid +{ + namespace DataHandling + { + + /** + * Saves a workspace into a NeXus/HDF5 NXTomo file. + * File format is defined here: http://download.nexusformat.org/sphinx/classes/applications/NXtomo.html + * + * Required properties: + *
    + *
  • InputWorkspace - The workspace to save.
  • + *
  • Filename - The filename for output
  • + *
+ * + * @author John R Hill, RAL + * @date 10/09/2014 + * + * 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 . + * + * File change history is stored at: + * Code Documentation is available at: + * + */ + + class DLLExport SaveNXTomo: public API::Algorithm + { + public: + SaveNXTomo(); + /// Virtual dtor + virtual ~SaveNXTomo() {} + + /// Algorithm's name for identification overriding a virtual method + virtual const std::string name() const { return "SaveNXTomo"; } + + ///Summary of algorithms purpose + virtual const std::string summary() const {return "Writes a MatrixWorkspace to a file in the NXTomo format.";} + + /// Algorithm's version + virtual int version() const { return (1); } + + /// Algorithm's category for identification + virtual const std::string category() const { return "DataHandling\\Nexus;DataHandling\\Tomo;Diffraction"; } + + private: + /// Initialisation code + void init(); + /// Execution code + void exec(); + + /// Save all data to file + + /// Save batch of images to the file + + /// Fetch all rectangular Detector objects defined for an instrument + std::vector> getRectangularDetectors(const Geometry::Instrument_const_sptr &instrument); + + /// Populate dims_array with the dimensions defined in the rectangular detector in the instrument + std::vector getDimensionsFromDetector(const std::vector> &rectDetectors, size_t useDetectorIndex = 0); + + // Number of rows to + size_t m_numberOfRows; + + // Include error data in the written file + bool m_includeError; + + ///the number of bins in each histogram, as the histogram must have common bins this shouldn't change + //size_t m_nBins; + /// The filename of the output file + std::string m_filename; + + // Some constants to be written for masked values. + /// Value for data if pixel is masked + static const double MASK_FLAG; + /// Value for error if pixel is masked + static const double MASK_ERROR; + /// file format version + static const std::string NXTOMO_VER; + }; + + } // namespace DataHandling +} // namespace Mantid + +#endif // MANTID_DATAHANDLING_SAVENXTOMO_H_ diff --git a/Code/Mantid/Framework/DataHandling/inc/MantidDataHandling/SaveNexus.h b/Code/Mantid/Framework/DataHandling/inc/MantidDataHandling/SaveNexus.h index 2aa0dac3e9bc..e5440fed7dc8 100644 --- a/Code/Mantid/Framework/DataHandling/inc/MantidDataHandling/SaveNexus.h +++ b/Code/Mantid/Framework/DataHandling/inc/MantidDataHandling/SaveNexus.h @@ -88,8 +88,11 @@ namespace Mantid /// sets non workspace properties for the algorithm void setOtherProperties(IAlgorithm* alg,const std::string & propertyName,const std::string &propertyValue,int perioidNum); + protected: + + /// Override process groups + virtual bool processGroups(); - }; } // namespace DataHandling diff --git a/Code/Mantid/Framework/DataHandling/inc/MantidDataHandling/SaveNexusProcessed.h b/Code/Mantid/Framework/DataHandling/inc/MantidDataHandling/SaveNexusProcessed.h index 8c885b020b8f..c0721e31ee72 100644 --- a/Code/Mantid/Framework/DataHandling/inc/MantidDataHandling/SaveNexusProcessed.h +++ b/Code/Mantid/Framework/DataHandling/inc/MantidDataHandling/SaveNexusProcessed.h @@ -65,6 +65,11 @@ namespace Mantid /// Algorithm's category for identification overriding a virtual method virtual const std::string category() const { return "DataHandling\\Nexus";} + protected: + + /// Override process groups + virtual bool processGroups(); + private: /// Overwrites Algorithm method. @@ -80,6 +85,9 @@ namespace Mantid void execEvent(Mantid::NeXus::NexusFileIO * nexusFile,const bool uniformSpectra,const std::vector spec); /// sets non workspace properties for the algorithm void setOtherProperties(IAlgorithm* alg,const std::string & propertyName,const std::string &propertyValue,int perioidNum); + /// execute the algorithm. + void doExec(Mantid::API::Workspace_sptr workspace, Mantid::NeXus::NexusFileIO_sptr& nexusFile, + const bool keepFile=false, NeXus::NexusFileIO::optional_size_t entryNumber = NeXus::NexusFileIO::optional_size_t()); /// The name and path of the input file std::string m_filename; diff --git a/Code/Mantid/Framework/DataHandling/inc/MantidDataHandling/SavePDFGui.h b/Code/Mantid/Framework/DataHandling/inc/MantidDataHandling/SavePDFGui.h new file mode 100644 index 000000000000..3d147e8dc442 --- /dev/null +++ b/Code/Mantid/Framework/DataHandling/inc/MantidDataHandling/SavePDFGui.h @@ -0,0 +1,55 @@ +#ifndef MANTID_DATAHANDLING_SAVEPDFGUI_H_ +#define MANTID_DATAHANDLING_SAVEPDFGUI_H_ + +#include "MantidKernel/System.h" +#include "MantidAPI/Algorithm.h" + +namespace Mantid +{ +namespace DataHandling +{ + + /** SavePDFGui : TODO: DESCRIPTION + + Copyright © 2014 ISIS Rutherford Appleton Laboratory & NScD Oak Ridge National Laboratory + + This file is part of Mantid. + + Mantid is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + Mantid is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + + File change history is stored at: + Code Documentation is available at: + */ + class DLLExport SavePDFGui : public API::Algorithm + { + public: + SavePDFGui(); + virtual ~SavePDFGui(); + + virtual const std::string name() const; + virtual int version() const; + virtual const std::string category() const; + virtual const std::string summary() const; + virtual std::map validateInputs(); + + private: + void init(); + void exec(); + }; + + +} // namespace DataHandling +} // namespace Mantid + +#endif /* MANTID_DATAHANDLING_SAVEPDFGUI_H_ */ diff --git a/Code/Mantid/Framework/DataHandling/inc/MantidDataHandling/SaveParameterFile.h b/Code/Mantid/Framework/DataHandling/inc/MantidDataHandling/SaveParameterFile.h index fcf51fb54fc0..3ef96391c4ba 100644 --- a/Code/Mantid/Framework/DataHandling/inc/MantidDataHandling/SaveParameterFile.h +++ b/Code/Mantid/Framework/DataHandling/inc/MantidDataHandling/SaveParameterFile.h @@ -3,7 +3,7 @@ #include "MantidKernel/System.h" #include "MantidAPI/Algorithm.h" - +#include "MantidGeometry/Instrument/FitParameter.h" namespace Mantid { diff --git a/Code/Mantid/Framework/DataHandling/inc/MantidDataHandling/SaveSPE.h b/Code/Mantid/Framework/DataHandling/inc/MantidDataHandling/SaveSPE.h index b555d7bc84f5..cdf722dd672f 100644 --- a/Code/Mantid/Framework/DataHandling/inc/MantidDataHandling/SaveSPE.h +++ b/Code/Mantid/Framework/DataHandling/inc/MantidDataHandling/SaveSPE.h @@ -62,7 +62,7 @@ class DLLExport SaveSPE : public API::Algorithm private: - /// Initialisation code + /// Initialization code void init(); ///Execution code void exec(); @@ -75,13 +75,21 @@ class DLLExport SaveSPE : public API::Algorithm void writeValue(const double value, FILE * const outFile) const; void logMissingMasked(const std::vector &inds, const size_t nonMasked, const int masked) const; - ///the SPE files have a constant number of numbers writen on each line, but depending on the number of bins there will be some "spare" numbers at the end of the block, this holds that number of spares + ///the SPE files have a constant number of numbers written on each line, but depending on the number of bins there will be some "spare" numbers at the end of the block, this holds that number of spares int m_remainder; ///the number of bins in each histogram, as the histogram must have common bins this shouldn't change size_t m_nBins; /// the error value (=0.0) for spectra whose detectors are all masked, from the SPE specification http://www.mantidproject.org/images/3/3d/Spe_file_format.pdf static const double MASK_ERROR; + + // temporary variable to keep verified signal values for current spectra + mutable MantidVec m_tSignal; + // temporary variable to keep verified error values for current spectra + mutable MantidVec m_tError; + + // method verifies if a spectra contains any NaN or Inf values and replaces these values with SPE-specified constants + void check_and_copy_spectra(const MantidVec &inSignal,const MantidVec &inErr,MantidVec &Signal,MantidVec &Error)const; }; } // namespace DataHandling diff --git a/Code/Mantid/Framework/DataHandling/src/CreateChunkingFromInstrument.cpp b/Code/Mantid/Framework/DataHandling/src/CreateChunkingFromInstrument.cpp index 6ddd1217ede0..2a3a6deaac8e 100644 --- a/Code/Mantid/Framework/DataHandling/src/CreateChunkingFromInstrument.cpp +++ b/Code/Mantid/Framework/DataHandling/src/CreateChunkingFromInstrument.cpp @@ -139,14 +139,14 @@ namespace DataHandling // get the input paramters string filename = getPropertyValue(PARAM_IN_FILE); - MatrixWorkspace_sptr inWS = getProperty(PARAM_IN_WKSP); + string inWSname = getPropertyValue(PARAM_IN_WKSP); string instName = getPropertyValue(PARAM_INST_NAME); string instFilename = getPropertyValue(PARAM_INST_FILE); // count how many ways the input instrument was specified int numInst = 0; if (!filename.empty()) numInst++; - if (inWS) numInst++; + if (!inWSname.empty()) numInst++; if (!instName.empty()) numInst++; if (!instFilename.empty()) numInst++; diff --git a/Code/Mantid/Framework/DataHandling/src/GroupDetectors2.cpp b/Code/Mantid/Framework/DataHandling/src/GroupDetectors2.cpp index 3818feceee72..452195d95db0 100644 --- a/Code/Mantid/Framework/DataHandling/src/GroupDetectors2.cpp +++ b/Code/Mantid/Framework/DataHandling/src/GroupDetectors2.cpp @@ -127,7 +127,6 @@ void GroupDetectors2::exec() unGroupedInds.push_back(i); } - // read in the input parameters to make that map, if KeepUngroupedSpectra was set we'll need a list of the ungrouped spectrra too getGroups(inputWS, unGroupedInds); // converting the list into a set gets rid of repeated values, here the multiple GroupDetectors2::USED become one USED at the start diff --git a/Code/Mantid/Framework/DataHandling/src/Load.cpp b/Code/Mantid/Framework/DataHandling/src/Load.cpp index 3e9be9923491..e9702b44c91c 100644 --- a/Code/Mantid/Framework/DataHandling/src/Load.cpp +++ b/Code/Mantid/Framework/DataHandling/src/Load.cpp @@ -170,12 +170,30 @@ namespace Mantid // ... store it's name and version and check that all other files have loaders with the same name and version. std::string name = loader->name(); int version = loader->version(); + + //std::string ext = fileNames[0].substr(fileNames[0].find_last_of(".")); + + auto ifl = boost::dynamic_pointer_cast>(loader); + auto iflNexus = boost::dynamic_pointer_cast>(loader); + for(size_t i = 1; i < fileNames.size(); ++i) { - loader = getFileLoader(fileNames[i]); - - if( name != loader->name() || version != loader->version() ) - throw std::runtime_error("Cannot load multiple files when more than one Loader is needed."); + // If it's loading into a single file, perform a cursory check on file extensions only. + if((ifl && ifl->loadMutipleAsOne()) || (iflNexus && iflNexus->loadMutipleAsOne())) + { + // Currently disabled for ticket http://trac.mantidproject.org/mantid/ticket/10397 : should be put back in when completing 10231 + /* if( fileNames[i].substr(fileNames[i].find_last_of(".")) != ext) + { + throw std::runtime_error("Cannot load multiple files when more than one Loader is needed."); + }*/ + } + else + { + loader = getFileLoader(fileNames[i]); + + if( name != loader->name() || version != loader->version() ) + throw std::runtime_error("Cannot load multiple files when more than one Loader is needed."); + } } } @@ -224,11 +242,18 @@ namespace Mantid // Use the first file property as the main Filename const auto & props = loader->getProperties(); for(auto it = props.begin(); it != props.end(); ++it) - { - if(auto *fp = dynamic_cast(*it)) + { + auto *fp = dynamic_cast(*it); + auto *fp2 = dynamic_cast(*it); + if(fp) { m_filenamePropName = fp->name(); break; + } + if(fp2) + { + m_filenamePropName = fp2->name(); + break; } } if(m_filenamePropName.empty()) @@ -296,6 +321,7 @@ namespace Mantid exts.push_back(".h5"); exts.push_back(".hd5"); exts.push_back(".sqw"); + exts.push_back(".fits"); declareProperty(new MultipleFileProperty("Filename", exts), "The name of the file(s) to read, including the full or relative " @@ -324,10 +350,15 @@ namespace Mantid */ void Load::exec() { - std::vector > fileNames = getProperty("Filename"); + std::vector > fileNames = getProperty("Filename"); + + // Test for loading as a single file + IAlgorithm_sptr loader = getFileLoader(fileNames[0][0]); + auto ifl = boost::dynamic_pointer_cast>(loader); + auto iflNexus = boost::dynamic_pointer_cast>(loader); - if(isSingleFile(fileNames)) - { + if(isSingleFile(fileNames) || (ifl && ifl->loadMutipleAsOne()) || (iflNexus && iflNexus->loadMutipleAsOne())) + { // This is essentially just the same code that was called before multiple files were supported. loadSingleFile(); } diff --git a/Code/Mantid/Framework/DataHandling/src/LoadANSTOHelper.cpp b/Code/Mantid/Framework/DataHandling/src/LoadANSTOHelper.cpp new file mode 100644 index 000000000000..00af12434739 --- /dev/null +++ b/Code/Mantid/Framework/DataHandling/src/LoadANSTOHelper.cpp @@ -0,0 +1,321 @@ +#include "MantidDataHandling/LoadANSTOHelper.h" +#include "MantidDataObjects/EventWorkspace.h" +#include "MantidAPI/FileProperty.h" +#include "MantidAPI/RegisterFileLoader.h" +#include "MantidAPI/WorkspaceValidators.h" +#include "MantidKernel/UnitFactory.h" +#include "MantidGeometry/Instrument.h" +#include "MantidGeometry/Instrument/RectangularDetector.h" +#include "MantidGeometry/Objects/ShapeFactory.h" +#include "MantidNexus/NexusClasses.h" + +//#include + +namespace Mantid +{ + namespace DataHandling + { + namespace ANSTO + { + // ProgressTracker + ProgressTracker::ProgressTracker(API::Progress &progBar, const char *msg, int64_t target, size_t count) : + m_msg(msg), m_count(count), m_step(target / count), m_next(m_step), + m_progBar(progBar) { + + m_progBar.doReport(m_msg); + } + ProgressTracker::~ProgressTracker() { + complete(); + } + void ProgressTracker::update(int64_t position) { + while (m_next <= position) { + m_progBar.report(m_msg); + + switch (m_count) { + case 0: + return; + + case 1: + m_count = 0; + m_next = std::numeric_limits::max(); + return; + + default: + m_count--; + m_next += m_step; + } + } + } + void ProgressTracker::complete() { + if (m_count != 0) { + m_progBar.reportIncrement(m_count, m_msg); + m_count = 0; + } + } + + // EventCounter + EventCounter::EventCounter(std::vector &eventCounts, const std::vector &mask) : + m_eventCounts(eventCounts), + m_mask(mask), + m_tofMin(std::numeric_limits::max()), + m_tofMax(std::numeric_limits::min()) { + } + double EventCounter::tofMin() const { + return m_tofMin <= m_tofMax ? m_tofMin : 0.0; + } + double EventCounter::tofMax() const { + return m_tofMin <= m_tofMax ? m_tofMax : 0.0; + } + void EventCounter::addEvent(size_t s, double tof) { + if (m_mask[s]) { + if (m_tofMin > tof) + m_tofMin = tof; + if (m_tofMax < tof) + m_tofMax = tof; + + m_eventCounts[s]++; + } + } + + // EventAssigner + EventAssigner::EventAssigner(std::vector &eventVectors, const std::vector &mask) : + m_eventVectors(eventVectors), + m_mask(mask) { + } + void EventAssigner::addEvent(size_t s, double tof) { + if (m_mask[s]) + m_eventVectors[s]->push_back(tof); + } + + // FastReadOnlyFile +#ifdef WIN32 + FastReadOnlyFile::FastReadOnlyFile(const char *filename) { + m_handle = CreateFileA(filename, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); + } + FastReadOnlyFile::~FastReadOnlyFile() { + CloseHandle(m_handle); + m_handle = NULL; + } + void* FastReadOnlyFile::handle() const { + return m_handle; + } + bool FastReadOnlyFile::read(void *buffer, uint32_t size) { + DWORD bytesRead; + return (FALSE != ReadFile(m_handle, buffer, size, &bytesRead, NULL)) && (bytesRead == size); + } + bool FastReadOnlyFile::seek(int64_t offset, int whence, int64_t *newPosition) { + return FALSE != SetFilePointerEx( + m_handle, + *(LARGE_INTEGER*)&offset, + (LARGE_INTEGER*)newPosition, + whence); + } +#else + FastReadOnlyFile::FastReadOnlyFile(const char *filename) { + m_handle = fopen(filename, "rb"); + } + FastReadOnlyFile::~FastReadOnlyFile() { + fclose(m_handle); + m_handle = NULL; + } + void* FastReadOnlyFile::handle() const { + return m_handle; + } + bool FastReadOnlyFile::read(void *buffer, uint32_t size) { + return 1 == fread(buffer, (size_t)size, 1, m_handle); + } + bool FastReadOnlyFile::seek(int64_t offset, int whence, int64_t *newPosition) { + return + (0 == fseek(m_handle, offset, whence)) && + ((newPosition == NULL) || (0 <= (*newPosition = (int64_t)ftell(m_handle)))); + } +#endif + + namespace Tar { + + template + int64_t octalToInt(char (&str)[N]) { + int64_t result = 0; + char *p = str; + for (size_t n = N; n > 1; --n) { // last character is '\0' + char c = *p++; + if (('0' <= c) && (c <= '9')) + result = result * 8 + (c - '0'); + } + return result; + } + + // construction + File::File(const std::string &path) : + m_good(true), + m_file(path.c_str()), + m_selected((size_t)-1), + m_position(0), + m_size(0), + m_bufferPosition(0), + m_bufferAvailable(0) { + + m_good = m_file.handle() != NULL; + while (m_good) { + EntryHeader header; + int64_t position; + + m_good &= m_file.read(&header, sizeof(EntryHeader)); + m_good &= m_file.seek(512 - sizeof(EntryHeader), SEEK_CUR, &position); + if (!m_good) + break; + + std::string fileName(header.FileName); + if (fileName.length() == 0) + return; + + FileInfo fileInfo; + fileInfo.Offset = position; + fileInfo.Size = octalToInt(header.FileSize); + + if (header.TypeFlag == TarTypeFlag_NormalFile) { + m_fileNames.push_back(fileName); + m_fileInfos.push_back(fileInfo); + } + + size_t offset = (size_t)(fileInfo.Size % 512); + if (offset != 0) + offset = 512 - offset; + + m_good &= m_file.seek(fileInfo.Size + offset, SEEK_CUR); + } + } + + // properties + bool File::good() const { + return m_good; + } + const std::vector& File::files() const { + return m_fileNames; + } + const std::string& File::selected_name() const { + return m_fileNames[m_selected]; + } + int64_t File::selected_position() const { + return m_position; + } + int64_t File::selected_size() const { + return m_size; + } + + // methods + bool File::select(const char *file) { + if (!m_good) + return false; + + // reset buffer + m_bufferPosition = 0; + m_bufferAvailable = 0; + + for (size_t i = 0; i != m_fileNames.size(); i++) + if (m_fileNames[i] == file) { + const FileInfo &info = m_fileInfos[i]; + + m_selected = i; + m_position = 0; + m_size = info.Size; + + return m_good &= m_file.seek(info.Offset, SEEK_SET); + } + + m_selected = (size_t)-1; + m_position = 0; + m_size = 0; + return false; + } + bool File::skip(uint64_t offset) { + if (!m_good || (m_selected == (size_t)-1)) + return false; + + bool overrun = offset > (uint64_t)(m_size - m_position); + if (overrun) + offset = m_size - m_position; + + m_position += offset; + + uint64_t bufferPosition = (uint64_t)m_bufferPosition + offset; + if (bufferPosition <= m_bufferAvailable) + m_bufferPosition = (size_t)bufferPosition; + else { + m_good &= m_file.seek(bufferPosition - m_bufferAvailable, SEEK_CUR); + + m_bufferPosition = 0; + m_bufferAvailable = 0; + } + + return m_good && !overrun; + } + size_t File::read(void *dst, size_t size) { + if (!m_good || (m_selected == (size_t)-1)) + return 0; + + if ((int64_t)size > (m_size - m_position)) + size = (size_t)(m_size - m_position); + + auto ptr = (uint8_t*)dst; + size_t result = 0; + + if (m_bufferPosition != m_bufferAvailable) { + result = m_bufferAvailable - m_bufferPosition; + if (result > size) + result = size; + + memcpy(ptr, m_buffer, result); + ptr += result; + + size -= result; + m_position += result; + m_bufferPosition += result; + } + + while (size != 0) { + auto bytesToRead = (uint32_t)std::min( + size, + std::numeric_limits::max()); + + m_good &= m_file.read(ptr, bytesToRead); + if (!m_good) + break; + + ptr += bytesToRead; + + size -= bytesToRead; + result += bytesToRead; + m_position += bytesToRead; + } + + return result; + } + int File::read_byte() { + if (!m_good || (m_selected == (size_t)-1)) + return -1; + + if (m_bufferPosition == m_bufferAvailable) { + if (m_position >= m_size) + return -1; + + m_bufferPosition = 0; + m_bufferAvailable = 0; + + uint32_t size = (uint32_t)std::min(sizeof(m_buffer), m_size - m_position); + m_good &= m_file.read(m_buffer, size); + + if (m_good) + m_bufferAvailable = size; + else + return -1; + } + + m_position++; + return m_buffer[m_bufferPosition++]; + } + + } + } + }//namespace +}//namespace diff --git a/Code/Mantid/Framework/DataHandling/src/LoadBBY.cpp b/Code/Mantid/Framework/DataHandling/src/LoadBBY.cpp index 7767c05be5c5..74827af98d5c 100644 --- a/Code/Mantid/Framework/DataHandling/src/LoadBBY.cpp +++ b/Code/Mantid/Framework/DataHandling/src/LoadBBY.cpp @@ -11,15 +11,6 @@ #include -#define TarTypeFlag_NormalFile '0' -#define TarTypeFlag_HardLink '1' -#define TarTypeFlag_SymbolicLink '2' -#define TarTypeFlag_CharacterSpecial '3' -#define TarTypeFlag_BlockSpecial '4' -#define TarTypeFlag_Directory '5' -#define TarTypeFlag_FIFO '6' -#define TarTypeFlag_ContiguousFile '7' - namespace Mantid { namespace DataHandling @@ -33,57 +24,10 @@ namespace Mantid // 100 = 40 + 20 + 40 static const size_t Progress_LoadBinFile = 40; static const size_t Progress_ReserveMemory = 20; - - // pointer to the vector of events - typedef std::vector *EventVector_pt; - - // helper class to keep track - class ProgressTracker { - private: - // fields - const std::string _msg; - size_t _count; - int64_t _step; - int64_t _next; - // matntid - API::Progress &_progBar; - public: - // construction - ProgressTracker(API::Progress &progBar, const char *msg, int64_t target, size_t count); - ~ProgressTracker(); + using ANSTO::EventVector_pt; - // methods - void update(int64_t position); - void complete(); - }; - - class TmpFile { - private: - // fields - Poco::TemporaryFile _tmppath; - bool _good; - std::string _path; - - // not supported - TmpFile(const TmpFile&); - TmpFile& operator =(const TmpFile&); - - public: - // construction - TmpFile(); - ~TmpFile(); - - // properties - bool good() const; - const char * path() const; - - // methods - FILE* create(const char *mode); - bool remove(); - }; - - class DetectorBankFactory { + class BbyDetectorBankFactory { private: // fields const Geometry::Instrument_sptr _instrument; @@ -96,7 +40,7 @@ namespace Mantid public: // construction - DetectorBankFactory( + BbyDetectorBankFactory( Geometry::Instrument_sptr instrument, Geometry::Object_sptr pixelShape, size_t xPixelCount, @@ -106,326 +50,9 @@ namespace Mantid const Kernel::V3D ¢er); // methods - void createAndAssign(size_t startIndex, const Kernel::V3D &pos, const Kernel::Quat &rot); - }; - - class EventCounter { - private: - // fields - std::vector &_eventCounts; - double _tofMin; - double _tofMax; - - public: - // construction - EventCounter(std::vector &eventCounts); - - // properties - double tofMin() const; - double tofMax() const; - - // methods - void addEvent(size_t x, size_t y, double tof); - }; - - class EventAssigner { - private: - // fields - std::vector &_eventVectors; - - public: - // construction - EventAssigner(std::vector &eventVectors); - - // methods - void addEvent(size_t x, size_t y, double tof); - }; - - class FastReadOnlyFile { - private: -#ifdef WIN32 - HANDLE _handle; -#else - FILE *_handle; -#endif - public: - // construction - FastReadOnlyFile(const char *filename); - ~FastReadOnlyFile(); - - // properties - void* handle() const; - - // methods - bool read(void *buffer, uint32_t size); - bool seek(int64_t offset, int whence, int64_t *newPosition = NULL); + void createAndAssign(size_t startIndex, const Kernel::V3D &pos, const Kernel::Quat &rot) const; }; - - namespace BbyTar { - - struct EntryHeader { - char FileName[100]; - // cppcheck-suppress unusedStructMember - char FileMode[8]; - // cppcheck-suppress unusedStructMember - char OwnerUserID[8]; - // cppcheck-suppress unusedStructMember - char OwnerGroupID[8]; - char FileSize[12]; // in bytes (octal base) - // cppcheck-suppress unusedStructMember - char LastModification[12]; // time in numeric Unix time format (octal) - // cppcheck-suppress unusedStructMember - char Checksum[8]; - char TypeFlag; - // cppcheck-suppress unusedStructMember - char LinkedFileName[100]; - // cppcheck-suppress unusedStructMember - char UStar[8]; - // cppcheck-suppress unusedStructMember - char OwnerUserName[32]; - // cppcheck-suppress unusedStructMember - char OwnerGroupName[32]; - // cppcheck-suppress unusedStructMember - char DeviceMajorNumber[8]; - // cppcheck-suppress unusedStructMember - char DeviceMinorNumber[8]; - // cppcheck-suppress unusedStructMember - char FilenamePrefix[155]; - }; - - template - int64_t octalToInt(char (&str)[N]); - - class File { - - static const auto BufferSize = 4096; - - struct FileInfo { - int64_t Offset; - int64_t Size; - }; - - private: - // fields - bool _good; - FastReadOnlyFile _file; - std::vector _fileNames; - std::vector _fileInfos; - // selected file - size_t _selected; // index - int64_t _position; - int64_t _size; - // buffer - uint8_t _buffer[BufferSize]; - size_t _bufferPosition; - size_t _bufferAvailable; - - // not supported - File(const File&); - File& operator =(const File&); - - public: - // construction - File(const std::string &path); - - // properties - bool good() const; - const std::vector& files() const; - // from selected file - const std::string& selected_name() const; - int64_t selected_position() const; - int64_t selected_size() const; - - // methods - bool select(const char *file); - bool skip(uint64_t offset); - size_t read(void *dst, size_t size); - int read_byte(); - }; - - template - int64_t octalToInt(char (&str)[N]) { - int64_t result = 0; - char *p = str; - for (size_t n = N; n > 1; --n) { // last character is '\0' - char c = *p++; - if (('0' <= c) && (c <= '9')) - result = result * 8 + (c - '0'); - } - return result; - } - - // construction - File::File(const std::string &path) : - _good(true), - _file(path.c_str()), - _selected((size_t)-1), - _position(0), - _size(0), - _bufferPosition(0), - _bufferAvailable(0) { - - _good = _file.handle() != NULL; - while (_good) { - EntryHeader header; - int64_t position; - - _good &= _file.read(&header, sizeof(EntryHeader)); - _good &= _file.seek(512 - sizeof(EntryHeader), SEEK_CUR, &position); - if (!_good) - break; - - std::string fileName(header.FileName); - if (fileName.length() == 0) - return; - - FileInfo fileInfo; - fileInfo.Offset = position; - fileInfo.Size = octalToInt(header.FileSize); - - if (header.TypeFlag == TarTypeFlag_NormalFile) { - _fileNames.push_back(fileName); - _fileInfos.push_back(fileInfo); - } - - size_t offset = (size_t)(fileInfo.Size % 512); - if (offset != 0) - offset = 512 - offset; - - _good &= _file.seek(fileInfo.Size + offset, SEEK_CUR); - } - } - - // properties - bool File::good() const { - return _good; - } - const std::vector& File::files() const { - return _fileNames; - } - const std::string& File::selected_name() const { - return _fileNames[_selected]; - } - int64_t File::selected_position() const { - return _position; - } - int64_t File::selected_size() const { - return _size; - } - - // methods - bool File::select(const char *file) { - if (!_good) - return false; - - // reset buffer - _bufferPosition = 0; - _bufferAvailable = 0; - - for (size_t i = 0; i != _fileNames.size(); i++) - if (_fileNames[i] == file) { - const FileInfo &info = _fileInfos[i]; - - _selected = i; - _position = 0; - _size = info.Size; - - return _good &= _file.seek(info.Offset, SEEK_SET); - } - - _selected = (size_t)-1; - _position = 0; - _size = 0; - return false; - } - bool File::skip(uint64_t offset) { - if (!_good || (_selected == (size_t)-1)) - return false; - - bool overrun = offset > (uint64_t)(_size - _position); - if (overrun) - offset = _size - _position; - - _position += offset; - - uint64_t bufferPosition = (uint64_t)_bufferPosition + offset; - if (bufferPosition <= _bufferAvailable) - _bufferPosition = (size_t)bufferPosition; - else { - _good &= _file.seek(bufferPosition - _bufferAvailable, SEEK_CUR); - - _bufferPosition = 0; - _bufferAvailable = 0; - } - - return _good && !overrun; - } - size_t File::read(void *dst, size_t size) { - if (!_good || (_selected == (size_t)-1)) - return 0; - - if ((int64_t)size > (_size - _position)) - size = (size_t)(_size - _position); - - auto ptr = (uint8_t*)dst; - size_t result = 0; - - if (_bufferPosition != _bufferAvailable) { - result = _bufferAvailable - _bufferPosition; - if (result > size) - result = size; - - memcpy(ptr, _buffer, result); - ptr += result; - - size -= result; - _position += result; - _bufferPosition += result; - } - - while (size != 0) { - auto bytesToRead = (uint32_t)std::min( - size, - std::numeric_limits::max()); - - _good &= _file.read(ptr, bytesToRead); - if (!_good) - break; - - ptr += bytesToRead; - - size -= bytesToRead; - result += bytesToRead; - _position += bytesToRead; - } - - return result; - } - int File::read_byte() { - if (!_good || (_selected == (size_t)-1)) - return -1; - - if (_bufferPosition == _bufferAvailable) { - if (_position >= _size) - return -1; - _bufferPosition = 0; - _bufferAvailable = 0; - - uint32_t size = (uint32_t)std::min(sizeof(_buffer), _size - _position); - _good &= _file.read(_buffer, size); - - if (_good) - _bufferAvailable = size; - else - return -1; - } - - _position++; - return _buffer[_bufferPosition++]; - } - } - /** * Return the confidence value that this algorithm can load the file * @param descriptor A descriptor for the file @@ -435,7 +62,7 @@ namespace Mantid if (descriptor.extension() != ".tar") return 0; - BbyTar::File file(descriptor.filename()); + ANSTO::Tar::File file(descriptor.filename()); if (!file.good()) return 0; @@ -469,6 +96,13 @@ namespace Mantid new API::FileProperty("Filename", "", API::FileProperty::Load, exts), "The input filename of the stored data"); + // filter + exts.clear(); + exts.push_back(".xml"); + declareProperty( + new API::FileProperty("Mask", "", API::FileProperty::OptionalLoad, exts), + "The input filename of the mask data"); + declareProperty( new API::WorkspaceProperty("OutputWorkspace", "", Kernel::Direction::Output)); @@ -503,12 +137,16 @@ namespace Mantid if (API::AnalysisDataService::Instance().doesExist(outName)) API::AnalysisDataService::Instance().remove(outName); - // Get the name of the file. + // Get the name of the data file. std::string filename = getPropertyValue("Filename"); - BbyTar::File file(filename); + ANSTO::Tar::File file(filename); if (!file.good()) return; + // Get the name of the mask file. + bool maskFileLoaded = false; + std::vector mask = createMaskVector(getPropertyValue("Mask"), maskFileLoaded); + size_t nBins = 1; double tofMinBoundary = getProperty("FilterByTofMin"); double tofMaxBoundary = getProperty("FilterByTofMax"); @@ -556,7 +194,7 @@ namespace Mantid eventWS->setInstrument(instrument); // load events - + size_t numberHistograms = eventWS->getNumberHistograms(); std::vector eventVectors(numberHistograms, NULL); @@ -564,11 +202,11 @@ namespace Mantid std::vector detIDs = instrument->getDetectorIDs(); // count total events per pixel to reserve necessary memory - EventCounter eventCounter(eventCounts); - loadEvents(prog, "loading neutron counts", file, tofMinBoundary, tofMaxBoundary, eventCounter); + ANSTO::EventCounter eventCounter(eventCounts, mask); + loadEvents(prog, "loading neutron counts", file, tofMinBoundary, tofMaxBoundary, eventCounter); // prepare event storage - ProgressTracker progTracker(prog, "creating neutron event lists", numberHistograms, Progress_ReserveMemory); + ANSTO::ProgressTracker progTracker(prog, "creating neutron event lists", numberHistograms, Progress_ReserveMemory); for (size_t i = 0; i != numberHistograms; ++i) { DataObjects::EventList& eventList = eventWS->getEventList(i); @@ -585,8 +223,8 @@ namespace Mantid } progTracker.complete(); - EventAssigner eventAssigner(eventVectors); - loadEvents(prog, "loading neutron events", file, tofMinBoundary, tofMaxBoundary, eventAssigner); + ANSTO::EventAssigner eventAssigner(eventVectors, mask); + loadEvents(prog, "loading neutron events", file, tofMinBoundary, tofMaxBoundary, eventAssigner); Kernel::cow_ptr axis; MantidVec &xRef = axis.access(); @@ -595,11 +233,32 @@ namespace Mantid xRef[1] = eventCounter.tofMax() + 1; eventWS->setAllX(axis); + if (maskFileLoaded) { + // count total number of masked pixels + size_t maskedPixels = 0; + for (auto itr = mask.begin(); itr != mask.end(); ++itr) + if (!*itr) + maskedPixels++; + + // create list of masked pixels + std::vector maskIndexList(maskedPixels); + size_t pixelIndex = 0; + size_t maskedPixelIndex = 0; + for (auto itr = mask.begin(); itr != mask.end(); ++itr, ++pixelIndex) + if (!*itr) + maskIndexList[maskedPixelIndex++] = pixelIndex; + + API::IAlgorithm_sptr maskingAlg = createChildAlgorithm("MaskDetectors"); + maskingAlg->setProperty("Workspace", eventWS); + maskingAlg->setProperty("WorkspaceIndexList", maskIndexList); + maskingAlg->executeAsChildAlg(); + } + setProperty("OutputWorkspace", eventWS); } // instrument creation - Geometry::Instrument_sptr LoadBBY::createInstrument(BbyTar::File &tarFile) { + Geometry::Instrument_sptr LoadBBY::createInstrument(ANSTO::Tar::File &tarFile) { // instrument Geometry::Instrument_sptr instrument = boost::make_shared("BILBY"); instrument->setDefaultViewAxis("Z-"); @@ -619,21 +278,21 @@ namespace Mantid instrument->add(samplePos); instrument->markAsSamplePos(samplePos); + double L2_det_value = 33.15616015625; double L1_chopper_value = 18.47258984375; //double L1_source_value = 9.35958984375; - double L2_det_value = 33.15616015625; - double L2_curtainl_value = 23.28446093750; - double L2_curtainr_value = 23.28201953125; - double L2_curtainu_value = 24.28616015625; - double L2_curtaind_value = 24.28235937500; + double L2_curtainl_value = 23.28446093750; + double L2_curtainr_value = 23.28201953125; + double L2_curtainu_value = 24.28616015625; + double L2_curtaind_value = 24.28235937500; double D_det_value = (8.4 + 2.0) / (2 * 1000); - double D_curtainl_value = 0.3816; - double D_curtainr_value = 0.4024; - double D_curtainu_value = 0.3947; - double D_curtaind_value = 0.3978; + double D_curtainl_value = 0.3816; + double D_curtainr_value = 0.4024; + double D_curtainu_value = 0.3947; + double D_curtaind_value = 0.3978; // extract hdf file int64_t fileSize = 0; @@ -647,8 +306,8 @@ namespace Mantid if (fileSize != 0) { // create tmp file - TmpFile hdfFile; - boost::shared_ptr handle(hdfFile.create("wb"), fclose); + Poco::TemporaryFile hdfFile; + boost::shared_ptr handle(fopen(hdfFile.path().c_str(), "wb"), fclose); if (handle) { // copy content char buffer[4096]; @@ -660,49 +319,33 @@ namespace Mantid NeXus::NXRoot root(hdfFile.path()); NeXus::NXEntry entry = root.openFirstEntry(); - NeXus::NXFloat L1 = entry.openNXDataSet("instrument/L1"); - NeXus::NXFloat L2_det = entry.openNXDataSet("instrument/L2_det"); - NeXus::NXFloat Ltof_det = entry.openNXDataSet("instrument/Ltof_det"); - - L1.load(); - L2_det.load(); - Ltof_det.load(); - - NeXus::NXFloat L2_curtainl = entry.openNXDataSet("instrument/L2_curtainl"); - NeXus::NXFloat L2_curtainr = entry.openNXDataSet("instrument/L2_curtainr"); - NeXus::NXFloat L2_curtainu = entry.openNXDataSet("instrument/L2_curtainu"); - NeXus::NXFloat L2_curtaind = entry.openNXDataSet("instrument/L2_curtaind"); - - L2_curtainl.load(); - L2_curtainr.load(); - L2_curtainu.load(); - L2_curtaind.load(); - - NeXus::NXFloat D_curtainl = entry.openNXDataSet("instrument/detector/curtainl"); - NeXus::NXFloat D_curtainr = entry.openNXDataSet("instrument/detector/curtainr"); - NeXus::NXFloat D_curtainu = entry.openNXDataSet("instrument/detector/curtainu"); - NeXus::NXFloat D_curtaind = entry.openNXDataSet("instrument/detector/curtaind"); - - D_curtainl.load(); - D_curtainr.load(); - D_curtainu.load(); - D_curtaind.load(); - + float tmp; const double toMeters = 1.0 / 1000; - L2_det_value = *L2_det() * toMeters; - L1_chopper_value = *Ltof_det() * toMeters - L2_det_value; - //L1_source_value = *L1() * toMeters; - - L2_curtainl_value = *L2_curtainl() * toMeters; - L2_curtainr_value = *L2_curtainr() * toMeters; - L2_curtainu_value = *L2_curtainu() * toMeters; - L2_curtaind_value = *L2_curtaind() * toMeters; + if (loadNXDataSet(tmp, entry, "instrument/L2_det")) + L2_det_value = tmp * toMeters; + if (loadNXDataSet(tmp, entry, "instrument/Ltof_det")) + L1_chopper_value = tmp * toMeters - L2_det_value; + //if (loadNXDataSet(tmp, entry, "instrument/L1")) + // L1_source_value = tmp * toMeters; + + if (loadNXDataSet(tmp, entry, "instrument/L2_curtainl")) + L2_curtainl_value = tmp * toMeters; + if (loadNXDataSet(tmp, entry, "instrument/L2_curtainr")) + L2_curtainr_value = tmp * toMeters; + if (loadNXDataSet(tmp, entry, "instrument/L2_curtainu")) + L2_curtainu_value = tmp * toMeters; + if (loadNXDataSet(tmp, entry, "instrument/L2_curtaind")) + L2_curtaind_value = tmp * toMeters; - D_curtainl_value = *D_curtainl() * toMeters; - D_curtainr_value = *D_curtainr() * toMeters; - D_curtainu_value = *D_curtainu() * toMeters; - D_curtaind_value = *D_curtaind() * toMeters; + if (loadNXDataSet(tmp, entry, "instrument/detector/curtainl")) + D_curtainl_value = tmp * toMeters; + if (loadNXDataSet(tmp, entry, "instrument/detector/curtainr")) + D_curtainr_value = tmp * toMeters; + if (loadNXDataSet(tmp, entry, "instrument/detector/curtainu")) + D_curtainu_value = tmp * toMeters; + if (loadNXDataSet(tmp, entry, "instrument/detector/curtaind")) + D_curtaind_value = tmp * toMeters; } } @@ -742,7 +385,7 @@ namespace Mantid Geometry::Object_sptr pixelShape = Geometry::ShapeFactory().createShape(detXML); // create detector banks - DetectorBankFactory factory( + BbyDetectorBankFactory factory( instrument, pixelShape, xPixelCount, @@ -789,13 +432,30 @@ namespace Mantid return instrument; } + + // load nx dataset + template + bool LoadBBY::loadNXDataSet(T &value, NeXus::NXEntry &entry, const std::string &path) { + try { + if (entry.isValid(path)) { + NeXus::NXDataSetTyped dataSet = entry.openNXDataSet(path); + dataSet.load(); + + value = *dataSet(); + return true; + } + } + catch (std::runtime_error&) { + } + return false; + } // read counts/events from binary file template void LoadBBY::loadEvents( API::Progress &prog, const char *progMsg, - BbyTar::File &file, + ANSTO::Tar::File &file, const double tofMinBoundary, const double tofMaxBoundary, Counter &counter) { @@ -812,7 +472,7 @@ namespace Mantid } // for progress notifications - ProgressTracker progTracker(prog, progMsg, fileSize, Progress_LoadBinFile); + ANSTO::ProgressTracker progTracker(prog, progMsg, fileSize, Progress_LoadBinFile); unsigned int x = 0; // 9 bits [0-239] tube number unsigned int y = 0; // 8 bits [0-255] position along tube @@ -875,7 +535,7 @@ namespace Mantid double tof = dt * 0.1; if ((tofMinBoundary <= tof) && (tof <= tofMaxBoundary)) - counter.addEvent(x, y, tof); + counter.addEvent(HISTO_BINS_Y * x + y, tof); } progTracker.update(file.selected_position()); @@ -883,75 +543,65 @@ namespace Mantid } } - // ProgressTracker - ProgressTracker::ProgressTracker(API::Progress &progBar, const char *msg, int64_t target, size_t count) : - _msg(msg), _count(count), _step(target / count), _next(_step), - _progBar(progBar) { + // load mask file + std::vector LoadBBY::createMaskVector(const std::string &maskFilename, bool &maskFileLoaded) { + std::vector result(HISTO_BINS_X * HISTO_BINS_Y, true); + + std::ifstream input(maskFilename.c_str()); + if (input.good()) { + std::string line; + while (std::getline(input, line)) { + + auto i0 = line.find(""); + auto iN = line.find(""); + + if ( + (i0 != std::string::npos) && + (iN != std::string::npos) && + (i0 < iN)) { - _progBar.doReport(_msg); - } - ProgressTracker::~ProgressTracker() { - complete(); - } - void ProgressTracker::update(int64_t position) { - if (_next <= position) { - if (_count != 0) { - _progBar.report(_msg); - _next += _step; - _count--; - } - else { - _next = -1; + line = line.substr(i0 + 8, iN - i0 - 8); + std::stringstream ss(line); + + std::string item; + while (std::getline(ss, item, ',')) { + auto k = item.find('-'); + + size_t p0, p1; + if (k != std::string::npos) { + p0 = boost::lexical_cast(item.substr(k)); + p1 = boost::lexical_cast(item.substr(k + 1, item.size() - k - 1)); + + if (p0 > p1) + std::swap(p0, p1); + } + else { + p0 = boost::lexical_cast(item); + p1 = p0; + } + + if (p0 < result.size()) { + + if (p1 >= result.size()) + p1 = result.size() - 1; + + while (p0 <= p1) + result[p0++] = false; + } + } } } - } - void ProgressTracker::complete() { - if (_count != 0) { - _progBar.reportIncrement(_count, _msg); - _count = 0; + maskFileLoaded = true; } - } - - // TmpFile - TmpFile::TmpFile() : - _tmppath(), - _good(false), - _path() { - } - TmpFile::~TmpFile() { - // Poco will remove the file. - } - bool TmpFile::good() const { - return _good; - } - const char* TmpFile::path() const { - return _good ? _path.c_str() : NULL; - } - FILE* TmpFile::create(const char *mode) { - remove(); - _path = _tmppath.path(); - FILE* file = fopen(_path.c_str(), mode); - _good = (file != NULL); - return file; - } - bool TmpFile::remove() { - if (_good) { - _good = false; - try - { - _tmppath.remove(); - } - catch(std::exception &) - { - return false; - } - return true; + else { + maskFileLoaded = false; } - return false; + + return result; } - + // DetectorBankFactory - DetectorBankFactory::DetectorBankFactory( + BbyDetectorBankFactory::BbyDetectorBankFactory( Geometry::Instrument_sptr instrument, Geometry::Object_sptr pixelShape, size_t xPixelCount, @@ -967,7 +617,7 @@ namespace Mantid _pixelHeight(pixelHeight), _center(center) { } - void DetectorBankFactory::createAndAssign(size_t startIndex, const Kernel::V3D &pos, const Kernel::Quat &rot) { + void BbyDetectorBankFactory::createAndAssign(size_t startIndex, const Kernel::V3D &pos, const Kernel::Quat &rot) const { // create a RectangularDetector which represents a rectangular array of pixels Geometry::RectangularDetector* bank = new Geometry::RectangularDetector("bank", _instrument.get()); // ??? possible memory leak!? "new" without "delete" @@ -996,79 +646,6 @@ namespace Mantid bank->rotate(rot); bank->translate(pos - center); } - - // EventCounter - EventCounter::EventCounter(std::vector &eventCounts) : - _eventCounts(eventCounts), - _tofMin(std::numeric_limits::max()), - _tofMax(std::numeric_limits::min()) { - } - double EventCounter::tofMin() const { - return _tofMin <= _tofMax ? _tofMin : 0.0; - } - double EventCounter::tofMax() const { - return _tofMin <= _tofMax ? _tofMax : 0.0; - } - void EventCounter::addEvent(size_t x, size_t y, double tof) { - if (_tofMin > tof) - _tofMin = tof; - if (_tofMax < tof) - _tofMax = tof; - - _eventCounts[HISTO_BINS_Y * (x) + y]++; - } - // EventAssigner - EventAssigner::EventAssigner(std::vector &eventVectors) : - _eventVectors(eventVectors) { - } - void EventAssigner::addEvent(size_t x, size_t y, double tof) { - // conversion from 100 nanoseconds to 1 microseconds - _eventVectors[HISTO_BINS_Y * (x) + y]->push_back(tof); - } - - // FastReadOnlyFile -#ifdef WIN32 - FastReadOnlyFile::FastReadOnlyFile(const char *filename) { - _handle = CreateFileA(filename, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); - } - FastReadOnlyFile::~FastReadOnlyFile() { - CloseHandle(_handle); - _handle = NULL; - } - void* FastReadOnlyFile::handle() const { - return _handle; - } - bool FastReadOnlyFile::read(void *buffer, uint32_t size) { - DWORD bytesRead; - return (FALSE != ReadFile(_handle, buffer, size, &bytesRead, NULL)) && (bytesRead == size); - } - bool FastReadOnlyFile::seek(int64_t offset, int whence, int64_t *newPosition) { - return FALSE != SetFilePointerEx( - _handle, - *(LARGE_INTEGER*)&offset, - (LARGE_INTEGER*)newPosition, - whence); - } -#else - FastReadOnlyFile::FastReadOnlyFile(const char *filename) { - _handle = fopen(filename, "rb"); - } - FastReadOnlyFile::~FastReadOnlyFile() { - fclose(_handle); - _handle = NULL; - } - void* FastReadOnlyFile::handle() const { - return _handle; - } - bool FastReadOnlyFile::read(void *buffer, uint32_t size) { - return 1 == fread(buffer, (size_t)size, 1, _handle); - } - bool FastReadOnlyFile::seek(int64_t offset, int whence, int64_t *newPosition) { - return - (0 == fseek(_handle, offset, whence)) && - ((newPosition == NULL) || (0 <= (*newPosition = (int64_t)ftell(_handle)))); - } -#endif }//namespace }//namespace diff --git a/Code/Mantid/Framework/DataHandling/src/LoadEventNexus.cpp b/Code/Mantid/Framework/DataHandling/src/LoadEventNexus.cpp index ef501b221f70..25219a7d8de0 100644 --- a/Code/Mantid/Framework/DataHandling/src/LoadEventNexus.cpp +++ b/Code/Mantid/Framework/DataHandling/src/LoadEventNexus.cpp @@ -30,2016 +30,2100 @@ using namespace ::NeXus; namespace Mantid { -namespace DataHandling -{ + namespace DataHandling + { - DECLARE_NEXUS_FILELOADER_ALGORITHM(LoadEventNexus) + DECLARE_NEXUS_FILELOADER_ALGORITHM(LoadEventNexus) - using namespace Kernel; - using namespace Geometry; - using namespace API; - using namespace DataObjects; + using namespace Kernel; + using namespace Geometry; + using namespace API; + using namespace DataObjects; - //=============================================================================================== - // BankPulseTimes - //=============================================================================================== + //=============================================================================================== + // BankPulseTimes + //=============================================================================================== - //---------------------------------------------------------------------------------------------- - /** Constructor. Loads the pulse times from the bank entry of the file - * - * @param file :: nexus file open in the right bank entry - */ - BankPulseTimes::BankPulseTimes(::NeXus::File & file) - { - file.openData("event_time_zero"); - // Read the offset (time zero) - file.getAttr("offset", startTime); - DateAndTime start(startTime); - // Load the seconds offsets - std::vector seconds; - file.getData(seconds); - file.closeData(); - // Now create the pulseTimes - numPulses = seconds.size(); - if (numPulses == 0) - throw std::runtime_error("event_time_zero field has no data!"); - pulseTimes = new DateAndTime[numPulses]; - for (size_t i=0; i & times) - { - numPulses = times.size(); - pulseTimes = NULL; - if (numPulses == 0) - return; - pulseTimes = new DateAndTime[numPulses]; - for (size_t i=0; ipulseTimes; - } - - //---------------------------------------------------------------------------------------------- - /** Comparison. Is this bank's pulse times array the same as another one. - * - * @param otherNumPulse :: number of pulses in the OTHER bank event_time_zero. - * @param otherStartTime :: "offset" attribute of the OTHER bank event_time_zero. - * @return true if the pulse times are the same and so don't need to be reloaded. - */ - bool BankPulseTimes::equals(size_t otherNumPulse, std::string otherStartTime) - { - return ((this->startTime == otherStartTime) && (this->numPulses == otherNumPulse)); - } - - //============================================================================================== - // Class ProcessBankData - //============================================================================================== - /** This task does the disk IO from loading the NXS file, - * and so will be on a disk IO mutex */ - class ProcessBankData : public Task - { - public: //---------------------------------------------------------------------------------------------- - /** Constructor - * - * @param alg :: LoadEventNexus - * @param entry_name :: name of the bank - * @param prog :: Progress reporter - * @param scheduler :: ThreadScheduler running this task - * @param event_id :: array with event IDs - * @param event_time_of_flight :: array with event TOFS - * @param numEvents :: how many events in the arrays - * @param startAt :: index of the first event from event_index - * @param event_index :: vector of event index (length of # of pulses) - * @param thisBankPulseTimes :: ptr to the pulse times for this particular bank. - * @param have_weight :: flag for handling simulated files - * @param event_weight :: array with weights for events - * @param min_event_id ;: minimum detector ID to load - * @param max_event_id :: maximum detector ID to load - * @return - */ - ProcessBankData(LoadEventNexus * alg, std::string entry_name, - Progress * prog, ThreadScheduler * scheduler, - boost::shared_array event_id, - boost::shared_array event_time_of_flight, - size_t numEvents, size_t startAt, - boost::shared_ptr > event_index, - boost::shared_ptr thisBankPulseTimes, - bool have_weight, boost::shared_array event_weight, - detid_t min_event_id, detid_t max_event_id) - : Task(), alg(alg), entry_name(entry_name), pixelID_to_wi_vector(alg->pixelID_to_wi_vector), - pixelID_to_wi_offset(alg->pixelID_to_wi_offset), - prog(prog), scheduler(scheduler), - event_id(event_id), event_time_of_flight(event_time_of_flight), numEvents(numEvents), startAt(startAt), - event_index(event_index), - thisBankPulseTimes(thisBankPulseTimes), have_weight(have_weight), - event_weight(event_weight), m_min_id(min_event_id), m_max_id(max_event_id) + /** Constructor. Loads the pulse times from the bank entry of the file + * + * @param file :: nexus file open in the right bank entry + */ + BankPulseTimes::BankPulseTimes(::NeXus::File & file) + { + file.openData("event_time_zero"); + // Read the offset (time zero) + file.getAttr("offset", startTime); + DateAndTime start(startTime); + // Load the seconds offsets + std::vector seconds; + file.getData(seconds); + file.closeData(); + // Now create the pulseTimes + numPulses = seconds.size(); + if (numPulses == 0) + throw std::runtime_error("event_time_zero field has no data!"); + pulseTimes = new DateAndTime[numPulses]; + for (size_t i=0; i & times) { - // Cost is approximately proportional to the number of events to process. - m_cost = static_cast(numEvents); + numPulses = times.size(); + pulseTimes = NULL; + if (numPulses == 0) + return; + pulseTimes = new DateAndTime[numPulses]; + for (size_t i=0; i(std::numeric_limits::max()) * 0.1; - double my_longest_tof = 0.; - // A count of "bad" TOFs that were too high - size_t badTofs = 0; - size_t my_discarded_events(0); + delete [] this->pulseTimes; + } - prog->report(entry_name + ": precount"); + //---------------------------------------------------------------------------------------------- + /** Comparison. Is this bank's pulse times array the same as another one. + * + * @param otherNumPulse :: number of pulses in the OTHER bank event_time_zero. + * @param otherStartTime :: "offset" attribute of the OTHER bank event_time_zero. + * @return true if the pulse times are the same and so don't need to be reloaded. + */ + bool BankPulseTimes::equals(size_t otherNumPulse, std::string otherStartTime) + { + return ((this->startTime == otherStartTime) && (this->numPulses == otherNumPulse)); + } - // ---- Pre-counting events per pixel ID ---- - auto & outputWS = *(alg->WS); + //============================================================================================== + // Class ProcessBankData + //============================================================================================== + /** This task does the disk IO from loading the NXS file, + * and so will be on a disk IO mutex */ + class ProcessBankData : public Task + { + public: + //---------------------------------------------------------------------------------------------- + /** Constructor + * + * @param alg :: LoadEventNexus + * @param entry_name :: name of the bank + * @param prog :: Progress reporter + * @param scheduler :: ThreadScheduler running this task + * @param event_id :: array with event IDs + * @param event_time_of_flight :: array with event TOFS + * @param numEvents :: how many events in the arrays + * @param startAt :: index of the first event from event_index + * @param event_index :: vector of event index (length of # of pulses) + * @param thisBankPulseTimes :: ptr to the pulse times for this particular bank. + * @param have_weight :: flag for handling simulated files + * @param event_weight :: array with weights for events + * @param min_event_id ;: minimum detector ID to load + * @param max_event_id :: maximum detector ID to load + * @return + */ + ProcessBankData(LoadEventNexus * alg, std::string entry_name, + Progress * prog, ThreadScheduler * scheduler, + boost::shared_array event_id, + boost::shared_array event_time_of_flight, + size_t numEvents, size_t startAt, + boost::shared_ptr > event_index, + boost::shared_ptr thisBankPulseTimes, + bool have_weight, boost::shared_array event_weight, + detid_t min_event_id, detid_t max_event_id) + : Task(), alg(alg), entry_name(entry_name), pixelID_to_wi_vector(alg->pixelID_to_wi_vector), + pixelID_to_wi_offset(alg->pixelID_to_wi_offset), + prog(prog), scheduler(scheduler), + event_id(event_id), event_time_of_flight(event_time_of_flight), numEvents(numEvents), startAt(startAt), + event_index(event_index), + thisBankPulseTimes(thisBankPulseTimes), have_weight(have_weight), + event_weight(event_weight), m_min_id(min_event_id), m_max_id(max_event_id) + { + // Cost is approximately proportional to the number of events to process. + m_cost = static_cast(numEvents); + } - if (alg->precount) + //---------------------------------------------------------------------------------------------- + /** Run the data processing + */ + void run() { - std::vector counts(m_max_id-m_min_id+1, 0); - for (size_t i=0; i < numEvents; i++) + //Local tof limits + double my_shortest_tof = static_cast(std::numeric_limits::max()) * 0.1; + double my_longest_tof = 0.; + // A count of "bad" TOFs that were too high + size_t badTofs = 0; + size_t my_discarded_events(0); + + prog->report(entry_name + ": precount"); + + // ---- Pre-counting events per pixel ID ---- + auto & outputWS = *(alg->WS); + if (alg->precount) { - detid_t thisId = detid_t(event_id[i]); - if (thisId >= m_min_id && thisId <= m_max_id) - counts[thisId-m_min_id]++; - } - // Now we pre-allocate (reserve) the vectors of events in each pixel counted - const size_t numEventLists = outputWS.getNumberHistograms(); - for (detid_t pixID = m_min_id; pixID <= m_max_id; pixID++) - { - if (counts[pixID-m_min_id] > 0) + if ( alg->m_specMin !=EMPTY_INT() && alg->m_specMax !=EMPTY_INT() ) + { + m_min_id = alg->m_specMin; + m_max_id = alg->m_specMax; + } + + std::vector counts(m_max_id-m_min_id+1, 0); + for (size_t i=0; i < numEvents; i++) + { + detid_t thisId = detid_t(event_id[i]); + if (thisId >= m_min_id && thisId <= m_max_id) + counts[thisId-m_min_id]++; + } + + // Now we pre-allocate (reserve) the vectors of events in each pixel counted + const size_t numEventLists = outputWS.getNumberHistograms(); + for (detid_t pixID = m_min_id; pixID <= m_max_id; pixID++) { - //Find the the workspace index corresponding to that pixel ID - size_t wi = pixelID_to_wi_vector[pixID+pixelID_to_wi_offset]; - // Allocate it - if ( wi < numEventLists ) + if (counts[pixID-m_min_id] > 0) { - outputWS.getEventList(wi).reserve( counts[pixID-m_min_id] ); + //Find the the workspace index corresponding to that pixel ID + size_t wi = pixelID_to_wi_vector[pixID+pixelID_to_wi_offset]; + // Allocate it + if ( wi < numEventLists ) + { + outputWS.getEventList(wi).reserve( counts[pixID-m_min_id] ); + } + if (alg->getCancel()) break; // User cancellation } - if (alg->getCancel()) break; // User cancellation } } - } - // Check for cancelled algorithm - if (alg->getCancel()) - { - return; - } + // Check for canceled algorithm + if (alg->getCancel()) + { + return; + } - //Default pulse time (if none are found) - Mantid::Kernel::DateAndTime pulsetime; - Mantid::Kernel::DateAndTime lastpulsetime(0); + //Default pulse time (if none are found) + Mantid::Kernel::DateAndTime pulsetime; + Mantid::Kernel::DateAndTime lastpulsetime(0); - bool pulsetimesincreasing = true; + bool pulsetimesincreasing = true; - // Index into the pulse array - int pulse_i = 0; + // Index into the pulse array + int pulse_i = 0; - // And there are this many pulses - int numPulses = static_cast(thisBankPulseTimes->numPulses); - if (numPulses > static_cast(event_index->size())) - { - alg->getLogger().warning() << "Entry " << entry_name << "'s event_index vector is smaller than the event_time_zero field. This is inconsistent, so we cannot find pulse times for this entry.\n"; - //This'll make the code skip looking for any pulse times. - pulse_i = numPulses + 1; - } + // And there are this many pulses + int numPulses = static_cast(thisBankPulseTimes->numPulses); + if (numPulses > static_cast(event_index->size())) + { + alg->getLogger().warning() << "Entry " << entry_name << "'s event_index vector is smaller than the event_time_zero field. This is inconsistent, so we cannot find pulse times for this entry.\n"; + //This'll make the code skip looking for any pulse times. + pulse_i = numPulses + 1; + } - prog->report(entry_name + ": filling events"); + prog->report(entry_name + ": filling events"); - // Will we need to compress? - bool compress = (alg->compressTolerance >= 0); + // Will we need to compress? + bool compress = (alg->compressTolerance >= 0); - // Which detector IDs were touched? - only matters if compress is on - std::vector usedDetIds; - if (compress) usedDetIds.assign(m_max_id-m_min_id+1, false); + // Which detector IDs were touched? - only matters if compress is on + std::vector usedDetIds; + if (compress) usedDetIds.assign(m_max_id-m_min_id+1, false); - //Go through all events in the list - for (std::size_t i = 0; i < numEvents; i++) - { - //------ Find the pulse time for this event index --------- - if (pulse_i < numPulses-1) + //Go through all events in the list + for (std::size_t i = 0; i < numEvents; i++) { - bool breakOut = false; - //Go through event_index until you find where the index increases to encompass the current index. Your pulse = the one before. - while ( (i+startAt < event_index->operator[](pulse_i)) - || (i+startAt >= event_index->operator[](pulse_i+1)) ) + //------ Find the pulse time for this event index --------- + if (pulse_i < numPulses-1) { - pulse_i++; - // Check once every new pulse if you need to cancel (checking on every event might slow things down more) - if (alg->getCancel()) breakOut = true; - if (pulse_i >= (numPulses-1)) - break; - } + bool breakOut = false; + //Go through event_index until you find where the index increases to encompass the current index. Your pulse = the one before. + while ( (i+startAt < event_index->operator[](pulse_i)) + || (i+startAt >= event_index->operator[](pulse_i+1)) ) + { + pulse_i++; + // Check once every new pulse if you need to cancel (checking on every event might slow things down more) + if (alg->getCancel()) breakOut = true; + if (pulse_i >= (numPulses-1)) + break; + } - //Save the pulse time at this index for creating those events - pulsetime = thisBankPulseTimes->pulseTimes[pulse_i]; + //Save the pulse time at this index for creating those events + pulsetime = thisBankPulseTimes->pulseTimes[pulse_i]; - // Determine if pulse times continue to increase - if (pulsetime < lastpulsetime) - pulsetimesincreasing = false; - else - lastpulsetime = pulsetime; + // Determine if pulse times continue to increase + if (pulsetime < lastpulsetime) + pulsetimesincreasing = false; + else + lastpulsetime = pulsetime; - // Flag to break out of the event loop without using goto - if (breakOut) - break; - } + // Flag to break out of the event loop without using goto + if (breakOut) + break; + } - // We cached a pointer to the vector -> so retrieve it and add the event - detid_t detId = event_id[i]; - if (detId >= m_min_id && detId <= m_max_id) - { - //Create the tofevent - double tof = static_cast( event_time_of_flight[i] ); - if ((tof >= alg->filter_tof_min) && (tof <= alg->filter_tof_max)) + // We cached a pointer to the vector -> so retrieve it and add the event + detid_t detId = event_id[i]; + if (detId >= m_min_id && detId <= m_max_id) { - // Handle simulated data if present - if (have_weight) + //Create the tofevent + double tof = static_cast( event_time_of_flight[i] ); + if ((tof >= alg->filter_tof_min) && (tof <= alg->filter_tof_max)) { - double weight = static_cast(event_weight[i]); - double errorSq = weight * weight; - std::vector *eventVector = alg->weightedEventVectors[detId]; - // NULL eventVector indicates a bad spectrum lookup - if(eventVector) + // Handle simulated data if present + if (have_weight) { + double weight = static_cast(event_weight[i]); + double errorSq = weight * weight; + std::vector *eventVector = alg->weightedEventVectors[detId]; + // NULL eventVector indicates a bad spectrum lookup + if(eventVector) + { #if !(defined(__INTEL_COMPILER)) && !(defined(__clang__)) - // This avoids a copy constructor call but is only available with GCC (requires variadic templates) - eventVector->emplace_back( tof, pulsetime, weight, errorSq ); + // This avoids a copy constructor call but is only available with GCC (requires variadic templates) + eventVector->emplace_back( tof, pulsetime, weight, errorSq ); #else - eventVector->push_back( WeightedEvent(tof, pulsetime, weight, errorSq) ); + eventVector->push_back( WeightedEvent(tof, pulsetime, weight, errorSq) ); #endif + } + else + { + ++my_discarded_events; + } } else { - ++my_discarded_events; - } - } - else - { - // We have cached the vector of events for this detector ID - std::vector *eventVector = alg->eventVectors[detId]; - // NULL eventVector indicates a bad spectrum lookup - if(eventVector) - { + // We have cached the vector of events for this detector ID + std::vector *eventVector = alg->eventVectors[detId]; + // NULL eventVector indicates a bad spectrum lookup + if(eventVector) + { #if !(defined(__INTEL_COMPILER)) && !(defined(__clang__)) - // This avoids a copy constructor call but is only available with GCC (requires variadic templates) - eventVector->emplace_back( tof, pulsetime ); + // This avoids a copy constructor call but is only available with GCC (requires variadic templates) + eventVector->emplace_back( tof, pulsetime ); #else - eventVector->push_back( TofEvent(tof, pulsetime) ); + eventVector->push_back( TofEvent(tof, pulsetime) ); #endif + } + else + { + ++my_discarded_events; + } } - else + + //Local tof limits + if (tof < my_shortest_tof) { my_shortest_tof = tof;} + // Skip any events that are the cause of bad DAS data (e.g. a negative number in uint32 -> 2.4 billion * 100 nanosec = 2.4e8 microsec) + if (tof < 2e8) { - ++my_discarded_events; + if (tof > my_longest_tof) { my_longest_tof = tof;} } - } - - //Local tof limits - if (tof < my_shortest_tof) { my_shortest_tof = tof;} - // Skip any events that are the cause of bad DAS data (e.g. a negative number in uint32 -> 2.4 billion * 100 nanosec = 2.4e8 microsec) - if (tof < 2e8) - { - if (tof > my_longest_tof) { my_longest_tof = tof;} - } - else - badTofs++; + else + badTofs++; - // Track all the touched wi (only necessary when compressing events, for thread safety) - if (compress) usedDetIds[detId-m_min_id] = true; - } // valid time-of-flight + // Track all the touched wi (only necessary when compressing events, for thread safety) + if (compress) usedDetIds[detId-m_min_id] = true; + } // valid time-of-flight - } // valid detector IDs - } //(for each event) + } // valid detector IDs + } //(for each event) - //------------ Compress Events (or set sort order) ------------------ - // Do it on all the detector IDs we touched - if (compress) - { - for (detid_t pixID = m_min_id; pixID <= m_max_id; pixID++) + //------------ Compress Events (or set sort order) ------------------ + // Do it on all the detector IDs we touched + if (compress) { - if (usedDetIds[pixID-m_min_id]) + for (detid_t pixID = m_min_id; pixID <= m_max_id; pixID++) { - //Find the the workspace index corresponding to that pixel ID - size_t wi = pixelID_to_wi_vector[pixID+pixelID_to_wi_offset]; - EventList * el = outputWS.getEventListPtr(wi); - if (compress) - el->compressEvents(alg->compressTolerance, el); - else + if (usedDetIds[pixID-m_min_id]) { - if (pulsetimesincreasing) - el->setSortOrder(DataObjects::PULSETIME_SORT); + //Find the the workspace index corresponding to that pixel ID + size_t wi = pixelID_to_wi_vector[pixID+pixelID_to_wi_offset]; + EventList * el = outputWS.getEventListPtr(wi); + if (compress) + el->compressEvents(alg->compressTolerance, el); else - el->setSortOrder(DataObjects::UNSORTED); + { + if (pulsetimesincreasing) + el->setSortOrder(DataObjects::PULSETIME_SORT); + else + el->setSortOrder(DataObjects::UNSORTED); + } } } } - } - prog->report(entry_name + ": filled events"); + prog->report(entry_name + ": filled events"); - alg->getLogger().debug() << entry_name << (pulsetimesincreasing ? " had " : " DID NOT have ") << - "monotonically increasing pulse times" << std::endl; + alg->getLogger().debug() << entry_name << (pulsetimesincreasing ? " had " : " DID NOT have ") << + "monotonically increasing pulse times" << std::endl; - //Join back up the tof limits to the global ones - PARALLEL_CRITICAL(tof_limits) - { + //Join back up the tof limits to the global ones //This is not thread safe, so only one thread at a time runs this. - if (my_shortest_tof < alg->shortest_tof) { alg->shortest_tof = my_shortest_tof;} - if (my_longest_tof > alg->longest_tof ) { alg->longest_tof = my_longest_tof;} - alg->bad_tofs += badTofs; - alg->discarded_events += my_discarded_events; - } - - - // For Linux with tcmalloc, make sure memory goes back; - // but don't call if more than 15% of memory is still available, since that slows down the loading. - MemoryManager::Instance().releaseFreeMemoryIfAbove(0.85); + { + Poco::FastMutex::ScopedLock _lock(alg->m_tofMutex); + if (my_shortest_tof < alg->shortest_tof) { alg->shortest_tof = my_shortest_tof;} + if (my_longest_tof > alg->longest_tof ) { alg->longest_tof = my_longest_tof;} + alg->bad_tofs += badTofs; + alg->discarded_events += my_discarded_events; + } + + // For Linux with tcmalloc, make sure memory goes back; + // but don't call if more than 15% of memory is still available, since that slows down the loading. + MemoryManager::Instance().releaseFreeMemoryIfAbove(0.85); #ifndef _WIN32 - alg->getLogger().debug() << "Time to process " << entry_name << " " << m_timer << "\n"; + alg->getLogger().debug() << "Time to process " << entry_name << " " << m_timer << "\n"; #endif - } + } - private: - /// Algorithm being run - LoadEventNexus * alg; - /// NXS path to bank - std::string entry_name; - /// Vector where (index = pixel ID+pixelID_to_wi_offset), value = workspace index) - const std::vector & pixelID_to_wi_vector; - /// Offset in the pixelID_to_wi_vector to use. - detid_t pixelID_to_wi_offset; - /// Progress reporting - Progress * prog; - /// ThreadScheduler running this task - ThreadScheduler * scheduler; - /// event pixel ID array - boost::shared_array event_id; - /// event TOF array - boost::shared_array event_time_of_flight; - /// # of events in arrays - size_t numEvents; - /// index of the first event from event_index - size_t startAt; - /// vector of event index (length of # of pulses) - boost::shared_ptr > event_index; - /// Pulse times for this bank - boost::shared_ptr thisBankPulseTimes; - /// Flag for simulated data - bool have_weight; - /// event weights array - boost::shared_array event_weight; - /// Minimum pixel id - detid_t m_min_id; - /// Maximum pixel id - detid_t m_max_id; - /// timer for performance - Mantid::Kernel::Timer m_timer; - }; // END-DEF-CLASS ProcessBankData - - - //============================================================================================== - // Class LoadBankFromDiskTask - //============================================================================================== - /** This task does the disk IO from loading the NXS file, - * and so will be on a disk IO mutex */ - class LoadBankFromDiskTask : public Task - { + private: + /// Algorithm being run + LoadEventNexus * alg; + /// NXS path to bank + std::string entry_name; + /// Vector where (index = pixel ID+pixelID_to_wi_offset), value = workspace index) + const std::vector & pixelID_to_wi_vector; + /// Offset in the pixelID_to_wi_vector to use. + detid_t pixelID_to_wi_offset; + /// Progress reporting + Progress * prog; + /// ThreadScheduler running this task + ThreadScheduler * scheduler; + /// event pixel ID array + boost::shared_array event_id; + /// event TOF array + boost::shared_array event_time_of_flight; + /// # of events in arrays + size_t numEvents; + /// index of the first event from event_index + size_t startAt; + /// vector of event index (length of # of pulses) + boost::shared_ptr > event_index; + /// Pulse times for this bank + boost::shared_ptr thisBankPulseTimes; + /// Flag for simulated data + bool have_weight; + /// event weights array + boost::shared_array event_weight; + /// Minimum pixel id + detid_t m_min_id; + /// Maximum pixel id + detid_t m_max_id; + /// timer for performance + Mantid::Kernel::Timer m_timer; + }; // END-DEF-CLASS ProcessBankData + + + //============================================================================================== + // Class LoadBankFromDiskTask + //============================================================================================== + /** This task does the disk IO from loading the NXS file, + * and so will be on a disk IO mutex */ + class LoadBankFromDiskTask : public Task + { - public: - //--------------------------------------------------------------------------------------------------- - /** Constructor - * - * @param alg :: Handle to the main algorithm - * @param entry_name :: The pathname of the bank to load - * @param entry_type :: The classtype of the entry to load - * @param numEvents :: The number of events in the bank. - * @param oldNeXusFileNames :: Identify if file is of old variety. - * @param prog :: an optional Progress object - * @param ioMutex :: a mutex shared for all Disk I-O tasks - * @param scheduler :: the ThreadScheduler that runs this task. - */ - LoadBankFromDiskTask(LoadEventNexus * alg, const std::string& entry_name, const std::string & entry_type, - const std::size_t numEvents, const bool oldNeXusFileNames, - Progress * prog, boost::shared_ptr ioMutex, ThreadScheduler * scheduler) - : Task(), + public: + //--------------------------------------------------------------------------------------------------- + /** Constructor + * + * @param alg :: Handle to the main algorithm + * @param entry_name :: The pathname of the bank to load + * @param entry_type :: The classtype of the entry to load + * @param numEvents :: The number of events in the bank. + * @param oldNeXusFileNames :: Identify if file is of old variety. + * @param prog :: an optional Progress object + * @param ioMutex :: a mutex shared for all Disk I-O tasks + * @param scheduler :: the ThreadScheduler that runs this task. + */ + LoadBankFromDiskTask(LoadEventNexus * alg, const std::string& entry_name, const std::string & entry_type, + const std::size_t numEvents, const bool oldNeXusFileNames, + Progress * prog, boost::shared_ptr ioMutex, ThreadScheduler * scheduler) + : Task(), alg(alg), entry_name(entry_name), entry_type(entry_type), pixelID_to_wi_vector(alg->pixelID_to_wi_vector), pixelID_to_wi_offset(alg->pixelID_to_wi_offset), // prog(prog), scheduler(scheduler), thisBankPulseTimes(NULL), m_loadError(false), prog(prog), scheduler(scheduler), m_loadError(false), m_oldNexusFileNames(oldNeXusFileNames), m_loadStart(), m_loadSize(), m_event_id(NULL), m_event_time_of_flight(NULL), m_have_weight(false), m_event_weight(NULL) - { - setMutex(ioMutex); - m_cost = static_cast(numEvents); - m_min_id = std::numeric_limits::max(); - m_max_id = 0; - } - - //--------------------------------------------------------------------------------------------------- - /** Load the pulse times, if needed. This sets - * thisBankPulseTimes to the right pointer. - * */ - void loadPulseTimes(::NeXus::File & file) - { - try { - // First, get info about the event_time_zero field in this bank - file.openData("event_time_zero"); + setMutex(ioMutex); + m_cost = static_cast(numEvents); + m_min_id = std::numeric_limits::max(); + m_max_id = 0; } - catch (::NeXus::Exception&) - { - // Field not found error is most likely. - // Use the "proton_charge" das logs. - thisBankPulseTimes = alg->m_allBanksPulseTimes; - return; - } - std::string thisStartTime = ""; - size_t thisNumPulses = 0; - file.getAttr("offset", thisStartTime); - if (file.getInfo().dims.size() > 0) - thisNumPulses = file.getInfo().dims[0]; - file.closeData(); - // Now, we look through existing ones to see if it is already loaded - // thisBankPulseTimes = NULL; - for (size_t i=0; im_bankPulseTimes.size(); i++) + //--------------------------------------------------------------------------------------------------- + /** Load the pulse times, if needed. This sets + * thisBankPulseTimes to the right pointer. + * */ + void loadPulseTimes(::NeXus::File & file) { - if (alg->m_bankPulseTimes[i]->equals(thisNumPulses, thisStartTime)) + try { - thisBankPulseTimes = alg->m_bankPulseTimes[i]; + // First, get info about the event_time_zero field in this bank + file.openData("event_time_zero"); + } + catch (::NeXus::Exception&) + { + // Field not found error is most likely. + // Use the "proton_charge" das logs. + thisBankPulseTimes = alg->m_allBanksPulseTimes; return; } - } + std::string thisStartTime = ""; + size_t thisNumPulses = 0; + file.getAttr("offset", thisStartTime); + if (file.getInfo().dims.size() > 0) + thisNumPulses = file.getInfo().dims[0]; + file.closeData(); - // Not found? Need to load and add it - thisBankPulseTimes = boost::make_shared(boost::ref(file)); - alg->m_bankPulseTimes.push_back(thisBankPulseTimes); - } + // Now, we look through existing ones to see if it is already loaded + // thisBankPulseTimes = NULL; + for (size_t i=0; im_bankPulseTimes.size(); i++) + { + if (alg->m_bankPulseTimes[i]->equals(thisNumPulses, thisStartTime)) + { + thisBankPulseTimes = alg->m_bankPulseTimes[i]; + return; + } + } + // Not found? Need to load and add it + thisBankPulseTimes = boost::make_shared(boost::ref(file)); + alg->m_bankPulseTimes.push_back(thisBankPulseTimes); + } - //--------------------------------------------------------------------------------------------------- - /** Load the event_index field - (a list of size of # of pulses giving the index in the event list for that pulse) - * @param file :: File handle for the NeXus file - * @param event_index :: ref to the vector - */ - void loadEventIndex(::NeXus::File & file, std::vector & event_index) - { - // Get the event_index (a list of size of # of pulses giving the index in the event list for that pulse) - file.openData("event_index"); - //Must be uint64 - if (file.getInfo().type == ::NeXus::UINT64) - file.getData(event_index); - else - { - alg->getLogger().warning() << "Entry " << entry_name << "'s event_index field is not UINT64! It will be skipped.\n"; - m_loadError = true; - } - file.closeData(); + //--------------------------------------------------------------------------------------------------- + /** Load the event_index field + (a list of size of # of pulses giving the index in the event list for that pulse) - // Look for the sign that the bank is empty - if (event_index.size()==1) + * @param file :: File handle for the NeXus file + * @param event_index :: ref to the vector + */ + void loadEventIndex(::NeXus::File & file, std::vector & event_index) { - if (event_index[0] == 0) + // Get the event_index (a list of size of # of pulses giving the index in the event list for that pulse) + file.openData("event_index"); + //Must be uint64 + if (file.getInfo().type == ::NeXus::UINT64) + file.getData(event_index); + else { - //One entry, only zero. This means NO events in this bank. + alg->getLogger().warning() << "Entry " << entry_name << "'s event_index field is not UINT64! It will be skipped.\n"; m_loadError = true; - alg->getLogger().debug() << "Bank " << entry_name << " is empty.\n"; } - } - - return; - } + file.closeData(); + // Look for the sign that the bank is empty + if (event_index.size()==1) + { + if (event_index[0] == 0) + { + //One entry, only zero. This means NO events in this bank. + m_loadError = true; + alg->getLogger().debug() << "Bank " << entry_name << " is empty.\n"; + } + } - //--------------------------------------------------------------------------------------------------- - /** Open the event_id field and validate the contents - * - * @param file :: File handle for the NeXus file - * @param start_event :: set to the index of the first event - * @param stop_event :: set to the index of the last event + 1 - * @param event_index :: (a list of size of # of pulses giving the index in the event list for that pulse) - */ - void prepareEventId(::NeXus::File & file, size_t & start_event, size_t & stop_event, std::vector & event_index) - { - // Get the list of pixel ID's - if (m_oldNexusFileNames) - file.openData("event_pixel_id"); - else - file.openData("event_id"); + return; + } - // By default, use all available indices - start_event = 0; - ::NeXus::Info id_info = file.getInfo(); - // dims[0] can be negative in ISIS meaning 2^32 + dims[0]. Take that into account - int64_t dim0 = recalculateDataSize(id_info.dims[0]); - stop_event = static_cast(dim0); - //Handle the time filtering by changing the start/end offsets. - for (size_t i=0; i < thisBankPulseTimes->numPulses; i++) + //--------------------------------------------------------------------------------------------------- + /** Open the event_id field and validate the contents + * + * @param file :: File handle for the NeXus file + * @param start_event :: set to the index of the first event + * @param stop_event :: set to the index of the last event + 1 + * @param event_index :: (a list of size of # of pulses giving the index in the event list for that pulse) + */ + void prepareEventId(::NeXus::File & file, size_t & start_event, size_t & stop_event, std::vector & event_index) { - if (thisBankPulseTimes->pulseTimes[i] >= alg->filter_time_start) + // Get the list of pixel ID's + if (m_oldNexusFileNames) + file.openData("event_pixel_id"); + else + file.openData("event_id"); + + // By default, use all available indices + start_event = 0; + ::NeXus::Info id_info = file.getInfo(); + // dims[0] can be negative in ISIS meaning 2^32 + dims[0]. Take that into account + int64_t dim0 = recalculateDataSize(id_info.dims[0]); + stop_event = static_cast(dim0); + + //Handle the time filtering by changing the start/end offsets. + for (size_t i=0; i < thisBankPulseTimes->numPulses; i++) { - start_event = event_index[i]; - break; // stop looking + if (thisBankPulseTimes->pulseTimes[i] >= alg->filter_time_start) + { + start_event = event_index[i]; + break; // stop looking + } } - } - if (start_event > static_cast(dim0)) - { - // If the frame indexes are bad then we can't construct the times of the events properly and filtering by time - // will not work on this data - alg->getLogger().warning() + if (start_event > static_cast(dim0)) + { + // If the frame indexes are bad then we can't construct the times of the events properly and filtering by time + // will not work on this data + alg->getLogger().warning() << this->entry_name << "'s field 'event_index' seems to be invalid (start_index > than the number of events in the bank)." << "All events will appear in the same frame and filtering by time will not be possible on this data.\n"; - start_event = 0; - stop_event = static_cast(dim0); - } - else - { - for (size_t i=0; i < thisBankPulseTimes->numPulses; i++) + start_event = 0; + stop_event = static_cast(dim0); + } + else { - if (thisBankPulseTimes->pulseTimes[i] > alg->filter_time_stop) + for (size_t i=0; i < thisBankPulseTimes->numPulses; i++) { - stop_event = event_index[i]; - break; + if (thisBankPulseTimes->pulseTimes[i] > alg->filter_time_stop) + { + stop_event = event_index[i]; + break; + } } } - } - // We are loading part - work out the event number range - if (alg->chunk != EMPTY_INT()) - { - start_event = (alg->chunk - alg->firstChunkForBank) * alg->eventsPerChunk; - // Don't change stop_event for the final chunk - if ( start_event + alg->eventsPerChunk < stop_event ) stop_event = start_event + alg->eventsPerChunk; - } + // We are loading part - work out the event number range + if (alg->chunk != EMPTY_INT()) + { + start_event = (alg->chunk - alg->firstChunkForBank) * alg->eventsPerChunk; + // Don't change stop_event for the final chunk + if ( start_event + alg->eventsPerChunk < stop_event ) stop_event = start_event + alg->eventsPerChunk; + } - // Make sure it is within range - if (stop_event > static_cast(dim0)) - stop_event = dim0; + // Make sure it is within range + if (stop_event > static_cast(dim0)) + stop_event = dim0; - alg->getLogger().debug() << entry_name << ": start_event " << start_event << " stop_event "<< stop_event << "\n"; + alg->getLogger().debug() << entry_name << ": start_event " << start_event << " stop_event "<< stop_event << "\n"; - return; - } + return; + } - //--------------------------------------------------------------------------------------------------- - /** Load the event_id field, which has been open + //--------------------------------------------------------------------------------------------------- + /** Load the event_id field, which has been open */ - void loadEventId(::NeXus::File & file) - { - // This is the data size - ::NeXus::Info id_info = file.getInfo(); - int64_t dim0 = recalculateDataSize(id_info.dims[0]); + void loadEventId(::NeXus::File & file) + { + // This is the data size + ::NeXus::Info id_info = file.getInfo(); + int64_t dim0 = recalculateDataSize(id_info.dims[0]); - // Now we allocate the required arrays - m_event_id = new uint32_t[m_loadSize[0]]; + // Now we allocate the required arrays + m_event_id = new uint32_t[m_loadSize[0]]; - // Check that the required space is there in the file. - if (dim0 < m_loadSize[0]+m_loadStart[0]) - { - alg->getLogger().warning() << "Entry " << entry_name << "'s event_id field is too small (" << dim0 - << ") to load the desired data size (" << m_loadSize[0]+m_loadStart[0] << ").\n"; - m_loadError = true; - } + // Check that the required space is there in the file. + if (dim0 < m_loadSize[0]+m_loadStart[0]) + { + alg->getLogger().warning() << "Entry " << entry_name << "'s event_id field is too small (" << dim0 + << ") to load the desired data size (" << m_loadSize[0]+m_loadStart[0] << ").\n"; + m_loadError = true; + } - if (alg->getCancel()) m_loadError = true; //To allow cancelling the algorithm + if (alg->getCancel()) m_loadError = true; //To allow cancelling the algorithm - if (!m_loadError) - { - //Must be uint32 - if (id_info.type == ::NeXus::UINT32) - file.getSlab(m_event_id, m_loadStart, m_loadSize); - else - { - alg->getLogger().warning() << "Entry " << entry_name << "'s event_id field is not UINT32! It will be skipped.\n"; - m_loadError = true; - } - file.closeData(); + if (!m_loadError) + { + //Must be uint32 + if (id_info.type == ::NeXus::UINT32) + file.getSlab(m_event_id, m_loadStart, m_loadSize); + else + { + alg->getLogger().warning() << "Entry " << entry_name << "'s event_id field is not UINT32! It will be skipped.\n"; + m_loadError = true; + } + file.closeData(); - // determine the range of pixel ids - uint32_t temp; - for (auto i = 0; i < m_loadSize[0]; ++i) - { - temp = m_event_id[i]; - if (temp < m_min_id) m_min_id = temp; - if (temp > m_max_id) m_max_id = temp; + // determine the range of pixel ids + uint32_t temp; + for (auto i = 0; i < m_loadSize[0]; ++i) + { + temp = m_event_id[i]; + if (temp < m_min_id) m_min_id = temp; + if (temp > m_max_id) m_max_id = temp; + } + + if ( m_min_id > static_cast(alg->eventid_max) ) + { + // All the detector IDs in the bank are higher than the highest 'known' (from the IDF) + // ID. Setting this will abort the loading of the bank. + m_loadError = true; + } + // fixup the maximum pixel id in the case that it's higher than the highest 'known' id + if (m_max_id > static_cast(alg->eventid_max)) m_max_id = static_cast(alg->eventid_max); + } + + return; } - if ( m_min_id > static_cast(alg->eventid_max) ) + //--------------------------------------------------------------------------------------------------- + /** Open and load the times-of-flight data + */ + void loadTof(::NeXus::File & file) { - // All the detector IDs in the bank are higher than the highest 'known' (from the IDF) - // ID. Setting this will abort the loading of the bank. - m_loadError = true; - } - // fixup the maximum pixel id in the case that it's higher than the highest 'known' id - if (m_max_id > static_cast(alg->eventid_max)) m_max_id = static_cast(alg->eventid_max); - } + // Allocate the array + float* temp = new float[m_loadSize[0]]; + delete [] m_event_time_of_flight; + m_event_time_of_flight = temp; + + // Get the list of event_time_of_flight's + if (!m_oldNexusFileNames) + file.openData("event_time_offset"); + else + file.openData("event_time_of_flight"); + + // Check that the required space is there in the file. + ::NeXus::Info tof_info = file.getInfo(); + int64_t tof_dim0 = recalculateDataSize(tof_info.dims[0]); + if (tof_dim0 < m_loadSize[0]+m_loadStart[0]) + { + alg->getLogger().warning() << "Entry " << entry_name << "'s event_time_offset field is too small to load the desired data.\n"; + m_loadError = true; + } - return; - } + //Check that the type is what it is supposed to be + if (tof_info.type == ::NeXus::FLOAT32) + file.getSlab(m_event_time_of_flight, m_loadStart, m_loadSize); + else + { + alg->getLogger().warning() << "Entry " << entry_name << "'s event_time_offset field is not FLOAT32! It will be skipped.\n"; + m_loadError = true; + } - //--------------------------------------------------------------------------------------------------- - /** Open and load the times-of-flight data - */ - void loadTof(::NeXus::File & file) - { - // Allocate the array - float* temp = new float[m_loadSize[0]]; - delete [] m_event_time_of_flight; - m_event_time_of_flight = temp; - - // Get the list of event_time_of_flight's - if (!m_oldNexusFileNames) - file.openData("event_time_offset"); - else - file.openData("event_time_of_flight"); + if (!m_loadError) + { + std::string units; + file.getAttr("units", units); + if (units != "microsecond") + { + alg->getLogger().warning() << "Entry " << entry_name << "'s event_time_offset field's units are not microsecond. It will be skipped.\n"; + m_loadError = true; + } + file.closeData(); + } //no error - // Check that the required space is there in the file. - ::NeXus::Info tof_info = file.getInfo(); - int64_t tof_dim0 = recalculateDataSize(tof_info.dims[0]); - if (tof_dim0 < m_loadSize[0]+m_loadStart[0]) - { - alg->getLogger().warning() << "Entry " << entry_name << "'s event_time_offset field is too small to load the desired data.\n"; - m_loadError = true; + return; } - //Check that the type is what it is supposed to be - if (tof_info.type == ::NeXus::FLOAT32) - file.getSlab(m_event_time_of_flight, m_loadStart, m_loadSize); - else + //---------------------------------------------------------------------------------------------- + /** Load weight of weigthed events + */ + void loadEventWeights(::NeXus::File &file) { - alg->getLogger().warning() << "Entry " << entry_name << "'s event_time_offset field is not FLOAT32! It will be skipped.\n"; - m_loadError = true; - } + try + { + // First, get info about the event_weight field in this bank + file.openData("event_weight"); + } + catch (::NeXus::Exception&) + { + // Field not found error is most likely. + m_have_weight = false; + return; + } + // OK, we've got them + m_have_weight = true; - if (!m_loadError) - { - std::string units; - file.getAttr("units", units); - if (units != "microsecond") + // Allocate the array + float* temp = new float[m_loadSize[0]]; + delete [] m_event_weight; + m_event_weight = temp; + + ::NeXus::Info weight_info = file.getInfo(); + int64_t weight_dim0 = recalculateDataSize(weight_info.dims[0]); + if (weight_dim0 < m_loadSize[0]+m_loadStart[0]) { - alg->getLogger().warning() << "Entry " << entry_name << "'s event_time_offset field's units are not microsecond. It will be skipped.\n"; + alg->getLogger().warning() << "Entry " << entry_name << "'s event_weight field is too small to load the desired data.\n"; m_loadError = true; } - file.closeData(); - } //no error - return; - } + // Check that the type is what it is supposed to be + if (weight_info.type == ::NeXus::FLOAT32) + file.getSlab(m_event_weight, m_loadStart, m_loadSize); + else + { + alg->getLogger().warning() << "Entry " << entry_name << "'s event_weight field is not FLOAT32! It will be skipped.\n"; + m_loadError = true; + } + + if (!m_loadError) + { + file.closeData(); + } - //---------------------------------------------------------------------------------------------- - /** Load weight of weigthed events - */ - void loadEventWeights(::NeXus::File &file) - { - try - { - // First, get info about the event_weight field in this bank - file.openData("event_weight"); - } - catch (::NeXus::Exception&) - { - // Field not found error is most likely. - m_have_weight = false; return; } - // OK, we've got them - m_have_weight = true; - // Allocate the array - float* temp = new float[m_loadSize[0]]; - delete [] m_event_weight; - m_event_weight = temp; - - ::NeXus::Info weight_info = file.getInfo(); - int64_t weight_dim0 = recalculateDataSize(weight_info.dims[0]); - if (weight_dim0 < m_loadSize[0]+m_loadStart[0]) + //--------------------------------------------------------------------------------------------------- + void run() { - alg->getLogger().warning() << "Entry " << entry_name << "'s event_weight field is too small to load the desired data.\n"; - m_loadError = true; - } + //The vectors we will be filling + std::vector * event_index_ptr = new std::vector(); + std::vector & event_index = *event_index_ptr; - // Check that the type is what it is supposed to be - if (weight_info.type == ::NeXus::FLOAT32) - file.getSlab(m_event_weight, m_loadStart, m_loadSize); - else - { - alg->getLogger().warning() << "Entry " << entry_name << "'s event_weight field is not FLOAT32! It will be skipped.\n"; - m_loadError = true; - } + // These give the limits in each file as to which events we actually load (when filtering by time). + m_loadStart.resize(1, 0); + m_loadSize.resize(1, 0); - if (!m_loadError) - { - file.closeData(); - } - - return; - } - - //--------------------------------------------------------------------------------------------------- - void run() - { - //The vectors we will be filling - std::vector * event_index_ptr = new std::vector(); - std::vector & event_index = *event_index_ptr; - - // These give the limits in each file as to which events we actually load (when filtering by time). - m_loadStart.resize(1, 0); - m_loadSize.resize(1, 0); + // Data arrays + m_event_id = NULL; + m_event_time_of_flight = NULL; + m_event_weight = NULL; - // Data arrays - m_event_id = NULL; - m_event_time_of_flight = NULL; - m_event_weight = NULL; + m_loadError = false; + m_have_weight = alg->m_haveWeights; - m_loadError = false; - m_have_weight = alg->m_haveWeights; + prog->report(entry_name + ": load from disk"); - prog->report(entry_name + ": load from disk"); - - // Open the file - ::NeXus::File file(alg->m_filename); - try - { - // Navigate into the file - file.openGroup(alg->m_top_entry_name, "NXentry"); - //Open the bankN_event group - file.openGroup(entry_name, entry_type); - - // Load the event_index field. - this->loadEventIndex(file, event_index); - - if (!m_loadError) + // Open the file + ::NeXus::File file(alg->m_filename); + try { - // Load and validate the pulse times - this->loadPulseTimes(file); + // Navigate into the file + file.openGroup(alg->m_top_entry_name, "NXentry"); + //Open the bankN_event group + file.openGroup(entry_name, entry_type); + + // Load the event_index field. + this->loadEventIndex(file, event_index); - // The event_index should be the same length as the pulse times from DAS logs. - if (event_index.size() != thisBankPulseTimes->numPulses) - alg->getLogger().warning() << "Bank " << entry_name << " has a mismatch between the number of event_index entries and the number of pulse times in event_time_zero.\n"; + if (!m_loadError) + { + // Load and validate the pulse times + this->loadPulseTimes(file); - // Open and validate event_id field. - size_t start_event = 0; - size_t stop_event = 0; - this->prepareEventId(file, start_event, stop_event, event_index); + // The event_index should be the same length as the pulse times from DAS logs. + if (event_index.size() != thisBankPulseTimes->numPulses) + alg->getLogger().warning() << "Bank " << entry_name << " has a mismatch between the number of event_index entries and the number of pulse times in event_time_zero.\n"; - // These are the arguments to getSlab() - m_loadStart[0] = static_cast(start_event); - m_loadSize[0] = static_cast(stop_event - start_event); + // Open and validate event_id field. + size_t start_event = 0; + size_t stop_event = 0; + this->prepareEventId(file, start_event, stop_event, event_index); - if ((m_loadSize[0] > 0) && (m_loadStart[0]>=0) ) - { - // Load pixel IDs - this->loadEventId(file); - if (alg->getCancel()) m_loadError = true; //To allow cancelling the algorithm + // These are the arguments to getSlab() + m_loadStart[0] = static_cast(start_event); + m_loadSize[0] = static_cast(stop_event - start_event); - // And TOF. - if (!m_loadError) + if ((m_loadSize[0] > 0) && (m_loadStart[0]>=0) ) { - this->loadTof(file); - if (m_have_weight) + // Load pixel IDs + this->loadEventId(file); + if (alg->getCancel()) m_loadError = true; //To allow cancelling the algorithm + + // And TOF. + if (!m_loadError) { - this->loadEventWeights(file); + this->loadTof(file); + if (m_have_weight) + { + this->loadEventWeights(file); + } } + } // Size is at least 1 + else + { + // Found a size that was 0 or less; stop processing + m_loadError=true; } - } // Size is at least 1 - else - { - // Found a size that was 0 or less; stop processing - m_loadError=true; - } - } //no error + } //no error - } // try block - catch (std::exception & e) - { - alg->getLogger().error() << "Error while loading bank " << entry_name << ":" << std::endl; - alg->getLogger().error() << e.what() << std::endl; - m_loadError = true; - } - catch (...) - { - alg->getLogger().error() << "Unspecified error while loading bank " << entry_name << std::endl; - m_loadError = true; - } + } // try block + catch (std::exception & e) + { + alg->getLogger().error() << "Error while loading bank " << entry_name << ":" << std::endl; + alg->getLogger().error() << e.what() << std::endl; + m_loadError = true; + } + catch (...) + { + alg->getLogger().error() << "Unspecified error while loading bank " << entry_name << std::endl; + m_loadError = true; + } - //Close up the file even if errors occured. - file.closeGroup(); - file.close(); + //Close up the file even if errors occured. + file.closeGroup(); + file.close(); - //Abort if anything failed - if (m_loadError) - { - prog->reportIncrement(4, entry_name + ": skipping"); - delete [] m_event_id; - delete [] m_event_time_of_flight; - if (m_have_weight) + //Abort if anything failed + if (m_loadError) { - delete [] m_event_weight; + prog->reportIncrement(4, entry_name + ": skipping"); + delete [] m_event_id; + delete [] m_event_time_of_flight; + if (m_have_weight) + { + delete [] m_event_weight; + } + delete event_index_ptr; + return; } - delete event_index_ptr; - return; - } - // No error? Launch a new task to process that data. - size_t numEvents = m_loadSize[0]; - size_t startAt = m_loadStart[0]; + // No error? Launch a new task to process that data. + size_t numEvents = m_loadSize[0]; + size_t startAt = m_loadStart[0]; - // convert things to shared_arrays - boost::shared_array event_id_shrd(m_event_id); - boost::shared_array event_time_of_flight_shrd(m_event_time_of_flight); - boost::shared_array event_weight_shrd(m_event_weight); - boost::shared_ptr > event_index_shrd(event_index_ptr); + // convert things to shared_arrays + boost::shared_array event_id_shrd(m_event_id); + boost::shared_array event_time_of_flight_shrd(m_event_time_of_flight); + boost::shared_array event_weight_shrd(m_event_weight); + boost::shared_ptr > event_index_shrd(event_index_ptr); - // schedule the job to generate the event lists - auto mid_id = m_max_id; - if (alg->splitProcessing) - mid_id = (m_max_id + m_min_id) / 2; + // schedule the job to generate the event lists + auto mid_id = m_max_id; + if (alg->splitProcessing) + mid_id = (m_max_id + m_min_id) / 2; - ProcessBankData * newTask1 = new ProcessBankData(alg, entry_name, prog,scheduler, + ProcessBankData * newTask1 = new ProcessBankData(alg, entry_name, prog,scheduler, event_id_shrd, event_time_of_flight_shrd, numEvents, startAt, event_index_shrd, thisBankPulseTimes, m_have_weight, event_weight_shrd, m_min_id, mid_id); - scheduler->push(newTask1); - if (alg->splitProcessing) + scheduler->push(newTask1); + if (alg->splitProcessing) + { + ProcessBankData * newTask2 = new ProcessBankData(alg, entry_name, prog,scheduler, + event_id_shrd, event_time_of_flight_shrd, numEvents, startAt, event_index_shrd, + thisBankPulseTimes, m_have_weight, event_weight_shrd, + (mid_id+1), m_max_id); + scheduler->push(newTask2); + } + } + + //--------------------------------------------------------------------------------------------------- + /** + * Interpret the value describing the number of events. If the number is positive return it unchanged. + * If the value is negative (can happen at ISIS) add 2^32 to it. + * @param size :: The size of events value. + */ + int64_t recalculateDataSize(const int64_t& size) { - ProcessBankData * newTask2 = new ProcessBankData(alg, entry_name, prog,scheduler, - event_id_shrd, event_time_of_flight_shrd, numEvents, startAt, event_index_shrd, - thisBankPulseTimes, m_have_weight, event_weight_shrd, - (mid_id+1), m_max_id); - scheduler->push(newTask2); + if (size < 0) + { + const int64_t shift = int64_t(1) << 32; + return shift + size; + } + return size; } - } - //--------------------------------------------------------------------------------------------------- - /** - * Interpret the value describing the number of events. If the number is positive return it unchanged. - * If the value is negative (can happen at ISIS) add 2^32 to it. - * @param size :: The size of events value. + private: + /// Algorithm being run + LoadEventNexus * alg; + /// NXS path to bank + std::string entry_name; + /// NXS type + std::string entry_type; + /// Vector where (index = pixel ID+pixelID_to_wi_offset), value = workspace index) + const std::vector & pixelID_to_wi_vector; + /// Offset in the pixelID_to_wi_vector to use. + detid_t pixelID_to_wi_offset; + /// Progress reporting + Progress * prog; + /// ThreadScheduler running this task + ThreadScheduler * scheduler; + /// Object with the pulse times for this bank + boost::shared_ptr thisBankPulseTimes; + /// Did we get an error in loading + bool m_loadError; + /// Old names in the file? + bool m_oldNexusFileNames; + /// Index to load start at in the file + std::vector m_loadStart; + /// How much to load in the file + std::vector m_loadSize; + /// Event pixel ID data + uint32_t * m_event_id; + /// Minimum pixel ID in this data + uint32_t m_min_id; + /// Maximum pixel ID in this data + uint32_t m_max_id; + /// TOF data + float * m_event_time_of_flight; + /// Flag for simulated data + bool m_have_weight; + /// Event weights + float * m_event_weight; + }; // END-DEF-CLASS LoadBankFromDiskTask + + + //=============================================================================================== + // LoadEventNexus + //=============================================================================================== + + //---------------------------------------------------------------------------------------------- + /** Empty default constructor */ - int64_t recalculateDataSize(const int64_t& size) + LoadEventNexus::LoadEventNexus() : IFileLoader(), + discarded_events(0), event_id_is_spec(false) { - if (size < 0) - { - const int64_t shift = int64_t(1) << 32; - return shift + size; - } - return size; } - private: - /// Algorithm being run - LoadEventNexus * alg; - /// NXS path to bank - std::string entry_name; - /// NXS type - std::string entry_type; - /// Vector where (index = pixel ID+pixelID_to_wi_offset), value = workspace index) - const std::vector & pixelID_to_wi_vector; - /// Offset in the pixelID_to_wi_vector to use. - detid_t pixelID_to_wi_offset; - /// Progress reporting - Progress * prog; - /// ThreadScheduler running this task - ThreadScheduler * scheduler; - /// Object with the pulse times for this bank - boost::shared_ptr thisBankPulseTimes; - /// Did we get an error in loading - bool m_loadError; - /// Old names in the file? - bool m_oldNexusFileNames; - /// Index to load start at in the file - std::vector m_loadStart; - /// How much to load in the file - std::vector m_loadSize; - /// Event pixel ID data - uint32_t * m_event_id; - /// Minimum pixel ID in this data - uint32_t m_min_id; - /// Maximum pixel ID in this data - uint32_t m_max_id; - /// TOF data - float * m_event_time_of_flight; - /// Flag for simulated data - bool m_have_weight; - /// Event weights - float * m_event_weight; - }; // END-DEF-CLASS LoadBankFromDiskTask - - - //=============================================================================================== - // LoadEventNexus - //=============================================================================================== - - //---------------------------------------------------------------------------------------------- - /** Empty default constructor - */ - LoadEventNexus::LoadEventNexus() : IFileLoader(), - discarded_events(0), event_id_is_spec(false) - { - } + //---------------------------------------------------------------------------------------------- + /** Destructor */ + LoadEventNexus::~LoadEventNexus() + { + } - //---------------------------------------------------------------------------------------------- - /** Destructor */ - LoadEventNexus::~LoadEventNexus() - { - } - - //---------------------------------------------------------------------------------------------- - /** - * Return the confidence with with this algorithm can load the file - * @param descriptor A descriptor for the file - * @returns An integer specifying the confidence level. 0 indicates it will not be used - */ - int LoadEventNexus::confidence(Kernel::NexusDescriptor & descriptor) const - { - int confidence(0); - if(descriptor.classTypeExists("NXevent_data")) + //---------------------------------------------------------------------------------------------- + /** + * Return the confidence with with this algorithm can load the file + * @param descriptor A descriptor for the file + * @returns An integer specifying the confidence level. 0 indicates it will not be used + */ + int LoadEventNexus::confidence(Kernel::NexusDescriptor & descriptor) const { - if(descriptor.pathOfTypeExists("/entry", "NXentry") || descriptor.pathOfTypeExists("/raw_data_1", "NXentry")) + int confidence(0); + if(descriptor.classTypeExists("NXevent_data")) { - confidence = 80; + if(descriptor.pathOfTypeExists("/entry", "NXentry") || descriptor.pathOfTypeExists("/raw_data_1", "NXentry")) + { + confidence = 80; + } } + return confidence; } - return confidence; - } - //---------------------------------------------------------------------------------------------- - /** Initialisation method. - */ - void LoadEventNexus::init() - { - std::vector exts; - exts.push_back("_event.nxs"); - exts.push_back(".nxs.h5"); - exts.push_back(".nxs"); - this->declareProperty(new FileProperty("Filename", "", FileProperty::Load, exts), - "The name of the Event NeXus file to read, including its full or relative path. " - "The file name is typically of the form INST_####_event.nxs (N.B. case sensitive if running on Linux)." ); - - this->declareProperty( - new WorkspaceProperty("OutputWorkspace", "", Direction::Output), - "The name of the output EventWorkspace in which to load the EventNexus file." ); - - declareProperty( - new PropertyWithValue("FilterByTofMin", EMPTY_DBL(), Direction::Input), - "Optional: To exclude events that do not fall within a range of times-of-flight. "\ - "This is the minimum accepted value in microseconds. Keep blank to load all events." ); - - declareProperty( - new PropertyWithValue("FilterByTofMax", EMPTY_DBL(), Direction::Input), - "Optional: To exclude events that do not fall within a range of times-of-flight. "\ - "This is the maximum accepted value in microseconds. Keep blank to load all events." ); - - declareProperty( - new PropertyWithValue("FilterByTimeStart", EMPTY_DBL(), Direction::Input), - "Optional: To only include events after the provided start time, in seconds (relative to the start of the run)."); - - declareProperty( - new PropertyWithValue("FilterByTimeStop", EMPTY_DBL(), Direction::Input), - "Optional: To only include events before the provided stop time, in seconds (relative to the start of the run)."); - - std::string grp1 = "Filter Events"; - setPropertyGroup("FilterByTofMin", grp1); - setPropertyGroup("FilterByTofMax", grp1); - setPropertyGroup("FilterByTimeStart", grp1); - setPropertyGroup("FilterByTimeStop", grp1); - - declareProperty( - new PropertyWithValue("NXentryName", "", Direction::Input), - "Optional: Name of the NXentry to load if it's not the default."); - - declareProperty( - new ArrayProperty("BankName", Direction::Input), - "Optional: To only include events from one bank. Any bank whose name does not match the given string will have no events."); - - declareProperty( - new PropertyWithValue("SingleBankPixelsOnly", true, Direction::Input), - "Optional: Only applies if you specified a single bank to load with BankName. " - "Only pixels in the specified bank will be created if true; all of the instrument's pixels will be created otherwise."); - setPropertySettings("SingleBankPixelsOnly", new VisibleWhenProperty("BankName", IS_NOT_DEFAULT) ); - - std::string grp2 = "Loading a Single Bank"; - setPropertyGroup("BankName", grp2); - setPropertyGroup("SingleBankPixelsOnly", grp2); - - declareProperty( - new PropertyWithValue("Precount", true, Direction::Input), - "Pre-count the number of events in each pixel before allocating memory (optional, default False). " - "This can significantly reduce memory use and memory fragmentation; it may also speed up loading."); - - declareProperty( - new PropertyWithValue("CompressTolerance", -1.0, Direction::Input), - "Run CompressEvents while loading (optional, leave blank or negative to not do). " - "This specified the tolerance to use (in microseconds) when compressing."); - - auto mustBePositive = boost::make_shared >(); - mustBePositive->setLower(1); - declareProperty("ChunkNumber", EMPTY_INT(), mustBePositive, - "If loading the file by sections ('chunks'), this is the section number of this execution of the algorithm."); - declareProperty("TotalChunks", EMPTY_INT(), mustBePositive, - "If loading the file by sections ('chunks'), this is the total number of sections."); - // TotalChunks is only meaningful if ChunkNumber is set - // Would be nice to be able to restrict ChunkNumber to be <= TotalChunks at validation - setPropertySettings("TotalChunks", new VisibleWhenProperty("ChunkNumber", IS_NOT_DEFAULT)); - - std::string grp3 = "Reduce Memory Use"; - setPropertyGroup("Precount", grp3); - setPropertyGroup("CompressTolerance", grp3); - setPropertyGroup("ChunkNumber", grp3); - setPropertyGroup("TotalChunks", grp3); - - declareProperty( - new PropertyWithValue("LoadMonitors", false, Direction::Input), - "Load the monitors from the file (optional, default False)."); - - declareProperty(new PropertyWithValue("MonitorsAsEvents", false, Direction::Input), - "If present, load the monitors as events. '''WARNING:''' WILL SIGNIFICANTLY INCREASE MEMORY USAGE (optional, default False). "); - - declareProperty( - new PropertyWithValue("FilterMonByTofMin", EMPTY_DBL(), Direction::Input), - "Optional: To exclude events from monitors that do not fall within a range of times-of-flight. "\ - "This is the minimum accepted value in microseconds." ); - - declareProperty( - new PropertyWithValue("FilterMonByTofMax", EMPTY_DBL(), Direction::Input), - "Optional: To exclude events from monitors that do not fall within a range of times-of-flight. "\ - "This is the maximum accepted value in microseconds." ); - - declareProperty( - new PropertyWithValue("FilterMonByTimeStart", EMPTY_DBL(), Direction::Input), - "Optional: To only include events from monitors after the provided start time, in seconds (relative to the start of the run)."); - - declareProperty( - new PropertyWithValue("FilterMonByTimeStop", EMPTY_DBL(), Direction::Input), - "Optional: To only include events from monitors before the provided stop time, in seconds (relative to the start of the run)."); - - setPropertySettings("MonitorsAsEvents", new VisibleWhenProperty("LoadMonitors", IS_EQUAL_TO, "1") ); - IPropertySettings *asEventsIsOn = new VisibleWhenProperty("MonitorsAsEvents", IS_EQUAL_TO, "1"); - setPropertySettings("FilterMonByTofMin", asEventsIsOn); - setPropertySettings("FilterMonByTofMax", asEventsIsOn->clone()); - setPropertySettings("FilterMonByTimeStart", asEventsIsOn->clone()); - setPropertySettings("FilterMonByTimeStop", asEventsIsOn->clone()); - - std::string grp4 = "Monitors"; - setPropertyGroup("LoadMonitors", grp4); - setPropertyGroup("MonitorsAsEvents", grp4); - setPropertyGroup("FilterMonByTofMin", grp4); - setPropertyGroup("FilterMonByTofMax", grp4); - setPropertyGroup("FilterMonByTimeStart", grp4); - setPropertyGroup("FilterMonByTimeStop", grp4); - - declareProperty( - new PropertyWithValue("MetaDataOnly", false, Direction::Input), - "If true, only the meta data and sample logs will be loaded."); - - declareProperty( - new PropertyWithValue("LoadLogs", true, Direction::Input), - "Load the Sample/DAS logs from the file (default True)."); - } - - //---------------------------------------------------------------------------------------------- - /** set the name of the top level NXentry m_top_entry_name + //---------------------------------------------------------------------------------------------- + /** Initialisation method. */ - void LoadEventNexus::setTopEntryName() - { - std::string nxentryProperty = getProperty("NXentryName"); - if (nxentryProperty.size()>0) + void LoadEventNexus::init() { - m_top_entry_name = nxentryProperty; - return; + std::vector exts; + exts.push_back("_event.nxs"); + exts.push_back(".nxs.h5"); + exts.push_back(".nxs"); + this->declareProperty(new FileProperty("Filename", "", FileProperty::Load, exts), + "The name of the Event NeXus file to read, including its full or relative path. " + "The file name is typically of the form INST_####_event.nxs (N.B. case sensitive if running on Linux)." ); + + this->declareProperty( + new WorkspaceProperty("OutputWorkspace", "", Direction::Output), + "The name of the output EventWorkspace in which to load the EventNexus file." ); + + declareProperty( + new PropertyWithValue("FilterByTofMin", EMPTY_DBL(), Direction::Input), + "Optional: To exclude events that do not fall within a range of times-of-flight. "\ + "This is the minimum accepted value in microseconds. Keep blank to load all events." ); + + declareProperty( + new PropertyWithValue("FilterByTofMax", EMPTY_DBL(), Direction::Input), + "Optional: To exclude events that do not fall within a range of times-of-flight. "\ + "This is the maximum accepted value in microseconds. Keep blank to load all events." ); + + declareProperty( + new PropertyWithValue("FilterByTimeStart", EMPTY_DBL(), Direction::Input), + "Optional: To only include events after the provided start time, in seconds (relative to the start of the run)."); + + declareProperty( + new PropertyWithValue("FilterByTimeStop", EMPTY_DBL(), Direction::Input), + "Optional: To only include events before the provided stop time, in seconds (relative to the start of the run)."); + + std::string grp1 = "Filter Events"; + setPropertyGroup("FilterByTofMin", grp1); + setPropertyGroup("FilterByTofMax", grp1); + setPropertyGroup("FilterByTimeStart", grp1); + setPropertyGroup("FilterByTimeStop", grp1); + + declareProperty( + new PropertyWithValue("NXentryName", "", Direction::Input), + "Optional: Name of the NXentry to load if it's not the default."); + + declareProperty( + new ArrayProperty("BankName", Direction::Input), + "Optional: To only include events from one bank. Any bank whose name does not match the given string will have no events."); + + declareProperty( + new PropertyWithValue("SingleBankPixelsOnly", true, Direction::Input), + "Optional: Only applies if you specified a single bank to load with BankName. " + "Only pixels in the specified bank will be created if true; all of the instrument's pixels will be created otherwise."); + setPropertySettings("SingleBankPixelsOnly", new VisibleWhenProperty("BankName", IS_NOT_DEFAULT) ); + + std::string grp2 = "Loading a Single Bank"; + setPropertyGroup("BankName", grp2); + setPropertyGroup("SingleBankPixelsOnly", grp2); + + declareProperty( + new PropertyWithValue("Precount", true, Direction::Input), + "Pre-count the number of events in each pixel before allocating memory (optional, default False). " + "This can significantly reduce memory use and memory fragmentation; it may also speed up loading."); + + declareProperty( + new PropertyWithValue("CompressTolerance", -1.0, Direction::Input), + "Run CompressEvents while loading (optional, leave blank or negative to not do). " + "This specified the tolerance to use (in microseconds) when compressing."); + + auto mustBePositive = boost::make_shared >(); + mustBePositive->setLower(1); + declareProperty("ChunkNumber", EMPTY_INT(), mustBePositive, + "If loading the file by sections ('chunks'), this is the section number of this execution of the algorithm."); + declareProperty("TotalChunks", EMPTY_INT(), mustBePositive, + "If loading the file by sections ('chunks'), this is the total number of sections."); + // TotalChunks is only meaningful if ChunkNumber is set + // Would be nice to be able to restrict ChunkNumber to be <= TotalChunks at validation + setPropertySettings("TotalChunks", new VisibleWhenProperty("ChunkNumber", IS_NOT_DEFAULT)); + + std::string grp3 = "Reduce Memory Use"; + setPropertyGroup("Precount", grp3); + setPropertyGroup("CompressTolerance", grp3); + setPropertyGroup("ChunkNumber", grp3); + setPropertyGroup("TotalChunks", grp3); + + declareProperty( + new PropertyWithValue("LoadMonitors", false, Direction::Input), + "Load the monitors from the file (optional, default False)."); + + declareProperty(new PropertyWithValue("MonitorsAsEvents", false, Direction::Input), + "If present, load the monitors as events. '''WARNING:''' WILL SIGNIFICANTLY INCREASE MEMORY USAGE (optional, default False). "); + + declareProperty( + new PropertyWithValue("FilterMonByTofMin", EMPTY_DBL(), Direction::Input), + "Optional: To exclude events from monitors that do not fall within a range of times-of-flight. "\ + "This is the minimum accepted value in microseconds." ); + + declareProperty( + new PropertyWithValue("FilterMonByTofMax", EMPTY_DBL(), Direction::Input), + "Optional: To exclude events from monitors that do not fall within a range of times-of-flight. "\ + "This is the maximum accepted value in microseconds." ); + + declareProperty( + new PropertyWithValue("FilterMonByTimeStart", EMPTY_DBL(), Direction::Input), + "Optional: To only include events from monitors after the provided start time, in seconds (relative to the start of the run)."); + + declareProperty( + new PropertyWithValue("FilterMonByTimeStop", EMPTY_DBL(), Direction::Input), + "Optional: To only include events from monitors before the provided stop time, in seconds (relative to the start of the run)."); + + setPropertySettings("MonitorsAsEvents", new VisibleWhenProperty("LoadMonitors", IS_EQUAL_TO, "1") ); + IPropertySettings *asEventsIsOn = new VisibleWhenProperty("MonitorsAsEvents", IS_EQUAL_TO, "1"); + setPropertySettings("FilterMonByTofMin", asEventsIsOn); + setPropertySettings("FilterMonByTofMax", asEventsIsOn->clone()); + setPropertySettings("FilterMonByTimeStart", asEventsIsOn->clone()); + setPropertySettings("FilterMonByTimeStop", asEventsIsOn->clone()); + + std::string grp4 = "Monitors"; + setPropertyGroup("LoadMonitors", grp4); + setPropertyGroup("MonitorsAsEvents", grp4); + setPropertyGroup("FilterMonByTofMin", grp4); + setPropertyGroup("FilterMonByTofMax", grp4); + setPropertyGroup("FilterMonByTimeStart", grp4); + setPropertyGroup("FilterMonByTimeStop", grp4); + + declareProperty("SpectrumMin",(int32_t)EMPTY_INT(), mustBePositive, + "The number of the first spectrum to read."); + declareProperty("SpectrumMax",(int32_t)EMPTY_INT(), mustBePositive, + "The number of the last spectrum to read."); + declareProperty(new ArrayProperty("SpectrumList"), + "A comma-separated list of individual spectra to read."); + + declareProperty( + new PropertyWithValue("MetaDataOnly", false, Direction::Input), + "If true, only the meta data and sample logs will be loaded."); + + declareProperty( + new PropertyWithValue("LoadLogs", true, Direction::Input), + "Load the Sample/DAS logs from the file (default True)."); } - typedef std::map string_map_t; - try + + //---------------------------------------------------------------------------------------------- + /** set the name of the top level NXentry m_top_entry_name + */ + void LoadEventNexus::setTopEntryName() { - string_map_t::const_iterator it; - ::NeXus::File file = ::NeXus::File(m_filename); - string_map_t entries = file.getEntries(); + std::string nxentryProperty = getProperty("NXentryName"); + if (nxentryProperty.size()>0) + { + m_top_entry_name = nxentryProperty; + return; + } + typedef std::map string_map_t; + try + { + string_map_t::const_iterator it; + ::NeXus::File file = ::NeXus::File(m_filename); + string_map_t entries = file.getEntries(); - // Choose the first entry as the default - m_top_entry_name = entries.begin()->first; + // Choose the first entry as the default + m_top_entry_name = entries.begin()->first; - for (it = entries.begin(); it != entries.end(); ++it) - { - if ( ((it->first == "entry") || (it->first == "raw_data_1")) && (it->second == "NXentry") ) + for (it = entries.begin(); it != entries.end(); ++it) { - m_top_entry_name = it->first; - break; + if ( ((it->first == "entry") || (it->first == "raw_data_1")) && (it->second == "NXentry") ) + { + m_top_entry_name = it->first; + break; + } } } + catch(const std::exception&) + { + g_log.error() << "Unable to determine name of top level NXentry - assuming \"entry\"." << std::endl; + m_top_entry_name = "entry"; + } } - catch(const std::exception&) - { - g_log.error() << "Unable to determine name of top level NXentry - assuming \"entry\"." << std::endl; - m_top_entry_name = "entry"; - } - } - //------------------------------------------------------------------------------------------------ - /** Executes the algorithm. Reading in the file and creating and populating - * the output workspace - */ - void LoadEventNexus::exec() - { - // Retrieve the filename from the properties - m_filename = getPropertyValue("Filename"); + //------------------------------------------------------------------------------------------------ + /** Executes the algorithm. Reading in the file and creating and populating + * the output workspace + */ + void LoadEventNexus::exec() + { + // Retrieve the filename from the properties + m_filename = getPropertyValue("Filename"); - precount = getProperty("Precount"); - compressTolerance = getProperty("CompressTolerance"); + precount = getProperty("Precount"); + compressTolerance = getProperty("CompressTolerance"); - loadlogs = getProperty("LoadLogs"); + loadlogs = getProperty("LoadLogs"); - // Check to see if the monitors need to be loaded later - bool load_monitors = this->getProperty("LoadMonitors"); - setTopEntryName(); + // Check to see if the monitors need to be loaded later + bool load_monitors = this->getProperty("LoadMonitors"); + setTopEntryName(); - //Initialize progress reporting. - int reports = 3; - if (load_monitors) - reports++; - Progress prog(this,0.0,0.3, reports); - - // Load the detector events - WS = createEmptyEventWorkspace(); // Algorithm currently relies on an object-level workspace ptr - loadEvents(&prog, false); // Do not load monitor blocks + //Initialize progress reporting. + int reports = 3; + if (load_monitors) + reports++; + Progress prog(this,0.0,0.3, reports); - if ( discarded_events > 0 ) - { - g_log.information() << discarded_events - << " events were encountered coming from pixels which are not in the Instrument Definition File." - "These events were discarded.\n"; - } - - // If the run was paused at any point, filter out those events (SNS only, I think) - filterDuringPause(WS); - - //add filename - WS->mutableRun().addProperty("Filename",m_filename); - //Save output - this->setProperty("OutputWorkspace", WS); - // Load the monitors - if (load_monitors) - { - prog.report("Loading monitors"); - const bool eventMonitors = getProperty("MonitorsAsEvents"); - if( eventMonitors && this->hasEventMonitors() ) - { - // Note the reuse of the WS member variable below. Means I need to grab a copy of its current value. - auto dataWS = WS; + // Load the detector events WS = createEmptyEventWorkspace(); // Algorithm currently relies on an object-level workspace ptr - //add filename - WS->mutableRun().addProperty("Filename",m_filename); - // Perform the load - loadEvents(&prog, true); - std::string mon_wsname = this->getProperty("OutputWorkspace"); - mon_wsname.append("_monitors"); - this->declareProperty(new WorkspaceProperty - ("MonitorWorkspace", mon_wsname, Direction::Output), "Monitors from the Event NeXus file"); - this->setProperty("MonitorWorkspace", WS); - // Set the internal monitor workspace pointer as well - dataWS->setMonitorWorkspace(WS); + loadEvents(&prog, false); // Do not load monitor blocks + + if ( discarded_events > 0 ) + { + g_log.information() << discarded_events + << " events were encountered coming from pixels which are not in the Instrument Definition File." + "These events were discarded.\n"; + } + // If the run was paused at any point, filter out those events (SNS only, I think) filterDuringPause(WS); - } - else - { - this->runLoadMonitors(); - } - } - // Some memory feels like it sticks around (on Linux). Free it. - MemoryManager::Instance().releaseFreeMemory(); + //add filename + WS->mutableRun().addProperty("Filename",m_filename); + //Save output + this->setProperty("OutputWorkspace", WS); + // Load the monitors + if (load_monitors) + { + prog.report("Loading monitors"); + const bool eventMonitors = getProperty("MonitorsAsEvents"); + if( eventMonitors && this->hasEventMonitors() ) + { + // Note the reuse of the WS member variable below. Means I need to grab a copy of its current value. + auto dataWS = WS; + WS = createEmptyEventWorkspace(); // Algorithm currently relies on an object-level workspace ptr + //add filename + WS->mutableRun().addProperty("Filename",m_filename); + // Perform the load + loadEvents(&prog, true); + std::string mon_wsname = this->getProperty("OutputWorkspace"); + mon_wsname.append("_monitors"); + this->declareProperty(new WorkspaceProperty + ("MonitorWorkspace", mon_wsname, Direction::Output), "Monitors from the Event NeXus file"); + this->setProperty("MonitorWorkspace", WS); + // Set the internal monitor workspace pointer as well + dataWS->setMonitorWorkspace(WS); + // If the run was paused at any point, filter out those events (SNS only, I think) + filterDuringPause(WS); + } + else + { + this->runLoadMonitors(); + } + } - return; -} + // Some memory feels like it sticks around (on Linux). Free it. + MemoryManager::Instance().releaseFreeMemory(); + return; + } -//----------------------------------------------------------------------------- -/** Generate a look-up table where the index = the pixel ID of an event - * and the value = a pointer to the EventList in the workspace - * @param vectors :: the array to create the map on - */ -template -void LoadEventNexus::makeMapToEventLists(std::vector & vectors) -{ - if( this->event_id_is_spec ) - { - // Find max spectrum no - Axis *ax1 = WS->getAxis(1); - specid_t maxSpecNo = -std::numeric_limits::max(); // So that any number will be greater than this - for (size_t i=0; i < ax1->length(); i++) - { - specid_t spec = ax1->spectraNo(i); - if (spec > maxSpecNo) maxSpecNo = spec; - } - // These are used by the bank loader to figure out where to put the events - // The index of eventVectors is a spectrum number so it is simply resized to the maximum - // possible spectrum number - eventid_max = maxSpecNo; - vectors.resize(maxSpecNo+1, NULL); - for(size_t i = 0; i < WS->getNumberHistograms(); ++i) + //----------------------------------------------------------------------------- + /** Generate a look-up table where the index = the pixel ID of an event + * and the value = a pointer to the EventList in the workspace + * @param vectors :: the array to create the map on + */ + template + void LoadEventNexus::makeMapToEventLists(std::vector & vectors) { - const ISpectrum * spec = WS->getSpectrum(i); - if(spec) + if( this->event_id_is_spec ) { - getEventsFrom(WS->getEventList(i), vectors[spec->getSpectrumNo()]); + // Find max spectrum no + Axis *ax1 = WS->getAxis(1); + specid_t maxSpecNo = -std::numeric_limits::max(); // So that any number will be greater than this + for (size_t i=0; i < ax1->length(); i++) + { + specid_t spec = ax1->spectraNo(i); + if (spec > maxSpecNo) maxSpecNo = spec; + } + + // These are used by the bank loader to figure out where to put the events + // The index of eventVectors is a spectrum number so it is simply resized to the maximum + // possible spectrum number + eventid_max = maxSpecNo; + vectors.resize(maxSpecNo+1, NULL); + for(size_t i = 0; i < WS->getNumberHistograms(); ++i) + { + const ISpectrum * spec = WS->getSpectrum(i); + if(spec) + { + getEventsFrom(WS->getEventList(i), vectors[spec->getSpectrumNo()]); + } + } } - } - } - else - { - // To avoid going out of range in the vector, this is the MAX index that can go into it - eventid_max = static_cast(pixelID_to_wi_vector.size()) + pixelID_to_wi_offset; - - // Make an array where index = pixel ID - // Set the value to NULL by default - vectors.resize(eventid_max+1, NULL); - - for (size_t j=size_t(pixelID_to_wi_offset); jgetNumberHistograms() ) + else { - getEventsFrom(WS->getEventList(wi), vectors[j-pixelID_to_wi_offset]); - } - } - } -} + // To avoid going out of range in the vector, this is the MAX index that can go into it + eventid_max = static_cast(pixelID_to_wi_vector.size()) + pixelID_to_wi_offset; -/** - * Get the number of events in the currently opened group. - * - * @param file The handle to the nexus file opened to the group to look at. - * @param hasTotalCounts Whether to try looking at the total_counts field. This - * variable will be changed if the field is not there. - * @param oldNeXusFileNames Whether to try using old names. This variable will - * be changed if it is determined that old names are being used. - * - * @return The number of events. - */ -std::size_t numEvents(::NeXus::File &file, bool &hasTotalCounts, bool &oldNeXusFileNames) -{ - // try getting the value of total_counts - if (hasTotalCounts) - { - try - { - uint64_t numEvents; - file.readData("total_counts", numEvents); - return numEvents; - } - catch (::NeXus::Exception& ) - { - hasTotalCounts=false; // carry on with the field not existing - } - } + // Make an array where index = pixel ID + // Set the value to NULL by default + vectors.resize(eventid_max+1, NULL); - // just get the length of the event pixel ids - try - { - if (oldNeXusFileNames) - file.openData("event_pixel_id"); - else - file.openData("event_id"); - } - catch (::NeXus::Exception& ) - { - // Older files (before Nov 5, 2010) used this field. - try - { - file.openData("event_pixel_id"); - oldNeXusFileNames = true; - } - catch(::NeXus::Exception&) - { - // Some groups have neither indicating there are not events here - return 0; + for (size_t j=size_t(pixelID_to_wi_offset); jgetNumberHistograms() ) + { + getEventsFrom(WS->getEventList(wi), vectors[j-pixelID_to_wi_offset]); + } + } + } } - } - size_t numEvents = static_cast(file.getInfo().dims[0]); - file.closeData(); - return numEvents; -} - -//----------------------------------------------------------------------------- -/** - * Load events from the file - * @param prog :: A pointer to the progress reporting object - * @param monitors :: If true the events from the monitors are loaded and not the main banks - */ -void LoadEventNexus::loadEvents(API::Progress * const prog, const bool monitors) -{ - bool metaDataOnly = getProperty("MetaDataOnly"); - - // Get the time filters - setTimeFilters(monitors); - - // The run_start will be loaded from the pulse times. - DateAndTime run_start(0,0); - // Initialize the counter of bad TOFs - bad_tofs = 0; - - if (loadlogs) - { - prog->doReport("Loading DAS logs"); - m_allBanksPulseTimes = runLoadNexusLogs(m_filename, WS, *this, true); - run_start = WS->getFirstPulseTime(); - } - else - { - g_log.information() << "Skipping the loading of sample logs!\n" - << "Reading the start time directly from /" << m_top_entry_name - << "/start_time\n"; - // start_time is read and set - ::NeXus::File nxfile(m_filename); - nxfile.openGroup(m_top_entry_name, "NXentry"); - std::string tmp; - nxfile.readData("start_time", tmp); - run_start = DateAndTime(tmp); - WS->mutableRun().addProperty("run_start", run_start.toISO8601String(), true ); - } - - // Make sure you have a non-NULL m_allBanksPulseTimes - if (m_allBanksPulseTimes == NULL) - { - std::vector temp; - // m_allBanksPulseTimes = new BankPulseTimes(temp); - m_allBanksPulseTimes = boost::make_shared(temp); - } - - - //Load the instrument - prog->report("Loading instrument"); - instrument_loaded_correctly = loadInstrument(m_filename, WS, m_top_entry_name, this); - - if (!this->instrument_loaded_correctly) - throw std::runtime_error("Instrument was not initialized correctly! Loading cannot continue."); - - - // top level file information - ::NeXus::File file(m_filename); - - //Start with the base entry - file.openGroup(m_top_entry_name, "NXentry"); - - //Now we want to go through all the bankN_event entries - vector bankNames; - vector bankNumEvents; - size_t total_events = 0; - map entries = file.getEntries(); - map::const_iterator it = entries.begin(); - std::string classType = monitors ? "NXmonitor" : "NXevent_data"; - ::NeXus::Info info; - bool oldNeXusFileNames(false); - bool hasTotalCounts(true); - m_haveWeights = false; - for (; it != entries.end(); ++it) - { - std::string entry_name(it->first); - std::string entry_class(it->second); - if ( entry_class == classType ) + /** + * Get the number of events in the currently opened group. + * + * @param file The handle to the nexus file opened to the group to look at. + * @param hasTotalCounts Whether to try looking at the total_counts field. This + * variable will be changed if the field is not there. + * @param oldNeXusFileNames Whether to try using old names. This variable will + * be changed if it is determined that old names are being used. + * + * @return The number of events. + */ + std::size_t numEvents(::NeXus::File &file, bool &hasTotalCounts, bool &oldNeXusFileNames) { - // open the group - file.openGroup(entry_name, classType); - - // get the number of events - std::size_t num = numEvents(file, hasTotalCounts, oldNeXusFileNames); - bankNames.push_back( entry_name ); - bankNumEvents.push_back(num); - total_events += num; + // try getting the value of total_counts + if (hasTotalCounts) + { + try + { + uint64_t numEvents; + file.readData("total_counts", numEvents); + return numEvents; + } + catch (::NeXus::Exception& ) + { + hasTotalCounts=false; // carry on with the field not existing + } + } - // Look for weights in simulated file + // just get the length of the event pixel ids try { - file.openData("event_weight"); - m_haveWeights = true; - file.closeData(); + if (oldNeXusFileNames) + file.openData("event_pixel_id"); + else + file.openData("event_id"); } - catch (::NeXus::Exception &) + catch (::NeXus::Exception& ) { - // Swallow exception since flag is already false; + // Older files (before Nov 5, 2010) used this field. + try + { + file.openData("event_pixel_id"); + oldNeXusFileNames = true; + } + catch(::NeXus::Exception&) + { + // Some groups have neither indicating there are not events here + return 0; + } } - file.closeGroup(); + size_t numEvents = static_cast(file.getInfo().dims[0]); + file.closeData(); + return numEvents; } - } - - loadSampleDataISIScompatibility(file, WS); - //Close up the file - file.closeGroup(); - file.close(); - - // Delete the output workspace name if it existed - std::string outName = getPropertyValue("OutputWorkspace"); - if (AnalysisDataService::Instance().doesExist(outName)) - AnalysisDataService::Instance().remove( outName ); - - // set more properties on the workspace - try - { - // this is a static method that is why it is passing the file path - loadEntryMetadata(m_filename, WS, m_top_entry_name); - } - catch (std::runtime_error & e) - { - // Missing metadata is not a fatal error. Log and go on with your life - g_log.error() << "Error loading metadata: " << e.what() << std::endl; - } - - // --------------------------- Time filtering ------------------------------------ - double filter_time_start_sec, filter_time_stop_sec; - filter_time_start_sec = getProperty("FilterByTimeStart"); - filter_time_stop_sec = getProperty("FilterByTimeStop"); - chunk = getProperty("ChunkNumber"); - totalChunks = getProperty("TotalChunks"); - - //Default to ALL pulse times - bool is_time_filtered = false; - filter_time_start = Kernel::DateAndTime::minimum(); - filter_time_stop = Kernel::DateAndTime::maximum(); - - if (m_allBanksPulseTimes->numPulses > 0) - { - //If not specified, use the limits of doubles. Otherwise, convert from seconds to absolute PulseTime - if (filter_time_start_sec != EMPTY_DBL()) + //----------------------------------------------------------------------------- + /** + * Load events from the file + * @param prog :: A pointer to the progress reporting object + * @param monitors :: If true the events from the monitors are loaded and not the main banks + */ + void LoadEventNexus::loadEvents(API::Progress * const prog, const bool monitors) { - filter_time_start = run_start + filter_time_start_sec; - is_time_filtered = true; - } + bool metaDataOnly = getProperty("MetaDataOnly"); - if (filter_time_stop_sec != EMPTY_DBL()) - { - filter_time_stop = run_start + filter_time_stop_sec; - is_time_filtered = true; - } + // Get the time filters + setTimeFilters(monitors); - //Silly values? - if (filter_time_stop < filter_time_start) - { - std::string msg = "Your "; - if(monitors) msg += "monitor "; - msg += "filter for time's Stop value is smaller than the Start value."; - throw std::invalid_argument(msg); - } - } + // The run_start will be loaded from the pulse times. + DateAndTime run_start(0,0); + // Initialize the counter of bad TOFs + bad_tofs = 0; - if (is_time_filtered) - { - //Now filter out the run, using the DateAndTime type. - WS->mutableRun().filterByTime(filter_time_start, filter_time_stop); - } - - if(metaDataOnly) { - //Now, create a default X-vector for histogramming, with just 2 bins. - Kernel::cow_ptr axis; - MantidVec& xRef = axis.access(); - xRef.resize(2); - xRef[0] = static_cast(std::numeric_limits::max()) * 0.1 - 1; //Just to make sure the bins hold it all - xRef[1] = 1; - //Set the binning axis using this. - WS->setAllX(axis); - return; - } - - // --------- Loading only one bank ? ---------------------------------- - std::vector someBanks = getProperty("BankName"); - bool SingleBankPixelsOnly = getProperty("SingleBankPixelsOnly"); - if ((!someBanks.empty()) && (!monitors)) - { - // check that all of the requested banks are in the file - for (auto someBank = someBanks.begin(); someBank != someBanks.end(); ++someBank) - { - bool foundIt = false; - for (auto bankName = bankNames.begin(); bankName != bankNames.end(); ++bankName) + if (loadlogs) { - if ((*bankName) == (*someBank)+"_events") - { - foundIt = true; - break; - } + prog->doReport("Loading DAS logs"); + m_allBanksPulseTimes = runLoadNexusLogs(m_filename, WS, *this, true); + run_start = WS->getFirstPulseTime(); } - if (!foundIt) + else { - throw std::invalid_argument("No entry named '" + (*someBank) + "' was found in the .NXS file.\n"); + g_log.information() << "Skipping the loading of sample logs!\n" + << "Reading the start time directly from /" << m_top_entry_name + << "/start_time\n"; + // start_time is read and set + ::NeXus::File nxfile(m_filename); + nxfile.openGroup(m_top_entry_name, "NXentry"); + std::string tmp; + nxfile.readData("start_time", tmp); + run_start = DateAndTime(tmp); + WS->mutableRun().addProperty("run_start", run_start.toISO8601String(), true ); } - } - // change the number of banks to load - bankNames.clear(); - for (auto someBank = someBanks.begin(); someBank != someBanks.end(); ++someBank) - bankNames.push_back((*someBank) + "_events"); + // Make sure you have a non-NULL m_allBanksPulseTimes + if (m_allBanksPulseTimes == NULL) + { + std::vector temp; + // m_allBanksPulseTimes = new BankPulseTimes(temp); + m_allBanksPulseTimes = boost::make_shared(temp); + } - // how many events are in a bank - bankNumEvents.clear(); - bankNumEvents.assign(someBanks.size(), 1); // TODO this equally weights the banks - if( !SingleBankPixelsOnly ) someBanks.clear(); // Marker to load all pixels - } - else - { - someBanks.clear(); - } + //Load the instrument + prog->report("Loading instrument"); + instrument_loaded_correctly = loadInstrument(m_filename, WS, m_top_entry_name, this); - prog->report("Initializing all pixels"); - // Remove used banks if parameter is set - if (WS->getInstrument()->hasParameter("remove-unused-banks")) - { - std::vector instrumentUnused = WS->getInstrument()->getNumberParameter("remove-unused-banks", true); - if (!instrumentUnused.empty()) - { - const int unused = static_cast(instrumentUnused.front()); - if(unused == 1) deleteBanks(WS, bankNames); - } - } - //----------------- Pad Empty Pixels ------------------------------- - // Create the required spectra mapping so that the workspace knows what to pad to - createSpectraMapping(m_filename, monitors, someBanks); - - //This map will be used to find the workspace index - if( this->event_id_is_spec ) - WS->getSpectrumToWorkspaceIndexVector(pixelID_to_wi_vector, pixelID_to_wi_offset); - else - WS->getDetectorIDToWorkspaceIndexVector(pixelID_to_wi_vector, pixelID_to_wi_offset, true); - - // Cache a map for speed. - if (!m_haveWeights) - { - this->makeMapToEventLists(eventVectors); - } - else - { - // Convert to weighted events - for (size_t i=0; i < WS->getNumberHistograms(); i++) - { - WS->getEventList(i).switchTo(API::WEIGHTED); - } - this->makeMapToEventLists(weightedEventVectors); - } + if (!this->instrument_loaded_correctly) + throw std::runtime_error("Instrument was not initialized correctly! Loading cannot continue."); - // Set all (empty) event lists as sorted by pulse time. That way, calling SortEvents will not try to sort these empty lists. - for (size_t i=0; i < WS->getNumberHistograms(); i++) - WS->getEventList(i).setSortOrder(DataObjects::PULSETIME_SORT); - //Count the limits to time of flight - shortest_tof = static_cast(std::numeric_limits::max()) * 0.1; - longest_tof = 0.; + // top level file information + ::NeXus::File file(m_filename); - // Make the thread pool - ThreadScheduler * scheduler = new ThreadSchedulerMutexes(); - ThreadPool pool(scheduler); - auto diskIOMutex = boost::make_shared(); - size_t bank0 = 0; - size_t bankn = bankNames.size(); + //Start with the base entry + file.openGroup(m_top_entry_name, "NXentry"); - if (chunk != EMPTY_INT()) // We are loading part - work out the bank number range - { - eventsPerChunk = total_events / totalChunks; - // Sort banks by size - size_t tmp; - string stmp; - for (size_t i = 0; i < bankn; i++) - for (size_t j = 0; j < bankn - 1; j++) - if (bankNumEvents[j] < bankNumEvents[j + 1]) - { - tmp = bankNumEvents[j]; - bankNumEvents[j] = bankNumEvents[j + 1]; - bankNumEvents[j + 1] = tmp; - stmp = bankNames[j]; - bankNames[j] = bankNames[j + 1]; - bankNames[j + 1] = stmp; - } - int bigBanks = 0; - for (size_t i = 0; i < bankn; i++) if (bankNumEvents[i] > eventsPerChunk)bigBanks++; - // Each chunk is part of bank or multiple whole banks - // 0.5 for last chunk of a bank with multiple chunks - // 0.1 for multiple whole banks not completely filled - eventsPerChunk += static_cast((static_cast(bigBanks) / static_cast(totalChunks) * - 0.5 + 0.05) * static_cast(eventsPerChunk)); - double partialChunk = 0.; - firstChunkForBank = 1; - for (int chunki = 1; chunki <=chunk; chunki++) - { - if (partialChunk > 1.) - { - partialChunk = 0.; - firstChunkForBank = chunki; - bank0 = bankn; - } - if (bankNumEvents[bank0] > 1) + //Now we want to go through all the bankN_event entries + vector bankNames; + vector bankNumEvents; + size_t total_events = 0; + map entries = file.getEntries(); + map::const_iterator it = entries.begin(); + std::string classType = monitors ? "NXmonitor" : "NXevent_data"; + ::NeXus::Info info; + bool oldNeXusFileNames(false); + bool hasTotalCounts(true); + m_haveWeights = false; + for (; it != entries.end(); ++it) { - partialChunk += static_cast(eventsPerChunk)/static_cast(bankNumEvents[bank0]); - } - if (chunki < totalChunks) bankn = bank0 + 1; - else bankn = bankNames.size(); - if (chunki == firstChunkForBank && partialChunk > 1.0) bankn += static_cast(partialChunk) - 1; - if (bankn > bankNames.size()) bankn = bankNames.size(); - } - for (size_t i=bank0; i < bankn; i++) - { - size_t start_event = (chunk - firstChunkForBank) * eventsPerChunk; - size_t stop_event = bankNumEvents[i]; - // Don't change stop_event for the final chunk - if ( start_event + eventsPerChunk < stop_event ) stop_event = start_event + eventsPerChunk; - bankNumEvents[i] = stop_event - start_event; - } - } - - // split banks up if the number of cores is more than twice the number of banks - splitProcessing = bool(bankNames.size() * 2 < ThreadPool::getNumPhysicalCores()); + std::string entry_name(it->first); + std::string entry_class(it->second); + if ( entry_class == classType ) + { + // open the group + file.openGroup(entry_name, classType); - // set up progress bar for the rest of the (multi-threaded) process - size_t numProg = bankNames.size() * (1 + 3); // 1 = disktask, 3 = proc task - if (splitProcessing) numProg += bankNames.size() * 3; // 3 = second proc task - Progress * prog2 = new Progress(this,0.3,1.0, numProg); + // get the number of events + std::size_t num = numEvents(file, hasTotalCounts, oldNeXusFileNames); + bankNames.push_back( entry_name ); + bankNumEvents.push_back(num); + total_events += num; - for (size_t i=bank0; i < bankn; i++) - { - // We make tasks for loading - if (bankNumEvents[i] > 0) - pool.schedule( new LoadBankFromDiskTask(this, bankNames[i], classType, bankNumEvents[i], oldNeXusFileNames, - prog2, diskIOMutex, scheduler) ); - } - // Start and end all threads - pool.joinAll(); - diskIOMutex.reset(); - delete prog2; - - - //Info reporting - const std::size_t eventsLoaded = WS->getNumberEvents(); - g_log.information() << "Read " << eventsLoaded << " events" - << ". Shortest TOF: " << shortest_tof << " microsec; longest TOF: " - << longest_tof << " microsec." << std::endl; - - if (shortest_tof < 0) - g_log.warning() << "The shortest TOF was negative! At least 1 event has an invalid time-of-flight." << std::endl; - if (bad_tofs > 0) - g_log.warning() << "Found " << bad_tofs << " events with TOF > 2e8. This may indicate errors in the raw TOF data." << std::endl; - - //Now, create a default X-vector for histogramming, with just 2 bins. - Kernel::cow_ptr axis; - MantidVec& xRef = axis.access(); - xRef.resize(2,0.0); - if ( eventsLoaded > 0) - { - xRef[0] = shortest_tof - 1; //Just to make sure the bins hold it all - xRef[1] = longest_tof + 1; - } - //Set the binning axis using this. - WS->setAllX(axis); - - // if there is time_of_flight load it - loadTimeOfFlight(m_filename, WS, m_top_entry_name,classType); -} + // Look for weights in simulated file + try + { + file.openData("event_weight"); + m_haveWeights = true; + file.closeData(); + } + catch (::NeXus::Exception &) + { + // Swallow exception since flag is already false; + } -//----------------------------------------------------------------------------- -/** - * Create a blank event workspace - * @returns A shared pointer to a new empty EventWorkspace object - */ -EventWorkspace_sptr LoadEventNexus::createEmptyEventWorkspace() -{ - // Create the output workspace - EventWorkspace_sptr eventWS(new EventWorkspace()); - //Make sure to initialize. - // We can use dummy numbers for arguments, for event workspace it doesn't matter - eventWS->initialize(1,1,1); + file.closeGroup(); + } + } - // Set the units - eventWS->getAxis(0)->unit() = UnitFactory::Instance().create("TOF"); - eventWS->setYUnit("Counts"); + loadSampleDataISIScompatibility(file, WS); - return eventWS; -} + //Close up the file + file.closeGroup(); + file.close(); + // Delete the output workspace name if it existed + std::string outName = getPropertyValue("OutputWorkspace"); + if (AnalysisDataService::Instance().doesExist(outName)) + AnalysisDataService::Instance().remove( outName ); -//----------------------------------------------------------------------------- -/** Load the run number and other meta data from the given bank */ -void LoadEventNexus::loadEntryMetadata(const std::string &nexusfilename, Mantid::API::MatrixWorkspace_sptr WS, - const std::string &entry_name) -{ - // Open the file - ::NeXus::File file(nexusfilename); - file.openGroup(entry_name, "NXentry"); - - // get the title - file.openData("title"); - if (file.getInfo().type == ::NeXus::CHAR) { - string title = file.getStrData(); - if (!title.empty()) - WS->setTitle(title); - } - file.closeData(); - - // get the notes - try { - file.openData("notes"); - if (file.getInfo().type == ::NeXus::CHAR) { - string notes = file.getStrData(); - if (!notes.empty()) - WS->mutableRun().addProperty("file_notes", notes); - } - file.closeData(); - } catch (::NeXus::Exception &) { - // let it drop on floor - } - - // Get the run number - file.openData("run_number"); - string run(""); - if (file.getInfo().type == ::NeXus::CHAR) { - run = file.getStrData(); - }else if (file.isDataInt()){ - // inside ISIS the run_number type is int32 - vector value; - file.getData(value); - if (value.size() > 0) - run = boost::lexical_cast(value[0]); - } - if (!run.empty()) { - WS->mutableRun().addProperty("run_number", run); - } - file.closeData(); - - // get the duration - file.openData("duration"); - std::vector duration; - file.getDataCoerce(duration); - if (duration.size() == 1) - { - // get the units - std::vector infos = file.getAttrInfos(); - std::string units(""); - for (std::vector::const_iterator it = infos.begin(); it != infos.end(); ++it) - { - if (it->name.compare("units") == 0) + // set more properties on the workspace + try { - units = file.getStrAttr(*it); - break; + // this is a static method that is why it is passing the file path + loadEntryMetadata(m_filename, WS, m_top_entry_name); + } + catch (std::runtime_error & e) + { + // Missing metadata is not a fatal error. Log and go on with your life + g_log.error() << "Error loading metadata: " << e.what() << std::endl; } - } - // set the property - WS->mutableRun().addProperty("duration", duration[0], units); - } - file.closeData(); + // --------------------------- Time filtering ------------------------------------ + double filter_time_start_sec, filter_time_stop_sec; + filter_time_start_sec = getProperty("FilterByTimeStart"); + filter_time_stop_sec = getProperty("FilterByTimeStop"); + chunk = getProperty("ChunkNumber"); + totalChunks = getProperty("TotalChunks"); - // close the file - file.close(); -} + //Default to ALL pulse times + bool is_time_filtered = false; + filter_time_start = Kernel::DateAndTime::minimum(); + filter_time_stop = Kernel::DateAndTime::maximum(); + if (m_allBanksPulseTimes->numPulses > 0) + { + //If not specified, use the limits of doubles. Otherwise, convert from seconds to absolute PulseTime + if (filter_time_start_sec != EMPTY_DBL()) + { + filter_time_start = run_start + filter_time_start_sec; + is_time_filtered = true; + } -//----------------------------------------------------------------------------- -/** Load the instrument from the nexus file or if not found from the IDF file - * specified by the info in the Nexus file - * - * @param nexusfilename :: The Nexus file name - * @param localWorkspace :: MatrixWorkspace in which to put the instrument geometry - * @param top_entry_name :: entry name at the top of the Nexus file - * @param alg :: Handle of the algorithm - * @return true if successful - */ -bool LoadEventNexus::loadInstrument(const std::string & nexusfilename, MatrixWorkspace_sptr localWorkspace, - const std::string & top_entry_name, Algorithm * alg) -{ - bool foundInstrument = runLoadIDFFromNexus( nexusfilename, localWorkspace, top_entry_name, alg); - if (!foundInstrument) foundInstrument = runLoadInstrument( nexusfilename, localWorkspace, top_entry_name, alg ); - return foundInstrument; -} + if (filter_time_stop_sec != EMPTY_DBL()) + { + filter_time_stop = run_start + filter_time_stop_sec; + is_time_filtered = true; + } -//----------------------------------------------------------------------------- -/** Load the instrument from the nexus file - * - * @param nexusfilename :: The name of the nexus file being loaded - * @param localWorkspace :: MatrixWorkspace in which to put the instrument geometry - * @param top_entry_name :: entry name at the top of the Nexus file - * @param alg :: Handle of the algorithm - * @return true if successful - */ -bool LoadEventNexus::runLoadIDFFromNexus(const std::string & nexusfilename, API::MatrixWorkspace_sptr localWorkspace, - const std::string & top_entry_name, Algorithm * alg) -{ - // Test if IDF exists in file, move on quickly if not - try { - ::NeXus::File nxsfile(nexusfilename); - nxsfile.openPath(top_entry_name+"/instrument/instrument_xml"); - } catch (::NeXus::Exception&) { - alg->getLogger().information("No instrument definition found in "+nexusfilename+" at "+top_entry_name+"/instrument"); - return false; - } - - IAlgorithm_sptr loadInst= alg->createChildAlgorithm("LoadIDFFromNexus"); - - // Now execute the Child Algorithm. Catch and log any error, but don't stop. - try - { - loadInst->setPropertyValue("Filename", nexusfilename); - loadInst->setProperty ("Workspace", localWorkspace); - loadInst->setPropertyValue("InstrumentParentPath",top_entry_name); - loadInst->execute(); - } - catch( std::invalid_argument&) - { - alg->getLogger().error("Invalid argument to LoadIDFFromNexus Child Algorithm "); - } - catch (std::runtime_error&) - { - alg->getLogger().debug("No instrument definition found in "+nexusfilename+" at "+top_entry_name+"/instrument"); - } + //Silly values? + if (filter_time_stop < filter_time_start) + { + std::string msg = "Your "; + if(monitors) msg += "monitor "; + msg += "filter for time's Stop value is smaller than the Start value."; + throw std::invalid_argument(msg); + } + } - if ( !loadInst->isExecuted() ) alg->getLogger().information("No IDF loaded from Nexus file."); - return loadInst->isExecuted(); -} + if (is_time_filtered) + { + //Now filter out the run, using the DateAndTime type. + WS->mutableRun().filterByTime(filter_time_start, filter_time_stop); + } -//----------------------------------------------------------------------------- -/** Load the instrument defination file specified by info in the NXS file. - * - * @param nexusfilename :: Used to pick the instrument. - * @param localWorkspace :: MatrixWorkspace in which to put the instrument geometry - * @param top_entry_name :: entry name at the top of the NXS file - * @param alg :: Handle of the algorithm - * @return true if successful - */ -bool LoadEventNexus::runLoadInstrument(const std::string &nexusfilename, MatrixWorkspace_sptr localWorkspace, - const std::string & top_entry_name, Algorithm * alg) -{ - string instrument = ""; - - // Get the instrument name - ::NeXus::File nxfile(nexusfilename); - //Start with the base entry - nxfile.openGroup(top_entry_name, "NXentry"); - // Open the instrument - nxfile.openGroup("instrument", "NXinstrument"); - try - { - nxfile.openData("name"); - instrument = nxfile.getStrData(); - alg->getLogger().debug() << "Instrument name read from NeXus file is " << instrument << std::endl; - } - catch ( ::NeXus::Exception &) - { - // Get the instrument name from the file instead - size_t n = nexusfilename.rfind('/'); - if (n != std::string::npos) - { - std::string temp = nexusfilename.substr(n+1, nexusfilename.size()-n-1); - n = temp.find('_'); - if (n != std::string::npos && n > 0) + if(metaDataOnly) { + //Now, create a default X-vector for histogramming, with just 2 bins. + Kernel::cow_ptr axis; + MantidVec& xRef = axis.access(); + xRef.resize(2); + xRef[0] = static_cast(std::numeric_limits::max()) * 0.1 - 1; //Just to make sure the bins hold it all + xRef[1] = 1; + //Set the binning axis using this. + WS->setAllX(axis); + return; + } + + // --------- Loading only one bank ? ---------------------------------- + std::vector someBanks = getProperty("BankName"); + bool SingleBankPixelsOnly = getProperty("SingleBankPixelsOnly"); + if ((!someBanks.empty()) && (!monitors)) + { + // check that all of the requested banks are in the file + for (auto someBank = someBanks.begin(); someBank != someBanks.end(); ++someBank) + { + bool foundIt = false; + for (auto bankName = bankNames.begin(); bankName != bankNames.end(); ++bankName) + { + if ((*bankName) == (*someBank)+"_events") + { + foundIt = true; + break; + } + } + if (!foundIt) + { + throw std::invalid_argument("No entry named '" + (*someBank) + "' was found in the .NXS file.\n"); + } + } + + // change the number of banks to load + bankNames.clear(); + for (auto someBank = someBanks.begin(); someBank != someBanks.end(); ++someBank) + bankNames.push_back((*someBank) + "_events"); + + // how many events are in a bank + bankNumEvents.clear(); + bankNumEvents.assign(someBanks.size(), 1); // TODO this equally weights the banks + + if( !SingleBankPixelsOnly ) someBanks.clear(); // Marker to load all pixels + } + else + { + someBanks.clear(); + } + + prog->report("Initializing all pixels"); + // Remove used banks if parameter is set + if (WS->getInstrument()->hasParameter("remove-unused-banks")) + { + std::vector instrumentUnused = WS->getInstrument()->getNumberParameter("remove-unused-banks", true); + if (!instrumentUnused.empty()) + { + const int unused = static_cast(instrumentUnused.front()); + if(unused == 1) deleteBanks(WS, bankNames); + } + } + //----------------- Pad Empty Pixels ------------------------------- + // Create the required spectra mapping so that the workspace knows what to pad to + createSpectraMapping(m_filename, monitors, someBanks); + + //This map will be used to find the workspace index + if( this->event_id_is_spec ) + WS->getSpectrumToWorkspaceIndexVector(pixelID_to_wi_vector, pixelID_to_wi_offset); + else + WS->getDetectorIDToWorkspaceIndexVector(pixelID_to_wi_vector, pixelID_to_wi_offset, true); + + // Cache a map for speed. + if (!m_haveWeights) + { + this->makeMapToEventLists(eventVectors); + } + else + { + // Convert to weighted events + for (size_t i=0; i < WS->getNumberHistograms(); i++) + { + WS->getEventList(i).switchTo(API::WEIGHTED); + } + this->makeMapToEventLists(weightedEventVectors); + } + + // Set all (empty) event lists as sorted by pulse time. That way, calling SortEvents will not try to sort these empty lists. + for (size_t i=0; i < WS->getNumberHistograms(); i++) + WS->getEventList(i).setSortOrder(DataObjects::PULSETIME_SORT); + + //Count the limits to time of flight + shortest_tof = static_cast(std::numeric_limits::max()) * 0.1; + longest_tof = 0.; + + // Make the thread pool + ThreadScheduler * scheduler = new ThreadSchedulerMutexes(); + ThreadPool pool(scheduler); + auto diskIOMutex = boost::make_shared(); + size_t bank0 = 0; + size_t bankn = bankNames.size(); + + if (chunk != EMPTY_INT()) // We are loading part - work out the bank number range { - instrument = temp.substr(0, n); + eventsPerChunk = total_events / totalChunks; + // Sort banks by size + size_t tmp; + string stmp; + for (size_t i = 0; i < bankn; i++) + for (size_t j = 0; j < bankn - 1; j++) + if (bankNumEvents[j] < bankNumEvents[j + 1]) + { + tmp = bankNumEvents[j]; + bankNumEvents[j] = bankNumEvents[j + 1]; + bankNumEvents[j + 1] = tmp; + stmp = bankNames[j]; + bankNames[j] = bankNames[j + 1]; + bankNames[j + 1] = stmp; + } + int bigBanks = 0; + for (size_t i = 0; i < bankn; i++) if (bankNumEvents[i] > eventsPerChunk)bigBanks++; + // Each chunk is part of bank or multiple whole banks + // 0.5 for last chunk of a bank with multiple chunks + // 0.1 for multiple whole banks not completely filled + eventsPerChunk += static_cast((static_cast(bigBanks) / static_cast(totalChunks) * + 0.5 + 0.05) * static_cast(eventsPerChunk)); + double partialChunk = 0.; + firstChunkForBank = 1; + for (int chunki = 1; chunki <=chunk; chunki++) + { + if (partialChunk > 1.) + { + partialChunk = 0.; + firstChunkForBank = chunki; + bank0 = bankn; + } + if (bankNumEvents[bank0] > 1) + { + partialChunk += static_cast(eventsPerChunk)/static_cast(bankNumEvents[bank0]); + } + if (chunki < totalChunks) bankn = bank0 + 1; + else bankn = bankNames.size(); + if (chunki == firstChunkForBank && partialChunk > 1.0) bankn += static_cast(partialChunk) - 1; + if (bankn > bankNames.size()) bankn = bankNames.size(); + } + for (size_t i=bank0; i < bankn; i++) + { + size_t start_event = (chunk - firstChunkForBank) * eventsPerChunk; + size_t stop_event = bankNumEvents[i]; + // Don't change stop_event for the final chunk + if ( start_event + eventsPerChunk < stop_event ) stop_event = start_event + eventsPerChunk; + bankNumEvents[i] = stop_event - start_event; + } + } + + // split banks up if the number of cores is more than twice the number of banks + splitProcessing = bool(bankNames.size() * 2 < ThreadPool::getNumPhysicalCores()); + + // set up progress bar for the rest of the (multi-threaded) process + size_t numProg = bankNames.size() * (1 + 3); // 1 = disktask, 3 = proc task + if (splitProcessing) numProg += bankNames.size() * 3; // 3 = second proc task + Progress * prog2 = new Progress(this,0.3,1.0, numProg); + + for (size_t i=bank0; i < bankn; i++) + { + // We make tasks for loading + if (bankNumEvents[i] > 0) + pool.schedule( new LoadBankFromDiskTask(this, bankNames[i], classType, bankNumEvents[i], oldNeXusFileNames, + prog2, diskIOMutex, scheduler) ); } + // Start and end all threads + pool.joinAll(); + diskIOMutex.reset(); + delete prog2; + + + //Info reporting + const std::size_t eventsLoaded = WS->getNumberEvents(); + g_log.information() << "Read " << eventsLoaded << " events" + << ". Shortest TOF: " << shortest_tof << " microsec; longest TOF: " + << longest_tof << " microsec." << std::endl; + + if (shortest_tof < 0) + g_log.warning() << "The shortest TOF was negative! At least 1 event has an invalid time-of-flight." << std::endl; + if (bad_tofs > 0) + g_log.warning() << "Found " << bad_tofs << " events with TOF > 2e8. This may indicate errors in the raw TOF data." << std::endl; + + //Now, create a default X-vector for histogramming, with just 2 bins. + Kernel::cow_ptr axis; + MantidVec& xRef = axis.access(); + xRef.resize(2,0.0); + if ( eventsLoaded > 0) + { + xRef[0] = shortest_tof - 1; //Just to make sure the bins hold it all + xRef[1] = longest_tof + 1; + } + //Set the binning axis using this. + WS->setAllX(axis); + + // if there is time_of_flight load it + loadTimeOfFlight(m_filename, WS, m_top_entry_name,classType); } - } - if (instrument.compare("POWGEN3") == 0) // hack for powgen b/c of bad long name - instrument = "POWGEN"; - if (instrument.compare("NOM") == 0) // hack for nomad - instrument = "NOMAD"; - if (instrument.empty()) - throw std::runtime_error("Could not find the instrument name in the NXS file or using the filename. Cannot load instrument!"); + //----------------------------------------------------------------------------- + /** + * Create a blank event workspace + * @returns A shared pointer to a new empty EventWorkspace object + */ + EventWorkspace_sptr LoadEventNexus::createEmptyEventWorkspace() + { + // Create the output workspace + EventWorkspace_sptr eventWS(new EventWorkspace()); + //Make sure to initialize. + // We can use dummy numbers for arguments, for event workspace it doesn't matter + eventWS->initialize(1,1,1); - // Now let's close the file as we don't need it anymore to load the instrument. - nxfile.close(); + // Set the units + eventWS->getAxis(0)->unit() = UnitFactory::Instance().create("TOF"); + eventWS->setYUnit("Counts"); - // do the actual work - IAlgorithm_sptr loadInst= alg->createChildAlgorithm("LoadInstrument"); + return eventWS; + } - // Now execute the Child Algorithm. Catch and log any error, but don't stop. - bool executionSuccessful(true); - try - { - loadInst->setPropertyValue("InstrumentName", instrument); - loadInst->setProperty ("Workspace", localWorkspace); - loadInst->setProperty("RewriteSpectraMap", false); - loadInst->execute(); - - // Populate the instrument parameters in this workspace - this works around a bug - localWorkspace->populateInstrumentParameters(); - } catch (std::invalid_argument& e) - { - alg->getLogger().information() << "Invalid argument to LoadInstrument Child Algorithm : " << e.what() << std::endl; - executionSuccessful = false; - } catch (std::runtime_error& e) - { - alg->getLogger().information("Unable to successfully run LoadInstrument Child Algorithm"); - alg->getLogger().information(e.what()); - executionSuccessful = false; - } - // If loading instrument definition file fails - if (!executionSuccessful) - { - alg->getLogger().error() << "Error loading Instrument definition file\n"; - return false; - } - - // Ticket #2049: Cleanup all loadinstrument members to a single instance - // If requested update the instrument to positions in the data file - const Geometry::ParameterMap & pmap = localWorkspace->instrumentParameters(); - if( !pmap.contains(localWorkspace->getInstrument()->getComponentID(),"det-pos-source") ) - return executionSuccessful; - - boost::shared_ptr updateDets = pmap.get(localWorkspace->getInstrument()->getComponentID(),"det-pos-source"); - std::string value = updateDets->value(); - if(value.substr(0,8) == "datafile" ) - { - IAlgorithm_sptr updateInst = alg->createChildAlgorithm("UpdateInstrumentFromFile"); - updateInst->setProperty("Workspace", localWorkspace); - updateInst->setPropertyValue("Filename", nexusfilename); - if(value == "datafile-ignore-phi" ) + //----------------------------------------------------------------------------- + /** Load the run number and other meta data from the given bank */ + void LoadEventNexus::loadEntryMetadata(const std::string &nexusfilename, Mantid::API::MatrixWorkspace_sptr WS, + const std::string &entry_name) { - updateInst->setProperty("IgnorePhi", true); - alg->getLogger().information("Detector positions in IDF updated with positions in the data file except for the phi values"); + // Open the file + ::NeXus::File file(nexusfilename); + file.openGroup(entry_name, "NXentry"); + + // get the title + file.openData("title"); + if (file.getInfo().type == ::NeXus::CHAR) { + string title = file.getStrData(); + if (!title.empty()) + WS->setTitle(title); + } + file.closeData(); + + // get the notes + try { + file.openData("notes"); + if (file.getInfo().type == ::NeXus::CHAR) { + string notes = file.getStrData(); + if (!notes.empty()) + WS->mutableRun().addProperty("file_notes", notes); + } + file.closeData(); + } catch (::NeXus::Exception &) { + // let it drop on floor + } + + // Get the run number + file.openData("run_number"); + string run(""); + if (file.getInfo().type == ::NeXus::CHAR) { + run = file.getStrData(); + }else if (file.isDataInt()){ + // inside ISIS the run_number type is int32 + vector value; + file.getData(value); + if (value.size() > 0) + run = boost::lexical_cast(value[0]); + } + if (!run.empty()) { + WS->mutableRun().addProperty("run_number", run); + } + file.closeData(); + + // get the experiment identifier + try { + file.openData("experiment_identifier"); + string expId(""); + if (file.getInfo().type == ::NeXus::CHAR) + { + expId = file.getStrData(); + } + if (!expId.empty()) { + WS->mutableRun().addProperty("experiment_identifier", expId); + } + file.closeData(); + } catch (::NeXus::Exception &) { + // let it drop on floor + } + + // get the sample name + try { + file.openGroup("sample", "NXsample"); + file.openData("name"); + string name(""); + if (file.getInfo().type == ::NeXus::CHAR) + { + name = file.getStrData(); + } + if (!name.empty()) { + WS->mutableSample().setName(name); + } + file.closeData(); + file.closeGroup(); + } catch (::NeXus::Exception &) { + // let it drop on floor + } + + // get the duration + file.openData("duration"); + std::vector duration; + file.getDataCoerce(duration); + if (duration.size() == 1) + { + // get the units + std::vector infos = file.getAttrInfos(); + std::string units(""); + for (std::vector::const_iterator it = infos.begin(); it != infos.end(); ++it) + { + if (it->name.compare("units") == 0) + { + units = file.getStrAttr(*it); + break; + } + } + + // set the property + WS->mutableRun().addProperty("duration", duration[0], units); + } + file.closeData(); + + // close the file + file.close(); } - else + + + //----------------------------------------------------------------------------- + /** Load the instrument from the nexus file or if not found from the IDF file + * specified by the info in the Nexus file + * + * @param nexusfilename :: The Nexus file name + * @param localWorkspace :: MatrixWorkspace in which to put the instrument geometry + * @param top_entry_name :: entry name at the top of the Nexus file + * @param alg :: Handle of the algorithm + * @return true if successful + */ + bool LoadEventNexus::loadInstrument(const std::string & nexusfilename, MatrixWorkspace_sptr localWorkspace, + const std::string & top_entry_name, Algorithm * alg) { - alg->getLogger().information("Detector positions in IDF updated with positions in the data file"); + bool foundInstrument = runLoadIDFFromNexus( nexusfilename, localWorkspace, top_entry_name, alg); + if (!foundInstrument) foundInstrument = runLoadInstrument( nexusfilename, localWorkspace, top_entry_name, alg ); + return foundInstrument; } - // We want this to throw if it fails to warn the user that the information is not correct. - updateInst->execute(); - } - return executionSuccessful; -} + //----------------------------------------------------------------------------- + /** Load the instrument from the nexus file + * + * @param nexusfilename :: The name of the nexus file being loaded + * @param localWorkspace :: MatrixWorkspace in which to put the instrument geometry + * @param top_entry_name :: entry name at the top of the Nexus file + * @param alg :: Handle of the algorithm + * @return true if successful + */ + bool LoadEventNexus::runLoadIDFFromNexus(const std::string & nexusfilename, API::MatrixWorkspace_sptr localWorkspace, + const std::string & top_entry_name, Algorithm * alg) + { + // Test if IDF exists in file, move on quickly if not + try { + ::NeXus::File nxsfile(nexusfilename); + nxsfile.openPath(top_entry_name+"/instrument/instrument_xml"); + } catch (::NeXus::Exception&) { + alg->getLogger().information("No instrument definition found in "+nexusfilename+" at "+top_entry_name+"/instrument"); + return false; + } + IAlgorithm_sptr loadInst= alg->createChildAlgorithm("LoadIDFFromNexus"); -//----------------------------------------------------------------------------- -/** - * Create the required spectra mapping. If the file contains an isis_vms_compat block then - * the mapping is read from there, otherwise a 1:1 map with the instrument is created (along - * with the associated spectra axis) - * @param workspace :: The workspace to contain the spectra mapping - * @param bankNames :: Bank names that are in Nexus file - */ -void LoadEventNexus::deleteBanks(API::MatrixWorkspace_sptr workspace, std::vector bankNames) -{ - Instrument_sptr inst = boost::const_pointer_cast(workspace->getInstrument()->baseInstrument()); - //Build a list of Rectangular Detectors - std::vector > detList; - for (int i=0; i < inst->nelements(); i++) + // Now execute the Child Algorithm. Catch and log any error, but don't stop. + try + { + loadInst->setPropertyValue("Filename", nexusfilename); + loadInst->setProperty ("Workspace", localWorkspace); + loadInst->setPropertyValue("InstrumentParentPath",top_entry_name); + loadInst->execute(); + } + catch( std::invalid_argument&) + { + alg->getLogger().error("Invalid argument to LoadIDFFromNexus Child Algorithm "); + } + catch (std::runtime_error&) + { + alg->getLogger().debug("No instrument definition found in "+nexusfilename+" at "+top_entry_name+"/instrument"); + } + + if ( !loadInst->isExecuted() ) alg->getLogger().information("No IDF loaded from Nexus file."); + return loadInst->isExecuted(); + } + /** method used to return instrument name for some old ISIS files where it is not written properly within the instrument + * @param hFile :: A reference to the NeXus file opened at the root entry + */ + std::string LoadEventNexus::readInstrumentFromISIS_VMSCompat(::NeXus::File &hFile) { - boost::shared_ptr det; - boost::shared_ptr assem; - boost::shared_ptr assem2; + std::string instrumentName(""); + try + { + hFile.openGroup("isis_vms_compat","IXvms"); + } + catch(std::runtime_error &) + { + return instrumentName; + } + try + { + hFile.openData("NAME"); + } + catch(std::runtime_error &) + { + hFile.closeGroup(); + return instrumentName; + } + + instrumentName = hFile.getStrData(); + hFile.closeData(); + hFile.closeGroup(); - det = boost::dynamic_pointer_cast( (*inst)[i] ); - if (det) + return instrumentName; + } + + + //----------------------------------------------------------------------------- + /** Load the instrument definition file specified by info in the NXS file. + * + * @param nexusfilename :: Used to pick the instrument. + * @param localWorkspace :: MatrixWorkspace in which to put the instrument geometry + * @param top_entry_name :: entry name at the top of the NXS file + * @param alg :: Handle of the algorithm + * @return true if successful + */ + bool LoadEventNexus::runLoadInstrument(const std::string &nexusfilename, MatrixWorkspace_sptr localWorkspace, + const std::string & top_entry_name, Algorithm * alg) + { + string instrument = ""; + + // Get the instrument name + ::NeXus::File nxfile(nexusfilename); + //Start with the base entry + nxfile.openGroup(top_entry_name, "NXentry"); + // Open the instrument + nxfile.openGroup("instrument", "NXinstrument"); + try { - detList.push_back(det); + nxfile.openData("name"); + instrument = nxfile.getStrData(); + alg->getLogger().debug() << "Instrument name read from NeXus file is " << instrument << std::endl; } - else + catch ( ::NeXus::Exception &) { - //Also, look in the first sub-level for RectangularDetectors (e.g. PG3). - // We are not doing a full recursive search since that will be very long for lots of pixels. - assem = boost::dynamic_pointer_cast( (*inst)[i] ); - if (assem) + // Try to fall back to isis compatibility options + nxfile.closeGroup(); + instrument = readInstrumentFromISIS_VMSCompat(nxfile); + if (instrument.empty()) { - for (int j=0; j < assem->nelements(); j++) + // Get the instrument name from the file instead + size_t n = nexusfilename.rfind('/'); + if (n != std::string::npos) { - det = boost::dynamic_pointer_cast( (*assem)[j] ); - if (det) + std::string temp = nexusfilename.substr(n+1, nexusfilename.size()-n-1); + n = temp.find('_'); + if (n != std::string::npos && n > 0) { - detList.push_back(det); - + instrument = temp.substr(0, n); } - else + } + } + } + if (instrument.compare("POWGEN3") == 0) // hack for powgen b/c of bad long name + instrument = "POWGEN"; + if (instrument.compare("NOM") == 0) // hack for nomad + instrument = "NOMAD"; + + if (instrument.empty()) + throw std::runtime_error("Could not find the instrument name in the NXS file or using the filename. Cannot load instrument!"); + + // Now let's close the file as we don't need it anymore to load the instrument. + nxfile.close(); + + // do the actual work + IAlgorithm_sptr loadInst= alg->createChildAlgorithm("LoadInstrument"); + + // Now execute the Child Algorithm. Catch and log any error, but don't stop. + bool executionSuccessful(true); + try + { + loadInst->setPropertyValue("InstrumentName", instrument); + loadInst->setProperty ("Workspace", localWorkspace); + loadInst->setProperty("RewriteSpectraMap", false); + loadInst->execute(); + + // Populate the instrument parameters in this workspace - this works around a bug + localWorkspace->populateInstrumentParameters(); + } catch (std::invalid_argument& e) + { + alg->getLogger().information() << "Invalid argument to LoadInstrument Child Algorithm : " << e.what() << std::endl; + executionSuccessful = false; + } catch (std::runtime_error& e) + { + alg->getLogger().information("Unable to successfully run LoadInstrument Child Algorithm"); + alg->getLogger().information(e.what()); + executionSuccessful = false; + } + + // If loading instrument definition file fails + if (!executionSuccessful) + { + alg->getLogger().error() << "Error loading Instrument definition file\n"; + return false; + } + + // Ticket #2049: Cleanup all loadinstrument members to a single instance + // If requested update the instrument to positions in the data file + const Geometry::ParameterMap & pmap = localWorkspace->instrumentParameters(); + if( !pmap.contains(localWorkspace->getInstrument()->getComponentID(),"det-pos-source") ) + return executionSuccessful; + + boost::shared_ptr updateDets = pmap.get(localWorkspace->getInstrument()->getComponentID(),"det-pos-source"); + std::string value = updateDets->value(); + if(value.substr(0,8) == "datafile" ) + { + IAlgorithm_sptr updateInst = alg->createChildAlgorithm("UpdateInstrumentFromFile"); + updateInst->setProperty("Workspace", localWorkspace); + updateInst->setPropertyValue("Filename", nexusfilename); + if(value == "datafile-ignore-phi" ) + { + updateInst->setProperty("IgnorePhi", true); + alg->getLogger().information("Detector positions in IDF updated with positions in the data file except for the phi values"); + } + else + { + alg->getLogger().information("Detector positions in IDF updated with positions in the data file"); + } + // We want this to throw if it fails to warn the user that the information is not correct. + updateInst->execute(); + } + + return executionSuccessful; + } + + + //----------------------------------------------------------------------------- + /** + * Create the required spectra mapping. If the file contains an isis_vms_compat block then + * the mapping is read from there, otherwise a 1:1 map with the instrument is created (along + * with the associated spectra axis) + * @param workspace :: The workspace to contain the spectra mapping + * @param bankNames :: Bank names that are in Nexus file + */ + void LoadEventNexus::deleteBanks(API::MatrixWorkspace_sptr workspace, std::vector bankNames) + { + Instrument_sptr inst = boost::const_pointer_cast(workspace->getInstrument()->baseInstrument()); + //Build a list of Rectangular Detectors + std::vector > detList; + for (int i=0; i < inst->nelements(); i++) + { + boost::shared_ptr det; + boost::shared_ptr assem; + boost::shared_ptr assem2; + + det = boost::dynamic_pointer_cast( (*inst)[i] ); + if (det) + { + detList.push_back(det); + } + else + { + //Also, look in the first sub-level for RectangularDetectors (e.g. PG3). + // We are not doing a full recursive search since that will be very long for lots of pixels. + assem = boost::dynamic_pointer_cast( (*inst)[i] ); + if (assem) + { + for (int j=0; j < assem->nelements(); j++) { - //Also, look in the second sub-level for RectangularDetectors (e.g. PG3). - // We are not doing a full recursive search since that will be very long for lots of pixels. - assem2 = boost::dynamic_pointer_cast( (*assem)[j] ); - if (assem2) + det = boost::dynamic_pointer_cast( (*assem)[j] ); + if (det) + { + detList.push_back(det); + + } + else { - for (int k=0; k < assem2->nelements(); k++) + //Also, look in the second sub-level for RectangularDetectors (e.g. PG3). + // We are not doing a full recursive search since that will be very long for lots of pixels. + assem2 = boost::dynamic_pointer_cast( (*assem)[j] ); + if (assem2) { - det = boost::dynamic_pointer_cast( (*assem2)[k] ); - if (det) + for (int k=0; k < assem2->nelements(); k++) { - detList.push_back(det); + det = boost::dynamic_pointer_cast( (*assem2)[k] ); + if (det) + { + detList.push_back(det); + } } } } @@ -2047,650 +2131,751 @@ void LoadEventNexus::deleteBanks(API::MatrixWorkspace_sptr workspace, std::vecto } } } - } - if (detList.size() == 0) return; - for (int i = 0; i(detList.size()); i++) - { + if (detList.size() == 0) return; + for (int i = 0; i(detList.size()); i++) + { bool keep = false; boost::shared_ptr det = detList[i]; std::string det_name = det->getName(); for (int j = 0; j(bankNames.size()); j++) { - size_t pos = bankNames[j].find("_events"); - if(det_name.compare(bankNames[j].substr(0,pos)) == 0) keep = true; - if(keep) break; + size_t pos = bankNames[j].find("_events"); + if(det_name.compare(bankNames[j].substr(0,pos)) == 0) keep = true; + if(keep) break; } if (!keep) { - boost::shared_ptr parent = inst->getComponentByName(det_name); - std::vector children; - boost::shared_ptr asmb = boost::dynamic_pointer_cast(parent); - asmb->getChildren(children, false); - for (int col = 0; col(children.size()); col++) - { - boost::shared_ptr asmb2 = boost::dynamic_pointer_cast(children[col]); - std::vector grandchildren; - asmb2->getChildren(grandchildren,false); + boost::shared_ptr parent = inst->getComponentByName(det_name); + std::vector children; + boost::shared_ptr asmb = boost::dynamic_pointer_cast(parent); + asmb->getChildren(children, false); + for (int col = 0; col(children.size()); col++) + { + boost::shared_ptr asmb2 = boost::dynamic_pointer_cast(children[col]); + std::vector grandchildren; + asmb2->getChildren(grandchildren,false); - for (int row = 0; row(grandchildren.size()); row++) - { - Detector* d = dynamic_cast(const_cast(grandchildren[row].get())); - inst->removeDetector(d); - } + for (int row = 0; row(grandchildren.size()); row++) + { + Detector* d = dynamic_cast(const_cast(grandchildren[row].get())); + inst->removeDetector(d); } - IComponent* comp = dynamic_cast(detList[i].get()); - inst->remove(comp); + } + IComponent* comp = dynamic_cast(detList[i].get()); + inst->remove(comp); } - } + } return; -} -//----------------------------------------------------------------------------- -/** - * Create the required spectra mapping. If the file contains an isis_vms_compat block then - * the mapping is read from there, otherwise a 1:1 map with the instrument is created (along - * with the associated spectra axis) - * @param nxsfile :: The name of a nexus file to load the mapping from - * @param monitorsOnly :: Load only the monitors is true - * @param bankNames :: An optional bank name for loading specified banks - */ -void LoadEventNexus::createSpectraMapping(const std::string &nxsfile, - const bool monitorsOnly, const std::vector &bankNames) -{ - bool spectramap = false; - // set up the - if( !monitorsOnly && !bankNames.empty() ) - { - std::vector allDets; - - for (auto name = bankNames.begin(); name != bankNames.end(); ++name) - { - // Only build the map for the single bank - std::vector dets; - WS->getInstrument()->getDetectorsInBank(dets, (*name)); - if (dets.empty()) - throw std::runtime_error("Could not find the bank named '" + (*name) + - "' as a component assembly in the instrument tree; or it did not contain any detectors." - " Try unchecking SingleBankPixelsOnly."); - allDets.insert(allDets.end(), dets.begin(), dets.end()); } - if (!allDets.empty()) + //----------------------------------------------------------------------------- + /** + * Create the required spectra mapping. If the file contains an isis_vms_compat block then + * the mapping is read from there, otherwise a 1:1 map with the instrument is created (along + * with the associated spectra axis) + * @param nxsfile :: The name of a nexus file to load the mapping from + * @param monitorsOnly :: Load only the monitors is true + * @param bankNames :: An optional bank name for loading specified banks + */ + void LoadEventNexus::createSpectraMapping(const std::string &nxsfile, + const bool monitorsOnly, const std::vector &bankNames) { - WS->resizeTo(allDets.size()); - // Make an event list for each. - for(size_t wi=0; wi < allDets.size(); wi++) + bool spectramap = false; + m_specMin = getProperty("SpectrumMin"); + m_specMax = getProperty("SpectrumMax"); + m_specList = getProperty("SpectrumList"); + + // set up the + if( !monitorsOnly && !bankNames.empty() ) { - const detid_t detID = allDets[wi]->getID(); - WS->getSpectrum(wi)->setDetectorID(detID); - } - spectramap = true; - g_log.debug() << "Populated spectra map for select banks\n"; - } + std::vector allDets; - } - else - { - spectramap = loadSpectraMapping(nxsfile, monitorsOnly, m_top_entry_name); - // Did we load one? If so then the event ID is the spectrum number and not det ID - if( spectramap ) this->event_id_is_spec = true; - } + for (auto name = bankNames.begin(); name != bankNames.end(); ++name) + { + // Only build the map for the single bank + std::vector dets; + WS->getInstrument()->getDetectorsInBank(dets, (*name)); + if (dets.empty()) + throw std::runtime_error("Could not find the bank named '" + (*name) + + "' as a component assembly in the instrument tree; or it did not contain any detectors." + " Try unchecking SingleBankPixelsOnly."); + allDets.insert(allDets.end(), dets.begin(), dets.end()); + } + if (!allDets.empty()) + { + WS->resizeTo(allDets.size()); + // Make an event list for each. + for(size_t wi=0; wi < allDets.size(); wi++) + { + const detid_t detID = allDets[wi]->getID(); + WS->getSpectrum(wi)->setDetectorID(detID); + } + spectramap = true; + g_log.debug() << "Populated spectra map for select banks\n"; + } - if( !spectramap ) - { - g_log.debug() << "No custom spectra mapping found, continuing with default 1:1 mapping of spectrum:detectorID\n"; - // The default 1:1 will suffice but exclude the monitors as they are always in a separate workspace - WS->padSpectra(); - g_log.debug() << "Populated 1:1 spectra map for the whole instrument \n"; - } -} + } + else + { + spectramap = loadSpectraMapping(nxsfile, monitorsOnly, m_top_entry_name); + // Did we load one? If so then the event ID is the spectrum number and not det ID + if( spectramap ) this->event_id_is_spec = true; + } -//----------------------------------------------------------------------------- -/** - * Returns whether the file contains monitors with events in them - * @returns True if the file contains monitors with event data, false otherwise - */ -bool LoadEventNexus::hasEventMonitors() -{ - bool result(false); - // Determine whether to load histograms or events - try - { - ::NeXus::File file(m_filename); - file.openPath(m_top_entry_name); - //Start with the base entry - typedef std::map string_map_t; - //Now we want to go through and find the monitors - string_map_t entries = file.getEntries(); - for( string_map_t::const_iterator it = entries.begin(); it != entries.end(); ++it) - { - if( it->second == "NXmonitor" ) + if( !spectramap ) { - file.openGroup(it->first, it->second); - break; + g_log.debug() << "No custom spectra mapping found, continuing with default 1:1 mapping of spectrum:detectorID\n"; + auto specList= WS->getInstrument()->getDetectorIDs(true); + createSpectraList(*std::min_element(specList.begin(),specList.end()),*std::max_element(specList.begin(),specList.end())); + // The default 1:1 will suffice but exclude the monitors as they are always in a separate workspace + WS->padSpectra(m_specList); + g_log.debug() << "Populated 1:1 spectra map for the whole instrument \n"; } } - file.openData("event_id"); - result = true; - file.close(); - } - catch(::NeXus::Exception &) - { - result = false; - } - return result; -} -//----------------------------------------------------------------------------- -/** - * Load the Monitors from the NeXus file into a workspace. The original - * workspace name is used and appended with _monitors. - */ -void LoadEventNexus::runLoadMonitors() -{ - std::string mon_wsname = this->getProperty("OutputWorkspace"); - mon_wsname.append("_monitors"); - - IAlgorithm_sptr loadMonitors = this->createChildAlgorithm("LoadNexusMonitors"); - try - { - g_log.information("Loading monitors from NeXus file..."); - loadMonitors->setPropertyValue("Filename", m_filename); - g_log.information() << "New workspace name for monitors: " << mon_wsname << std::endl; - loadMonitors->setPropertyValue("OutputWorkspace", mon_wsname); - loadMonitors->execute(); - MatrixWorkspace_sptr mons = loadMonitors->getProperty("OutputWorkspace"); - this->declareProperty(new WorkspaceProperty<>("MonitorWorkspace", - mon_wsname, Direction::Output), "Monitors from the Event NeXus file"); - this->setProperty("MonitorWorkspace", mons); - // Set the internal monitor workspace pointer as well - WS->setMonitorWorkspace(mons); - - filterDuringPause(mons); - } - catch (...) - { - g_log.error("Error while loading the monitors from the file. File may contain no monitors."); - } -} - -// -/** - * Load a spectra mapping from the given file. This currently checks for the existence of - * an isis_vms_compat block in the file, if it exists it pulls out the spectra mapping listed there - * @param filename :: A filename - * @param monitorsOnly :: If true then only the monitor spectra are loaded - * @param entry_name :: name of the NXentry to open. - * @returns True if the mapping was loaded or false if the block does not exist - */ -bool LoadEventNexus::loadSpectraMapping(const std::string& filename, const bool monitorsOnly, const std::string& entry_name ) -{ - ::NeXus::File file(filename); - try - { - g_log.debug() << "Attempting to load custom spectra mapping from '" << entry_name << "/isis_vms_compat'.\n"; - file.openPath(entry_name + "/isis_vms_compat"); - } - catch(::NeXus::Exception&) - { - return false; // Doesn't exist - } - - // The ISIS spectrum mapping is defined by 2 arrays in isis_vms_compat block: - // UDET - An array of detector IDs - // SPEC - An array of spectrum numbers - // There sizes must match. Hardware allows more than one detector ID to be mapped to a single spectrum - // and this is encoded in the SPEC/UDET arrays by repeating the spectrum number in the array - // for each mapped detector, e.g. - // - // 1 1001 - // 1 1002 - // 2 2001 - // 3 3001 - // - // defines 3 spectra, where the first spectrum contains 2 detectors - - // UDET - file.openData("UDET"); - std::vector udet; - file.getData(udet); - file.closeData(); - // SPEC - file.openData("SPEC"); - std::vector spec; - file.getData(spec); - file.closeData(); - // Close - file.closeGroup(); - file.close(); - - // The spec array will contain a spectrum number for each udet but the spectrum number - // may be the same for more that one detector - const size_t ndets(udet.size()); - if( ndets != spec.size() ) - { - std::ostringstream os; - os << "UDET/SPEC list size mismatch. UDET=" << udet.size() << ", SPEC=" << spec.size() << "\n"; - throw std::runtime_error(os.str()); - } - // Monitor filtering/selection - const std::vector monitors = WS->getInstrument()->getMonitors(); - const size_t nmons(monitors.size()); - if( monitorsOnly ) - { - g_log.debug() << "Loading only monitor spectra from " << filename << "\n"; - // Find the det_ids in the udet array. - WS->resizeTo(nmons); - for( size_t i = 0; i < nmons; ++i ) + //----------------------------------------------------------------------------- + /** + * Returns whether the file contains monitors with events in them + * @returns True if the file contains monitors with event data, false otherwise + */ + bool LoadEventNexus::hasEventMonitors() { - // Find the index in the udet array - const detid_t & id = monitors[i]; - std::vector::const_iterator it = std::find(udet.begin(), udet.end(), id); - if( it != udet.end() ) + bool result(false); + // Determine whether to load histograms or events + try { - auto spectrum = WS->getSpectrum(i); - const specid_t & specNo = spec[it - udet.begin()]; - spectrum->setSpectrumNo(specNo); - spectrum->setDetectorID(id); + ::NeXus::File file(m_filename); + file.openPath(m_top_entry_name); + //Start with the base entry + typedef std::map string_map_t; + //Now we want to go through and find the monitors + string_map_t entries = file.getEntries(); + for( string_map_t::const_iterator it = entries.begin(); it != entries.end(); ++it) + { + if( it->second == "NXmonitor" ) + { + file.openGroup(it->first, it->second); + break; + } + } + file.openData("event_id"); + result = true; + file.close(); } + catch(::NeXus::Exception &) + { + result = false; + } + return result; } - } - else - { - g_log.debug() << "Loading only detector spectra from " << filename << "\n"; - SpectrumDetectorMapping mapping(spec,udet, monitors); - WS->resizeTo(mapping.getMapping().size()); - // Make sure spectrum numbers are correct - auto uniqueSpectra = mapping.getSpectrumNumbers(); - auto itend = uniqueSpectra.end(); - size_t counter = 0; - for(auto it = uniqueSpectra.begin(); it != itend; ++it) - { - WS->getSpectrum(counter)->setSpectrumNo(*it); - ++counter; - } - // Fill detectors based on this mapping - WS->updateSpectraUsing(mapping); - } - return true; -} - -/** - * Set the filters on TOF. - * @param monitors :: If true check the monitor properties else use the standard ones - */ -void LoadEventNexus::setTimeFilters(const bool monitors) -{ - //Get the limits to the filter - std::string prefix("Filter"); - if(monitors) prefix += "Mon"; - - filter_tof_min = getProperty(prefix + "ByTofMin"); - filter_tof_max = getProperty(prefix + "ByTofMax"); - if ( (filter_tof_min == EMPTY_DBL()) && (filter_tof_max == EMPTY_DBL())) - { - //Nothing specified. Include everything - filter_tof_min = -1e20; - filter_tof_max = +1e20; - } - else if ( (filter_tof_min != EMPTY_DBL()) && (filter_tof_max != EMPTY_DBL())) - { - //Both specified. Keep these values - } - else - { - std::string msg("You must specify both min & max or neither TOF filters"); - if(monitors) msg = " for the monitors."; - throw std::invalid_argument(msg); - } - -} -//----------------------------------------------------------------------------- -// ISIS event corrections -//----------------------------------------------------------------------------- -/** - * Check if time_of_flight can be found in the file and load it - * @param nexusfilename :: The name of the ISIS nexus event file. - * @param WS :: The event workspace which events will be modified. - * @param entry_name :: An NXentry tag in the file - * @param classType :: The type of the events: either detector or monitor - */ -void LoadEventNexus::loadTimeOfFlight(const std::string &nexusfilename, DataObjects::EventWorkspace_sptr WS, - const std::string &entry_name, const std::string &classType) -{ - bool done = false; - // Open the file - ::NeXus::File file(nexusfilename); - file.openGroup(entry_name, "NXentry"); - - typedef std::map string_map_t; - string_map_t entries = file.getEntries(); - - if (entries.find("detector_1_events") == entries.end()) - {// not an ISIS file - return; - } - - // try if monitors have their own bins - if (classType == "NXmonitor") - { - std::vector bankNames; - for (string_map_t::const_iterator it = entries.begin(); it != entries.end(); ++it) + //----------------------------------------------------------------------------- + /** + * Load the Monitors from the NeXus file into a workspace. The original + * workspace name is used and appended with _monitors. + */ + void LoadEventNexus::runLoadMonitors() { - std::string entry_name(it->first); - std::string entry_class(it->second); - if ( entry_class == classType ) + std::string mon_wsname = this->getProperty("OutputWorkspace"); + mon_wsname.append("_monitors"); + + IAlgorithm_sptr loadMonitors = this->createChildAlgorithm("LoadNexusMonitors"); + try { - bankNames.push_back( entry_name ); + g_log.information("Loading monitors from NeXus file..."); + loadMonitors->setPropertyValue("Filename", m_filename); + g_log.information() << "New workspace name for monitors: " << mon_wsname << std::endl; + loadMonitors->setPropertyValue("OutputWorkspace", mon_wsname); + loadMonitors->execute(); + MatrixWorkspace_sptr mons = loadMonitors->getProperty("OutputWorkspace"); + this->declareProperty(new WorkspaceProperty<>("MonitorWorkspace", + mon_wsname, Direction::Output), "Monitors from the Event NeXus file"); + this->setProperty("MonitorWorkspace", mons); + // Set the internal monitor workspace pointer as well + WS->setMonitorWorkspace(mons); + + filterDuringPause(mons); + } + catch (...) + { + g_log.error("Error while loading the monitors from the file. File may contain no monitors."); } } - for(size_t i = 0; i < bankNames.size(); ++i) + + // + /** + * Load a spectra mapping from the given file. This currently checks for the existence of + * an isis_vms_compat block in the file, if it exists it pulls out the spectra mapping listed there + * @param filename :: A filename + * @param monitorsOnly :: If true then only the monitor spectra are loaded + * @param entry_name :: name of the NXentry to open. + * @returns True if the mapping was loaded or false if the block does not exist + */ + bool LoadEventNexus::loadSpectraMapping(const std::string& filename, const bool monitorsOnly, const std::string& entry_name ) { - const std::string& mon = bankNames[i]; - file.openGroup(mon,classType); - entries = file.getEntries(); - string_map_t::const_iterator bins = entries.find("event_time_bins"); - if (bins == entries.end()) - { - //bins = entries.find("time_of_flight"); // I think time_of_flight doesn't work here - //if (bins == entries.end()) - //{ - done = false; - file.closeGroup(); - break; // done == false => use bins from the detectors - //} + ::NeXus::File file(filename); + try + { + g_log.debug() << "Attempting to load custom spectra mapping from '" << entry_name << "/isis_vms_compat'.\n"; + file.openPath(entry_name + "/isis_vms_compat"); } - done = true; - loadTimeOfFlightData(file,WS,bins->first,i,i+1); + catch(::NeXus::Exception&) + { + return false; // Doesn't exist + } + + // The ISIS spectrum mapping is defined by 2 arrays in isis_vms_compat block: + // UDET - An array of detector IDs + // SPEC - An array of spectrum numbers + // There sizes must match. Hardware allows more than one detector ID to be mapped to a single spectrum + // and this is encoded in the SPEC/UDET arrays by repeating the spectrum number in the array + // for each mapped detector, e.g. + // + // 1 1001 + // 1 1002 + // 2 2001 + // 3 3001 + // + // defines 3 spectra, where the first spectrum contains 2 detectors + + // UDET + file.openData("UDET"); + std::vector udet; + file.getData(udet); + file.closeData(); + // SPEC + file.openData("SPEC"); + std::vector spec; + file.getData(spec); + file.closeData(); + // Close file.closeGroup(); - } - } + file.close(); - if (!done) - { - // first check detector_1_events - file.openGroup("detector_1_events", "NXevent_data"); - entries = file.getEntries(); - for(string_map_t::const_iterator it = entries.begin();it != entries.end(); ++it) + // The spec array will contain a spectrum number for each udet but the spectrum number + // may be the same for more that one detector + const size_t ndets(udet.size()); + if( ndets != spec.size() ) + { + std::ostringstream os; + os << "UDET/SPEC list size mismatch. UDET=" << udet.size() << ", SPEC=" << spec.size() << "\n"; + throw std::runtime_error(os.str()); + } + // Monitor filtering/selection + const std::vector monitors = WS->getInstrument()->getMonitors(); + const size_t nmons(monitors.size()); + if( monitorsOnly ) + { + g_log.debug() << "Loading only monitor spectra from " << filename << "\n"; + // Find the det_ids in the udet array. + WS->resizeTo(nmons); + for( size_t i = 0; i < nmons; ++i ) + { + // Find the index in the udet array + const detid_t & id = monitors[i]; + std::vector::const_iterator it = std::find(udet.begin(), udet.end(), id); + if( it != udet.end() ) + { + auto spectrum = WS->getSpectrum(i); + const specid_t & specNo = spec[it - udet.begin()]; + spectrum->setSpectrumNo(specNo); + spectrum->setDetectorID(id); + } + } + } + else + { + g_log.debug() << "Loading only detector spectra from " << filename << "\n"; + + // If optional spectra are provided, if so, m_specList is initialized. spec is used if necessary + createSpectraList(*std::min_element(spec.begin(),spec.end()), *std::max_element(spec.begin(),spec.end())); + + if ( !m_specList.empty() ) { + int i=0; + std::vector spec_temp, udet_temp; + for(auto it=spec.begin(); it!=spec.end(); it++) + { + if ( find(m_specList.begin(),m_specList.end(),*it)!= m_specList.end() ) // spec element *it is not in spec_list + { + spec_temp.push_back( *it ); + udet_temp.push_back( udet.at(i) ); + } + i++; + } + spec=spec_temp; + udet=udet_temp; + } + + SpectrumDetectorMapping mapping(spec,udet, monitors); + WS->resizeTo(mapping.getMapping().size()); + // Make sure spectrum numbers are correct + auto uniqueSpectra = mapping.getSpectrumNumbers(); + auto itend = uniqueSpectra.end(); + size_t counter = 0; + for(auto it = uniqueSpectra.begin(); it != itend; ++it) + { + WS->getSpectrum(counter)->setSpectrumNo(*it); + ++counter; + } + // Fill detectors based on this mapping + WS->updateSpectraUsing(mapping); + } + return true; + } + + /** + * Set the filters on TOF. + * @param monitors :: If true check the monitor properties else use the standard ones + */ + void LoadEventNexus::setTimeFilters(const bool monitors) { - if (it->first == "time_of_flight" || it->first == "event_time_bins") + //Get the limits to the filter + std::string prefix("Filter"); + if(monitors) prefix += "Mon"; + + filter_tof_min = getProperty(prefix + "ByTofMin"); + filter_tof_max = getProperty(prefix + "ByTofMax"); + if ( (filter_tof_min == EMPTY_DBL()) && (filter_tof_max == EMPTY_DBL())) + { + //Nothing specified. Include everything + filter_tof_min = -1e20; + filter_tof_max = +1e20; + } + else if ( (filter_tof_min != EMPTY_DBL()) && (filter_tof_max != EMPTY_DBL())) { - loadTimeOfFlightData(file,WS,it->first); - done = true; + //Both specified. Keep these values } + else + { + std::string msg("You must specify both min & max or neither TOF filters"); + if(monitors) msg = " for the monitors."; + throw std::invalid_argument(msg); + } + } - file.closeGroup(); // detector_1_events - if (!done) // if time_of_flight was not found try instrument/dae/time_channels_# + //----------------------------------------------------------------------------- + // ISIS event corrections + //----------------------------------------------------------------------------- + /** + * Check if time_of_flight can be found in the file and load it + * @param nexusfilename :: The name of the ISIS nexus event file. + * @param WS :: The event workspace which events will be modified. + * @param entry_name :: An NXentry tag in the file + * @param classType :: The type of the events: either detector or monitor + */ + void LoadEventNexus::loadTimeOfFlight(const std::string &nexusfilename, DataObjects::EventWorkspace_sptr WS, + const std::string &entry_name, const std::string &classType) { - file.openGroup("instrument","NXinstrument"); - file.openGroup("dae","IXdae"); - entries = file.getEntries(); - size_t time_channels_number = 0; - for(string_map_t::const_iterator it = entries.begin();it != entries.end(); ++it) + bool done = false; + // Open the file + ::NeXus::File file(nexusfilename); + file.openGroup(entry_name, "NXentry"); + + typedef std::map string_map_t; + string_map_t entries = file.getEntries(); + + if (entries.find("detector_1_events") == entries.end()) + {// not an ISIS file + return; + } + + // try if monitors have their own bins + if (classType == "NXmonitor") { - // check if there are groups with names "time_channels_#" and select the one with the highest number - if (it->first.size() > 14 && it->first.substr(0,14) == "time_channels_") + std::vector bankNames; + for (string_map_t::const_iterator it = entries.begin(); it != entries.end(); ++it) + { + std::string entry_name(it->first); + std::string entry_class(it->second); + if ( entry_class == classType ) + { + bankNames.push_back( entry_name ); + } + } + for(size_t i = 0; i < bankNames.size(); ++i) { - size_t n = boost::lexical_cast(it->first.substr(14)); - if (n > time_channels_number) + const std::string& mon = bankNames[i]; + file.openGroup(mon,classType); + entries = file.getEntries(); + string_map_t::const_iterator bins = entries.find("event_time_bins"); + if (bins == entries.end()) { - time_channels_number = n; + //bins = entries.find("time_of_flight"); // I think time_of_flight doesn't work here + //if (bins == entries.end()) + //{ + done = false; + file.closeGroup(); + break; // done == false => use bins from the detectors + //} } + done = true; + loadTimeOfFlightData(file,WS,bins->first,i,i+1); + file.closeGroup(); } } - if (time_channels_number > 0) // the numbers start with 1 + + if (!done) { - file.openGroup("time_channels_" + boost::lexical_cast(time_channels_number),"IXtime_channels"); + // first check detector_1_events + file.openGroup("detector_1_events", "NXevent_data"); entries = file.getEntries(); for(string_map_t::const_iterator it = entries.begin();it != entries.end(); ++it) { if (it->first == "time_of_flight" || it->first == "event_time_bins") { loadTimeOfFlightData(file,WS,it->first); + done = true; } } - file.closeGroup(); - } - file.closeGroup(); // dae - file.closeGroup(); // instrument - } - } + file.closeGroup(); // detector_1_events - file.close(); -} + if (!done) // if time_of_flight was not found try instrument/dae/time_channels_# + { + file.openGroup("instrument","NXinstrument"); + file.openGroup("dae","IXdae"); + entries = file.getEntries(); + size_t time_channels_number = 0; + for(string_map_t::const_iterator it = entries.begin();it != entries.end(); ++it) + { + // check if there are groups with names "time_channels_#" and select the one with the highest number + if (it->first.size() > 14 && it->first.substr(0,14) == "time_channels_") + { + size_t n = boost::lexical_cast(it->first.substr(14)); + if (n > time_channels_number) + { + time_channels_number = n; + } + } + } + if (time_channels_number > 0) // the numbers start with 1 + { + file.openGroup("time_channels_" + boost::lexical_cast(time_channels_number),"IXtime_channels"); + entries = file.getEntries(); + for(string_map_t::const_iterator it = entries.begin();it != entries.end(); ++it) + { + if (it->first == "time_of_flight" || it->first == "event_time_bins") + { + loadTimeOfFlightData(file,WS,it->first); + } + } + file.closeGroup(); + } + file.closeGroup(); // dae + file.closeGroup(); // instrument + } + } -//----------------------------------------------------------------------------- -/** - * Load the time of flight data. file must have open the group containing "time_of_flight" data set. - * @param file :: The nexus file to read from. - * @param WS :: The event workspace to write to. - * @param binsName :: bins name - * @param start_wi :: First workspace index to process - * @param end_wi :: Last workspace index to process - */ -void LoadEventNexus::loadTimeOfFlightData(::NeXus::File& file, DataObjects::EventWorkspace_sptr WS, - const std::string& binsName,size_t start_wi, size_t end_wi) -{ - // first check if the data is already randomized - std::map entries; - file.getEntries(entries); - std::map::const_iterator shift = entries.find("event_time_offset_shift"); - if (shift != entries.end()) - { - std::string random; - file.readData("event_time_offset_shift",random); - if (random == "random") - { - return; + file.close(); } - } - - // if the data is not randomized randomize it uniformly within each bin - file.openData(binsName); - // time of flights of events - std::vector tof; - file.getData(tof); - // todo: try to find if tof can be reduced to just 3 numbers: start, end and dt - if (end_wi <= start_wi) - { - end_wi = WS->getNumberHistograms(); - } - - // random number generator - boost::mt19937 rand_gen; - // loop over spectra - for(size_t wi = start_wi; wi < end_wi; ++wi) - { - EventList& event_list = WS->getEventList(wi); - // sort the events - event_list.sortTof(); - std::vector& events = event_list.getEvents(); - if (events.empty()) continue; - size_t n = tof.size(); - // iterate over the events and time bins - std::vector::iterator ev = events.begin(); - std::vector::iterator ev_end = events.end(); - for(size_t i = 1; i < n; ++i) + //----------------------------------------------------------------------------- + /** + * Load the time of flight data. file must have open the group containing "time_of_flight" data set. + * @param file :: The nexus file to read from. + * @param WS :: The event workspace to write to. + * @param binsName :: bins name + * @param start_wi :: First workspace index to process + * @param end_wi :: Last workspace index to process + */ + void LoadEventNexus::loadTimeOfFlightData(::NeXus::File& file, DataObjects::EventWorkspace_sptr WS, + const std::string& binsName,size_t start_wi, size_t end_wi) { - double right = double(tof[i]); - // find the right boundary for the current event - if(ev != ev_end && right < ev->tof() ) + // first check if the data is already randomized + std::map entries; + file.getEntries(entries); + std::map::const_iterator shift = entries.find("event_time_offset_shift"); + if (shift != entries.end()) { - continue; - } - // count events which have the same right boundary - size_t m = 0; - while(ev != ev_end && ev->tof() < right) - { - ++ev; - ++m; // count events in the i-th bin - } - - if (m > 0) - {// m events in this bin - double left = double(tof[i-1]); - // spread the events uniformly inside the bin - boost::uniform_real<> distribution(left,right); - std::vector random_numbers(m); - for(std::vector::iterator it = random_numbers.begin(); it != random_numbers.end(); ++it) - { - *it = distribution(rand_gen); - } - std::sort(random_numbers.begin(),random_numbers.end()); - std::vector::iterator it = random_numbers.begin(); - for(std::vector::iterator ev1 = ev - m; ev1 != ev; ++ev1,++it) + std::string random; + file.readData("event_time_offset_shift",random); + if (random == "random") { - ev1->m_tof = *it; + return; } } - - } // for i - event_list.sortTof(); - } // for wi - file.closeData(); -} + // if the data is not randomized randomize it uniformly within each bin + file.openData(binsName); + // time of flights of events + std::vector tof; + file.getData(tof); + // todo: try to find if tof can be reduced to just 3 numbers: start, end and dt + if (end_wi <= start_wi) + { + end_wi = WS->getNumberHistograms(); + } -/** Load information of the sample. It is valid only for ISIS it get the information from - * the group isis_vms_compat. - * - * If it does not find this group, it assumes that there is nothing to do. - * But, if the information is there, but not in the way it was expected, it will log the occurrence. - * - * @note: It does essentially the same thing of the method: LoadISISNexus2::loadSampleData - * - * @param file : handle to the nexus file - * @param WS : pointer to the workspace - */ -void LoadEventNexus::loadSampleDataISIScompatibility(::NeXus::File& file, Mantid::API::MatrixWorkspace_sptr WS){ - try - { - file.openGroup("isis_vms_compat", "IXvms"); - } - catch( ::NeXus::Exception & ) - { - // No problem, it just means that this entry does not exist - return; - } + // random number generator + boost::mt19937 rand_gen; - // read the data - try - { - std::vector spb; - std::vector rspb; - file.readData("SPB", spb); - file.readData("RSPB",rspb); - - WS->mutableSample().setGeometryFlag(spb[2]); // the flag is in the third value - WS->mutableSample().setThickness(rspb[3]); - WS->mutableSample().setHeight(rspb[4]); - WS->mutableSample().setWidth(rspb[5]); - } - catch ( ::NeXus::Exception & ex) - { - // it means that the data was not as expected, report the problem - std::stringstream s; - s << "Wrong definition found in isis_vms_compat :> " << ex.what(); - file.closeGroup(); - throw std::runtime_error(s.str()); - } - - file.closeGroup(); -} + // loop over spectra + for(size_t wi = start_wi; wi < end_wi; ++wi) + { + EventList& event_list = WS->getEventList(wi); + // sort the events + event_list.sortTof(); + std::vector& events = event_list.getEvents(); + if (events.empty()) continue; + size_t n = tof.size(); + // iterate over the events and time bins + std::vector::iterator ev = events.begin(); + std::vector::iterator ev_end = events.end(); + for(size_t i = 1; i < n; ++i) + { + double right = double(tof[i]); + // find the right boundary for the current event + if(ev != ev_end && right < ev->tof() ) + { + continue; + } + // count events which have the same right boundary + size_t m = 0; + while(ev != ev_end && ev->tof() < right) + { + ++ev; + ++m; // count events in the i-th bin + } -void LoadEventNexus::filterDuringPause(API::MatrixWorkspace_sptr workspace) -{ - try { - if ( ( ! ConfigService::Instance().hasProperty("loadeventnexus.keeppausedevents") ) && ( WS->run().getLogData("pause")->size() > 1 ) ) - { - g_log.notice("Filtering out events when the run was marked as paused. " - "Set the loadeventnexus.keeppausedevents configuration property to override this."); - - auto filter = createChildAlgorithm("FilterByLogValue"); - filter->setProperty("InputWorkspace", workspace); - filter->setProperty("OutputWorkspace", workspace); - filter->setProperty("LogName", "pause"); - // The log value is set to 1 when the run is paused, 0 otherwise. - filter->setProperty("MinimumValue", 0.0); - filter->setProperty("MaximumValue", 0.0); - filter->setProperty("LogBoundary", "Left"); - filter->execute(); - } - } catch ( Exception::NotFoundError& ) { - // No "pause" log, just carry on - } -} + if (m > 0) + {// m events in this bin + double left = double(tof[i-1]); + // spread the events uniformly inside the bin + boost::uniform_real<> distribution(left,right); + std::vector random_numbers(m); + for(std::vector::iterator it = random_numbers.begin(); it != random_numbers.end(); ++it) + { + *it = distribution(rand_gen); + } + std::sort(random_numbers.begin(),random_numbers.end()); + std::vector::iterator it = random_numbers.begin(); + for(std::vector::iterator ev1 = ev - m; ev1 != ev; ++ev1,++it) + { + ev1->m_tof = *it; + } + } + } // for i -/** Load the instrument from the nexus file - * - * @param nexusfilename :: The name of the nexus file being loaded - * @param localWorkspace :: MatrixWorkspace in which to put the instrument geometry - * @param alg :: Handle of the algorithm - * @param returnpulsetimes :: flag to return shared pointer for BankPulseTimes, otherwise NULL. - * @return true if successful - */ -boost::shared_ptr LoadEventNexus::runLoadNexusLogs(const std::string &nexusfilename, - API::MatrixWorkspace_sptr localWorkspace, - API::Algorithm &alg, bool returnpulsetimes) -{ - // --------------------- Load DAS Logs ----------------- - //The pulse times will be empty if not specified in the DAS logs. - // BankPulseTimes * out = NULL; - boost::shared_ptr out; - API::IAlgorithm_sptr loadLogs = alg.createChildAlgorithm("LoadNexusLogs"); - - // Now execute the Child Algorithm. Catch and log any error, but don't stop. - try - { - alg.getLogger().information() << "Loading logs from NeXus file..." << "\n"; - loadLogs->setPropertyValue("Filename", nexusfilename); - loadLogs->setProperty ("Workspace", localWorkspace); - loadLogs->execute(); + event_list.sortTof(); + } // for wi + file.closeData(); + } - //If successful, we can try to load the pulse times - Kernel::TimeSeriesProperty * log = dynamic_cast *>( - localWorkspace->mutableRun().getProperty("proton_charge") ); - const std::vector temp = log->timesAsVector(); - // if (returnpulsetimes) out = new BankPulseTimes(temp); - if (returnpulsetimes) - out = boost::make_shared(temp); + /** Load information of the sample. It is valid only for ISIS it get the information from + * the group isis_vms_compat. + * + * If it does not find this group, it assumes that there is nothing to do. + * But, if the information is there, but not in the way it was expected, it will log the occurrence. + * + * @note: It does essentially the same thing of the method: LoadISISNexus2::loadSampleData + * + * @param file : handle to the nexus file + * @param WS : pointer to the workspace + */ + void LoadEventNexus::loadSampleDataISIScompatibility(::NeXus::File& file, Mantid::API::MatrixWorkspace_sptr WS){ + try + { + file.openGroup("isis_vms_compat", "IXvms"); + } + catch( ::NeXus::Exception & ) + { + // No problem, it just means that this entry does not exist + return; + } - // Use the first pulse as the run_start time. - if (!temp.empty()) - { - if (temp[0] < Kernel::DateAndTime("1991-01-01T00:00:00")) - alg.getLogger().warning() << "Found entries in the proton_charge sample log with invalid pulse time!\n"; + // read the data + try + { + std::vector spb; + std::vector rspb; + file.readData("SPB", spb); + file.readData("RSPB",rspb); + + WS->mutableSample().setGeometryFlag(spb[2]); // the flag is in the third value + WS->mutableSample().setThickness(rspb[3]); + WS->mutableSample().setHeight(rspb[4]); + WS->mutableSample().setWidth(rspb[5]); + } + catch ( ::NeXus::Exception & ex) + { + // it means that the data was not as expected, report the problem + std::stringstream s; + s << "Wrong definition found in isis_vms_compat :> " << ex.what(); + file.closeGroup(); + throw std::runtime_error(s.str()); + } - Kernel::DateAndTime run_start = localWorkspace->getFirstPulseTime(); - // add the start of the run as a ISO8601 date/time string. The start = first non-zero time. - // (this is used in LoadInstrument to find the right instrument file to use). - localWorkspace->mutableRun().addProperty("run_start", run_start.toISO8601String(), true ); - } - else - { - alg.getLogger().warning() << "Empty proton_charge sample log. You will not be able to filter by time.\n"; + file.closeGroup(); } - /// Attempt to make a gonoimeter from the logs - try + + void LoadEventNexus::filterDuringPause(API::MatrixWorkspace_sptr workspace) { - Geometry::Goniometer gm; - gm.makeUniversalGoniometer(); - localWorkspace->mutableRun().setGoniometer(gm, true); + try { + if ( ( ! ConfigService::Instance().hasProperty("loadeventnexus.keeppausedevents") ) && ( WS->run().getLogData("pause")->size() > 1 ) ) + { + g_log.notice("Filtering out events when the run was marked as paused. " + "Set the loadeventnexus.keeppausedevents configuration property to override this."); + + auto filter = createChildAlgorithm("FilterByLogValue"); + filter->setProperty("InputWorkspace", workspace); + filter->setProperty("OutputWorkspace", workspace); + filter->setProperty("LogName", "pause"); + // The log value is set to 1 when the run is paused, 0 otherwise. + filter->setProperty("MinimumValue", 0.0); + filter->setProperty("MaximumValue", 0.0); + filter->setProperty("LogBoundary", "Left"); + filter->execute(); + } + } catch ( Exception::NotFoundError& ) { + // No "pause" log, just carry on + } } - catch(std::runtime_error &) + + + /** Load the instrument from the nexus file + * + * @param nexusfilename :: The name of the nexus file being loaded + * @param localWorkspace :: MatrixWorkspace in which to put the instrument geometry + * @param alg :: Handle of the algorithm + * @param returnpulsetimes :: flag to return shared pointer for BankPulseTimes, otherwise NULL. + * @return true if successful + */ + boost::shared_ptr LoadEventNexus::runLoadNexusLogs(const std::string &nexusfilename, + API::MatrixWorkspace_sptr localWorkspace, + API::Algorithm &alg, bool returnpulsetimes) { + // --------------------- Load DAS Logs ----------------- + //The pulse times will be empty if not specified in the DAS logs. + // BankPulseTimes * out = NULL; + boost::shared_ptr out; + API::IAlgorithm_sptr loadLogs = alg.createChildAlgorithm("LoadNexusLogs"); + + // Now execute the Child Algorithm. Catch and log any error, but don't stop. + try + { + alg.getLogger().information() << "Loading logs from NeXus file..." << "\n"; + loadLogs->setPropertyValue("Filename", nexusfilename); + loadLogs->setProperty ("Workspace", localWorkspace); + loadLogs->execute(); + + //If successful, we can try to load the pulse times + Kernel::TimeSeriesProperty * log = dynamic_cast *>( + localWorkspace->mutableRun().getProperty("proton_charge") ); + const std::vector temp = log->timesAsVector(); + // if (returnpulsetimes) out = new BankPulseTimes(temp); + if (returnpulsetimes) + out = boost::make_shared(temp); + + // Use the first pulse as the run_start time. + if (!temp.empty()) + { + if (temp[0] < Kernel::DateAndTime("1991-01-01T00:00:00")) + alg.getLogger().warning() << "Found entries in the proton_charge sample log with invalid pulse time!\n"; + + Kernel::DateAndTime run_start = localWorkspace->getFirstPulseTime(); + // add the start of the run as a ISO8601 date/time string. The start = first non-zero time. + // (this is used in LoadInstrument to find the right instrument file to use). + localWorkspace->mutableRun().addProperty("run_start", run_start.toISO8601String(), true ); + } + else + { + alg.getLogger().warning() << "Empty proton_charge sample log. You will not be able to filter by time.\n"; + } + /// Attempt to make a gonoimeter from the logs + try + { + Geometry::Goniometer gm; + gm.makeUniversalGoniometer(); + localWorkspace->mutableRun().setGoniometer(gm, true); + } + catch(std::runtime_error &) + { + } + } + catch (...) + { + alg.getLogger().error() << "Error while loading Logs from SNS Nexus. Some sample logs may be missing." << "\n"; + return out; + } + return out; } - } - catch (...) - { - alg.getLogger().error() << "Error while loading Logs from SNS Nexus. Some sample logs may be missing." << "\n"; - return out; - } - return out; -} +/** +* Check the validity of the optional spectrum range/list provided and identify if partial data should be loaded. +* +* @param min :: The minimum spectrum number read from file +* @param max :: The maximum spectrum number read from file +*/ + +void LoadEventNexus::createSpectraList(int32_t min, int32_t max){ + + // check if range [SpectrumMin, SpectrumMax] was supplied + if( m_specMin != EMPTY_INT() || m_specMax != EMPTY_INT() ) + { + if ( m_specMax == EMPTY_INT() ) + { + m_specMax = max; + } + if ( m_specMin == EMPTY_INT() ) + { + m_specMin = min; + } + + if ( m_specMax > max ) + { + throw std::invalid_argument("Inconsistent range property: SpectrumMax is larger than maximum spectrum found in file."); + } + + // Sanity checks for min/max + if ( m_specMin > m_specMax ) + { + throw std::invalid_argument("Inconsistent range property: SpectrumMin is larger than SpectrumMax."); + } + + // Populate spec_list + for (int32_t i=m_specMin; i<=m_specMax; i++) + m_specList.push_back(i); + } + else{ + // Check if SpectrumList was supplied + + if ( !m_specList.empty() ) + { + // Check no negative/zero numbers have been passed + std::vector::iterator itr = std::find_if(m_specList.begin(), m_specList.end(), std::bind2nd(std::less(), 1)); + if( itr != m_specList.end() ) + { + throw std::invalid_argument("Negative/Zero SpectraList property encountered."); + } + + // Check range and set m_specMax to maximum value in m_specList + if ( (m_specMax=*std::max_element(m_specList.begin(),m_specList.end())) > *std::max_element(m_specList.begin(),m_specList.end()) ) + { + throw std::invalid_argument("Inconsistent range property: SpectrumMax is larger than number of spectra."); + } + + // Set m_specMin to minimum value in m_specList + m_specMin=*std::min_element(m_specList.begin(),m_specList.end()); + } + + } + + if ( !m_specList.empty() ) { + + // Check that spectra supplied by user do not correspond to monitors + auto nmonitors = WS->getInstrument()->getMonitors().size(); + + for( size_t i = 0; i < nmonitors; ++i ) + { + if ( std::find(m_specList.begin(),m_specList.end(),i+1)!= m_specList.end() ) + { + throw std::invalid_argument("Inconsistent range property: some of the selected spectra correspond to monitors."); + } + } + + } + +} -} // namespace DataHandling + } // namespace DataHandling } // namespace Mantid diff --git a/Code/Mantid/Framework/DataHandling/src/LoadFITS.cpp b/Code/Mantid/Framework/DataHandling/src/LoadFITS.cpp new file mode 100644 index 000000000000..156624e62224 --- /dev/null +++ b/Code/Mantid/Framework/DataHandling/src/LoadFITS.cpp @@ -0,0 +1,476 @@ +#include "MantidDataHandling/LoadFITS.h" +#include "MantidAPI/MultipleFileProperty.h" +#include "MantidAPI/RegisterFileLoader.h" +#include "MantidDataObjects/Workspace2D.h" +#include "MantidKernel/UnitFactory.h" +#include +#include +#include + +using namespace Mantid::DataHandling; +using namespace Mantid::API; +using namespace Mantid::Kernel; +using namespace std; +using namespace boost; +using Poco::BinaryReader; + +namespace +{ + /** + * Used with find_if to check a string isn't a fits file (by checking extension) + * @param s string to check for extension + * @returns bool Value indicating if the string ends with .fits or not + */ + bool IsNotFits(std::string s) + { + std::string tmp = s; + to_lower(tmp); + return !ends_with(tmp,".fits"); + } +} + +namespace Mantid +{ +namespace DataHandling +{ + // Register the algorithm into the AlgorithmFactory + DECLARE_FILELOADER_ALGORITHM(LoadFITS); + + /** + * Return the confidence with with this algorithm can load the file + * @param descriptor A descriptor for the file + * @returns An integer specifying the confidence level. 0 indicates it will not be used + */ + int LoadFITS::confidence(Kernel::FileDescriptor & descriptor) const + { + // Should really improve this to check the file header (of first file at least) to make sure it contains the fields wanted + return (descriptor.extension() == ".fits" || descriptor.extension() == ".fit") ? 80 : 0; + } + + /** + * Initialise the algorithm. Declare properties which can be set before execution (input) or + * read from after the execution (output). + */ + void LoadFITS::init() + { + // Specify file extensions which can be associated with a FITS file. + std::vector exts; + + // Declare the Filename algorithm property. Mandatory. Sets the path to the file to load. + exts.clear(); + exts.push_back(".fits"); + exts.push_back(".fit"); + + declareProperty(new MultipleFileProperty("Filename", exts), "The input filename of the stored data"); + declareProperty(new PropertyWithValue("FileChunkSize", 100, Direction::Input), "Number of files to read into memory at a time - use lower values for machines with low memory"); + + declareProperty(new API::WorkspaceProperty("OutputWorkspace", "", Kernel::Direction::Output)); + } + + /** + * Execute the algorithm. + */ + void LoadFITS::exec() + { + // Create FITS file information for each file selected + std::vector paths; + string fName = getPropertyValue("Filename"); + boost::split(paths, fName, boost::is_any_of(",")); + m_binChunkSize = getProperty("FileChunkSize"); + + // If paths contains a non fits file, assume (for now) that it contains information about the rotations + std::string rotFilePath = ""; + std::vector::iterator it = std::find_if(paths.begin(),paths.end(),IsNotFits); + if(it != paths.end()) + { + rotFilePath = *it; + paths.erase(it); + } + + // Shrink chunk size to match number of files if it's over the amount (less memory allocated later) + if(m_binChunkSize > paths.size()) m_binChunkSize = static_cast(paths.size()); + + m_allHeaderInfo.resize(paths.size()); + + // Check each header is valid for this loader, - standard (no extension to FITS), and has two axis + bool headerValid = true; + + for(size_t i=0; i(tmpBitPix); + m_allHeaderInfo[i].numberOfAxis = lexical_cast(m_allHeaderInfo[i].headerKeys["NAXIS"]); + + for(int j=0; j(j+1); + m_allHeaderInfo[i].axisPixelLengths.push_back(lexical_cast(m_allHeaderInfo[i].headerKeys[keyName])); + } + + //m_allHeaderInfo[i].tof = lexical_cast(m_allHeaderInfo[i].headerKeys["TOF"]); + //m_allHeaderInfo[i].timeBin = lexical_cast(m_allHeaderInfo[i].headerKeys["TIMEBIN"]); + //m_allHeaderInfo[i].countsInImage = lexical_cast(m_allHeaderInfo[i].headerKeys["N_COUNTS"]); + //m_allHeaderInfo[i].numberOfTriggers = lexical_cast(m_allHeaderInfo[i].headerKeys["N_TRIGS"]); + m_allHeaderInfo[i].extension = m_allHeaderInfo[i].headerKeys["XTENSION"]; // Various extensions are available to the FITS format, and must be parsed differently if this is present. Loader doesn't support this. + + } + catch(std::exception &) + { + //todo write error and fail this load with invalid data in file. + throw std::runtime_error("Unable to locate one or more valid BITPIX, NAXIS, TOF, TIMEBIN, N_COUNTS or N_TRIGS values in the FITS file header."); + } + + if(m_allHeaderInfo[i].extension != "") headerValid = false; + if(m_allHeaderInfo[i].numberOfAxis != 2) headerValid = false; + + // Test current item has same axis values as first item. + if(m_allHeaderInfo[0].axisPixelLengths[0] != m_allHeaderInfo[i].axisPixelLengths[0]) headerValid = false; + if(m_allHeaderInfo[0].axisPixelLengths[1] != m_allHeaderInfo[i].axisPixelLengths[1]) headerValid = false; + } + else + { + // Unable to parse the header, throw. + throw std::runtime_error("Unable to open the FITS file."); + } + + } + + // Check that the files use bit depths of either 8, 16 or 32 + if(m_allHeaderInfo[0].bitsPerPixel != 8 && m_allHeaderInfo[0].bitsPerPixel != 16 && m_allHeaderInfo[0].bitsPerPixel != 32) + { + throw std::runtime_error("FITS loader only supports 8, 16 or 32 bits per pixel."); + } + + // Check the format is correct and create the Workspace + if(headerValid) + { + // No extension is set, therefore it's the standard format which we can parse. + + // Delete the output workspace name if it existed + std::string outName = getPropertyValue("OutputWorkspace"); + if (AnalysisDataService::Instance().doesExist(outName)) AnalysisDataService::Instance().remove(outName); + + MatrixWorkspace_sptr ws; + + ws = initAndPopulateHistogramWorkspace(); + + // Set info in WS log to hold rotational information + if(rotFilePath != "") + { + string csvRotations = ReadRotations(rotFilePath, paths.size()); + Run &theRun = ws->mutableRun(); + theRun.addLogData(new PropertyWithValue("Rotations", csvRotations)); + } + + // Assign it to the output workspace property + setProperty("OutputWorkspace",ws); + } + else + { + // Invalid files, record error + throw std::runtime_error("Loader currently doesn't support FITS files with non-standard extensions, greater than two axis of data, or has detected that all the files are not similar."); + } + } + + /** + * Read a single files header and populate an object with the information + * @param headerInfo A FITSInfo file object to parse header information into + * @returns A bool specifying succes of the operation + */ + bool LoadFITS::parseHeader(FITSInfo &headerInfo) + { + bool ranSuccessfully = true; + try + { + ifstream istr(headerInfo.filePath.c_str(), ios::binary); + Poco::BinaryReader reader(istr); + + // Iterate 80 bytes at a time until header is parsed | 2880 bytes is the fixed header length of FITS + // 2880/80 = 36 iterations required + for(int i=0; i < 36; ++i) + { + // Keep vect of each header item, including comments, and also keep a map of individual keys. + string part; + reader.readRaw(80,part); + headerInfo.headerItems.push_back(part); + + // Add key/values - these are separated by the = symbol. + // If it doesn't have an = it's a comment to ignore. All keys should be unique + auto eqPos = part.find('='); + if(eqPos > 0) + { + string key = part.substr(0, eqPos); + string value = part.substr(eqPos+1); + + // Comments are added after the value separated by a / symbol. Remove. + auto slashPos = value.find('/'); + if(slashPos > 0) value = value.substr(0, slashPos); + + boost::trim(key); + boost::trim(value); + headerInfo.headerKeys[key] = value; + } + } + + istr.close(); + } + catch(...) + { + // Unable to read the file + ranSuccessfully = false; + } + + return ranSuccessfully; + } + + /** + * Create histogram workspace + * @returns Created workspace + */ + MatrixWorkspace_sptr LoadFITS::initAndPopulateHistogramWorkspace() + { + MantidVecPtr x; + x.access().resize(m_allHeaderInfo.size() + 1); + + // Init time bins + double binCount = 0; + for(size_t i=0;i 0) spectraCount += m_allHeaderInfo[0].axisPixelLengths[0]; + + // Presumably 2 axis, but futureproofing. + for(int i=1;iinitialize(spectraCount, m_allHeaderInfo.size()+1, m_allHeaderInfo.size()); + + IAlgorithm_sptr loadInst = createChildAlgorithm("LoadInstrument"); + + try + { + std::string directoryName = Kernel::ConfigService::Instance().getInstrumentDirectory(); + directoryName = directoryName + "/IMAT_Definition.xml"; + + loadInst->setPropertyValue("Filename", directoryName); + loadInst->setProperty("Workspace", retVal); + loadInst->execute(); + } + catch (std::exception & ex) + { + g_log.information("Cannot load the instrument definition. " + string(ex.what()) ); + } + + int bitsPerPixel = m_allHeaderInfo[0].bitsPerPixel; // assumes all files have the same, which they should. + vector > yVals(spectraCount, std::vector(m_binChunkSize)); + vector > eVals(spectraCount, std::vector(m_binChunkSize)); + + // allocate memory to contain the data section of the file: + void * bufferAny = NULL; + bufferAny = malloc ((bitsPerPixel/8)*spectraCount); + + if (bufferAny == NULL) + { + throw std::runtime_error("FITS loader couldn't allocate enough memory to run. Try a smaller chunk size."); + } + + size_t steps = static_cast(ceil(m_allHeaderInfo.size()/m_binChunkSize)); + Progress prog(this,0.0,1.0,steps); + + // Load a chunk of files at a time into workspace + try + { + for(size_t i=0; imutableRun().addProperty("Filename", m_allHeaderInfo[0].filePath); + + // Set the Unit of the X Axis + try + { + retVal->getAxis(0)->unit() = UnitFactory::Instance().create("TOF"); + } + catch ( Exception::NotFoundError & ) + { + retVal->getAxis(0)->unit() = UnitFactory::Instance().create("Label"); + Unit_sptr unit = retVal->getAxis(0)->unit(); + boost::shared_ptr label = boost::dynamic_pointer_cast(unit); + label->setLabel("TOF", "TOF"); + } + + retVal->setYUnit("Counts"); + retVal->setTitle("Test Workspace"); + + return retVal; + } + + /** + * Loads data from a selection of the FITS files into the workspace + * @param workspace The workspace to insert data into + * @param yVals Reference to a pre-allocated vector to hold data values for the workspace + * @param eVals Reference to a pre-allocated vector to hold error values for the workspace + * @param bufferAny Pointer to an allocated memory region which will hold a files worth of data + * @param x Vector holding the X bin values + * @param spectraCount Number of data points in each file + * @param bitsPerPixel Number of bits used to represent one data point + * @param binChunkStartIndex Index for the first file to be processed in this chunk + */ + void LoadFITS::loadChunkOfBinsFromFile(MatrixWorkspace_sptr &workspace, vector > &yVals, vector > &eVals, void *&bufferAny, MantidVecPtr &x, size_t spectraCount, int bitsPerPixel, size_t binChunkStartIndex) + { + size_t binsThisChunk = m_binChunkSize; + if((binChunkStartIndex + m_binChunkSize) > m_allHeaderInfo.size()) + { + // No need to do extra processing if number of bins to process is lower than m_binChunkSize + // Also used to prevent out of bounds error where a greater number of elements have been reserved. + binsThisChunk = static_cast(m_allHeaderInfo.size() - binChunkStartIndex); + } + + uint8_t *buffer8 = NULL; + uint16_t *buffer16 = NULL; + uint32_t *buffer32 = NULL; + + // create pointer of correct data type to void pointer of the buffer: + buffer8 = static_cast(bufferAny); + buffer16 = static_cast(bufferAny); + buffer32 = static_cast(bufferAny); + + for(size_t i=binChunkStartIndex; i < binChunkStartIndex+binsThisChunk ; ++i) + { + // Read Data + bool fileErr = false; + FILE * currFile = fopen ( m_allHeaderInfo[i].filePath.c_str(), "rb" ); + if (currFile==NULL) fileErr = true; + + size_t result = 0; + if(!fileErr) + { + fseek (currFile , FIXED_HEADER_SIZE , SEEK_CUR); + result = fread(bufferAny, bitsPerPixel/8, spectraCount, currFile); + } + + if (result != spectraCount) fileErr = true; + + if(fileErr) + { + throw std::runtime_error("Error reading file; possibly invalid data."); + } + + for(size_t j=0; j(buffer8[j]); + if(bitsPerPixel == 16) val = static_cast(buffer16[j]); + if(bitsPerPixel == 32) val = static_cast(buffer32[j]); + + yVals[j][i-binChunkStartIndex] = val; + eVals[j][i-binChunkStartIndex] = sqrt(val); + } + + // Clear memory associated with the file load + fclose (currFile); + } + + // Now load chunk into workspace + PARALLEL_FOR1(workspace) + for (int64_t wi = 0; wi < static_cast(spectraCount); ++wi) + { + workspace->setX(wi, x); + MantidVec *currY = &workspace->dataY(wi); + MantidVec *currE = &workspace->dataE(wi); + + std::copy(yVals[wi].begin(), yVals[wi].end()-(m_binChunkSize-binsThisChunk), currY->begin()+binChunkStartIndex ); + std::copy(eVals[wi].begin(), eVals[wi].end()-(m_binChunkSize-binsThisChunk), currE->begin()+binChunkStartIndex ); + + // I expect this will be wanted once IDF is in a more useful state. + //workspace->getSpectrum(wi)->setDetectorID(detid_t(wi)); + //workspace->getSpectrum(wi)->setSpectrumNo(specid_t(wi+1)); + } + } + + /** + * Reads a file containing rotation values for each image into a comma separated string + * @param rotFilePath The path to a file containing rotation values + * @param fileCount number of images which should have corresponding rotation values in the file + * + * @returns string A comma separated string of doubles + */ + std::string LoadFITS::ReadRotations(std::string rotFilePath, size_t fileCount) + { + ifstream fStream(rotFilePath.c_str()); + std::string csvRotations = ""; + + try + { + // Ensure valid file + if(fStream.good()) + { + // Get lines, split words, verify and add to map. + string line; + vector lineSplit; + size_t ind = -1; + while(getline(fStream, line)) + { + ind++; + boost::split(lineSplit,line, boost::is_any_of("\t")); + + if(ind==0 || lineSplit[0] == "") + continue; // Skip first iteration or where rotation value is empty + + if(ind!=1) // append a comma to separate values if not the first index + csvRotations += ","; + + csvRotations += lineSplit[1]; + } + + // Check the number of rotations in file matches number of files + if(ind != fileCount) + throw std::runtime_error("File error, throw higher up."); + + fStream.close(); + } + else + { + throw std::runtime_error("File error, throw higher up."); + } + } + catch(...) + { + throw std::runtime_error("Invalid file path or file format: Expected a file with a line separated list of rotations with the same number of entries as other files."); + } + + return csvRotations; + } + +} +} diff --git a/Code/Mantid/Framework/DataHandling/src/LoadFullprofResolution.cpp b/Code/Mantid/Framework/DataHandling/src/LoadFullprofResolution.cpp index 52dcec9ac8dd..7ae2769db3ab 100644 --- a/Code/Mantid/Framework/DataHandling/src/LoadFullprofResolution.cpp +++ b/Code/Mantid/Framework/DataHandling/src/LoadFullprofResolution.cpp @@ -6,7 +6,6 @@ #include "MantidGeometry/Instrument.h" #include "MantidAPI/InstrumentDataService.h" #include "MantidGeometry/Instrument/InstrumentDefinitionParser.h" -#include "MantidDataHandling/LoadParameterFile.h" #include #include @@ -39,6 +38,8 @@ namespace DataHandling DECLARE_ALGORITHM(LoadFullprofResolution) + std::map LoadFullprofResolution::m_rowNumbers; + //---------------------------------------------------------------------------------------------- /** Constructor */ @@ -214,7 +215,7 @@ namespace DataHandling } else // Numbers match, so put parameters into workspaces. { - getTableRowNumbers( outTabWs, m_rowNumbers); + getTableRowNumbers( outTabWs, LoadFullprofResolution::m_rowNumbers); for (size_t i=0; i < vec_bankids.size(); ++i) { int bankId = vec_bankids[i]; @@ -223,7 +224,15 @@ namespace DataHandling auto workspace = boost::dynamic_pointer_cast(wsi); // Get column from table workspace API::Column_const_sptr OutTabColumn = outTabWs->getColumn( i+1 ); - putParametersIntoWorkspace( OutTabColumn, workspace, nProf ); + std::string parameterXMLString; + putParametersIntoWorkspace( OutTabColumn, workspace, nProf, parameterXMLString ); + + // Load the string into the workspace + Algorithm_sptr loadParamAlg = createChildAlgorithm("LoadParameterFile"); + loadParamAlg->setProperty("ParameterXML", parameterXMLString); + loadParamAlg->setProperty("Workspace", workspace); + loadParamAlg->execute(); + } } } @@ -836,7 +845,7 @@ namespace DataHandling * @param ws :: [input/output] the group workspace parameters are to be put in * @param nProf :: the PROF Number, which is used to determine fitting function for the parameters. */ - void LoadFullprofResolution::putParametersIntoWorkspace( API::Column_const_sptr column, API::MatrixWorkspace_sptr ws, int nProf) + void LoadFullprofResolution::putParametersIntoWorkspace( API::Column_const_sptr column, API::MatrixWorkspace_sptr ws, int nProf, std::string & parameterXMLString) { // Get instrument name from matrix workspace @@ -883,17 +892,13 @@ namespace DataHandling // Convert DOM XML document into string std::ostringstream outFile; writer.writeNode(outFile, mDoc); - std::string parameterXMLString = outFile.str(); + parameterXMLString = outFile.str(); // Useful code for testing upgrades commented out for production use //std::ofstream outfileDebug("C:/Temp/test4_fullprof.xml"); //outfileDebug << parameterXMLString; //outfileDebug.close(); - - // Load the string into the workspace - LoadParameterFile::execManually(true, "", parameterXMLString, ws); - } /* Add an Ikeda Carpenter PV ALFBE parameter to the XML document according to the table workspace @@ -1040,7 +1045,7 @@ namespace DataHandling */ std::string LoadFullprofResolution::getXMLEqValue( const API::Column_const_sptr column, const std::string& name ) { - size_t paramNumber = m_rowNumbers[name]; + size_t paramNumber = LoadFullprofResolution::m_rowNumbers[name]; //API::Column_const_sptr column = tablews->getColumn( columnIndex ); double eqValue = column->cell(paramNumber); return boost::lexical_cast(eqValue); @@ -1052,7 +1057,7 @@ namespace DataHandling */ std::string LoadFullprofResolution::getXMLSquaredEqValue( const API::Column_const_sptr column, const std::string& name ) { - size_t paramNumber = m_rowNumbers[name]; + size_t paramNumber = LoadFullprofResolution::m_rowNumbers[name]; //API::Column_const_sptr column = tablews->getColumn( columnIndex ); double eqValue = column->cell(paramNumber); return boost::lexical_cast(eqValue*eqValue); diff --git a/Code/Mantid/Framework/DataHandling/src/LoadGSS.cpp b/Code/Mantid/Framework/DataHandling/src/LoadGSS.cpp index 9333163d053c..dc62761b30e2 100644 --- a/Code/Mantid/Framework/DataHandling/src/LoadGSS.cpp +++ b/Code/Mantid/Framework/DataHandling/src/LoadGSS.cpp @@ -337,20 +337,25 @@ namespace DataHandling } std::istringstream inputLine(currentLine, std::ios::in); - inputLine >> xValue >> yValue >> eValue; // It is different for the definition of X, Y, Z in SLOG and RALF format if (filetype == 'r') { // RALF + // LoadGSS produces overlapping columns for some datasets, due to std::setw + // For this reason we need to read the column values as string and then convert to double + std::string xString, yString, eString; + inputLine >> std::setw(11) >> xString >> std::setw(18) >> yString >> std::setw(18) >> eString; + xValue = boost::lexical_cast(xString); + yValue = boost::lexical_cast(yString); + eValue = boost::lexical_cast(eString); xValue = (2 * xValue) - xPrev; - yValue = yValue / (xPrev * bc4); - eValue = eValue / (xPrev * bc4); } else if (filetype == 's') { // SLOG + inputLine >> xValue >> yValue >> eValue; if (calslogx0) { // calculation of x0 must use the x'[0] @@ -364,12 +369,18 @@ namespace DataHandling } xValue = (2 * xValue) - xPrev; - if (multiplybybinwidth) - { - yValue = yValue / (xValue - xPrev); - eValue = eValue / (xValue - xPrev); - } } + else + { + g_log.error() << "Unsupported GSAS File Type: " << filetype << "\n"; + throw Exception::FileError("Not a GSAS file", filename); + } + + if (multiplybybinwidth) + { + yValue = yValue / (xValue - xPrev); + eValue = eValue / (xValue - xPrev); + } // store read in data (x, y, e) to vector vecX.push_back(xValue); diff --git a/Code/Mantid/Framework/DataHandling/src/LoadHelper.cpp b/Code/Mantid/Framework/DataHandling/src/LoadHelper.cpp index 181cc4dec1ae..e447fa14b561 100644 --- a/Code/Mantid/Framework/DataHandling/src/LoadHelper.cpp +++ b/Code/Mantid/Framework/DataHandling/src/LoadHelper.cpp @@ -84,7 +84,7 @@ namespace Mantid } /** * Calculate Neutron Energy from wavelength: \f$ E = h^2 / 2m\lambda ^2 \f$ - * @param wavelength :: wavelength in \f$ \AA \f$ + * @param wavelength :: wavelength in \f$ \mbox{\AA} \f$ * @return tof in seconds */ double LoadHelper::calculateEnergy(double wavelength) diff --git a/Code/Mantid/Framework/DataHandling/src/LoadIDFFromNexus.cpp b/Code/Mantid/Framework/DataHandling/src/LoadIDFFromNexus.cpp index be250b077adf..358d49004f54 100644 --- a/Code/Mantid/Framework/DataHandling/src/LoadIDFFromNexus.cpp +++ b/Code/Mantid/Framework/DataHandling/src/LoadIDFFromNexus.cpp @@ -2,7 +2,6 @@ // Includes //---------------------------------------------------------------------- #include "MantidDataHandling/LoadIDFFromNexus.h" -#include "MantidDataHandling/LoadParameterFile.h" #include "MantidKernel/ConfigService.h" #include "MantidAPI/FileProperty.h" @@ -80,16 +79,25 @@ void LoadIDFFromNexus::exec() if ( parameterString.empty() ) { // Create the 'fallback' parameter file name to look for - const std::string directory = ConfigService::Instance().getString("parameterDefinition.directory"); + std::vector directoryNames = ConfigService::Instance().getInstrumentDirectories(); const std::string instrumentName = localWorkspace->getInstrument()->getName(); - const std::string paramFile = directory + instrumentName + "_Parameters.xml"; - - try { - // load and also populate instrument parameters from this 'fallback' parameter file - LoadParameterFile::execManually(false, paramFile,"", localWorkspace); - g_log.notice() << "Instrument parameter file: " << paramFile << " has been loaded" << std::endl; - } catch ( std::runtime_error& ) { - g_log.debug() << "Instrument parameter file: " << paramFile << " not found or un-parsable. "; + for ( auto instDirs_itr = directoryNames.begin(); instDirs_itr != directoryNames.end(); ++instDirs_itr) + { + //This will iterate around the directories from user ->etc ->install, and find the first beat file + std::string directoryName = *instDirs_itr; + const std::string paramFile = directoryName + instrumentName + "_Parameters.xml"; + + try { + // load and also populate instrument parameters from this 'fallback' parameter file + Algorithm_sptr loadParamAlg = createChildAlgorithm("LoadParameterFile"); + loadParamAlg->setProperty("Filename", paramFile); + loadParamAlg->setProperty("Workspace", localWorkspace); + loadParamAlg->execute(); + g_log.notice() << "Instrument parameter file: " << paramFile << " has been loaded" << std::endl; + break; //stop at the first one + } catch ( std::runtime_error& ) { + g_log.debug() << "Instrument parameter file: " << paramFile << " not found or un-parsable. "; + } } } else diff --git a/Code/Mantid/Framework/DataHandling/src/LoadILLReflectometry.cpp b/Code/Mantid/Framework/DataHandling/src/LoadILLReflectometry.cpp index 5c9bdea5f205..edd73e513929 100644 --- a/Code/Mantid/Framework/DataHandling/src/LoadILLReflectometry.cpp +++ b/Code/Mantid/Framework/DataHandling/src/LoadILLReflectometry.cpp @@ -9,6 +9,7 @@ #include "MantidGeometry/Instrument/ComponentHelper.h" #include +#include #include #include @@ -25,9 +26,6 @@ namespace Mantid // Register the algorithm into the AlgorithmFactory DECLARE_NEXUS_FILELOADER_ALGORITHM(LoadILLReflectometry); -// PI again ! - const double PI = 3.14159265358979323846264338327950288419716939937510582; - //---------------------------------------------------------------------------------------------- /** Constructor */ @@ -106,6 +104,30 @@ namespace Mantid "The name to use for the output workspace"); } +//---------------------------------------------------------------------------------------------- + /** + * Run the Child Algorithm LoadInstrument. + */ + void LoadILLReflectometry::runLoadInstrument() + { + + IAlgorithm_sptr loadInst = createChildAlgorithm("LoadInstrument"); + + // Now execute the Child Algorithm. Catch and log any error, but don't stop. + try + { + + loadInst->setPropertyValue("InstrumentName", m_instrumentName); + loadInst->setProperty("Workspace", m_localWorkspace); + loadInst->execute(); + + } catch (std::runtime_error& e) + { + g_log.information() << "Unable to successfully run LoadInstrument Child Algorithm : " + << e.what() << std::endl; + } + } + //---------------------------------------------------------------------------------------------- /** Execute the algorithm. */ @@ -132,7 +154,7 @@ namespace Mantid g_log.debug("Building properties..."); loadNexusEntriesIntoProperties(filenameData); -// g_log.debug("Loading data..."); + g_log.debug("Loading data..."); loadDataIntoTheWorkSpace(firstEntry, monitorsData); // load the instrument from the IDF if it exists @@ -143,18 +165,14 @@ namespace Mantid // Get distance and tilt angle stored in nexus file // Mantid way - // auto angleProp = dynamic_cast*>(m_localWorkspace->run().getProperty("dan.value")); + //// auto angleProp = dynamic_cast*>(m_localWorkspace->run().getProperty("dan.value")); // Nexus way double angle = firstEntry.getFloat("instrument/dan/value"); // detector angle in degrees double distance = firstEntry.getFloat("instrument/det/value"); // detector distance in millimeter - distance /= 1000; // convert to meter - placeDetector(distance, angle); - // 2) Center, (must be done after move) - int par1_101 = firstEntry.getInt("instrument/PSD/ny"); - g_log.debug("Note: using PSD/ny instead of PSD/nx. Should be corrected in next D17 nexus file."); - double xCenter = 0.1325 / par1_101; // As in lamp, but in meter - centerDetector(xCenter); + distance /= 1000.0; // convert to meter + g_log.debug() << "Moving detector at angle " << angle << " and distance " << distance << std::endl; + placeDetector(distance, angle); // Set the channel width property auto channel_width = dynamic_cast*>(m_localWorkspace->run().getProperty( @@ -306,15 +324,28 @@ namespace Mantid "monitor1.time_of_flight_2")); double tof_delay = *tof_delay_prop; /* PAR1[96] */ + double POFF = entry.getFloat("instrument/VirtualChopper/poff"); /* par1[54] */ - double mean_chop_2_phase = entry.getFloat("instrument/VirtualChopper/chopper2_phase_average"); /* PAR2[114] */ + double open_offset=entry.getFloat("instrument/VirtualChopper/open_offset"); /* par1[56] */ + double mean_chop_1_phase=0.0; + double mean_chop_2_phase=0.0; + // [30/09/14] Test on availability of VirtualChopper data + double chop1_speed = entry.getFloat("instrument/VirtualChopper/chopper1_speed_average"); /* PAR2[109] */ + if (chop1_speed != 0.0) { + // Virtual Chopper entries are valid - //double mean_chop_1_phase = entry.getFloat("instrument/VirtualChopper/chopper1_phase_average"); /* PAR2[110] */ - // this entry seems to be wrong for now, we use the old one instead [YR 5/06/2014] - double mean_chop_1_phase = entry.getFloat("instrument/Chopper1/phase"); + //double mean_chop_1_phase = entry.getFloat("instrument/VirtualChopper/chopper1_phase_average"); /* PAR2[110] */ + // this entry seems to be wrong for now, we use the old one instead [YR 5/06/2014] + mean_chop_1_phase = entry.getFloat("instrument/Chopper1/phase"); + mean_chop_2_phase = entry.getFloat("instrument/VirtualChopper/chopper2_phase_average"); /* PAR2[114] */ - double open_offset = entry.getFloat("instrument/VirtualChopper/open_offset"); /* par1[56] */ - double chop1_speed = entry.getFloat("instrument/VirtualChopper/chopper1_speed_average"); /* PAR2[109] */ + } else { + // Use Chopper values instead + chop1_speed = entry.getFloat("instrument/Chopper1/rotation_speed"); /* PAR2[109] */ + + mean_chop_1_phase = entry.getFloat("instrument/Chopper1/phase"); + mean_chop_2_phase = entry.getFloat("instrument/Chopper2/phase"); + } g_log.debug() << "m_numberOfChannels: " << m_numberOfChannels << std::endl; g_log.debug() << "m_channelWidth: " << m_channelWidth << std::endl; @@ -325,28 +356,31 @@ namespace Mantid g_log.debug() << "mean_chop_1_phase: " << mean_chop_1_phase << std::endl; g_log.debug() << "chop1_speed: " << chop1_speed << std::endl; + double t_TOF2 = 0.0; + if (chop1_speed == 0.0) + { + g_log.debug() << "Warning: chop1_speed is null." << std::endl; + // stay with t_TOF2 to O.0 + } + else + { // Thanks to Miguel Gonzales/ILL for this TOF formula - double t_TOF2 = -1.e6 * 60.0 * (POFF - 45.0 + mean_chop_2_phase - mean_chop_1_phase + open_offset) + t_TOF2 = -1.e6 * 60.0 * (POFF - 45.0 + mean_chop_2_phase - mean_chop_1_phase + open_offset) / (2.0 * 360 * chop1_speed); + } g_log.debug() << "t_TOF2: " << t_TOF2 << std::endl; // 2) Compute tof values for (size_t timechannelnumber = 0; timechannelnumber <= m_numberOfChannels; ++timechannelnumber) { - double t_TOF1 = (static_cast(timechannelnumber) + 0.5) * m_channelWidth + tof_delay; - - //g_log.debug() << "t_TOF1: " << t_TOF1 << std::endl; - m_localWorkspace->dataX(0)[timechannelnumber] = t_TOF1 + t_TOF2; - } // Load monitors for (size_t im = 0; im < nb_monitors; im++) { - if (im > 0) { m_localWorkspace->dataX(im) = m_localWorkspace->readX(0); @@ -359,8 +393,6 @@ namespace Mantid progress.report(); } - // TODO - // copy data if m_numberOfTubes = 1 or m_numberOfPixelsPerTube = 1 // Then Tubes for (size_t i = 0; i < m_numberOfTubes; ++i) @@ -371,7 +403,7 @@ namespace Mantid // just copy the time binning axis to every spectra m_localWorkspace->dataX(spec + nb_monitors) = m_localWorkspace->readX(0); - // Assign Y + //// Assign Y int* data_p = &data(static_cast(i), static_cast(j), 0); m_localWorkspace->dataY(spec + nb_monitors).assign(data_p, data_p + m_numberOfChannels); @@ -387,6 +419,10 @@ namespace Mantid } // LoadILLIndirect::loadDataIntoTheWorkSpace + + /** + * Use the LoadHelper utility to load most of the nexus entries into workspace log properties + */ void LoadILLReflectometry::loadNexusEntriesIntoProperties(std::string nexusfilename) { @@ -408,28 +444,10 @@ namespace Mantid stat = NXclose(&nxfileID); } + /** - * Run the Child Algorithm LoadInstrument. + * Utility to center detector. */ - void LoadILLReflectometry::runLoadInstrument() - { - - IAlgorithm_sptr loadInst = createChildAlgorithm("LoadInstrument"); - - // Now execute the Child Algorithm. Catch and log any error, but don't stop. - try - { - - loadInst->setPropertyValue("InstrumentName", m_instrumentName); - loadInst->setProperty("Workspace", m_localWorkspace); - loadInst->execute(); - - } catch (...) - { - g_log.information("Cannot load the instrument definition."); - } - } - void LoadILLReflectometry::centerDetector(double xCenter) { @@ -441,18 +459,19 @@ namespace Mantid } + /** + * Utility to place detector in space, according to data file + */ void LoadILLReflectometry::placeDetector(double distance /* meter */, double angle /* degree */) { - + const double deg2rad = M_PI/180.0; std::string componentName("uniq_detector"); V3D pos = m_loader.getComponentPosition(m_localWorkspace, componentName); +// double r, theta, phi; +// pos.getSpherical(r, theta, phi); - double r, theta, phi; - pos.getSpherical(r, theta, phi); - - V3D newpos; - newpos.spherical(distance, angle, phi); - + double angle_rad = angle*deg2rad; + V3D newpos(distance*sin(angle_rad), pos.Y(), distance*cos(angle_rad)); m_loader.moveComponent(m_localWorkspace, componentName, newpos); // Apply a local rotation to stay perpendicular to the beam diff --git a/Code/Mantid/Framework/DataHandling/src/LoadISISNexus2.cpp b/Code/Mantid/Framework/DataHandling/src/LoadISISNexus2.cpp index eae40f63fd92..8e8fe0ca6bc4 100644 --- a/Code/Mantid/Framework/DataHandling/src/LoadISISNexus2.cpp +++ b/Code/Mantid/Framework/DataHandling/src/LoadISISNexus2.cpp @@ -3,10 +3,12 @@ //---------------------------------------------------------------------- #include "MantidDataHandling/LoadISISNexus2.h" #include "MantidDataHandling/LoadEventNexus.h" +#include "MantidDataHandling/LoadRawHelper.h" #include "MantidKernel/ArrayProperty.h" #include "MantidKernel/BoundedValidator.h" #include "MantidKernel/ConfigService.h" +#include "MantidKernel/ListValidator.h" #include "MantidKernel/LogParser.h" #include "MantidKernel/LogFilter.h" #include "MantidKernel/TimeSeriesProperty.h" @@ -16,7 +18,6 @@ #include "MantidAPI/RegisterFileLoader.h" #include "MantidGeometry/Instrument/Detector.h" -#include "MantidGeometry/Instrument/XMLlogfile.h" #include #include @@ -28,6 +29,7 @@ #include #include +#include #include #include #include @@ -47,9 +49,9 @@ namespace Mantid /// Empty default constructor LoadISISNexus2::LoadISISNexus2() : - m_filename(), m_instrument_name(), m_samplename(), m_numberOfSpectra(0), m_numberOfSpectraInFile(0), - m_numberOfPeriods(0), m_numberOfPeriodsInFile(0), m_numberOfChannels(0), m_numberOfChannelsInFile(0), - m_have_detector(false),m_range_supplied(true), m_spec_min(0), m_spec_max(EMPTY_INT()), + m_filename(), m_instrument_name(), m_samplename(), + m_detBlockInfo(),m_monBlockInfo(),m_loadBlockInfo(), + m_have_detector(false), m_load_selected_spectra(false),m_specInd2specNum_map(),m_spec2det_map(), m_entrynumber(0), m_tof_data(), m_proton_charge(0.), m_spec(), m_monitors(), m_logCreator(), m_progress() @@ -83,6 +85,26 @@ namespace Mantid declareProperty(new ArrayProperty("SpectrumList")); declareProperty("EntryNumber", (int64_t)0, mustBePositive, "The particular entry number to read (default: Load all workspaces and creates a workspace group)"); + + std::vector monitorOptions; + monitorOptions.push_back("Include"); + monitorOptions.push_back("Exclude"); + monitorOptions.push_back("Separate"); + std::map monitorOptionsAliases; + monitorOptionsAliases["1"] = "Separate"; + monitorOptionsAliases["0"] = "Exclude"; + declareProperty("LoadMonitors","Include", boost::make_shared(monitorOptions,monitorOptionsAliases), + "Option to control the loading of monitors.\n" + "Allowed options are Include,Exclude, Separate.\n" + "Include:The default is Include option would load monitors with the workspace if monitors spectra are within the range of loaded detectors.\n" + "If the time binning for the monitors is different from the\n" + "binning of the detectors this option is equivalent to the Separate option\n" + "Exclude:Exclude option excludes monitors from the output workspace.\n" + "Separate:Separate option loads monitors into a separate workspace called: OutputWorkspace_monitors.\n" + "Defined aliases:\n" + "1: Equivalent to Separate.\n" + "0: Equivalent to Exclude.\n"); + } /** Executes the algorithm. Reading in the file and creating and populating @@ -93,12 +115,19 @@ namespace Mantid */ void LoadISISNexus2::exec() { + + //********************************************************************** + // process load monitor options request + bool bincludeMonitors,bseparateMonitors, bexcludeMonitors; + LoadRawHelper::ProcessLoadMonitorOptions(bincludeMonitors,bseparateMonitors, bexcludeMonitors,this); + + //********************************************************************** m_filename = getPropertyValue("Filename"); // Create the root Nexus class NXRoot root(m_filename); // "Open" the same file but with the C++ interface - m_cppFile = new ::NeXus::File(root.m_fileID); + m_cppFile.reset( new ::NeXus::File(root.m_fileID)); // Open the raw data group 'raw_data_1' NXEntry entry = root.openEntry("raw_data_1"); @@ -131,8 +160,10 @@ namespace Mantid NXInt spec = entry.openNXInt("isis_vms_compat/SPEC"); spec.load(); - //Pull out the monitor blocks, if any exist size_t nmons(0); + + + //Pull out the monitor blocks, if any exist for(std::vector::const_iterator it = entry.groups().begin(); it != entry.groups().end(); ++it) { @@ -140,50 +171,41 @@ namespace Mantid { NXInt index = entry.openNXInt(std::string(it->nxname) + "/spectrum_index"); index.load(); - m_monitors[*index()] = it->nxname; + int64_t ind = *index(); + m_monitors[ind ] = it->nxname; + ++nmons; } } - if( ndets == 0 && nmons == 0 ) - { - g_log.error() << "Invalid NeXus structure, cannot find detector or monitor blocks."; - throw std::runtime_error("Inconsistent NeXus file structure."); - } - if( ndets == 0 ) - { - - //Grab the number of channels - NXInt chans = entry.openNXInt(m_monitors.begin()->second + "/data"); - m_numberOfPeriodsInFile = m_numberOfPeriods = chans.dim0(); - m_numberOfSpectraInFile = m_numberOfSpectra = nmons; - m_numberOfChannelsInFile = m_numberOfChannels = chans.dim2(); - } - else + if( ndets == 0 && nmons == 0 ) { - NXData nxData = entry.openNXData("detector_1"); - NXInt data = nxData.openIntData(); - m_numberOfPeriodsInFile = m_numberOfPeriods = data.dim0(); - m_numberOfSpectraInFile = m_numberOfSpectra = nsp1[0]; - m_numberOfChannelsInFile = m_numberOfChannels = data.dim2(); - - if( nmons > 0 && m_numberOfSpectra == static_cast(data.dim1()) ) + if (bexcludeMonitors) { - m_monitors.clear(); + g_log.warning() << "Nothing to do. No detectors found and no monitor loading requested"; + return; + } + else + { + g_log.error() << "Invalid NeXus structure, cannot find detector or monitor blocks."; + throw std::runtime_error("Inconsistent NeXus file structure."); } } - const size_t x_length = m_numberOfChannels + 1; + std::map ExcluedMonitorsSpectra; + bseparateMonitors=findSpectraDetRangeInFile(entry,m_spec,ndets,nsp1[0],m_monitors,bexcludeMonitors,bseparateMonitors,ExcluedMonitorsSpectra); + + size_t x_length = m_loadBlockInfo.numberOfChannels + 1; - // Check input is consistent with the file, throwing if not - checkOptionalProperties(); + // Check input is consistent with the file, throwing if not, exclude spectra selected at findSpectraDetRangeInFile; + checkOptionalProperties(ExcluedMonitorsSpectra); // Fill up m_spectraBlocks - size_t total_specs = prepareSpectraBlocks(); + size_t total_specs = prepareSpectraBlocks(m_monitors,m_specInd2specNum_map,m_loadBlockInfo); - m_progress = boost::shared_ptr(new Progress(this, 0.0, 1.0, total_specs * m_numberOfPeriods)); + m_progress = boost::shared_ptr(new Progress(this, 0.0, 1.0, total_specs * m_detBlockInfo.numberOfPeriods)); DataObjects::Workspace2D_sptr local_workspace = boost::dynamic_pointer_cast - (WorkspaceFactory::Instance().create("Workspace2D", total_specs, x_length, m_numberOfChannels)); + (WorkspaceFactory::Instance().create("Workspace2D", total_specs, x_length, m_loadBlockInfo.numberOfChannels)); // Set the units on the workspace to TOF & Counts local_workspace->getAxis(0)->unit() = UnitFactory::Instance().create("TOF"); local_workspace->setYUnit("Counts"); @@ -212,7 +234,7 @@ namespace Mantid // Load logs and sample information m_cppFile->openPath(entry.path()); - local_workspace->loadSampleAndLogInfoNexus(m_cppFile); + local_workspace->loadSampleAndLogInfoNexus(m_cppFile.get()); // Load logs and sample information further information... See maintenance ticket #8697 loadSampleData(local_workspace, entry); @@ -237,7 +259,7 @@ namespace Mantid createPeriodLogs(firstentry, local_workspace); - if( m_numberOfPeriods > 1 && m_entrynumber == 0 ) + if( m_detBlockInfo.numberOfPeriods > 1 && m_entrynumber == 0 ) { WorkspaceGroup_sptr wksp_group(new WorkspaceGroup); @@ -247,7 +269,7 @@ namespace Mantid const std::string base_name = getPropertyValue("OutputWorkspace") + "_"; const std::string prop_name = "OutputWorkspace_"; - for( int p = 1; p <= m_numberOfPeriods; ++p ) + for( int p = 1; p <= m_detBlockInfo.numberOfPeriods; ++p ) { std::ostringstream os; os << p; @@ -266,17 +288,66 @@ namespace Mantid setProperty(prop_name + os.str(), boost::static_pointer_cast(local_workspace)); } // The group is the root property value - setProperty("OutputWorkspace", boost::dynamic_pointer_cast(wksp_group)); + if(!bseparateMonitors) + setProperty("OutputWorkspace", boost::dynamic_pointer_cast(wksp_group)); } else + { + if(!bseparateMonitors) + setProperty("OutputWorkspace", boost::dynamic_pointer_cast(local_workspace)); + } + + //*************************************************************************************************** + // Workspace or group of workspaces without monitors is loaded. Now we are loading monitors separately. + if(bseparateMonitors) { setProperty("OutputWorkspace", boost::dynamic_pointer_cast(local_workspace)); + if(m_detBlockInfo.numberOfPeriods>1) + { + g_log.error()<<" Separate monitor workspace loading have not been implemented for multiperiod workspaces. Performed separate monitors loading\n"; + } + else + { + std::string wsName = getProperty("OutputWorkspace"); + if(m_monBlockInfo.numberOfSpectra==0) + { + g_log.information()<<" no monitors to load for workspace: "< + (WorkspaceFactory::Instance().create(local_workspace, m_monBlockInfo.numberOfSpectra,x_length,m_monBlockInfo.numberOfChannels)); + local_workspace->setMonitorWorkspace(monitor_workspace); + + m_spectraBlocks.clear(); + m_specInd2specNum_map.clear(); + std::vector dummyS1; + // at the moment here we clear this map to enable possibility to load monitors from the spectra block (wiring table bug). + // if monitor's spectra present in the detectors block due to this bug should be read from monitors, this map should be dealt with properly. + ExcluedMonitorsSpectra.clear(); + buildSpectraInd2SpectraNumMap(true,m_monBlockInfo.spectraID_min,m_monBlockInfo.spectraID_max,dummyS1,ExcluedMonitorsSpectra); + // lo + prepareSpectraBlocks(m_monitors,m_specInd2specNum_map,m_monBlockInfo); + + + int64_t firstentry = (m_entrynumber > 0) ? m_entrynumber : 1; + loadPeriodData(firstentry, entry, monitor_workspace); + + + std::string monitorwsName = wsName + "_monitors"; + declareProperty(new WorkspaceProperty ("MonitorWorkspace", monitorwsName,Direction::Output)); + setProperty("MonitorWorkspace", boost::static_pointer_cast(monitor_workspace)); + } + } + } // Clear off the member variable containers m_tof_data.reset(); m_spec.reset(); m_monitors.clear(); + m_specInd2specNum_map.clear(); } // Function object for remove_if STL algorithm @@ -298,36 +369,6 @@ namespace Mantid }; } - /** - build the list of spectra to load and include into spectra-detectors map - @param spec_list -- list of spectra to load - **/ - void LoadISISNexus2::buildSpectraInd2SpectraNumMap(const std::vector &spec_list) - { - - int64_t ic(0); - - if(spec_list.size()>0) - { - auto start_point = spec_list.begin(); - for(auto it =start_point ;it!=spec_list.end();it++) - { - ic = it-start_point; - m_specInd2specNum_map.insert(std::pair(ic,static_cast(*it))); - } - } - else - { - if(m_range_supplied) - { - ic = m_specInd2specNum_map.size(); - for(int64_t i=m_spec_min;i(i-m_spec_min+ic,static_cast(i))); - - } - } - } - /** Check for a set of synthetic logs associated with multi-period log data. Raise warnings where necessary. @@ -351,50 +392,71 @@ namespace Mantid /** * Check the validity of the optional properties of the algorithm and identify if partial data should be loaded. + * @param SpectraExcluded :: set of spectra ID-s to exclude from spectra list to load */ - void LoadISISNexus2::checkOptionalProperties() + void LoadISISNexus2::checkOptionalProperties(const std::map &SpectraExcluded) { // optional properties specify that only some spectra have to be loaded - m_load_selected_spectra = false; - m_spec_min = getProperty("SpectrumMin"); - m_spec_max = getProperty("SpectrumMax"); + bool range_supplied(false); - if( m_spec_min == 0 && m_spec_max == EMPTY_INT() ) + if (!SpectraExcluded.empty()) { - m_range_supplied = false; + range_supplied = true; + m_load_selected_spectra = true; } - if( m_spec_min == 0 ) - m_spec_min = 1; + int64_t spec_min(0); + int64_t spec_max(EMPTY_INT()); + // + spec_min = getProperty("SpectrumMin"); + spec_max = getProperty("SpectrumMax"); + + + // default spectra ID-s would not work if spectraID_min!=1 + if(m_loadBlockInfo.spectraID_min!=1) + { + range_supplied = true; + m_load_selected_spectra = true; + } + + + if( spec_min == 0 ) + spec_min = m_loadBlockInfo.spectraID_min; else + { + range_supplied = true; m_load_selected_spectra = true; + } - if( m_spec_max == EMPTY_INT() ) - m_spec_max = m_numberOfSpectra; + if( spec_max == EMPTY_INT() ) + spec_max = m_loadBlockInfo.spectraID_max; else + { + range_supplied = true; m_load_selected_spectra = true; + } // Sanity check for min/max - if( m_spec_min > m_spec_max ) + if( spec_min > spec_max ) { throw std::invalid_argument("Inconsistent range properties. SpectrumMin is larger than SpectrumMax."); } - if( static_cast(m_spec_max) > m_numberOfSpectra ) + if( spec_max > m_loadBlockInfo.spectraID_max) { - std::string err="Inconsistent range property. SpectrumMax is larger than number of spectra: "+boost::lexical_cast(m_numberOfSpectra ); + std::string err="Inconsistent range property. SpectrumMax is larger than number of spectra: "+boost::lexical_cast(m_loadBlockInfo.spectraID_max ); throw std::invalid_argument(err); } // Check the entry number m_entrynumber = getProperty("EntryNumber"); - if( static_cast(m_entrynumber) > m_numberOfPeriods || m_entrynumber < 0 ) + if( static_cast(m_entrynumber) > m_loadBlockInfo.numberOfPeriods || m_entrynumber < 0 ) { - std::string err="Invalid entry number entered. File contains "+boost::lexical_cast(m_numberOfPeriods )+ " period. "; + std::string err="Invalid entry number entered. File contains "+boost::lexical_cast(m_loadBlockInfo.numberOfPeriods)+ " period. "; throw std::invalid_argument(err); } - if( m_numberOfPeriods == 1 ) + if(m_loadBlockInfo.numberOfPeriods== 1 ) { m_entrynumber = 1; } @@ -408,44 +470,101 @@ namespace Mantid // Sort the list so that we can check it's range std::sort(spec_list.begin(), spec_list.end()); - if( spec_list.back() > static_cast(m_numberOfSpectra) ) + if( spec_list.back() > m_loadBlockInfo.spectraID_max ) { - std::string err="A spectra number in the spectra list exceeds total number of "+boost::lexical_cast(m_numberOfSpectra )+ " spectra "; + std::string err="A spectra number in the spectra list exceeds maximal spectra ID: "+boost::lexical_cast(m_loadBlockInfo.spectraID_max )+ " in the file "; throw std::invalid_argument(err); } - - //Check no negative numbers have been passed - std::vector::iterator itr = - std::find_if(spec_list.begin(), spec_list.end(), std::bind2nd(std::less(), 0)); - if( itr != spec_list.end() ) + if( spec_list.front() < m_loadBlockInfo.spectraID_min ) { - throw std::invalid_argument("Negative SpectraList property encountered."); + std::string err="A spectra number in the spectra list smaller then minimal spectra ID: "+boost::lexical_cast(m_loadBlockInfo.spectraID_min )+ " in the file"; + throw std::invalid_argument(err); } - range_check in_range(m_spec_min, m_spec_max); - if( m_range_supplied ) + + + range_check in_range(spec_min, spec_max); + if(range_supplied ) { spec_list.erase(remove_if(spec_list.begin(), spec_list.end(), in_range), spec_list.end()); // combine spectra numbers from ranges and the list if (spec_list.size()>0) { - for(int64_t i=m_spec_min;i(i)); + for(int64_t i=spec_min;i(i); + // remove excluded spectra now rather then inserting it here and removing later + if (SpectraExcluded.find(spec_num)==SpectraExcluded.end() ) + spec_list.push_back(spec_num); + } // Sort the list so that lower spectra indexes correspond to smaller spectra ID-s std::sort(spec_list.begin(), spec_list.end()); - + // supplied range converted into the list, so no more supplied range + range_supplied =false; } } + } - else + // + if (m_load_selected_spectra) { - m_range_supplied = true; + buildSpectraInd2SpectraNumMap(range_supplied,spec_min,spec_max,spec_list,SpectraExcluded); } - if (m_load_selected_spectra) + else // may be just range supplied and the range have to start from 1 to use defaults in spectra num to spectra ID map! { - buildSpectraInd2SpectraNumMap(spec_list); + m_loadBlockInfo.spectraID_max=spec_max; + m_loadBlockInfo.numberOfSpectra = m_loadBlockInfo.spectraID_max-m_loadBlockInfo.spectraID_min+1; } } + /** + build the list of spectra to load and include into spectra-detectors map + @param range_supplied -- if true specifies that the range of values provided below have to be processed rather then spectra list + @param range_min -- min value for spectra-ID to load + @param range_max -- max value for spectra-ID to load + @param spec_list -- list of spectra numbers to load + @param SpectraExcluded -- set of the spectra ID-s to exclude from loading + **/ + void LoadISISNexus2::buildSpectraInd2SpectraNumMap(bool range_supplied,int64_t range_min,int64_t range_max, + const std::vector &spec_list,const std::map &SpectraExcluded) + { + + int64_t ic(0); + + if(spec_list.size()>0) + { + ic = 0; + auto start_point = spec_list.begin(); + for(auto it =start_point ;it!=spec_list.end();it++) + { + + specid_t spec_num = static_cast(*it); + if (SpectraExcluded.find(spec_num)==SpectraExcluded.end() ) + { + m_specInd2specNum_map.insert(std::pair(ic,spec_num)); + ic++; + } + } + } + else + { + if(range_supplied) + { + ic = 0; + for(int64_t i=range_min;i(i); + if (SpectraExcluded.find(spec_num)==SpectraExcluded.end() ) + { + m_specInd2specNum_map.insert(std::pair(ic,spec_num)); + ic++; + } + } + + } + } + } + + namespace { @@ -466,66 +585,84 @@ namespace Mantid * in a separate block. * @return :: Number of spectra to load. */ - size_t LoadISISNexus2::prepareSpectraBlocks() + size_t LoadISISNexus2::prepareSpectraBlocks(std::map &monitors, const std::map &specInd2specNum_map,const DataBlock &LoadBlock) { std::vector includedMonitors; // fill in the data block descriptor vector - if ( ! m_specInd2specNum_map.empty() ) + if ( ! specInd2specNum_map.empty() ) { - auto itSpec= m_specInd2specNum_map.begin(); + auto itSpec= specInd2specNum_map.begin(); int64_t hist = itSpec->second; - SpectraBlock block(hist,hist,false); + SpectraBlock block(hist,hist,false,""); itSpec++; - for(; itSpec != m_specInd2specNum_map.end(); ++itSpec) + for(; itSpec != specInd2specNum_map.end(); ++itSpec) { // try to put all consecutive numbers in same block - bool isMonitor = m_monitors.find( hist ) != m_monitors.end(); + + auto it_mon = monitors.find( hist ); + bool isMonitor = it_mon != monitors.end(); if ( isMonitor || itSpec->second!= hist + 1 ) { + + if ( isMonitor ) + { + includedMonitors.push_back( hist ); + block.monName = it_mon->second; + } + block.last = hist; block.isMonitor = isMonitor; m_spectraBlocks.push_back( block ); - if ( isMonitor ) includedMonitors.push_back( hist ); - block = SpectraBlock(itSpec ->second,itSpec ->second,false); + + block = SpectraBlock(itSpec ->second,itSpec ->second,false,""); } hist = itSpec ->second; } + // push the last block - hist = m_specInd2specNum_map.rbegin()->second; + hist = specInd2specNum_map.rbegin()->second; block.last = hist; - if ( m_monitors.find( hist ) != m_monitors.end() ) + + auto it_mon = monitors.find( hist ); + if (it_mon != monitors.end() ) { includedMonitors.push_back( hist ); block.isMonitor = true; + block.monName = it_mon->second; } m_spectraBlocks.push_back( block ); - return m_specInd2specNum_map.size(); + return specInd2specNum_map.size(); } + // here we are only if ranges are not supplied + // // put in the spectra range, possibly breaking it into parts by monitors - int64_t first = m_spec_min; - for(int64_t hist = first; hist < m_spec_max; ++hist) + int64_t first = LoadBlock.spectraID_min; + for(int64_t hist = first; hist < LoadBlock.spectraID_max; ++hist) { - if ( m_monitors.find( hist ) != m_monitors.end() ) + auto it_mon = monitors.find( hist ); + if ( it_mon != monitors.end() ) { if ( hist != first ) { - m_spectraBlocks.push_back( SpectraBlock( first, hist - 1, false ) ); + m_spectraBlocks.push_back( SpectraBlock(first,hist - 1,false,"") ); } - m_spectraBlocks.push_back( SpectraBlock( hist, hist, true) ); + m_spectraBlocks.push_back( SpectraBlock( hist, hist, true,it_mon->second) ); includedMonitors.push_back( hist ); first = hist + 1; } } - if ( first == m_spec_max && m_monitors.find( first ) != m_monitors.end() ) + int64_t spec_max = LoadBlock.spectraID_max; + auto it_mon = monitors.find( first); + if ( first == spec_max && it_mon != monitors.end() ) { - m_spectraBlocks.push_back( SpectraBlock( first, m_spec_max, true ) ); - includedMonitors.push_back( m_spec_max ); + m_spectraBlocks.push_back( SpectraBlock( first, spec_max, true, it_mon->second ) ); + includedMonitors.push_back( spec_max ); } else { - m_spectraBlocks.push_back( SpectraBlock( first, m_spec_max, false ) ); + m_spectraBlocks.push_back( SpectraBlock(first,spec_max,false,"") ); } // sort and check for overlapping @@ -534,22 +671,18 @@ namespace Mantid std::sort( m_spectraBlocks.begin(), m_spectraBlocks.end(), compareSpectraBlocks ); } - // remove monitors that weren't requested - if ( m_monitors.size() != includedMonitors.size() ) + // remove monitors that have been used + if ( monitors.size() != includedMonitors.size() ) { - if ( includedMonitors.empty() ) + if ( !includedMonitors.empty() ) { - m_monitors.clear(); - } - else - { - for(auto it = m_monitors.begin(); it != m_monitors.end(); ) + for(auto it = monitors.begin(); it != monitors.end(); ) { - if ( std::find( includedMonitors.begin(), includedMonitors.end(), it->first ) == includedMonitors.end() ) + if ( std::find( includedMonitors.begin(), includedMonitors.end(), it->first ) != includedMonitors.end() ) { auto it1 = it; ++it; - m_monitors.erase( it1 ); + monitors.erase( it1 ); } else { @@ -573,7 +706,7 @@ namespace Mantid * @param entry :: The opened root entry node for accessing the monitor and data nodes * @param local_workspace :: The workspace to place the data in */ - void LoadISISNexus2::loadPeriodData(int64_t period, NXEntry & entry, DataObjects::Workspace2D_sptr local_workspace) + void LoadISISNexus2::loadPeriodData(int64_t period, NXEntry & entry, DataObjects::Workspace2D_sptr &local_workspace) { int64_t hist_index = 0; int64_t period_index(period - 1); @@ -583,14 +716,12 @@ namespace Mantid { if ( block->isMonitor ) { - auto it = m_monitors.find( block->first ); - assert( it != m_monitors.end() ); - NXData monitor = entry.openNXData(it->second); + NXData monitor = entry.openNXData(block->monName); NXInt mondata = monitor.openIntData(); m_progress->report("Loading monitor"); mondata.load(1,static_cast(period-1)); // TODO this is just wrong MantidVec& Y = local_workspace->dataY(hist_index); - Y.assign(mondata(),mondata() + m_numberOfChannels); + Y.assign(mondata(),mondata() + m_monBlockInfo.numberOfChannels); MantidVec& E = local_workspace->dataE(hist_index); std::transform(Y.begin(), Y.end(), E.begin(), dblSqrt); @@ -659,7 +790,7 @@ namespace Mantid * @param period :: period number * @param local_workspace :: workspace to add period log data to. */ - void LoadISISNexus2::createPeriodLogs(int64_t period, DataObjects::Workspace2D_sptr local_workspace) + void LoadISISNexus2::createPeriodLogs(int64_t period, DataObjects::Workspace2D_sptr &local_workspace) { m_logCreator->addPeriodLogs(static_cast(period), local_workspace->mutableRun()); } @@ -677,18 +808,19 @@ namespace Mantid */ void LoadISISNexus2::loadBlock(NXDataSetTyped & data, int64_t blocksize, int64_t period, int64_t start, int64_t &hist, int64_t& spec_num, - DataObjects::Workspace2D_sptr local_workspace) + DataObjects::Workspace2D_sptr &local_workspace) { data.load(static_cast(blocksize), static_cast(period), static_cast(start)); // TODO this is just wrong int *data_start = data(); - int *data_end = data_start + m_numberOfChannels; + int *data_end = data_start + m_loadBlockInfo.numberOfChannels; int64_t final(hist + blocksize); while( hist < final ) { m_progress->report("Loading data"); MantidVec& Y = local_workspace->dataY(hist); Y.assign(data_start, data_end); - data_start += m_numberOfChannels; data_end += m_numberOfChannels; + data_start += m_detBlockInfo.numberOfChannels; + data_end += m_detBlockInfo.numberOfChannels; MantidVec& E = local_workspace->dataE(hist); std::transform(Y.begin(), Y.end(), E.begin(), dblSqrt); // Populate the workspace. Loop starts from 1, hence i-1 @@ -710,7 +842,7 @@ namespace Mantid } /// Run the Child Algorithm LoadInstrument (or LoadInstrumentFromNexus) - void LoadISISNexus2::runLoadInstrument(DataObjects::Workspace2D_sptr localWorkspace) + void LoadISISNexus2::runLoadInstrument(DataObjects::Workspace2D_sptr &localWorkspace) { IAlgorithm_sptr loadInst = createChildAlgorithm("LoadInstrument"); @@ -769,7 +901,7 @@ namespace Mantid * @param local_workspace :: The workspace to load the run information in to * @param entry :: The Nexus entry */ - void LoadISISNexus2::loadRunDetails(DataObjects::Workspace2D_sptr local_workspace, NXEntry & entry) + void LoadISISNexus2::loadRunDetails(DataObjects::Workspace2D_sptr &local_workspace, NXEntry & entry) { API::Run & runDetails = local_workspace->mutableRun(); // Charge is stored as a float @@ -812,9 +944,9 @@ namespace Mantid runDetails.addProperty("run_header", std::string(header, header + 86)); // Data details on run not the workspace - runDetails.addProperty("nspectra", static_cast(m_numberOfSpectraInFile)); - runDetails.addProperty("nchannels", static_cast(m_numberOfChannelsInFile)); - runDetails.addProperty("nperiods", static_cast(m_numberOfPeriodsInFile)); + runDetails.addProperty("nspectra", static_cast(m_loadBlockInfo.numberOfSpectra)); + runDetails.addProperty("nchannels", static_cast(m_loadBlockInfo.numberOfChannels)); + runDetails.addProperty("nperiods", static_cast(m_loadBlockInfo.numberOfPeriods)); // RPB struct info NXInt rpb_int = vms_compat.openNXInt("IRPB"); @@ -885,7 +1017,7 @@ namespace Mantid * @param local_workspace :: The workspace to load the logs to. * @param entry :: The Nexus entry */ - void LoadISISNexus2::loadSampleData(DataObjects::Workspace2D_sptr local_workspace, NXEntry & entry) + void LoadISISNexus2::loadSampleData(DataObjects::Workspace2D_sptr &local_workspace, NXEntry & entry) { /// Sample geometry NXInt spb = entry.openNXInt("isis_vms_compat/SPB"); @@ -911,7 +1043,7 @@ namespace Mantid * @param ws :: The workspace to load the logs to. * @param entry :: Nexus entry */ - void LoadISISNexus2::loadLogs(DataObjects::Workspace2D_sptr ws, NXEntry & entry) + void LoadISISNexus2::loadLogs(DataObjects::Workspace2D_sptr &ws, NXEntry & entry) { IAlgorithm_sptr alg = createChildAlgorithm("LoadNexusLogs", 0.0, 0.5); alg->setPropertyValue("Filename", this->getProperty("Filename")); @@ -946,7 +1078,7 @@ namespace Mantid ws->populateInstrumentParameters(); // Make log creator object and add the run status log - m_logCreator.reset(new ISISRunLogs(ws->run(), m_numberOfPeriods)); + m_logCreator.reset(new ISISRunLogs(ws->run(), m_detBlockInfo.numberOfPeriods)); m_logCreator->addStatusLog(ws->mutableRun()); } @@ -954,6 +1086,140 @@ namespace Mantid { return sqrt(in); } + /**Method takes input parameters which describe monitor loading and analyze them against spectra/monitor block information in the file. + * The result is the option if monitors can be loaded together with spectra or mast be treated separately + * and additional information on how to treat monitor spectra. + * + *@param entry :: entry to the NeXus file, opened at root folder + *@param spectrum_index :: array of spectra indexes of the data present in the file + *@param ndets :: size of the spectrum index array + *@param n_vms_compat_spectra :: number of data entries containing common time bins (e.g. all spectra, or all spectra and monitors or some spectra (this is not fully supported) + *@param monitors :: map connecting monitor spectra ID against monitor group name in the file. + *@param excludeMonitors :: input property indicating if it is requested to exclude monitors from the target workspace + *@param separateMonitors :: input property indicating if it is requested to load monitors separately (and exclude them from target data workspace this way) + * + *@param OvelapMonitors :: output property containing the list of monitors ID for monitors, which are also included with spectra. + *@return excludeMonitors :: indicator if monitors should or mast be excluded from the main data workspace if they can not be loaded with the data + * (contain different number of time channels) + * + */ + bool LoadISISNexus2::findSpectraDetRangeInFile(NXEntry &entry,boost::shared_array &spectrum_index,int64_t ndets,int64_t n_vms_compat_spectra, + std::map &monitors,bool excludeMonitors,bool separateMonitors,std::map &OvelapMonitors) + { + OvelapMonitors.clear(); + size_t nmons = monitors.size(); + + if (nmons>0) + { + NXInt chans = entry.openNXInt(m_monitors.begin()->second + "/data"); + + m_monBlockInfo = DataBlock(chans); + m_monBlockInfo.numberOfSpectra = nmons; // each monitor is in separate group so number of spectra is equal to number of groups. + + // identify monitor ID range. + for(auto it = monitors.begin(); it!=monitors.end(); it++) + { + int64_t mon_id = static_cast(it->first); + if(m_monBlockInfo.spectraID_min>mon_id )m_monBlockInfo.spectraID_min=mon_id; + if(m_monBlockInfo.spectraID_max(nmons)) + { + g_log.warning()<<" non-consequent monitor ID-s in the monitor block. Unexpected situation for the loader\n"; + } + // at this stage we assume that the only going to load monitors + m_loadBlockInfo = m_monBlockInfo; + + } + + if( ndets == 0 ) + { + separateMonitors = false; // only monitors in the main workspace. No detectors. Will be loaded in the main workspace + return separateMonitors; + } + + // detectors are present in the file + NXData nxData = entry.openNXData("detector_1"); + NXInt data = nxData.openIntData(); + + m_detBlockInfo = DataBlock(data); + // We assume again that this spectrum list ID increase monotonically + m_detBlockInfo.spectraID_min = spectrum_index[0]; + m_detBlockInfo.spectraID_max = spectrum_index[ndets-1]; + if(m_detBlockInfo.spectraID_max-m_detBlockInfo.spectraID_min+1!=static_cast(m_detBlockInfo.numberOfSpectra)) + { + g_log.warning()<<" non-consequent spectra ID-s in the detectors block. Unexpected situation for the loader\n"; + } + + + m_loadBlockInfo = m_detBlockInfo; + + + // now we are analyzing what is actually going or can be loaded + + bool removeMonitors = excludeMonitors || separateMonitors; + if (((m_detBlockInfo.numberOfPeriods!=m_monBlockInfo.numberOfPeriods) || (m_detBlockInfo.numberOfChannels!=m_monBlockInfo.numberOfChannels)) && nmons>0) + { + // detectors and monitors have different characteristics. Can be loaded only to separate workspaces. + if(!removeMonitors) + { + g_log.warning()<<" Performing separate loading as can not load spectra and monitors in the single workspace:\n" ; + g_log.warning()<<" Monitors data contain :"<( n_vms_compat_spectra )) && (spectraID_max-spectraID_min+1 ==static_cast(n_vms_compat_spectra))) + { + // all information written in the file is correct, there are no spurious spectra and detectors & monitors form continuous block on HDD + return separateMonitors; + } + + + // something is wrong and we need to analyze spectra map. Currently we can identify and manage the case when all monitor's spectra are written together with detectors + //make settings for this situation + m_detBlockInfo.numberOfSpectra -= m_monBlockInfo.numberOfSpectra; + m_loadBlockInfo.numberOfSpectra-= m_monBlockInfo.numberOfSpectra; + + std::map remaining_monitors; + if(removeMonitors) + { + for(auto it = monitors.begin(); it!=monitors.end(); it++) + { + if(it->first>=m_detBlockInfo.spectraID_min && it->first <=m_detBlockInfo.spectraID_max) + { //monitors ID-s are included with spectra ID-s -- let's try not to load it twice. + OvelapMonitors.insert(*it); + } + else + { + remaining_monitors.insert(*it); + } + } + } + monitors.swap(remaining_monitors); + + + return separateMonitors; + + } + } // namespace DataHandling } // namespace Mantid diff --git a/Code/Mantid/Framework/DataHandling/src/LoadInstrument.cpp b/Code/Mantid/Framework/DataHandling/src/LoadInstrument.cpp index 43cc021af90d..45661ecd0d7d 100644 --- a/Code/Mantid/Framework/DataHandling/src/LoadInstrument.cpp +++ b/Code/Mantid/Framework/DataHandling/src/LoadInstrument.cpp @@ -5,13 +5,11 @@ #include "MantidAPI/InstrumentDataService.h" #include "MantidAPI/Progress.h" #include "MantidDataHandling/LoadInstrument.h" -#include "MantidDataHandling/LoadParameterFile.h" #include "MantidGeometry/Instrument.h" #include "MantidGeometry/Instrument/Component.h" #include "MantidGeometry/Instrument/Detector.h" #include "MantidGeometry/Instrument/ObjCompAssembly.h" #include "MantidGeometry/Instrument/RectangularDetector.h" -#include "MantidGeometry/Instrument/XMLlogfile.h" #include "MantidGeometry/Objects/ShapeFactory.h" #include "MantidGeometry/Rendering/vtkGeometryCacheReader.h" #include "MantidGeometry/Rendering/vtkGeometryCacheWriter.h" @@ -204,14 +202,17 @@ namespace Mantid { // Not found, so search the other places were it may occur Kernel::ConfigServiceImpl & configService = Kernel::ConfigService::Instance(); - std::string directoryName = configService.getString("parameterDefinition.directory"); - if (directoryName.empty()) + std::vector directoryNames = configService.getInstrumentDirectories(); + + for ( auto instDirs_itr = directoryNames.begin(); instDirs_itr != directoryNames.end(); ++instDirs_itr) { - // This is the assumed deployment directory for parameter files, where we need to be - // relative to the directory of the executable, not the current working directory. - directoryName = Poco::Path(configService.getPropertiesDir()).resolve("../instrument").toString(); + //This will iterate around the directories from user ->etc ->install, and find the first beat file + std::string directoryName = *instDirs_itr; + fullPathParamIDF = getFullPathParamIDF( directoryName ); + //stop when you find the first one + if (!fullPathParamIDF.empty()) + break; } - fullPathParamIDF = getFullPathParamIDF( directoryName ); } if(!fullPathParamIDF.empty()) { @@ -221,7 +222,10 @@ namespace Mantid try { // To allow the use of ExperimentInfo instead of workspace, we call it manually - LoadParameterFile::execManually(false, fullPathParamIDF, "", m_workspace); + Algorithm_sptr loadParamAlg = createChildAlgorithm("LoadParameterFile"); + loadParamAlg->setProperty("Filename", fullPathParamIDF); + loadParamAlg->setProperty("Workspace", m_workspace); + loadParamAlg->execute(); g_log.debug("Parameters loaded successfully."); } catch (std::invalid_argument& e) { diff --git a/Code/Mantid/Framework/DataHandling/src/LoadNXSPE.cpp b/Code/Mantid/Framework/DataHandling/src/LoadNXSPE.cpp index c8605ec72e57..8b2ed399d04e 100644 --- a/Code/Mantid/Framework/DataHandling/src/LoadNXSPE.cpp +++ b/Code/Mantid/Framework/DataHandling/src/LoadNXSPE.cpp @@ -2,11 +2,13 @@ #include "MantidKernel/UnitFactory.h" #include "MantidAPI/FileProperty.h" #include "MantidAPI/RegisterFileLoader.h" +#include "MantidAPI/SpectraAxis.h" #include #include #include "MantidNexus/NexusClasses.h" + #include "MantidGeometry/Instrument.h" #include "MantidGeometry/Instrument/Detector.h" #include "MantidGeometry/Surfaces/Plane.h" @@ -16,234 +18,261 @@ #include #include #include +#include namespace Mantid { -namespace DataHandling -{ - - DECLARE_NEXUS_FILELOADER_ALGORITHM(LoadNXSPE); - - using namespace Mantid::Kernel; - using namespace Mantid::API; + namespace DataHandling + { + DECLARE_NEXUS_FILELOADER_ALGORITHM(LoadNXSPE); - //---------------------------------------------------------------------------------------------- - /** Constructor - */ - LoadNXSPE::LoadNXSPE() - { - } + using namespace Mantid::Kernel; + using namespace Mantid::API; - //---------------------------------------------------------------------------------------------- - /** Destructor - */ - LoadNXSPE::~LoadNXSPE() - { - } + //---------------------------------------------------------------------------------------------- + /** Constructor + */ + LoadNXSPE::LoadNXSPE() + { + } + //---------------------------------------------------------------------------------------------- + /** Destructor + */ + LoadNXSPE::~LoadNXSPE() + { + } - //---------------------------------------------------------------------------------------------- + //---------------------------------------------------------------------------------------------- - /** - * Return the confidence with with this algorithm can load the file - * @param descriptor A descriptor for the file - * @returns An integer specifying the confidence level. 0 indicates it will not be used - */ - int LoadNXSPE::confidence(Kernel::NexusDescriptor & descriptor) const - { - int confidence(0); - typedef std::map string_map_t; - try + /** + * Calculate the confidence in the string value. This is used for file identification. + * @param value + * @return confidence 0 - 100% + */ + int LoadNXSPE::identiferConfidence(const std::string& value) { - ::NeXus::File file = ::NeXus::File(descriptor.filename()); - string_map_t entries = file.getEntries(); - for(string_map_t::const_iterator it = entries.begin(); it != entries.end(); ++it) + int confidence = 0; + if (value.compare("NXSPE") == 0) { - if (it->second == "NXentry") + confidence = 99; + } + else + { + boost::regex re("^NXSP", boost::regex::icase); + if (boost::regex_match(value, re)) { - file.openGroup(it->first, it->second); - file.openData("definition"); - if (file.getStrData().compare("NXSPE")==0) confidence =99; + confidence = 95; } } + return confidence; } - catch(::NeXus::Exception&) - { - } - return confidence; - } - //---------------------------------------------------------------------------------------------- - /** Initialize the algorithm's properties. - */ - void LoadNXSPE::init() - { - std::vector exts; - exts.push_back(".nxspe"); - exts.push_back(""); - declareProperty(new FileProperty("Filename", "", FileProperty::Load, exts), - "An NXSPE file"); - declareProperty(new WorkspaceProperty<>("OutputWorkspace", - "",Direction::Output), "The name of the workspace that will be created."); - } - - //---------------------------------------------------------------------------------------------- - /** Execute the algorithm. - */ - void LoadNXSPE::exec() - { - std::string filename = getProperty("Filename"); - //quicly check if it's really nxspe - try + /** + * Return the confidence with with this algorithm can load the file + * @param descriptor A descriptor for the file + * @returns An integer specifying the confidence level. 0 indicates it will not be used + */ + int LoadNXSPE::confidence(Kernel::NexusDescriptor & descriptor) const { - ::NeXus::File file(filename); - std::string mainEntry=(*(file.getEntries().begin())).first; - file.openGroup(mainEntry, "NXentry"); - file.openData("definition"); - if (file.getStrData().compare("NXSPE")) throw std::invalid_argument("Not NXSPE"); - file.close(); + int confidence(0); + typedef std::map string_map_t; + try + { + ::NeXus::File file = ::NeXus::File(descriptor.filename()); + string_map_t entries = file.getEntries(); + for (string_map_t::const_iterator it = entries.begin(); it != entries.end(); ++it) + { + if (it->second == "NXentry") + { + file.openGroup(it->first, it->second); + file.openData("definition"); + const std::string value = file.getStrData(); + confidence = identiferConfidence(value); + } + } + } catch (::NeXus::Exception&) + { + } + return confidence; } - catch(...) + + //---------------------------------------------------------------------------------------------- + /** Initialize the algorithm's properties. + */ + void LoadNXSPE::init() { - throw std::invalid_argument("Not NeXus or notNXSPE"); + std::vector exts; + exts.push_back(".nxspe"); + exts.push_back(""); + declareProperty(new FileProperty("Filename", "", FileProperty::Load, exts), "An NXSPE file"); + declareProperty(new WorkspaceProperty<>("OutputWorkspace", "", Direction::Output), + "The name of the workspace that will be created."); } - //Load the data - ::NeXus::File file(filename); + //---------------------------------------------------------------------------------------------- + /** Execute the algorithm. + */ + void LoadNXSPE::exec() + { + std::string filename = getProperty("Filename"); + //quicly check if it's really nxspe + try + { + ::NeXus::File file(filename); + std::string mainEntry = (*(file.getEntries().begin())).first; + file.openGroup(mainEntry, "NXentry"); + file.openData("definition"); + if (identiferConfidence(file.getStrData()) < 1) + { + throw std::invalid_argument("Not NXSPE"); + } + file.close(); + } + catch (...) + { + throw std::invalid_argument("Not NeXus or not NXSPE"); + } - std::string mainEntry=(*(file.getEntries().begin())).first; - file.openGroup(mainEntry, "NXentry"); + //Load the data + ::NeXus::File file(filename); - file.openGroup("NXSPE_info", "NXcollection"); - std::map entries=file.getEntries(); - std::vector temporary; - double fixed_energy,psi=0.; + std::string mainEntry = (*(file.getEntries().begin())).first; + file.openGroup(mainEntry, "NXentry"); - if (!entries.count("fixed_energy")) - { - throw std::invalid_argument("fixed_energy field was not found"); - } - file.openData("fixed_energy"); - file.getData(temporary); - fixed_energy=temporary.at(0); - file.closeData(); + file.openGroup("NXSPE_info", "NXcollection"); + std::map entries = file.getEntries(); + std::vector temporary; + double fixed_energy, psi = 0.; - if (entries.count("psi")) - { - file.openData("psi"); + if (!entries.count("fixed_energy")) + { + throw std::invalid_argument("fixed_energy field was not found"); + } + file.openData("fixed_energy"); file.getData(temporary); - psi=temporary.at(0); + fixed_energy = temporary.at(0); file.closeData(); - } - int kikfscaling=0; - if (entries.count("ki_over_kf_scaling")) - { - file.openData("ki_over_kf_scaling"); - std::vector temporaryint; - file.getData(temporaryint); - kikfscaling=temporaryint.at(0); - file.closeData(); - } + if (entries.count("psi")) + { + file.openData("psi"); + file.getData(temporary); + psi = temporary.at(0); + file.closeData(); + } - file.closeGroup();//NXSPE_Info + int kikfscaling = 0; + if (entries.count("ki_over_kf_scaling")) + { + file.openData("ki_over_kf_scaling"); + std::vector temporaryint; + file.getData(temporaryint); + kikfscaling = temporaryint.at(0); + file.closeData(); + } + file.closeGroup(); //NXSPE_Info - file.openGroup("data", "NXdata"); - entries=file.getEntries(); + file.openGroup("data", "NXdata"); + entries = file.getEntries(); - if (!entries.count("data")) - { - throw std::invalid_argument("data field was not found"); - } - file.openData("data"); - ::NeXus::Info info = file.getInfo(); - std::size_t numSpectra=static_cast(info.dims.at(0)); - std::size_t numBins=static_cast(info.dims.at(1)); - std::vector data; - file.getData(data); - file.closeData(); - - if (!entries.count("error")) - { - throw std::invalid_argument("error field was not found"); - } - file.openData("error"); - std::vector error; - file.getData(error); - file.closeData(); + if (!entries.count("data")) + { + throw std::invalid_argument("data field was not found"); + } + file.openData("data"); + ::NeXus::Info info = file.getInfo(); + std::size_t numSpectra = static_cast(info.dims.at(0)); + std::size_t numBins = static_cast(info.dims.at(1)); + std::vector data; + file.getData(data); + file.closeData(); - if (!entries.count("energy")) - { - throw std::invalid_argument("energy field was not found"); - } - file.openData("energy"); - std::vector energies; - file.getData(energies); - file.closeData(); + if (!entries.count("error")) + { + throw std::invalid_argument("error field was not found"); + } + file.openData("error"); + std::vector error; + file.getData(error); + file.closeData(); - if (!entries.count("azimuthal")) - { - throw std::invalid_argument("azimuthal field was not found"); - } - file.openData("azimuthal"); - std::vector azimuthal; - file.getData(azimuthal); - file.closeData(); + if (!entries.count("energy")) + { + throw std::invalid_argument("energy field was not found"); + } + file.openData("energy"); + std::vector energies; + file.getData(energies); + file.closeData(); - if (!entries.count("azimuthal_width")) - { - throw std::invalid_argument("azimuthal_width field was not found"); - } - file.openData("azimuthal_width"); - std::vector azimuthal_width; - file.getData(azimuthal_width); - file.closeData(); + if (!entries.count("azimuthal")) + { + throw std::invalid_argument("azimuthal field was not found"); + } + file.openData("azimuthal"); + std::vector azimuthal; + file.getData(azimuthal); + file.closeData(); - if (!entries.count("polar")) - { - throw std::invalid_argument("polar field was not found"); - } - file.openData("polar"); - std::vector polar; - file.getData(polar); - file.closeData(); + if (!entries.count("azimuthal_width")) + { + throw std::invalid_argument("azimuthal_width field was not found"); + } + file.openData("azimuthal_width"); + std::vector azimuthal_width; + file.getData(azimuthal_width); + file.closeData(); - if (!entries.count("polar_width")) - { - throw std::invalid_argument("polar_width field was not found"); - } - file.openData("polar_width"); - std::vector polar_width; - file.getData(polar_width); - file.closeData(); - - //distance might not have been saved in all NXSPE files - std::vector distance; - if (entries.count("distance")) - { - file.openData("distance"); - file.getData(distance); + if (!entries.count("polar")) + { + throw std::invalid_argument("polar field was not found"); + } + file.openData("polar"); + std::vector polar; + file.getData(polar); file.closeData(); - } - file.closeGroup();//data group - file.closeGroup();//Main entry - file.close(); + if (!entries.count("polar_width")) + { + throw std::invalid_argument("polar_width field was not found"); + } + file.openData("polar_width"); + std::vector polar_width; + file.getData(polar_width); + file.closeData(); - //check if dimensions of the vectors are correct - if ((error.size()!=data.size())||(azimuthal.size()!=numSpectra)||(azimuthal_width.size()!=numSpectra)|| - (polar.size()!=numSpectra)||(polar_width.size()!=numSpectra)||((energies.size()!=numBins)&&(energies.size()!=numBins+1))) - { - throw std::invalid_argument("incompatible sizes of fields in the NXSPE file"); - } + //distance might not have been saved in all NXSPE files + std::vector distance; + if (entries.count("distance")) + { + file.openData("distance"); + file.getData(distance); + file.closeData(); + } + + file.closeGroup(); //data group + file.closeGroup(); //Main entry + file.close(); + + //check if dimensions of the vectors are correct + if ((error.size() != data.size()) || (azimuthal.size() != numSpectra) + || (azimuthal_width.size() != numSpectra) || (polar.size() != numSpectra) + || (polar_width.size() != numSpectra) + || ((energies.size() != numBins) && (energies.size() != numBins + 1))) + { + throw std::invalid_argument("incompatible sizes of fields in the NXSPE file"); + } MatrixWorkspace_sptr outputWS = boost::dynamic_pointer_cast (WorkspaceFactory::Instance().create("Workspace2D",numSpectra,energies.size(),numBins)); // Need to get hold of the parameter map Geometry::ParameterMap& pmap = outputWS->instrumentParameters(); outputWS->getAxis(0)->unit() = UnitFactory::Instance().create("DeltaE"); + outputWS->setYUnit("SpectraNumber"); + std::vector::iterator itdata=data.begin(),iterror=error.begin(),itdataend,iterrorend; API::Progress prog = API::Progress(this, 0.0, 0.9, numSpectra); for (std::size_t i=0; imutableRun().addLogData(new PropertyWithValue("Ei", fixed_energy)); - outputWS->mutableRun().addLogData(new PropertyWithValue("psi", psi)); - outputWS->mutableRun().addLogData(new PropertyWithValue("ki_over_kf_scaling", kikfscaling==1?"true":"false")); - - //Set Goniometer - Geometry::Goniometer gm; - gm.pushAxis("psi",0,1,0,psi); - outputWS->mutableRun().setGoniometer(gm, true); - - //generate instrument - Geometry::Instrument_sptr instrument(new Geometry::Instrument("NXSPE")); - outputWS->setInstrument(instrument); - - Geometry::ObjComponent *source = new Geometry::ObjComponent("source"); - source->setPos(0.0,0.0,-10.0); - instrument->add(source); - instrument->markAsSource(source); - Geometry::ObjComponent *sample = new Geometry::ObjComponent("sample"); - instrument->add(sample); - instrument->markAsSamplePos(sample); - - Geometry::Object_const_sptr cuboid(createCuboid(0.1,0.1,0.1));//FIXME: memory hog on rendering. Also, make each detector separate size - for (std::size_t i=0;imutableRun().addLogData(new PropertyWithValue("Ei", fixed_energy)); + outputWS->mutableRun().addLogData(new PropertyWithValue("psi", psi)); + outputWS->mutableRun().addLogData( + new PropertyWithValue("ki_over_kf_scaling", kikfscaling == 1 ? "true" : "false")); + + //Set Goniometer + Geometry::Goniometer gm; + gm.pushAxis("psi", 0, 1, 0, psi); + outputWS->mutableRun().setGoniometer(gm, true); + + //generate instrument + Geometry::Instrument_sptr instrument(new Geometry::Instrument("NXSPE")); + outputWS->setInstrument(instrument); + + Geometry::ObjComponent *source = new Geometry::ObjComponent("source"); + source->setPos(0.0, 0.0, -10.0); + instrument->add(source); + instrument->markAsSource(source); + Geometry::ObjComponent *sample = new Geometry::ObjComponent("sample"); + instrument->add(sample); + instrument->markAsSamplePos(sample); + + Geometry::Object_const_sptr cuboid(createCuboid(0.1, 0.1, 0.1)); //FIXME: memory hog on rendering. Also, make each detector separate size + for (std::size_t i = 0; i < numSpectra; ++i) { - r=distance.at(i); - } + double r = 1.0; + if (!distance.empty()) + { + r = distance.at(i); + } - Kernel::V3D pos; - pos.spherical(r,polar.at(i),azimuthal.at(i)); + Kernel::V3D pos; + pos.spherical(r, polar.at(i), azimuthal.at(i)); - Geometry::Detector *det = new Geometry::Detector("pixel",static_cast(i+1),sample); - det->setPos(pos); - det->setShape(cuboid); - instrument->add(det); - instrument->markAsDetector(det); - } + Geometry::Detector *det = new Geometry::Detector("pixel", static_cast(i + 1), sample); + det->setPos(pos); + det->setShape(cuboid); + instrument->add(det); + instrument->markAsDetector(det); + } - setProperty("OutputWorkspace", outputWS); - } + setProperty("OutputWorkspace", outputWS); + } + Geometry::Object_sptr LoadNXSPE::createCuboid(double dx, double dy, double dz) + { - Geometry::Object_sptr LoadNXSPE:: createCuboid(double dx,double dy, double dz) - { + dx = 0.5 * std::fabs(dx); + dy = 0.5 * std::fabs(dy); + dz = 0.5 * std::fabs(dz); + /* + std::stringstream planeName; + + planeName.str("px ");planeName<<-dx; + std::string C1=planeName.str(); + planeName.str("px ");planeName< CubeSurMap; + CubeSurMap[1]=new Geometry::Plane(); + CubeSurMap[2]=new Geometry::Plane(); + CubeSurMap[3]=new Geometry::Plane(); + CubeSurMap[4]=new Geometry::Plane(); + CubeSurMap[5]=new Geometry::Plane(); + CubeSurMap[6]=new Geometry::Plane(); + + CubeSurMap[1]->setSurface(C1); + CubeSurMap[2]->setSurface(C2); + CubeSurMap[3]->setSurface(C3); + CubeSurMap[4]->setSurface(C4); + CubeSurMap[5]->setSurface(C5); + CubeSurMap[6]->setSurface(C6); + CubeSurMap[1]->setName(1); + CubeSurMap[2]->setName(2); + CubeSurMap[3]->setName(3); + CubeSurMap[4]->setName(4); + CubeSurMap[5]->setName(5); + CubeSurMap[6]->setName(6); + + // Cube (id 68) + // using surface ids: 1-6 + std::string ObjCube="1 -2 3 -4 5 -6"; + + Geometry::Object_sptr retVal = Geometry::Object_sptr(new Geometry::Object); + retVal->setObject(68,ObjCube); + retVal->populate(CubeSurMap); + */ + std::string S41 = "so 0.01"; // Sphere at origin radius 0.01 + + // First create some surfaces + std::map SphSurMap; + SphSurMap[41] = new Geometry::Sphere(); + SphSurMap[41]->setSurface(S41); + SphSurMap[41]->setName(41); + + // A sphere + std::string ObjSphere = "-41"; + Geometry::Object_sptr retVal = Geometry::Object_sptr(new Geometry::Object); + retVal->setObject(41, ObjSphere); + retVal->populate(SphSurMap); + + return retVal; + } - dx=0.5*std::fabs(dx); - dy=0.5*std::fabs(dy); - dz=0.5*std::fabs(dz); - /* - std::stringstream planeName; - - planeName.str("px ");planeName<<-dx; - std::string C1=planeName.str(); - planeName.str("px ");planeName< CubeSurMap; - CubeSurMap[1]=new Geometry::Plane(); - CubeSurMap[2]=new Geometry::Plane(); - CubeSurMap[3]=new Geometry::Plane(); - CubeSurMap[4]=new Geometry::Plane(); - CubeSurMap[5]=new Geometry::Plane(); - CubeSurMap[6]=new Geometry::Plane(); - - CubeSurMap[1]->setSurface(C1); - CubeSurMap[2]->setSurface(C2); - CubeSurMap[3]->setSurface(C3); - CubeSurMap[4]->setSurface(C4); - CubeSurMap[5]->setSurface(C5); - CubeSurMap[6]->setSurface(C6); - CubeSurMap[1]->setName(1); - CubeSurMap[2]->setName(2); - CubeSurMap[3]->setName(3); - CubeSurMap[4]->setName(4); - CubeSurMap[5]->setName(5); - CubeSurMap[6]->setName(6); - - // Cube (id 68) - // using surface ids: 1-6 - std::string ObjCube="1 -2 3 -4 5 -6"; - - Geometry::Object_sptr retVal = Geometry::Object_sptr(new Geometry::Object); - retVal->setObject(68,ObjCube); - retVal->populate(CubeSurMap); -*/ - std::string S41="so 0.01"; // Sphere at origin radius 0.01 - - // First create some surfaces - std::map SphSurMap; - SphSurMap[41]=new Geometry::Sphere(); - SphSurMap[41]->setSurface(S41); - SphSurMap[41]->setName(41); - - // A sphere - std::string ObjSphere="-41" ; - Geometry::Object_sptr retVal = Geometry::Object_sptr(new Geometry::Object); - retVal->setObject(41,ObjSphere); - retVal->populate(SphSurMap); - - return retVal; - } - - -} // namespace Mantid + } // namespace Mantid } // namespace DataHandling diff --git a/Code/Mantid/Framework/DataHandling/src/LoadNexusMonitors.cpp b/Code/Mantid/Framework/DataHandling/src/LoadNexusMonitors.cpp index 7418eaf89e6a..f28f17a6e772 100644 --- a/Code/Mantid/Framework/DataHandling/src/LoadNexusMonitors.cpp +++ b/Code/Mantid/Framework/DataHandling/src/LoadNexusMonitors.cpp @@ -42,7 +42,7 @@ LoadNexusMonitors::~LoadNexusMonitors() { } -/// Initialisation method. +/// Initialization method. void LoadNexusMonitors::init() { declareProperty(new API::FileProperty("Filename", "", API::FileProperty::Load, @@ -76,12 +76,12 @@ void LoadNexusMonitors::exec() string_map_t entries = file.getEntries(); for (it = entries.begin(); it != entries.end(); ++it) { - if ( ((it->first == "entry") || (it->first == "raw_data_1")) && (it->second == "NXentry") ) - { - file.openGroup(it->first, it->second); + if ( ((it->first == "entry") || (it->first == "raw_data_1")) && (it->second == "NXentry") ) + { + file.openGroup(it->first, it->second); m_top_entry_name = it->first; - break; - } + break; + } } prog1.report(); @@ -353,14 +353,25 @@ void LoadNexusMonitors::exec() // Need to get the instrument name from the file std::string instrumentName; file.openGroup("instrument", "NXinstrument"); - file.openData("name"); - instrumentName = file.getStrData(); + try + { + file.openData("name"); + instrumentName = file.getStrData(); + // Now let's close the file as we don't need it anymore to load the instrument. + file.closeData(); + file.closeGroup(); // Close the NXentry + file.close(); + + } + catch(std::runtime_error &) // no correct instrument definition (old ISIS file, fall back to isis_vms_compat) + { + file.closeGroup(); // Close the instrument NXentry + instrumentName =LoadEventNexus::readInstrumentFromISIS_VMSCompat(file); + file.close(); + } + g_log.debug() << "Instrument name read from NeXus file is " << instrumentName << std::endl; - // Now let's close the file as we don't need it anymore to load the instrument. - file.closeData(); - file.closeGroup(); // Close the NXentry - file.close(); this->WS->getAxis(0)->unit() = Kernel::UnitFactory::Instance().create("TOF"); this->WS->setYUnit("Counts"); @@ -460,6 +471,7 @@ void LoadNexusMonitors::runLoadLogs(const std::string filename, API::MatrixWorks { // do the actual work API::IAlgorithm_sptr loadLogs = createChildAlgorithm("LoadNexusLogs"); + // Now execute the Child Algorithm. Catch and log any error, but don't stop. try { diff --git a/Code/Mantid/Framework/DataHandling/src/LoadParameterFile.cpp b/Code/Mantid/Framework/DataHandling/src/LoadParameterFile.cpp index 48447b422238..e297a119680f 100644 --- a/Code/Mantid/Framework/DataHandling/src/LoadParameterFile.cpp +++ b/Code/Mantid/Framework/DataHandling/src/LoadParameterFile.cpp @@ -5,7 +5,6 @@ #include "MantidDataHandling/LoadInstrument.h" #include "MantidGeometry/Instrument.h" #include "MantidAPI/InstrumentDataService.h" -#include "MantidGeometry/Instrument/XMLlogfile.h" #include "MantidGeometry/Instrument/Detector.h" #include "MantidGeometry/Instrument/Component.h" #include "MantidAPI/Progress.h" @@ -72,11 +71,11 @@ void LoadParameterFile::init() void LoadParameterFile::exec() { // Retrieve the filename from the properties - std::string filename = getPropertyValue("Filename"); + const std::string filename = getPropertyValue("Filename"); // Retrieve the parameter XML string from the properties const Property * const parameterXMLProperty = getProperty("ParameterXML"); // to check whether it is default - std::string parameterXML = getPropertyValue("ParameterXML"); + const std::string parameterXML = getPropertyValue("ParameterXML"); // Check the two properties (at least one must be set) if( filename.empty() && parameterXMLProperty->isDefault()){ @@ -86,11 +85,6 @@ void LoadParameterFile::exec() // Get the input workspace const MatrixWorkspace_sptr localWorkspace = getProperty("Workspace"); - execManually(!parameterXMLProperty->isDefault(), filename, parameterXML, localWorkspace); -} - -void LoadParameterFile::execManually(bool useString, std::string filename, std::string parameterXML, Mantid::API::ExperimentInfo_sptr localWorkspace) -{ // TODO: Refactor to remove the need for the const cast (ticket #8521) Instrument_sptr instrument = boost::const_pointer_cast(localWorkspace->getInstrument()->baseInstrument()); @@ -98,7 +92,13 @@ void LoadParameterFile::execManually(bool useString, std::string filename, std:: DOMParser pParser; AutoPtr pDoc; - if(useString){ + //Progress reporting object + Progress prog(this, 0.0, 1.0, 100); + + prog.report("Parsing XML"); + //If we've been given an XML string parse that instead + if(!parameterXMLProperty->isDefault()) + { try { pDoc = pParser.parseString(parameterXML); @@ -137,11 +137,13 @@ void LoadParameterFile::execManually(bool useString, std::string filename, std:: // Set all parameters that specified in all component-link elements of pRootElem InstrumentDefinitionParser loadInstr; - loadInstr.setComponentLinks(instrument, pRootElem); + loadInstr.setComponentLinks(instrument, pRootElem, &prog); // populate parameter map of workspace localWorkspace->populateInstrumentParameters(); + prog.resetNumSteps(1, 0.0, 1.0); + prog.report("Done"); } } // namespace DataHandling diff --git a/Code/Mantid/Framework/DataHandling/src/LoadRaw3.cpp b/Code/Mantid/Framework/DataHandling/src/LoadRaw3.cpp index a09ee07e3501..812d7336ba51 100644 --- a/Code/Mantid/Framework/DataHandling/src/LoadRaw3.cpp +++ b/Code/Mantid/Framework/DataHandling/src/LoadRaw3.cpp @@ -3,7 +3,6 @@ //---------------------------------------------------------------------- #include "MantidDataHandling/LoadRaw3.h" #include "MantidDataObjects/Workspace2D.h" -#include "MantidGeometry/Instrument/XMLlogfile.h" #include "MantidAPI/MemoryManager.h" #include "MantidAPI/WorkspaceGroup.h" #include "MantidAPI/RegisterFileLoader.h" @@ -75,7 +74,7 @@ namespace Mantid "Allowed options are Include,Exclude, Separate.\n" "Include:The default is Include option which loads the monitors into the output workspace.\n" "Exclude:The Exclude option excludes monitors from the output workspace.\n" - "Separate:The Separate option loads monitors into a separate workspace called OutputWorkspace_Monitor.\n" + "Separate:The Separate option loads monitors into a separate workspace called OutputWorkspace_monitor.\n" "Defined aliases:\n" "1: Equivalent to Separate.\n" "0: Equivalent to Exclude.\n"); @@ -96,22 +95,9 @@ namespace Mantid bool bLoadlogFiles = getProperty("LoadLogFiles"); - // process monitor option - std::string monitorOption = getProperty("LoadMonitors"); - if (monitorOption =="1") - monitorOption = "Separate"; - if (monitorOption=="0") - monitorOption = "Exclude"; - - bool bincludeMonitors = isIncludeMonitors(monitorOption); - bool bseparateMonitors = false; - bool bexcludeMonitors = false; - if (!bincludeMonitors) - { - bseparateMonitors = isSeparateMonitors(monitorOption); - bexcludeMonitors = isExcludeMonitors(monitorOption); - } - // + bool bincludeMonitors,bseparateMonitors, bexcludeMonitors; + LoadRawHelper::ProcessLoadMonitorOptions(bincludeMonitors,bseparateMonitors, bexcludeMonitors,this); + std::string title; //read workspace title from raw file @@ -173,7 +159,7 @@ namespace Mantid if (bincludeMonitors) { - setWorkspaceProperty("OutputWorkspace", title, ws_grp, localWorkspace,m_numberOfPeriods, false); + setWorkspaceProperty("OutputWorkspace", title, ws_grp, localWorkspace,m_numberOfPeriods, false,this); } else { @@ -195,13 +181,13 @@ namespace Mantid if(normalwsSpecs > 0) { localWorkspace = createWorkspace(localWorkspace,normalwsSpecs,m_lengthIn,m_lengthIn-1); - setWorkspaceProperty("OutputWorkspace", title, ws_grp, localWorkspace,m_numberOfPeriods,false); + setWorkspaceProperty("OutputWorkspace", title, ws_grp, localWorkspace,m_numberOfPeriods,false,this); } //now create monitor workspace if separateMonitors selected if (bseparateMonitors) { createMonitorWorkspace(monitorWorkspace,localWorkspace,monitorws_grp,monitorwsSpecs, - normalwsSpecs,m_numberOfPeriods,m_lengthIn,title); + normalwsSpecs,m_numberOfPeriods,m_lengthIn,title,this); } } @@ -299,18 +285,18 @@ namespace Mantid if(normalwsSpecs > 0) { // declare and set monitor workspace for each period - setWorkspaceProperty(monitorWorkspace, monitorws_grp, period, true); + setWorkspaceProperty(monitorWorkspace, monitorws_grp, period, true,this); } else { localWorkspace = monitorWorkspace; } // declare and set output workspace for each period - setWorkspaceProperty(localWorkspace, ws_grp, period, false); + setWorkspaceProperty(localWorkspace, ws_grp, period, false,this); } else { - setWorkspaceProperty(localWorkspace, ws_grp, period, false); + setWorkspaceProperty(localWorkspace, ws_grp, period, false,this); } // progress for workspace groups setProg ( static_cast(period) / static_cast(m_numberOfPeriods - 1) ); @@ -578,36 +564,6 @@ namespace Mantid } } - /** This method checks the value of LoadMonitors property and returns true or false - * @return true if Exclude Monitors option is selected,otherwise false - */ - bool LoadRaw3::isExcludeMonitors(const std::string &monitorOption) - { - bool bExclude; - monitorOption.compare("Exclude") ? (bExclude = false) : (bExclude = true); - return bExclude; - } - - /**This method checks the value of LoadMonitors property and returns true or false - * @return true if Include Monitors option is selected,otherwise false - */ - bool LoadRaw3::isIncludeMonitors(const std::string &monitorOption) - { - bool bExclude; - monitorOption.compare("Include") ? (bExclude = false) : (bExclude = true); - - return bExclude; - } - - /** This method checks the value of LoadMonitors property and returns true or false - * @return true if Separate Monitors option is selected,otherwise false - */ - bool LoadRaw3::isSeparateMonitors(const std::string &monitorOption) - { - bool bSeparate; - monitorOption.compare("Separate") ? (bSeparate = false) : (bSeparate = true); - return bSeparate; - } /** This method checks given spectrum is a monitor * @param monitorIndexes :: a vector holding the list of monitors diff --git a/Code/Mantid/Framework/DataHandling/src/LoadRawBin0.cpp b/Code/Mantid/Framework/DataHandling/src/LoadRawBin0.cpp index 16dbd26b35e1..5c5d402850c8 100644 --- a/Code/Mantid/Framework/DataHandling/src/LoadRawBin0.cpp +++ b/Code/Mantid/Framework/DataHandling/src/LoadRawBin0.cpp @@ -3,7 +3,6 @@ //---------------------------------------------------------------------- #include "MantidDataHandling/LoadRawBin0.h" #include "MantidDataObjects/Workspace2D.h" -#include "MantidGeometry/Instrument/XMLlogfile.h" #include "MantidAPI/MemoryManager.h" #include "MantidAPI/WorkspaceGroup.h" #include "MantidKernel/UnitFactory.h" @@ -66,31 +65,31 @@ void LoadRawBin0::init() */ void LoadRawBin0::exec() { - // Retrieve the filename from the properties - m_filename = getPropertyValue("Filename"); + // Retrieve the filename from the properties + m_filename = getPropertyValue("Filename"); - bool bLoadlogFiles = getProperty("LoadLogFiles"); + bool bLoadlogFiles = getProperty("LoadLogFiles"); - //open the raw file - FILE* file=openRawFile(m_filename); + //open the raw file + FILE* file=openRawFile(m_filename); - // Need to check that the file is not a text file as the ISISRAW routines don't deal with these very well, i.e - // reading continues until a bad_alloc is encountered. - if( isAscii(file) ) - { - g_log.error() << "File \"" << m_filename << "\" is not a valid RAW file.\n"; - throw std::invalid_argument("Incorrect file type encountered."); - } - std::string title; - readTitle(file,title); + // Need to check that the file is not a text file as the ISISRAW routines don't deal with these very well, i.e + // reading continues until a bad_alloc is encountered. + if( isAscii(file) ) + { + g_log.error() << "File \"" << m_filename << "\" is not a valid RAW file.\n"; + throw std::invalid_argument("Incorrect file type encountered."); + } + std::string title; + readTitle(file,title); - readworkspaceParameters(m_numberOfSpectra,m_numberOfPeriods,m_lengthIn,m_noTimeRegimes); + readworkspaceParameters(m_numberOfSpectra,m_numberOfPeriods,m_lengthIn,m_noTimeRegimes); - /// - setOptionalProperties(); + /// + setOptionalProperties(); - // to validate the optional parameters, if set - checkOptionalProperties(); + // to validate the optional parameters, if set + checkOptionalProperties(); // Calculate the size of a workspace, given its number of periods & spectra to read m_total_specs = calculateWorkspaceSize(); @@ -115,7 +114,7 @@ void LoadRawBin0::exec() setProtonCharge(run); WorkspaceGroup_sptr ws_grp = createGroupWorkspace(); - setWorkspaceProperty("OutputWorkspace", title, ws_grp, localWorkspace,m_numberOfPeriods, false); + setWorkspaceProperty("OutputWorkspace", title, ws_grp, localWorkspace,m_numberOfPeriods, false,this); // Loop over the number of periods in the raw file, putting each period in a separate workspace for (int period = 0; period < m_numberOfPeriods; ++period) @@ -148,14 +147,14 @@ void LoadRawBin0::exec() { progress(m_prog, "Reading raw file data..."); //readData(file, histToRead); - //read spectrum - if (!readData(file, histToRead)) - { - throw std::runtime_error("Error reading raw file"); - } - int64_t binStart=0; - setWorkspaceData(localWorkspace, m_timeChannelsVec, wsIndex, i, m_noTimeRegimes,1,binStart); - ++wsIndex; + //read spectrum + if (!readData(file, histToRead)) + { + throw std::runtime_error("Error reading raw file"); + } + int64_t binStart=0; + setWorkspaceData(localWorkspace, m_timeChannelsVec, wsIndex, i, m_noTimeRegimes,1,binStart); + ++wsIndex; if (m_numberOfPeriods == 1) { @@ -167,19 +166,19 @@ void LoadRawBin0::exec() } } - else - { - skipData(file, histToRead); - } + else + { + skipData(file, histToRead); + } } - - if(m_numberOfPeriods>1) - { - setWorkspaceProperty(localWorkspace, ws_grp, period, false); - // progress for workspace groups - m_prog = static_cast(period) / static_cast(m_numberOfPeriods - 1); - } + + if(m_numberOfPeriods>1) + { + setWorkspaceProperty(localWorkspace, ws_grp, period, false,this); + // progress for workspace groups + m_prog = static_cast(period) / static_cast(m_numberOfPeriods - 1); + } } // loop over periods // Clean up diff --git a/Code/Mantid/Framework/DataHandling/src/LoadRawHelper.cpp b/Code/Mantid/Framework/DataHandling/src/LoadRawHelper.cpp index eeb48a16931d..fc8579dc9bd4 100644 --- a/Code/Mantid/Framework/DataHandling/src/LoadRawHelper.cpp +++ b/Code/Mantid/Framework/DataHandling/src/LoadRawHelper.cpp @@ -6,7 +6,6 @@ #include "MantidAPI/MemoryManager.h" #include "MantidAPI/SpectrumDetectorMapping.h" #include "MantidAPI/WorkspaceGroup.h" -#include "MantidGeometry/Instrument/XMLlogfile.h" #include "MantidKernel/UnitFactory.h" #include "MantidKernel/ConfigService.h" #include "MantidKernel/ArrayProperty.h" @@ -171,7 +170,7 @@ namespace Mantid run.addLogData( new PropertyWithValue("run_number", run_num) ); } /**reads workspace dimensions,number of periods etc from raw data - * @param numberOfSpectra :: number of spectrums + * @param numberOfSpectra :: number of spectra * @param numberOfPeriods :: number of periods * @param lengthIn :: size of workspace vectors * @param noTimeRegimes :: number of time regime. @@ -238,11 +237,11 @@ namespace Mantid *@param numberOfPeriods :: total number of periods from raw file *@param lengthIn :: size of workspace vectors *@param title :: title of the workspace - + *@param pAlg :: pointer to the algorithm, this method works with. */ void LoadRawHelper::createMonitorWorkspace(DataObjects::Workspace2D_sptr& monws_sptr,DataObjects::Workspace2D_sptr& normalws_sptr, WorkspaceGroup_sptr& mongrp_sptr,const int64_t mwsSpecs,const int64_t nwsSpecs, - const int64_t numberOfPeriods,const int64_t lengthIn,const std::string title) + const int64_t numberOfPeriods,const int64_t lengthIn,const std::string title,API::Algorithm *const pAlg) { try { @@ -263,31 +262,31 @@ namespace Mantid } if(!monws_sptr) return ; - std::string wsName= getPropertyValue("OutputWorkspace"); + std::string wsName= pAlg->getPropertyValue("OutputWorkspace"); // if the normal output workspace size>0 then set the workspace as "MonitorWorkspace" // otherwise set the workspace as "OutputWorkspace" if (nwsSpecs> 0) { std::string monitorwsName = wsName + "_monitors"; - declareProperty(new WorkspaceProperty ("MonitorWorkspace", monitorwsName, + pAlg->declareProperty(new WorkspaceProperty ("MonitorWorkspace", monitorwsName, Direction::Output)); - setWorkspaceProperty("MonitorWorkspace", title, mongrp_sptr, monws_sptr,numberOfPeriods, true); + setWorkspaceProperty("MonitorWorkspace", title, mongrp_sptr, monws_sptr,numberOfPeriods, true,pAlg); } else { //if only monitors range selected - //then set the monitor workspace as the outputworkspace - setWorkspaceProperty("OutputWorkspace", title, mongrp_sptr, monws_sptr,numberOfPeriods, false); + //then set the monitor workspace as the output workspace + setWorkspaceProperty("OutputWorkspace", title, mongrp_sptr, monws_sptr,numberOfPeriods, false,pAlg); } } catch(std::out_of_range& ) { - g_log.debug()<<"Error in creating monitor workspace"<getLogger().debug()<<"Error in creating monitor workspace"<getLogger().debug()<<"Error in creating monitor workspace"<getProperty("OutputWorkspace"); std::stringstream suffix; suffix << (period + 1); if (bmonitors) @@ -329,8 +329,8 @@ namespace Mantid outputWorkspace = "OutputWorkspace"; } outws = outputWorkspace + "_" + suffix.str(); - declareProperty(new WorkspaceProperty (outws, wsName, Direction::Output)); - setProperty(outws, boost::static_pointer_cast(ws_sptr)); + pAlg->declareProperty(new WorkspaceProperty (outws, wsName, Direction::Output)); + pAlg->setProperty(outws, boost::static_pointer_cast(ws_sptr)); grpws_sptr->addWorkspace( ws_sptr ); } @@ -339,14 +339,15 @@ namespace Mantid * @param title :: title of the workspace * @param grpws_sptr :: shared pointer to group workspace * @param ws_sptr :: shared pointer to workspace - * @param numberOfPeriods :: numer periods in the raw file + * @param numberOfPeriods :: number periods in the raw file * @param bMonitor to identify the workspace is an output workspace or monitor workspace + * @param pAlg :: pointer to algorithm this method works with. */ void LoadRawHelper::setWorkspaceProperty(const std::string& propertyName, const std::string& title, - WorkspaceGroup_sptr grpws_sptr, DataObjects::Workspace2D_sptr ws_sptr,int64_t numberOfPeriods, bool bMonitor) + WorkspaceGroup_sptr grpws_sptr, DataObjects::Workspace2D_sptr ws_sptr,int64_t numberOfPeriods, bool bMonitor, API::Algorithm *const pAlg) { UNUSED_ARG(bMonitor); - Property *ws = getProperty("OutputWorkspace"); + Property *ws = pAlg->getProperty("OutputWorkspace"); if(!ws) return; if(!grpws_sptr) return; if(!ws_sptr)return; @@ -354,18 +355,18 @@ namespace Mantid ws_sptr->getAxis(0)->unit() = UnitFactory::Instance().create("TOF"); if (numberOfPeriods > 1) { - setProperty(propertyName, boost::dynamic_pointer_cast(grpws_sptr)); + pAlg->setProperty(propertyName, boost::dynamic_pointer_cast(grpws_sptr)); } else { - setProperty(propertyName, boost::dynamic_pointer_cast(ws_sptr)); + pAlg->setProperty(propertyName, boost::dynamic_pointer_cast(ws_sptr)); } } /** This method sets the raw file data to workspace vectors * @param newWorkspace :: shared pointer to the workspace * @param timeChannelsVec :: vector holding the X data - * @param wsIndex variable used for indexing the ouputworkspace + * @param wsIndex variable used for indexing the output workspace * @param nspecNum spectrum number * @param noTimeRegimes :: regime no. * @param lengthIn :: length of the workspace @@ -1290,5 +1291,62 @@ namespace Mantid return true; } + /** This method checks the value of LoadMonitors property and returns true or false + * @return true if Exclude Monitors option is selected,otherwise false + */ + bool LoadRawHelper::isExcludeMonitors(const std::string &monitorOption) + { + bool bExclude; + monitorOption.compare("Exclude") ? (bExclude = false) : (bExclude = true); + return bExclude; + } + + /**This method checks the value of LoadMonitors property and returns true or false + * @return true if Include Monitors option is selected,otherwise false + */ + bool LoadRawHelper::isIncludeMonitors(const std::string &monitorOption) + { + bool bExclude; + monitorOption.compare("Include") ? (bExclude = false) : (bExclude = true); + + return bExclude; + } + + /** This method checks the value of LoadMonitors property and returns true or false + * @return true if Separate Monitors option is selected,otherwise false + */ + bool LoadRawHelper::isSeparateMonitors(const std::string &monitorOption) + { + bool bSeparate; + monitorOption.compare("Separate") ? (bSeparate = false) : (bSeparate = true); + return bSeparate; + } + /**The method to interpret LoadMonitors property options and convert then into boolean values + * @param bincludeMonitors :: if monitors requested to be included with workspace + * @param bseparateMonitors :: if monitors requested to be loaded separately from the workspace + * @param bexcludeMonitors :: if monitors should not be loaded at all. + * @param pAlgo :: pointer to the algorithm, which has LoadMonitors property. + */ + void LoadRawHelper::ProcessLoadMonitorOptions(bool &bincludeMonitors,bool &bseparateMonitors,bool &bexcludeMonitors,API::Algorithm *pAlgo) + { + // process monitor option + std::string monitorOption = pAlgo->getProperty("LoadMonitors"); + if (monitorOption =="1") + monitorOption = "Separate"; + if (monitorOption=="0") + monitorOption = "Exclude"; + + bincludeMonitors = LoadRawHelper::isIncludeMonitors(monitorOption); + bseparateMonitors = false; + bexcludeMonitors = false; + if (!bincludeMonitors) + { + bseparateMonitors = LoadRawHelper::isSeparateMonitors(monitorOption); + bexcludeMonitors = LoadRawHelper::isExcludeMonitors(monitorOption); + } + // + + } + } // namespace DataHandling } // namespace Mantid diff --git a/Code/Mantid/Framework/DataHandling/src/LoadRawSpectrum0.cpp b/Code/Mantid/Framework/DataHandling/src/LoadRawSpectrum0.cpp index 97bc25201a60..a79ee46b980e 100644 --- a/Code/Mantid/Framework/DataHandling/src/LoadRawSpectrum0.cpp +++ b/Code/Mantid/Framework/DataHandling/src/LoadRawSpectrum0.cpp @@ -6,7 +6,6 @@ #include "MantidDataHandling/LoadLog.h" #include "MantidAPI/FileProperty.h" #include "MantidDataObjects/Workspace2D.h" -#include "MantidGeometry/Instrument/XMLlogfile.h" #include "MantidAPI/MemoryManager.h" #include "MantidAPI/WorkspaceGroup.h" #include "MantidKernel/UnitFactory.h" @@ -20,155 +19,155 @@ namespace Mantid { - namespace DataHandling - { - // Register the algorithm into the algorithm factory - DECLARE_ALGORITHM(LoadRawSpectrum0) - - - using namespace Kernel; - using namespace API; - - /// Constructor - LoadRawSpectrum0::LoadRawSpectrum0() : - m_filename(), m_numberOfSpectra(0), - m_specTimeRegimes(), m_prog(0.0) - { - } - - LoadRawSpectrum0::~LoadRawSpectrum0() - { - } - - /// Initialisation method. - void LoadRawSpectrum0::init() - { - LoadRawHelper::init(); - - } - - /** Executes the algorithm. Reading in the file and creating and populating - * the output workspace - * - * @throw Exception::FileError If the RAW file cannot be found/opened - * @throw std::invalid_argument If the optional properties are set to invalid values - */ - void LoadRawSpectrum0::exec() - { - // Retrieve the filename from the properties - m_filename = getPropertyValue("Filename"); - - bool bLoadlogFiles = getProperty("LoadLogFiles"); - - //open the raw file + namespace DataHandling + { + // Register the algorithm into the algorithm factory + DECLARE_ALGORITHM(LoadRawSpectrum0) + + + using namespace Kernel; + using namespace API; + + /// Constructor + LoadRawSpectrum0::LoadRawSpectrum0() : + m_filename(), m_numberOfSpectra(0), + m_specTimeRegimes(), m_prog(0.0) + { + } + + LoadRawSpectrum0::~LoadRawSpectrum0() + { + } + + /// Initialisation method. + void LoadRawSpectrum0::init() + { + LoadRawHelper::init(); + + } + + /** Executes the algorithm. Reading in the file and creating and populating + * the output workspace + * + * @throw Exception::FileError If the RAW file cannot be found/opened + * @throw std::invalid_argument If the optional properties are set to invalid values + */ + void LoadRawSpectrum0::exec() + { + // Retrieve the filename from the properties + m_filename = getPropertyValue("Filename"); + + bool bLoadlogFiles = getProperty("LoadLogFiles"); + + //open the raw file FILE* file=openRawFile(m_filename); - // Need to check that the file is not a text file as the ISISRAW routines don't deal with these very well, i.e - // reading continues until a bad_alloc is encountered. - if( isAscii(file) ) - { - g_log.error() << "File \"" << m_filename << "\" is not a valid RAW file.\n"; - throw std::invalid_argument("Incorrect file type encountered."); - } + // Need to check that the file is not a text file as the ISISRAW routines don't deal with these very well, i.e + // reading continues until a bad_alloc is encountered. + if( isAscii(file) ) + { + g_log.error() << "File \"" << m_filename << "\" is not a valid RAW file.\n"; + throw std::invalid_argument("Incorrect file type encountered."); + } - std::string title; - readTitle(file,title); + std::string title; + readTitle(file,title); readworkspaceParameters(m_numberOfSpectra,m_numberOfPeriods,m_lengthIn,m_noTimeRegimes); - // Calculate the size of a workspace, given its number of periods & spectra to read - const int64_t total_specs = 1; + // Calculate the size of a workspace, given its number of periods & spectra to read + const int64_t total_specs = 1; - // Get the time channel array(s) and store in a vector inside a shared pointer - std::vector > timeChannelsVec = - getTimeChannels(m_noTimeRegimes, m_lengthIn); + // Get the time channel array(s) and store in a vector inside a shared pointer + std::vector > timeChannelsVec = + getTimeChannels(m_noTimeRegimes, m_lengthIn); - double histTotal = static_cast(total_specs * m_numberOfPeriods); - int64_t histCurrent = -1; + double histTotal = static_cast(total_specs * m_numberOfPeriods); + int64_t histCurrent = -1; - // Create the 2D workspace for the output - DataObjects::Workspace2D_sptr localWorkspace =createWorkspace(total_specs, m_lengthIn,m_lengthIn-1,title); - - Run& run = localWorkspace->mutableRun(); + // Create the 2D workspace for the output + DataObjects::Workspace2D_sptr localWorkspace =createWorkspace(total_specs, m_lengthIn,m_lengthIn-1,title); + + Run& run = localWorkspace->mutableRun(); - if(bLoadlogFiles) - { - runLoadLog(m_filename,localWorkspace, 0.0, 0.0); + if(bLoadlogFiles) + { + runLoadLog(m_filename,localWorkspace, 0.0, 0.0); const int period_number = 1; createPeriodLogs(period_number, localWorkspace); - } - // Set the total proton charge for this run - setProtonCharge(run); - - WorkspaceGroup_sptr wsgrp_sptr = createGroupWorkspace(); - setWorkspaceProperty("OutputWorkspace", title, wsgrp_sptr, localWorkspace,m_numberOfPeriods, false); - - // Loop over the number of periods in the raw file, putting each period in a separate workspace - for (int period = 0; period < m_numberOfPeriods; ++period) - { - if (period > 0) - { - localWorkspace = boost::dynamic_pointer_cast( - WorkspaceFactory::Instance().create(localWorkspace)); - - if(bLoadlogFiles) - { - //remove previous period data - std::stringstream prevPeriod; - prevPeriod << "PERIOD " << (period); - Run& runObj = localWorkspace->mutableRun(); - runObj.removeLogData(prevPeriod.str()); + } + // Set the total proton charge for this run + setProtonCharge(run); + + WorkspaceGroup_sptr wsgrp_sptr = createGroupWorkspace(); + setWorkspaceProperty("OutputWorkspace", title, wsgrp_sptr, localWorkspace,m_numberOfPeriods, false,this); + + // Loop over the number of periods in the raw file, putting each period in a separate workspace + for (int period = 0; period < m_numberOfPeriods; ++period) + { + if (period > 0) + { + localWorkspace = boost::dynamic_pointer_cast( + WorkspaceFactory::Instance().create(localWorkspace)); + + if(bLoadlogFiles) + { + //remove previous period data + std::stringstream prevPeriod; + prevPeriod << "PERIOD " << (period); + Run& runObj = localWorkspace->mutableRun(); + runObj.removeLogData(prevPeriod.str()); runObj.removeLogData("current_period"); - //add current period data + //add current period data int period_number = static_cast(period+1); createPeriodLogs(period_number, localWorkspace); - } - //skip all spectra except the first one in each period - for(int i=1;i<=m_numberOfSpectra;++i) - { - skipData(file, i+ (period-1)*(m_numberOfSpectra+1) ); - } - } - - int64_t wsIndex = 0; - // for each period read first spectrum - int64_t histToRead = period*(m_numberOfSpectra+1); - - progress(m_prog, "Reading raw file data..."); - //isisRaw->readData(file, histToRead); - //readData(file, histToRead); - //read spectrum - if (!readData(file, histToRead)) - { - throw std::runtime_error("Error reading raw file"); - } - - //set the workspace data - setWorkspaceData(localWorkspace, timeChannelsVec, wsIndex, 0, m_noTimeRegimes,m_lengthIn,1); - - if (m_numberOfPeriods == 1) - { - if (++histCurrent % 100 == 0) - { - m_prog = double(histCurrent) / histTotal; - } - interruption_point(); - } - if(m_numberOfPeriods>1) - { - setWorkspaceProperty(localWorkspace, wsgrp_sptr, period, false); - // progress for workspace groups - m_prog = static_cast(period) / static_cast(m_numberOfPeriods - 1); - } - - } // loop over periods - - // Clean up - reset(); - fclose(file); - - } - - - } + } + //skip all spectra except the first one in each period + for(int i=1;i<=m_numberOfSpectra;++i) + { + skipData(file, i+ (period-1)*(m_numberOfSpectra+1) ); + } + } + + int64_t wsIndex = 0; + // for each period read first spectrum + int64_t histToRead = period*(m_numberOfSpectra+1); + + progress(m_prog, "Reading raw file data..."); + //isisRaw->readData(file, histToRead); + //readData(file, histToRead); + //read spectrum + if (!readData(file, histToRead)) + { + throw std::runtime_error("Error reading raw file"); + } + + //set the workspace data + setWorkspaceData(localWorkspace, timeChannelsVec, wsIndex, 0, m_noTimeRegimes,m_lengthIn,1); + + if (m_numberOfPeriods == 1) + { + if (++histCurrent % 100 == 0) + { + m_prog = double(histCurrent) / histTotal; + } + interruption_point(); + } + if(m_numberOfPeriods>1) + { + setWorkspaceProperty(localWorkspace, wsgrp_sptr, period, false,this); + // progress for workspace groups + m_prog = static_cast(period) / static_cast(m_numberOfPeriods - 1); + } + + } // loop over periods + + // Clean up + reset(); + fclose(file); + + } + + + } } diff --git a/Code/Mantid/Framework/DataHandling/src/LoadReflTBL.cpp b/Code/Mantid/Framework/DataHandling/src/LoadReflTBL.cpp index 54322897ba86..025bdbd31917 100644 --- a/Code/Mantid/Framework/DataHandling/src/LoadReflTBL.cpp +++ b/Code/Mantid/Framework/DataHandling/src/LoadReflTBL.cpp @@ -291,8 +291,9 @@ namespace Mantid auto colQmin = ws->addColumn("str","Qmin"); auto colQmax = ws->addColumn("str","Qmax"); auto colDqq = ws->addColumn("str","dq/q"); - auto colScale = ws->addColumn("str","Scale"); + auto colScale = ws->addColumn("double","Scale"); auto colStitch = ws->addColumn("int","StitchGroup"); + auto colOptions = ws->addColumn("str","Options"); colRuns->setPlotType(0); colTheta->setPlotType(0); @@ -302,6 +303,7 @@ namespace Mantid colDqq->setPlotType(0); colScale->setPlotType(0); colStitch->setPlotType(0); + colOptions->setPlotType(0); std::vector columns; @@ -315,6 +317,11 @@ namespace Mantid } getCells(line, columns); + const std::string scaleStr = columns.at(16); + double scale = 1.0; + if(!scaleStr.empty()) + Mantid::Kernel::Strings::convert(columns.at(16), scale); + //check if the first run in the row has any data associated with it // 0 = runs, 1 = theta, 2 = trans, 3 = qmin, 4 = qmax if (columns[0] != "" || columns[1] != "" || columns[2] != "" || columns[3] != "" || columns[4] != "") @@ -325,7 +332,7 @@ namespace Mantid row << columns.at(i); } row << columns.at(15); - row << columns.at(16); + row << scale; row << stitchID; } @@ -339,7 +346,7 @@ namespace Mantid row << columns.at(i); } row << columns.at(15); - row << columns.at(16); + row << scale; row << stitchID; } @@ -350,7 +357,10 @@ namespace Mantid TableRow row = ws->appendRow(); for (int i = 10; i < 17; ++i) { - row << columns.at(i); + if(i == 16) + row << scale; + else + row << columns.at(i); } row << stitchID; } diff --git a/Code/Mantid/Framework/DataHandling/src/LoadVulcanCalFile.cpp b/Code/Mantid/Framework/DataHandling/src/LoadVulcanCalFile.cpp index 691b41e40413..b97c7d772f46 100644 --- a/Code/Mantid/Framework/DataHandling/src/LoadVulcanCalFile.cpp +++ b/Code/Mantid/Framework/DataHandling/src/LoadVulcanCalFile.cpp @@ -15,6 +15,7 @@ #include #include +#include #include @@ -40,7 +41,7 @@ namespace DataHandling //---------------------------------------------------------------------------------------------- /** Constructor */ - LoadVulcanCalFile::LoadVulcanCalFile() + LoadVulcanCalFile::LoadVulcanCalFile() : m_doAlignEventWS(false) { } @@ -279,6 +280,7 @@ namespace DataHandling */ void LoadVulcanCalFile::setupMaskWorkspace() { + // Skip if bad pixel file is not given if (m_badPixFilename.size() == 0) return; @@ -293,21 +295,24 @@ namespace DataHandling string line; while (std::getline(maskss, line)) { - // Get the bad pixel's detector ID. One per line - stringstream liness(line); - - try + boost::algorithm::trim(line); + if (!line.empty()) { - int pixelid; - liness >> pixelid; + // Get the bad pixel's detector ID. One per line + stringstream liness(line); + try + { + int pixelid; + liness >> pixelid; - // Set mask - m_maskWS->setValue(pixelid, 1.0); - } - catch (const std::invalid_argument& e) - { - g_log.debug() << "Unable to parse line " << line << ". Error message: " << e.what() << "\n"; - continue; + // Set mask + m_maskWS->setValue(pixelid, 1.0); + } + catch (const std::invalid_argument& e) + { + g_log.debug() << "Unable to parse line " << line << ". Error message: " << e.what() << "\n"; + continue; + } } } maskss.close(); @@ -322,6 +327,7 @@ namespace DataHandling m_maskWS->dataY(i)[0] = 1.0; msg << "Spectrum " << i << " is masked. DataY = " << m_maskWS->readY(i)[0] << "\n"; } + } g_log.information(msg.str()); @@ -572,6 +578,7 @@ namespace DataHandling // FIXME - The simple version of the algorithm to calculate 2theta is used here. // A check will be made to raise exception if the condition is not met to use the simple version. double s_r, s_2theta, s_phi; + s_r = s_2theta = s_phi = 0.; samplePos.spherical(s_r, s_2theta, s_phi); if (fabs(beamline.X()) > 1.0E-20 || fabs(beamline.Y()) > 1.0E-20 || s_r > 1.0E-20) throw runtime_error("Source is not at (0, 0, Z) or sample is not at (0, 0, 0). " diff --git a/Code/Mantid/Framework/DataHandling/src/MaskDetectors.cpp b/Code/Mantid/Framework/DataHandling/src/MaskDetectors.cpp index aa333c0fd571..a63cc9e8b89f 100644 --- a/Code/Mantid/Framework/DataHandling/src/MaskDetectors.cpp +++ b/Code/Mantid/Framework/DataHandling/src/MaskDetectors.cpp @@ -21,6 +21,7 @@ DECLARE_ALGORITHM(MaskDetectors) using namespace Kernel; using namespace API; +using namespace DataObjects; using Geometry::Instrument_const_sptr; using Geometry::IDetector_const_sptr; using namespace DataObjects; @@ -37,7 +38,7 @@ MaskDetectors::~MaskDetectors() {} void MaskDetectors::init() { declareProperty( - new WorkspaceProperty<>("Workspace","", Direction::InOut), + new WorkspaceProperty("Workspace","", Direction::InOut), "The name of the input and output workspace on which to perform the algorithm." ); declareProperty(new ArrayProperty("SpectraList"), "An ArrayProperty containing a list of spectra to mask" ); @@ -63,7 +64,14 @@ void MaskDetectors::init() void MaskDetectors::exec() { // Get the input workspace - const MatrixWorkspace_sptr WS = getProperty("Workspace"); + Workspace_sptr propWS = getProperty("Workspace"); + MatrixWorkspace_sptr WS = boost::dynamic_pointer_cast(propWS); + PeaksWorkspace_sptr peaksWS = boost::dynamic_pointer_cast(propWS); + if (peaksWS) + { + execPeaks(peaksWS); + return; + } // Is it an event workspace? EventWorkspace_sptr eventWS = boost::dynamic_pointer_cast(WS); @@ -189,7 +197,88 @@ void MaskDetectors::exec() */ WS->rebuildNearestNeighbours(); } +/* + * Peaks exec body + * @param WS :: The input peaks workspace to be masked + */ +void MaskDetectors::execPeaks(PeaksWorkspace_sptr WS) +{ + std::vector detectorList = getProperty("DetectorList"); + const MatrixWorkspace_sptr prevMasking = getProperty("MaskedWorkspace"); + + // each one of these values is optional but the user can't leave all four blank + if ( detectorList.empty() && !prevMasking ) + { + g_log.information(name() + ": There is nothing to mask, " + "detector lists and masked workspace properties are all empty"); + return; + } + + // Need to get hold of the parameter map and instrument + Geometry::ParameterMap& pmap = WS->instrumentParameters(); + Instrument_const_sptr instrument = WS->getInstrument(); + // If we have a workspace that could contain masking,copy that in too + + if( prevMasking ) + { + DataObjects::MaskWorkspace_sptr maskWS = boost::dynamic_pointer_cast(prevMasking); + if (maskWS) + { + Geometry::ParameterMap& maskPmap = maskWS->instrumentParameters(); + Instrument_const_sptr maskInstrument = maskWS->getInstrument(); + if (maskInstrument->getDetectorIDs().size() != WS->getInstrument()->getDetectorIDs().size()) + { + throw std::runtime_error("Size mismatch between input Workspace and MaskWorkspace"); + } + + g_log.debug() << "Extracting mask from MaskWorkspace (" << maskWS->name() << ")" << std::endl; + std::vector detectorIDs = maskInstrument->getDetectorIDs(); + std::vector::const_iterator it; + for (it = detectorIDs.begin(); it != detectorIDs.end(); ++it) + { + try + { + if ( const Geometry::ComponentID det = maskInstrument->getDetector(*it)->getComponentID() ) + { + Geometry::Parameter_sptr maskedParam = maskPmap.get(det, "masked"); + int detID =static_cast( maskInstrument->getDetector(*it)->getID()); + if (maskedParam) detectorList.push_back(detID); + } + } + catch(Kernel::Exception::NotFoundError &e) + { + g_log.warning() << e.what() << " Found while running MaskDetectors" << std::endl; + } + } + } + } + + + + // If explicitly given a list of detectors to mask, just mark those. + // Otherwise, mask all detectors pointing to the requested spectra in indexlist loop below + std::vector::const_iterator it; + if ( !detectorList.empty() ) + { + for (it = detectorList.begin(); it != detectorList.end(); ++it) + { + try + { + if ( const Geometry::ComponentID det = instrument->getDetector(*it)->getComponentID() ) + { + pmap.addBool(det,"masked",true); + } + } + catch(Kernel::Exception::NotFoundError &e) + { + g_log.warning() << e.what() << " Found while running MaskDetectors" << std::endl; + } + } + } + + +} /** * Convert a list of spectra numbers into the corresponding workspace indices * @param indexList :: An output index list from the given spectra list diff --git a/Code/Mantid/Framework/DataHandling/src/SNSDataArchive.cpp b/Code/Mantid/Framework/DataHandling/src/SNSDataArchive.cpp index 9575489061bc..59623db7dd16 100644 --- a/Code/Mantid/Framework/DataHandling/src/SNSDataArchive.cpp +++ b/Code/Mantid/Framework/DataHandling/src/SNSDataArchive.cpp @@ -35,6 +35,8 @@ namespace DataHandling { // Get a reference to the logger Kernel::Logger g_log("SNSDataArchive"); + /// Base url for restful web survice + const std::string BASE_URL("http://icat.sns.gov:2080/icat-rest-ws/datafile/filename/"); } DECLARE_ARCHIVESEARCH(SNSDataArchive,SNSDataSearch); @@ -59,9 +61,8 @@ std::string SNSDataArchive::getArchivePath(const std::set& filename } g_log.debug() << "\n"; - std::string baseURL("http://icat.sns.gov:8080/icat-rest-ws/datafile/filename/"); - std::string URL(baseURL + filename); + const std::string URL(BASE_URL + filename); g_log.debug() << "URL: " << URL << "\n"; Poco::URI uri(URL); diff --git a/Code/Mantid/Framework/DataHandling/src/SNSDataArchiveICAT2.cpp b/Code/Mantid/Framework/DataHandling/src/SNSDataArchiveICAT2.cpp deleted file mode 100644 index 737ad89b0bec..000000000000 --- a/Code/Mantid/Framework/DataHandling/src/SNSDataArchiveICAT2.cpp +++ /dev/null @@ -1,133 +0,0 @@ -//---------------------------------------------------------------------- -// Includes -//---------------------------------------------------------------------- -#include "MantidKernel/Logger.h" -#include "MantidDataHandling/SNSDataArchiveICAT2.h" -#include "MantidAPI/ArchiveSearchFactory.h" - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "Poco/SAX/InputSource.h" -#include -#include - -#include - -using Poco::Net::HTTPSClientSession; -using Poco::Net::HTTPRequest; -using Poco::Net::HTTPResponse; -using Poco::Net::HTTPMessage; -using Poco::Net::ConnectionRefusedException; -using Poco::URI; - -namespace Mantid -{ -namespace DataHandling -{ - namespace - { - // Get a reference to the logger - Kernel::Logger g_log("SNSDataArchiveICAT2"); - } - -DECLARE_ARCHIVESEARCH(SNSDataArchiveICAT2,SNSDataSearchICAT2); - -/** - * Calls a web service to get a full path to a file - * @param fName :: The file name. - * @return The path to the file or empty string in case of error. - */ -std::string SNSDataArchiveICAT2::getPath(const std::string& fName) const -{ - std::string baseURL( - "https://prod.sns.gov/sns-icat-ws/icat-location/fileName/"); - std::string URL(baseURL + fName); - g_log.debug() << "SNSDataArchiveICAT2 URL = \'" << URL << "\'\n"; - - std::string wsResult = ""; - - //#ifdef _WIN32 - // // Return an empty string - //#else - // - //#endif - - Poco::URI uri(URL); - std::string path(uri.getPathAndQuery()); - - Poco::Net::Context::Ptr context = new Poco::Net::Context(Poco::Net::Context::CLIENT_USE, "", "", - "", Poco::Net::Context::VERIFY_NONE, 9, false, "ALL:!ADH:!LOW:!EXP:!MD5:@STRENGTH"); - - try { // workaround for ubuntu 11.04 - Poco::Net::HTTPSClientSession session(uri.getHost(), uri.getPort(), context); // this line is broken - HTTPRequest req(HTTPRequest::HTTP_GET, path, HTTPMessage::HTTP_1_1); - session.sendRequest(req); - - HTTPResponse res; - std::istream& rs = session.receiveResponse(res); - - char buff[300]; - std::streamsize n; - - do - { - rs.read(&buff[0], 300); - n = rs.gcount(); - wsResult.append(&buff[0], n); - } while (n == 300); - } catch (ConnectionRefusedException &) { - g_log.information() << "Connection refused by prod.sns.gov\n"; - throw; - } catch(Poco::IOException &e) { - g_log.debug() << e.name() << " thrown.\n"; - g_log.information() << e.message() << "\n"; - throw; - } - - g_log.debug() << "SNSDataArchiveICAT2 Returning Filename = \'" << wsResult << "\'\n"; - - return wsResult; -} - -/** - * @param filenames : List of files to search - * @param exts : List of extensions to check against - * @return list of archive locations - */ -std::string SNSDataArchiveICAT2::getArchivePath(const std::set& filenames, const std::vector& exts) const -{ - std::vector::const_iterator ext = exts.begin(); - for (; ext != exts.end(); ++ext) - { - std::set::const_iterator it = filenames.begin(); - for(; it!=filenames.end(); ++it) - { - std::string path = getPath(*it + *ext); - try - { - if (!path.empty() && Poco::File(path).exists()) - { - return path; - } - } - catch(std::exception& e) - { - g_log.error() << "Cannot open file " << path << ": " << e.what() << '\n'; - return ""; - } - } // it - } // ext - return ""; -} // end of getArchivePath - -} // namespace DataHandling -} // namespace Mantid diff --git a/Code/Mantid/Framework/DataHandling/src/SaveAscii2.cpp b/Code/Mantid/Framework/DataHandling/src/SaveAscii2.cpp index f5d2bb8ee328..13b1a8908ce6 100644 --- a/Code/Mantid/Framework/DataHandling/src/SaveAscii2.cpp +++ b/Code/Mantid/Framework/DataHandling/src/SaveAscii2.cpp @@ -55,7 +55,7 @@ namespace Mantid "It is always written for workspaces with multiple spectra."); declareProperty("CommentIndicator", "#", "Character(s) to put in front of comment lines."); - + // For the ListValidator std::string spacers[6][2] = { {"CSV", ","}, {"Tab", "\t"}, {"Space", " "}, {"Colon", ":"}, {"SemiColon", ";"}, {"UserDefined", "UserDefined"} }; @@ -80,6 +80,7 @@ namespace Mantid declareProperty("AppendToFile", false, "If true, don't overwrite the file. Append to the end of it. "); + declareProperty("RaggedWorkspace", true, "If true, ensure that more than one xspectra is used. "); //in testing } /** @@ -92,6 +93,7 @@ namespace Mantid int nSpectra = static_cast(m_ws->getNumberHistograms()); m_nBins = static_cast(m_ws->blocksize()); m_isHistogram = m_ws->isHistogramData(); + m_isCommonBins = m_ws->isCommonBins(); //checking for ragged workspace m_writeID = getProperty("WriteSpectrumID"); if (nSpectra != 1) m_writeID = true; @@ -154,6 +156,7 @@ namespace Mantid idx.insert(i); } } + //figure out how to read in readX and have them be seperate lists // Add spectra list into the index list if (!spec_list.empty()) @@ -235,25 +238,31 @@ namespace Mantid @param spectraItr :: a set iterator pointing to a set of workspace IDs to be saved @param file :: the file writer object */ - void SaveAscii2::writeSpectra(const std::set::const_iterator & spectraItr, std::ofstream & file) + void SaveAscii2::writeSpectra(const std::set::const_iterator & spectraItr, std::ofstream & file) { auto spec = m_ws->getSpectrum(*spectraItr); auto specNo = spec->getSpectrumNo(); if (m_writeID) file << specNo << std::endl; - + for(int bin=0;binreadX(*spectraItr)[bin] + m_ws->readX(*spectraItr)[bin+1] )/2; + } - if (m_isHistogram) // bin centres + else if (m_isHistogram & m_isCommonBins) // bin centres, { - file << ( m_ws->readX(0)[bin] + m_ws->readX(0)[bin+1] )/2; + file << ( m_ws->readX(0)[bin] + m_ws->readX(0)[bin+1] )/2; } - else // data points + + else { file << m_ws->readX(0)[bin]; } file << m_sep; file << m_ws->readY(*spectraItr)[bin]; + file << m_sep; file << m_ws->readE(*spectraItr)[bin]; if (m_writeDX) @@ -277,7 +286,7 @@ namespace Mantid @param spectraIndex :: an integer relating to a workspace ID @param file :: the file writer object */ - void SaveAscii2::writeSpectra(const int & spectraIndex, std::ofstream & file) + void SaveAscii2::writeSpectra(const int & spectraIndex, std::ofstream & file) { auto spec = m_ws->getSpectrum(spectraIndex); auto specNo = spec->getSpectrumNo(); @@ -285,16 +294,21 @@ namespace Mantid for(int bin=0;binreadX(0)[bin] + m_ws->readX(0)[bin+1] )/2; } + else if (!m_isCommonBins) //checking for ragged workspace + { + file << ( m_ws->readX(spectraIndex)[bin] + m_ws->readX(spectraIndex)[bin+1] )/2; + } else // data points { file << m_ws->readX(0)[bin]; } file << m_sep; file << m_ws->readY(spectraIndex)[bin]; + file << m_sep; file << m_ws->readE(spectraIndex)[bin]; if (m_writeDX) diff --git a/Code/Mantid/Framework/DataHandling/src/SaveCalFile.cpp b/Code/Mantid/Framework/DataHandling/src/SaveCalFile.cpp index d5cc0fe19504..ff7934bc0db9 100644 --- a/Code/Mantid/Framework/DataHandling/src/SaveCalFile.cpp +++ b/Code/Mantid/Framework/DataHandling/src/SaveCalFile.cpp @@ -23,7 +23,7 @@ namespace DataHandling //---------------------------------------------------------------------------------------------- /** Constructor */ - SaveCalFile::SaveCalFile() + SaveCalFile::SaveCalFile() : m_precision(7) { } diff --git a/Code/Mantid/Framework/DataHandling/src/SaveNXTomo.cpp b/Code/Mantid/Framework/DataHandling/src/SaveNXTomo.cpp new file mode 100644 index 000000000000..70b590cd7334 --- /dev/null +++ b/Code/Mantid/Framework/DataHandling/src/SaveNXTomo.cpp @@ -0,0 +1,417 @@ +#include "MantidAPI/FileProperty.h" +#include "MantidAPI/WorkspaceValidators.h" +#include "MantidDataHandling/FindDetectorsPar.h" +#include "MantidDataHandling/SaveNXTomo.h" +#include "MantidGeometry/IComponent.h" +#include "MantidKernel/MantidVersion.h" +#include "MantidNexus/NexusClasses.h" + +namespace Mantid +{ + namespace DataHandling + { + // Register the algorithm into the algorithm factory + DECLARE_ALGORITHM(SaveNXTomo) + + using namespace Kernel; + using namespace API; + using Geometry::RectangularDetector; + + const double SaveNXTomo::MASK_FLAG = std::numeric_limits::quiet_NaN(); + const double SaveNXTomo::MASK_ERROR = 0.0; + const std::string SaveNXTomo::NXTOMO_VER = "2.0"; + + SaveNXTomo::SaveNXTomo() : API::Algorithm() + { + m_filename = ""; + m_includeError = false; + m_numberOfRows = 32; + } + + /** + * Initialise the algorithm + */ + void SaveNXTomo::init() + { + auto wsValidator = boost::make_shared() ; + //wsValidator->add(boost::make_shared("DeltaE")); + wsValidator->add(); + wsValidator->add(); + + declareProperty(new WorkspaceProperty ("InputWorkspace", "", Direction::Input, wsValidator), + "The name of the workspace to save."); + + declareProperty(new API::FileProperty("Filename", "", FileProperty::Save, std::vector(1,".nxs")), + "The name of the NXTomo file to write, as a full or relative path"); + + declareProperty(new PropertyWithValue("RowChunkSize", 32, Kernel::Direction::Input), + "Please use an evenly divisible number smaller than the image height"); + + declareProperty(new PropertyWithValue("IncludeError", false, Kernel::Direction::Input), + "Write the error values to NXTomo file?"); + } + + /** + * Execute the algorithm + */ + void SaveNXTomo::exec() + { + // Retrieve the input workspace + const MatrixWorkspace_const_sptr inputWS = getProperty("InputWorkspace"); + + m_numberOfRows = getProperty("RowChunkSize"); + m_includeError = getProperty("IncludeError"); + + const std::string workspaceID = inputWS->id(); + + if ((workspaceID.find("Workspace2D") == std::string::npos) && + (workspaceID.find("RebinnedOutput") == std::string::npos)) + throw Exception::NotImplementedError("SaveNXTomo passed invalid workspaces. Must be Workspace2D"); + + // Do the full check for common binning + if (!WorkspaceHelpers::commonBoundaries(inputWS)) + { + g_log.error("The input workspace must have common bins"); + throw std::invalid_argument("The input workspace must have common bins"); + } + + // Number of spectra + const size_t nHist = inputWS->getNumberHistograms(); + // Number of energy bins + //this->m_nBins = inputWS->blocksize(); + + // Get a pointer to the sample + //Geometry::IComponent_const_sptr sample = + // inputWS->getInstrument()->getSample(); + + // Retrieve the filename from the properties + this->m_filename = getPropertyValue("Filename"); + + // Dimensions for axis in nxTomo file. + std::vector dims_array; + + // Populate the array + dims_array = getDimensionsFromDetector(getRectangularDetectors(inputWS->getInstrument())); + + // Insert number of bins at front + dims_array.insert(dims_array.begin(), inputWS->blocksize()); // Number of bins + + // Create the file. + ::NeXus::File nxFile(this->m_filename, NXACC_CREATE5); + + // Make the top level entry (and open it) + nxFile.makeGroup("entry1", "NXentry", true); + + // Make a sub-group for the entry to work with DAWN software (and open it) + nxFile.makeGroup("tomo_entry", "NXsubentry", true); + + // Title + nxFile.writeData("title", this->m_filename); + + // Start Time; Format ISO8601 | unused but part of NXtomo schema + //nxFile.writeData("start_time", ); + + // End Time; Format ISO8601 | unused but part of NXtomo schema + //nxFile.writeData("end_time", ); + + // Definition name and version + nxFile.writeData("definition", "NXtomo"); + nxFile.openData("definition"); + nxFile.putAttr("version", NXTOMO_VER); + nxFile.closeData(); + + // Originating program name and version + nxFile.writeData("program_name", "mantid"); + nxFile.openData("program_name"); + nxFile.putAttr("version", Mantid::Kernel::MantidVersion::version()); + nxFile.closeData(); + + // ****************************************** + // NXinstrument + nxFile.makeGroup("instrument", "NXinstrument", true); + // Write the instrument name | could add short_name attribute to name + nxFile.writeData("name", inputWS->getInstrument()->getName()); + + // detector group - diamond example file contains {data,distance,image_key,x_pixel_size,y_pixel_size} Only adding image_key for now, 0 filled. + nxFile.makeGroup("detector", "NXdetector", true); + std::vector imageKeys(dims_array[0],0); + nxFile.writeData("image_key", imageKeys); + // Create link to image_key + nxFile.openData("image_key"); + //NXlink imageKeyLink = nxFile.getDataID(); + nxFile.closeData(); + nxFile.closeGroup(); + + // source group // from diamond file contains {current,energy,name,probe,type} - probe = [neutron | x-ray | electron] + + nxFile.closeGroup(); // NXinstrument + + // ****************************************** + // NXsample + nxFile.makeGroup("sample", "NXsample", true); + // TODO: Write sample info + // name + + // Initialise rotations - if unknown, fill with equal steps from 0 to 180 over all frames. + std::vector rotationAngles(dims_array[0]); + std::string rotValues = ""; + std::vector rotSplit; + + if(inputWS->run().hasProperty("Rotations")) + { + rotValues = inputWS->run().getLogData("Rotations")->value(); + boost::split(rotSplit, rotValues, boost::is_any_of(",")); + } + + if(rotSplit.size() == static_cast(dims_array[0]) ) + { + for(size_t i=0; i(rotSplit[i]); + } + } + else + { + // Make some fake values + g_log.notice("Unable to find a correctly formatted rotation angle file with same entry count as input; creating fake values."); + double step = static_cast(180/dims_array[0]); + rotationAngles[0] = step; + + for(auto it = rotationAngles.begin()+1; it != rotationAngles.end(); ++it) + { + *it = (*(it-1)) + step; + } + } + + nxFile.writeData("rotation_angle", rotationAngles); + + // Create a link object for rotation_angle to use later + nxFile.openData("rotation_angle"); + NXlink rotationLink = nxFile.getDataID(); + nxFile.closeData(); + // x_translation + // y_translation + // z_translation + nxFile.closeGroup(); // NXsample + + // ****************************************** + // Make the NXmonitor group - Holds base beam intensity for each image + // If information is not present, set as 1 + + std::vector intensity(dims_array[0],1); + nxFile.makeGroup("control", "NXmonitor", true); + nxFile.writeData("data", intensity); + nxFile.closeGroup(); // NXmonitor + + nxFile.makeGroup("data", "NXdata", true); + + nxFile.makeLink(rotationLink); + + nxFile.makeData("data", ::NeXus::FLOAT64, dims_array, false); + if(m_includeError) + nxFile.makeData("error", ::NeXus::FLOAT64, dims_array, false); + + std::vector slabStart; + std::vector slabSize; + + // What size slabs are we going to write + slabSize.push_back(dims_array[0]); + slabSize.push_back((int64_t)dims_array[1]); + slabSize.push_back((int64_t)m_numberOfRows); + + // Init start to first row + slabStart.push_back(0); + slabStart.push_back(0); + slabStart.push_back(0); + + // define the data and error vectors for masked detectors + std::vector masked_data (dims_array[0], MASK_FLAG); + if(m_includeError) + std::vector masked_error (dims_array[0], MASK_ERROR); + + // Create a progress reporting object + Progress progress(this,0,1,100); + const size_t progStep = static_cast(ceil(static_cast(nHist)/100.0)); + Geometry::IDetector_const_sptr det; + + double *dataArr = new double[dims_array[0]*dims_array[2]*m_numberOfRows]; + double *errorArr = NULL; + if(m_includeError) + errorArr = new double[dims_array[0]*dims_array[2]*m_numberOfRows]; + + int currY = 0; + size_t rowIndForSlab = 0; // as we're creating slabs of multiple rows, this says which y index we're at in current slab + + // Loop over detectors + for (size_t i = 0; i < nHist; ++i) + { + try + { + // detector exist + //det = inputWS->getDetector(i); + // Check that we aren't writing a monitor + //if (!det->isMonitor()) + //{ + //Geometry::IDetector_const_sptr det = inputWS->getDetector(i); + + // Figure out where this pixel is supposed to be going and set the correct slab start. + + if(i!=0 && (i)%dims_array[1] == 0){ // When this iteration matches end of a row + currY += 1; + } + size_t currX = (i) - (currY*dims_array[1]); + + const MantidVec & thisY = inputWS->readY(i); + // No masking - Set the data and error as is + for(int j=0; jisMasked()) + // { + dataArr[currInd] = thisY.at(j); + if(m_includeError) + errorArr[currInd] = inputWS->readE(i).at(j); + //} + //else + //{ + // dataArr[currInd] = masked_data[j]; + // if(m_includeError) + // errorArr[currInd] = masked_error[j]; + //} + } + + // If end of the row has been reached, check for end of slab (or end of row count) and write data/error + if(((i+1)%dims_array[2]) == 0) + { + rowIndForSlab += 1; + + // Check if we have collected all of the rows (prior to completing a slab) - if so, write the final section + // TODO:: + + + // if a slab has been collected. Put it into the file + if(rowIndForSlab >= m_numberOfRows) + { + slabStart[2] = currY-(rowIndForSlab-1); + + // Write Data + nxFile.openData("data"); + nxFile.putSlab(dataArr, slabStart, slabSize); + nxFile.closeData(); + // Write Error + if(m_includeError) + { + nxFile.openData("error"); + nxFile.putSlab(errorArr, slabStart, slabSize); + nxFile.closeData(); + } + // Reset slab index count + rowIndForSlab = 0; + } + } + } + catch(Exception::NotFoundError&) + { + /*Catch if no detector. Next line tests whether this happened - test placed + outside here because Mac Intel compiler doesn't like 'continue' in a catch + in an openmp block.*/ + } + // If no detector found, skip onto the next spectrum + if ( !det ) continue; + + // Make regular progress reports and check for canceling the algorithm + if ( i % progStep == 0 ) + { + progress.report(); + } + } + + // Create a link object for the data + nxFile.openData("data"); + NXlink dataLink = nxFile.getDataID(); + nxFile.closeData(); + + nxFile.closeGroup(); // Close Data group + + // Put a link to the data in instrument/detector + nxFile.openGroup("instrument","NXinstrument"); + nxFile.openGroup("detector","NXdetector"); + nxFile.makeLink(dataLink); + nxFile.closeGroup(); + nxFile.closeGroup(); + + + nxFile.closeGroup(); // tomo_entry sub-group + nxFile.closeGroup(); // Top level NXentry + + // Clean up memory + delete [] dataArr; + delete [] errorArr; + } + + /** + * Find all RectangularDetector objects in an instrument + * @param instrument instrument to search for detectors in + * @returns vector of all Rectangular Detectors + */ + std::vector> SaveNXTomo::getRectangularDetectors(const Geometry::Instrument_const_sptr &instrument) + { + std::vector> components; + instrument->getChildren(components,true); + + std::vector> rectDetectors; + + for(auto it = components.begin(); it != components.end(); ++it) + { + // for all components, compare to RectangularDetector - if it is one, add it to detectors list. + auto ptr = boost::dynamic_pointer_cast(*it); + if(ptr != NULL) + { + rectDetectors.push_back(ptr); + } + } + + return rectDetectors; + } + + /** + * Populates the dimensions vector with number of files, x and y sizes from a specified rectangular detector + * @param rectDetectors List of rectangular detectors to get axis sizes from + * @param useDetectorIndex index of the detector to select from the list, default = 0 + * @returns vector of both axis dimensions for specified detector + * + * @throw runtime_error Thrown if there are no rectangular detectors + */ + std::vector SaveNXTomo::getDimensionsFromDetector(const std::vector> &rectDetectors, size_t useDetectorIndex) + { + // Add number of pixels in X and Y from instrument definition + // Throws if no rectangular detector is present. + + std::vector dims; + + if(rectDetectors.size() != 0) + { + // Assume the first rect detector is the desired one. + dims.push_back(rectDetectors[useDetectorIndex]->xpixels()); + dims.push_back(rectDetectors[useDetectorIndex]->ypixels()); + } + else + { + // Incorrect workspace : requires the x/y pixel count from the instrument definition + g_log.error("Unable to retrieve x and y pixel count from an instrument definition associated with this workspace."); + throw std::runtime_error("Unable to retrieve x and y pixel count from an instrument definition associated with this workspace."); + } + + return dims; + } + + //void someRoutineToAddDataToExisting() + //{ + // //TODO: + //} + + } // namespace DataHandling +} // namespace Mantid + + diff --git a/Code/Mantid/Framework/DataHandling/src/SaveNexus.cpp b/Code/Mantid/Framework/DataHandling/src/SaveNexus.cpp index c6f7e785a38d..770016f435f8 100644 --- a/Code/Mantid/Framework/DataHandling/src/SaveNexus.cpp +++ b/Code/Mantid/Framework/DataHandling/src/SaveNexus.cpp @@ -89,27 +89,8 @@ void SaveNexus::exec() // Retrieve the filename from the properties m_filename = getPropertyValue("FileName"); m_inputWorkspace = getProperty("InputWorkspace"); - //retrieve the append property - bool bAppend = getProperty("Append"); - // if bAppend is default (false) overwrite (delete )the .nxs file - if (!bAppend) - { - Poco::File file(m_filename); - if (file.exists()) - { file.remove(); - } - } - m_filetype = "NexusProcessed"; - - if (m_filetype == "NexusProcessed") - { - runSaveNexusProcessed(); - } - else - { - throw Exception::NotImplementedError("SaveNexus passed invalid filetype."); - } + runSaveNexusProcessed(); return; } @@ -183,5 +164,21 @@ void SaveNexus::runSaveNexusProcessed() // progress(1); } + + /** + Overriden process groups. + */ + bool SaveNexus::processGroups() + { + this->exec(); + + // We finished successfully. + setExecuted(true); + notificationCenter().postNotification(new FinishedNotification(this,isExecuted())); + + return true; + } + + } // namespace DataHandling } // namespace Mantid diff --git a/Code/Mantid/Framework/DataHandling/src/SaveNexusProcessed.cpp b/Code/Mantid/Framework/DataHandling/src/SaveNexusProcessed.cpp index 35140e4a37b3..436c3e55f6d8 100644 --- a/Code/Mantid/Framework/DataHandling/src/SaveNexusProcessed.cpp +++ b/Code/Mantid/Framework/DataHandling/src/SaveNexusProcessed.cpp @@ -24,432 +24,454 @@ using namespace Mantid::API; namespace Mantid { -namespace DataHandling -{ - - using namespace Kernel; - using namespace API; - using namespace DataObjects; - using Geometry::Instrument_const_sptr; + namespace DataHandling + { - // Register the algorithm into the algorithm factory - DECLARE_ALGORITHM(SaveNexusProcessed) - + using namespace Kernel; + using namespace API; + using namespace DataObjects; + using Geometry::Instrument_const_sptr; + typedef NeXus::NexusFileIO::optional_size_t optional_size_t; - /// Empty default constructor - SaveNexusProcessed::SaveNexusProcessed() : Algorithm() - { - } + // Register the algorithm into the algorithm factory + DECLARE_ALGORITHM(SaveNexusProcessed) - //----------------------------------------------------------------------------------------------- - /** Initialisation method. - * - */ - void SaveNexusProcessed::init() - { - declareProperty(new WorkspaceProperty("InputWorkspace","",Direction::Input), - "Name of the workspace to be saved"); - // Declare required input parameters for algorithm - std::vector exts; - exts.push_back(".nxs"); - exts.push_back(".nx5"); - exts.push_back(".xml"); - - declareProperty(new FileProperty("Filename", "", FileProperty::Save, exts), - "The name of the Nexus file to write, as a full or relative\n" - "path"); - - // Declare optional parameters (title now optional, was mandatory) - declareProperty("Title", "", boost::make_shared(), - "A title to describe the saved workspace"); - auto mustBePositive = boost::make_shared >(); - mustBePositive->setLower(0); - - declareProperty("WorkspaceIndexMin", 0, mustBePositive, - "Index number of first spectrum to write, only for single\n" - "period data."); - declareProperty("WorkspaceIndexMax", Mantid::EMPTY_INT(), mustBePositive, - "Index of last spectrum to write, only for single period\n" - "data."); - declareProperty(new ArrayProperty("WorkspaceIndexList"), - "List of spectrum numbers to read, only for single period\n" - "data."); - - declareProperty("Append",false,"Determines whether .nxs file needs to be\n" - "over written or appended"); - - declareProperty("PreserveEvents", true, - "For EventWorkspaces, preserve the events when saving (default).\n" - "If false, will save the 2D histogram version of the workspace with the current binning parameters."); - setPropertySettings("PreserveEvents", new EnabledWhenWorkspaceIsType("InputWorkspace", true)); - - declareProperty("CompressNexus", false, - "For EventWorkspaces, compress the Nexus data field (default False).\n" - "This will make smaller files but takes much longer."); - setPropertySettings("CompressNexus", new EnabledWhenWorkspaceIsType("InputWorkspace", true)); + /// Empty default constructor + SaveNexusProcessed::SaveNexusProcessed() : + Algorithm() + { + } - } + //----------------------------------------------------------------------------------------------- + /** Initialisation method. + * + */ + void SaveNexusProcessed::init() + { + declareProperty(new WorkspaceProperty("InputWorkspace", "", Direction::Input), + "Name of the workspace to be saved"); + // Declare required input parameters for algorithm + std::vector exts; + exts.push_back(".nxs"); + exts.push_back(".nx5"); + exts.push_back(".xml"); + + declareProperty(new FileProperty("Filename", "", FileProperty::Save, exts), + "The name of the Nexus file to write, as a full or relative\n" + "path"); + + // Declare optional parameters (title now optional, was mandatory) + declareProperty("Title", "", boost::make_shared(), + "A title to describe the saved workspace"); + auto mustBePositive = boost::make_shared >(); + mustBePositive->setLower(0); + + declareProperty("WorkspaceIndexMin", 0, mustBePositive, + "Index number of first spectrum to write, only for single\n" + "period data."); + declareProperty("WorkspaceIndexMax", Mantid::EMPTY_INT(), mustBePositive, + "Index of last spectrum to write, only for single period\n" + "data."); + declareProperty(new ArrayProperty("WorkspaceIndexList"), + "List of spectrum numbers to read, only for single period\n" + "data."); + + declareProperty("Append", false, "Determines whether .nxs file needs to be\n" + "over written or appended"); + + declareProperty("PreserveEvents", true, + "For EventWorkspaces, preserve the events when saving (default).\n" + "If false, will save the 2D histogram version of the workspace with the current binning parameters."); + setPropertySettings("PreserveEvents", + new EnabledWhenWorkspaceIsType("InputWorkspace", true)); + + declareProperty("CompressNexus", false, + "For EventWorkspaces, compress the Nexus data field (default False).\n" + "This will make smaller files but takes much longer."); + setPropertySettings("CompressNexus", + new EnabledWhenWorkspaceIsType("InputWorkspace", true)); + } - /** Get the list of workspace indices to use - * - * @param spec :: returns the list of workspace indices - * @param matrixWorkspace :: pointer to a MatrixWorkspace - */ - void SaveNexusProcessed::getSpectrumList(std::vector & spec, MatrixWorkspace_const_sptr matrixWorkspace) - { - std::vector spec_list = getProperty("WorkspaceIndexList"); - int spec_min = getProperty("WorkspaceIndexMin"); - int spec_max = getProperty("WorkspaceIndexMax"); - const bool list = !spec_list.empty(); - const bool interval = (spec_max != Mantid::EMPTY_INT()); - if ( spec_max == Mantid::EMPTY_INT() ) spec_max = 0; - const int numberOfHist = static_cast(matrixWorkspace->getNumberHistograms()); - - if( interval ) + /** Get the list of workspace indices to use + * + * @param spec :: returns the list of workspace indices + * @param matrixWorkspace :: pointer to a MatrixWorkspace + */ + void SaveNexusProcessed::getSpectrumList(std::vector & spec, + MatrixWorkspace_const_sptr matrixWorkspace) { - if ( spec_max < spec_min || spec_max > numberOfHist-1 ) + std::vector spec_list = getProperty("WorkspaceIndexList"); + int spec_min = getProperty("WorkspaceIndexMin"); + int spec_max = getProperty("WorkspaceIndexMax"); + const bool list = !spec_list.empty(); + const bool interval = (spec_max != Mantid::EMPTY_INT()); + if (spec_max == Mantid::EMPTY_INT()) + spec_max = 0; + const int numberOfHist = static_cast(matrixWorkspace->getNumberHistograms()); + + if (interval) { - g_log.error("Invalid WorkspaceIndex min/max properties"); - throw std::invalid_argument("Inconsistent properties defined"); + if (spec_max < spec_min || spec_max > numberOfHist - 1) + { + g_log.error("Invalid WorkspaceIndex min/max properties"); + throw std::invalid_argument("Inconsistent properties defined"); + } + spec.reserve(1 + spec_max - spec_min); + for (int i = spec_min; i <= spec_max; i++) + spec.push_back(i); + if (list) + { + for (size_t i = 0; i < spec_list.size(); i++) + { + int s = spec_list[i]; + if (s < 0) + continue; + if (s < spec_min || s > spec_max) + spec.push_back(s); + } + } } - spec.reserve(1+spec_max-spec_min); - for(int i=spec_min;i<=spec_max;i++) - spec.push_back(i); - if (list) + else if (list) { - for(size_t i=0;i spec_max) - spec.push_back(s); + if (s < 0) + continue; + spec.push_back(s); + if (s > spec_max) + spec_max = s; + if (s < spec_min) + spec_min = s; } } - } - else if (list) - { - spec_max=0; - spec_min=numberOfHist-1; - for(size_t i=0;i spec_max) spec_max = s; - if (s < spec_min) spec_min = s; + spec_min = 0; + spec_max = numberOfHist - 1; + spec.reserve(1 + spec_max - spec_min); + for (int i = spec_min; i <= spec_max; i++) + spec.push_back(i); } } - else - { - spec_min=0; - spec_max=numberOfHist-1; - spec.reserve(1+spec_max-spec_min); - for(int i=spec_min;i<=spec_max;i++) - spec.push_back(i); - } - } - - - - //----------------------------------------------------------------------------------------------- - /** Executes the algorithm. - * - * @throw runtime_error Thrown if algorithm cannot execute - */ - void SaveNexusProcessed::exec() - { - //TODO: Remove? - NXMEnableErrorReporting(); - - Workspace_sptr inputWorkspace = getProperty("InputWorkspace"); - - // Retrieve the filename from the properties - m_filename = getPropertyValue("Filename"); - //m_entryname = getPropertyValue("EntryName"); - m_title = getPropertyValue("Title"); - // Do we prserve events? - bool PreserveEvents = getProperty("PreserveEvents"); - - MatrixWorkspace_const_sptr matrixWorkspace = boost::dynamic_pointer_cast(inputWorkspace); - ITableWorkspace_const_sptr tableWorkspace = boost::dynamic_pointer_cast(inputWorkspace); - PeaksWorkspace_const_sptr peaksWorkspace = boost::dynamic_pointer_cast(inputWorkspace); - OffsetsWorkspace_const_sptr offsetsWorkspace = boost::dynamic_pointer_cast(inputWorkspace); - if(peaksWorkspace) g_log.debug("We have a peaks workspace"); - // check if inputWorkspace is something we know how to save - if (!matrixWorkspace && !tableWorkspace) { - // get the workspace name for the error message - std::string name = getProperty("InputWorkspace"); - - // md workspaces should be saved using SaveMD - if (bool(boost::dynamic_pointer_cast(inputWorkspace)) - || bool(boost::dynamic_pointer_cast(inputWorkspace))) - g_log.warning() << name << " can be saved using SaveMD\n"; - - // standard error message - std::stringstream msg; - msg << "Workspace \"" << name << "\" not saved because it is not of a type we can presently save."; - - throw std::runtime_error(msg.str()); - } - m_eventWorkspace = boost::dynamic_pointer_cast(matrixWorkspace); - const std::string workspaceID = inputWorkspace->id(); - if ((workspaceID.find("Workspace2D") == std::string::npos) && - (workspaceID.find("RebinnedOutput") == std::string::npos) && - !m_eventWorkspace && !tableWorkspace && !offsetsWorkspace) - throw Exception::NotImplementedError("SaveNexusProcessed passed invalid workspaces. Must be Workspace2D, EventWorkspace, ITableWorkspace, or OffsetsWorkspace."); - - // Create progress object for initial part - depends on whether events are processed - if( PreserveEvents && m_eventWorkspace) - { - m_timeProgInit = 0.07; // Events processed 0.05 to 1.0 - } - else - { - m_timeProgInit = 1.0; // All work is done in the initial part - } - Progress prog_init(this, 0.0, m_timeProgInit, 7); - - // If no title's been given, use the workspace title field - if (m_title.empty()) - m_title = inputWorkspace->getTitle(); - - //get the workspace name to write to file - std::string wsName = inputWorkspace->getName(); - // If we don't want to append then remove the file if it already exists - bool append_to_file = getProperty("Append"); - if( !append_to_file ) + void SaveNexusProcessed::doExec(Workspace_sptr inputWorkspace, + Mantid::NeXus::NexusFileIO_sptr& nexusFile, const bool keepFile, optional_size_t entryNumber) { - Poco::File file(m_filename); - if( file.exists() ) - file.remove(); - } - // Then immediately open the file - Mantid::NeXus::NexusFileIO *nexusFile= new Mantid::NeXus::NexusFileIO( &prog_init ); - - nexusFile->openNexusWrite( m_filename ); - - // Equivalent C++ API handle - ::NeXus::File * cppFile = new ::NeXus::File(nexusFile->fileID); - - prog_init.reportIncrement(1, "Opening file"); - if( nexusFile->writeNexusProcessedHeader( m_title, wsName) != 0 ) - throw Exception::FileError("Failed to write to file", m_filename); - - prog_init.reportIncrement(1, "Writing header"); - - // write instrument data, if present and writer enabled - if (matrixWorkspace) - { - // Save the instrument names, ParameterMap, sample, run - matrixWorkspace->saveExperimentInfoNexus(cppFile); - prog_init.reportIncrement(1, "Writing sample and instrument"); + //TODO: Remove? + NXMEnableErrorReporting(); + + // Retrieve the filename from the properties + m_filename = getPropertyValue("Filename"); + //m_entryname = getPropertyValue("EntryName"); + m_title = getPropertyValue("Title"); + // Do we prserve events? + bool PreserveEvents = getProperty("PreserveEvents"); + + MatrixWorkspace_const_sptr matrixWorkspace = boost::dynamic_pointer_cast( + inputWorkspace); + ITableWorkspace_const_sptr tableWorkspace = boost::dynamic_pointer_cast( + inputWorkspace); + PeaksWorkspace_const_sptr peaksWorkspace = boost::dynamic_pointer_cast( + inputWorkspace); + OffsetsWorkspace_const_sptr offsetsWorkspace = boost::dynamic_pointer_cast( + inputWorkspace); + if (peaksWorkspace) + g_log.debug("We have a peaks workspace"); + // check if inputWorkspace is something we know how to save + if (!matrixWorkspace && !tableWorkspace) + { + // get the workspace name for the error message + std::string name = getProperty("InputWorkspace"); - // check if all X() are in fact the same array - const bool uniformSpectra = API::WorkspaceHelpers::commonBoundaries(matrixWorkspace); + // md workspaces should be saved using SaveMD + if (bool(boost::dynamic_pointer_cast(inputWorkspace)) + || bool(boost::dynamic_pointer_cast(inputWorkspace))) + g_log.warning() << name << " can be saved using SaveMD\n"; - // Retrieve the workspace indices (from params) - std::vector spec; - this->getSpectrumList(spec, matrixWorkspace); + // standard error message + std::stringstream msg; + msg << "Workspace \"" << name + << "\" not saved because it is not of a type we can presently save."; - prog_init.reportIncrement(1, "Writing data"); - // Write out the data (2D or event) - if (m_eventWorkspace && PreserveEvents) - { - this->execEvent(nexusFile,uniformSpectra,spec); + throw std::runtime_error(msg.str()); } - else if (offsetsWorkspace) + m_eventWorkspace = boost::dynamic_pointer_cast(matrixWorkspace); + const std::string workspaceID = inputWorkspace->id(); + if ((workspaceID.find("Workspace2D") == std::string::npos) + && (workspaceID.find("RebinnedOutput") == std::string::npos) && !m_eventWorkspace + && !tableWorkspace && !offsetsWorkspace) + throw Exception::NotImplementedError( + "SaveNexusProcessed passed invalid workspaces. Must be Workspace2D, EventWorkspace, ITableWorkspace, or OffsetsWorkspace."); + + // Create progress object for initial part - depends on whether events are processed + if (PreserveEvents && m_eventWorkspace) { - g_log.warning() << "Writing SpecialWorkspace2D ID=" << workspaceID << "\n"; - nexusFile->writeNexusProcessedData2D(matrixWorkspace,uniformSpectra,spec, "offsets_workspace", true); + m_timeProgInit = 0.07; // Events processed 0.05 to 1.0 } else { - nexusFile->writeNexusProcessedData2D(matrixWorkspace,uniformSpectra,spec, "workspace", true); + m_timeProgInit = 1.0; // All work is done in the initial part } + Progress prog_init(this, 0.0, m_timeProgInit, 7); + + // If no title's been given, use the workspace title field + if (m_title.empty()) + m_title = inputWorkspace->getTitle(); - // MW 27/10/10 - don't try and save the spectra-detector map if there isn't one - if ( matrixWorkspace->getAxis(1)->isSpectra() ) + //get the workspace name to write to file + std::string wsName = inputWorkspace->getName(); + + // If we don't want to append then remove the file if it already exists + bool append_to_file = getProperty("Append"); + if (!append_to_file && !keepFile) { - cppFile->openGroup("instrument", "NXinstrument"); - matrixWorkspace->saveSpectraMapNexus(cppFile, spec, ::NeXus::LZW); - cppFile->closeGroup(); + Poco::File file(m_filename); + if (file.exists()) + file.remove(); } - } // finish matrix workspace specifics + nexusFile->resetProgress(&prog_init); + nexusFile->openNexusWrite(m_filename, entryNumber); + // Equivalent C++ API handle + ::NeXus::File * cppFile = new ::NeXus::File(nexusFile->fileID); + prog_init.reportIncrement(1, "Opening file"); + if (nexusFile->writeNexusProcessedHeader(m_title, wsName) != 0) + throw Exception::FileError("Failed to write to file", m_filename); - if (peaksWorkspace) - { - // Save the instrument names, ParameterMap, sample, run - peaksWorkspace->saveExperimentInfoNexus(cppFile); - prog_init.reportIncrement(1, "Writing sample and instrument"); - } + prog_init.reportIncrement(1, "Writing header"); + // write instrument data, if present and writer enabled + if (matrixWorkspace) + { + // Save the instrument names, ParameterMap, sample, run + matrixWorkspace->saveExperimentInfoNexus(cppFile); + prog_init.reportIncrement(1, "Writing sample and instrument"); - // peaks workspace specifics - if (peaksWorkspace) - { - // g_log.information("Peaks Workspace saving to Nexus would be done"); - // int pNum = peaksWorkspace->getNumberPeaks(); - peaksWorkspace->saveNexus( cppFile ); + // check if all X() are in fact the same array + const bool uniformSpectra = API::WorkspaceHelpers::commonBoundaries(matrixWorkspace); + // Retrieve the workspace indices (from params) + std::vector spec; + this->getSpectrumList(spec, matrixWorkspace); + prog_init.reportIncrement(1, "Writing data"); + // Write out the data (2D or event) + if (m_eventWorkspace && PreserveEvents) + { + this->execEvent(nexusFile.get(), uniformSpectra, spec); + } + else if (offsetsWorkspace) + { + g_log.warning() << "Writing SpecialWorkspace2D ID=" << workspaceID << "\n"; + nexusFile->writeNexusProcessedData2D(matrixWorkspace, uniformSpectra, spec, + "offsets_workspace", true); + } + else + { + nexusFile->writeNexusProcessedData2D(matrixWorkspace, uniformSpectra, spec, "workspace", true); + } - } // finish peaks workspace specifics - else if (tableWorkspace) // Table workspace specifics - { - nexusFile->writeNexusTableWorkspace(tableWorkspace,"table_workspace"); - } // finish table workspace specifics - - // Switch to the Cpp API for the algorithm history - if (trackingHistory()) - { - m_history->fillAlgorithmHistory(this, Mantid::Kernel::DateAndTime::getCurrentTime(), -1, Algorithm::g_execCount); - if (!isChild()) - { - inputWorkspace->history().addHistory(m_history); - } - //this is a child algorithm, but we still want to keep the history. - else if (isRecordingHistoryForChild() && m_parentHistory) + // MW 27/10/10 - don't try and save the spectra-detector map if there isn't one + if (matrixWorkspace->getAxis(1)->isSpectra()) + { + cppFile->openGroup("instrument", "NXinstrument"); + matrixWorkspace->saveSpectraMapNexus(cppFile, spec, ::NeXus::LZW); + cppFile->closeGroup(); + } + + } // finish matrix workspace specifics + + if (peaksWorkspace) { - m_parentHistory->addChildHistory(m_history); + // Save the instrument names, ParameterMap, sample, run + peaksWorkspace->saveExperimentInfoNexus(cppFile); + prog_init.reportIncrement(1, "Writing sample and instrument"); } - } - - inputWorkspace->history().saveNexus(cppFile); - nexusFile->closeNexusFile(); - delete nexusFile; + // peaks workspace specifics + if (peaksWorkspace) + { + // g_log.information("Peaks Workspace saving to Nexus would be done"); + // int pNum = peaksWorkspace->getNumberPeaks(); + peaksWorkspace->saveNexus(cppFile); - return; - } + } // finish peaks workspace specifics + else if (tableWorkspace) // Table workspace specifics + { + nexusFile->writeNexusTableWorkspace(tableWorkspace, "table_workspace"); + } // finish table workspace specifics + // Switch to the Cpp API for the algorithm history + if (trackingHistory()) + { + m_history->fillAlgorithmHistory(this, Mantid::Kernel::DateAndTime::getCurrentTime(), -1, + Algorithm::g_execCount); + if (!isChild()) + { + inputWorkspace->history().addHistory(m_history); + } + //this is a child algorithm, but we still want to keep the history. + else if (isRecordingHistoryForChild() && m_parentHistory) + { + m_parentHistory->addChildHistory(m_history); + } + } - //------------------------------------------------------------------------------------- - /** Append out each field of a vector of events to separate array. - * - * @param events :: vector of TofEvent or WeightedEvent, etc. - * @param offset :: where the first event goes in the array - * @param tofs, weights, errorSquareds, pulsetimes :: arrays to write to. - * Must be initialized and big enough, - * or NULL if they are not meant to be written to. - */ - template - void SaveNexusProcessed::appendEventListData( std::vector events, size_t offset, double * tofs, float * weights, float * errorSquareds, int64_t * pulsetimes) - { - // Do nothing if there are no events. - if (events.empty()) + inputWorkspace->history().saveNexus(cppFile); + nexusFile->closeGroup(); return; + } - typename std::vector::const_iterator it; - typename std::vector::const_iterator it_end = events.end(); - size_t i = offset; - - // Fill the C-arrays with the fields from all the events, as requested. - for (it = events.begin(); it != it_end; it++) + //----------------------------------------------------------------------------------------------- + /** Executes the algorithm for a single workspace. + * + * @throw runtime_error Thrown if algorithm cannot execute + */ + void SaveNexusProcessed::exec() { - if (tofs) tofs[i] = it->tof(); - if (weights) weights[i] = static_cast(it->weight()); - if (errorSquareds) errorSquareds[i] = static_cast(it->errorSquared()); - if (pulsetimes) pulsetimes[i] = it->pulseTime().totalNanoseconds(); - i++; - } - } + Workspace_sptr inputWorkspace = getProperty("InputWorkspace"); + // Then immediately open the file + auto nexusFile = boost::make_shared(); + // Perform the execution. + doExec(inputWorkspace, nexusFile); + } - //----------------------------------------------------------------------------------------------- - /** Execute the saving of event data. - * This will make one long event list for all events contained. - * */ - void SaveNexusProcessed::execEvent(Mantid::NeXus::NexusFileIO * nexusFile,const bool uniformSpectra,const std::vector spec) - { - prog = new Progress(this, m_timeProgInit, 1.0, m_eventWorkspace->getNumberEvents()*2); + //------------------------------------------------------------------------------------- + /** Append out each field of a vector of events to separate array. + * + * @param events :: vector of TofEvent or WeightedEvent, etc. + * @param offset :: where the first event goes in the array + * @param tofs, weights, errorSquareds, pulsetimes :: arrays to write to. + * Must be initialized and big enough, + * or NULL if they are not meant to be written to. + */ + template + void SaveNexusProcessed::appendEventListData(std::vector events, size_t offset, double * tofs, + float * weights, float * errorSquareds, int64_t * pulsetimes) + { + // Do nothing if there are no events. + if (events.empty()) + return; - // Start by writing out the axes and crap - nexusFile->writeNexusProcessedData2D(m_eventWorkspace, uniformSpectra, spec, "event_workspace", false); + typename std::vector::const_iterator it; + typename std::vector::const_iterator it_end = events.end(); + size_t i = offset; - // Make a super long list of tofs, weights, etc. - std::vector indices; - indices.reserve( m_eventWorkspace->getNumberHistograms()+1 ); - // First we need to index the events in each spectrum - size_t index = 0; - for (int wi =0; wi < static_cast(m_eventWorkspace->getNumberHistograms()); wi++) - { - indices.push_back(index); - // Track the total # of events - index += m_eventWorkspace->getEventList(wi).getNumberEvents(); - } - indices.push_back(index); - - // Initialize all the arrays - int64_t num = index; - double * tofs = NULL; - float * weights = NULL; - float * errorSquareds = NULL; - int64_t * pulsetimes = NULL; - - // overall event type. - EventType type = m_eventWorkspace->getEventType(); - bool writeTOF = true; - bool writePulsetime = false; - bool writeWeight = false; - bool writeError = false; - - switch (type) - { - case TOF: - writePulsetime = true; - break; - case WEIGHTED: - writePulsetime = true; - writeWeight = true; - writeError = true; - break; - case WEIGHTED_NOTIME: - writeWeight = true; - writeError = true; - break; + // Fill the C-arrays with the fields from all the events, as requested. + for (it = events.begin(); it != it_end; it++) + { + if (tofs) + tofs[i] = it->tof(); + if (weights) + weights[i] = static_cast(it->weight()); + if (errorSquareds) + errorSquareds[i] = static_cast(it->errorSquared()); + if (pulsetimes) + pulsetimes[i] = it->pulseTime().totalNanoseconds(); + i++; + } } - // --- Initialize the combined event arrays ---- - if (writeTOF) - tofs = new double[num]; - if (writeWeight) - weights = new float[num]; - if (writeError) - errorSquareds = new float[num]; - if (writePulsetime) - pulsetimes = new int64_t[num]; - - // --- Fill in the combined event arrays ---- - PARALLEL_FOR_NO_WSP_CHECK() - for (int wi=0; wi < static_cast(m_eventWorkspace->getNumberHistograms()); wi++) + //----------------------------------------------------------------------------------------------- + /** Execute the saving of event data. + * This will make one long event list for all events contained. + * */ + void SaveNexusProcessed::execEvent(Mantid::NeXus::NexusFileIO * nexusFile, const bool uniformSpectra, + const std::vector spec) { - PARALLEL_START_INTERUPT_REGION - const DataObjects::EventList & el = m_eventWorkspace->getEventList(wi); - - // This is where it will land in the output array. - // It is okay to write in parallel since none should step on each other. - size_t offset = indices[wi]; + prog = new Progress(this, m_timeProgInit, 1.0, m_eventWorkspace->getNumberEvents() * 2); + + // Start by writing out the axes and crap + nexusFile->writeNexusProcessedData2D(m_eventWorkspace, uniformSpectra, spec, "event_workspace", + false); + + // Make a super long list of tofs, weights, etc. + std::vector indices; + indices.reserve(m_eventWorkspace->getNumberHistograms() + 1); + // First we need to index the events in each spectrum + size_t index = 0; + for (int wi = 0; wi < static_cast(m_eventWorkspace->getNumberHistograms()); wi++) + { + indices.push_back(index); + // Track the total # of events + index += m_eventWorkspace->getEventList(wi).getNumberEvents(); + } + indices.push_back(index); - switch (el.getEventType()) + // Initialize all the arrays + int64_t num = index; + double * tofs = NULL; + float * weights = NULL; + float * errorSquareds = NULL; + int64_t * pulsetimes = NULL; + + // overall event type. + EventType type = m_eventWorkspace->getEventType(); + bool writeTOF = true; + bool writePulsetime = false; + bool writeWeight = false; + bool writeError = false; + + switch (type) { case TOF: - appendEventListData( el.getEvents(), offset, tofs, weights, errorSquareds, pulsetimes); + writePulsetime = true; break; case WEIGHTED: - appendEventListData( el.getWeightedEvents(), offset, tofs, weights, errorSquareds, pulsetimes); + writePulsetime = true; + writeWeight = true; + writeError = true; break; case WEIGHTED_NOTIME: - appendEventListData( el.getWeightedEventsNoTime(), offset, tofs, weights, errorSquareds, pulsetimes); + writeWeight = true; + writeError = true; break; } - prog->reportIncrement(el.getNumberEvents(), "Copying EventList"); + + // --- Initialize the combined event arrays ---- + if (writeTOF) + tofs = new double[num]; + if (writeWeight) + weights = new float[num]; + if (writeError) + errorSquareds = new float[num]; + if (writePulsetime) + pulsetimes = new int64_t[num]; + + // --- Fill in the combined event arrays ---- + PARALLEL_FOR_NO_WSP_CHECK() + for (int wi = 0; wi < static_cast(m_eventWorkspace->getNumberHistograms()); wi++) + { + PARALLEL_START_INTERUPT_REGION + const DataObjects::EventList & el = m_eventWorkspace->getEventList(wi); + + // This is where it will land in the output array. + // It is okay to write in parallel since none should step on each other. + size_t offset = indices[wi]; + + switch (el.getEventType()) + { + case TOF: + appendEventListData(el.getEvents(), offset, tofs, weights, errorSquareds, pulsetimes); + break; + case WEIGHTED: + appendEventListData(el.getWeightedEvents(), offset, tofs, weights, errorSquareds, pulsetimes); + break; + case WEIGHTED_NOTIME: + appendEventListData(el.getWeightedEventsNoTime(), offset, tofs, weights, errorSquareds, + pulsetimes); + break; + } + prog->reportIncrement(el.getNumberEvents(), "Copying EventList"); PARALLEL_END_INTERUPT_REGION } @@ -459,14 +481,14 @@ namespace DataHandling bool CompressNexus = getProperty("CompressNexus"); // Write out to the NXS file. - nexusFile->writeNexusProcessedDataEventCombined(m_eventWorkspace, indices, tofs, weights, errorSquareds, pulsetimes, - CompressNexus); + nexusFile->writeNexusProcessedDataEventCombined(m_eventWorkspace, indices, tofs, weights, + errorSquareds, pulsetimes, CompressNexus); // Free mem. - delete [] tofs; - delete [] weights; - delete [] errorSquareds; - delete [] pulsetimes; + delete[] tofs; + delete[] weights; + delete[] errorSquareds; + delete[] pulsetimes; } //----------------------------------------------------------------------------------------------- @@ -476,16 +498,63 @@ namespace DataHandling * @param propertyValue :: value of the property * @param perioidNum :: period number */ - void SaveNexusProcessed::setOtherProperties(IAlgorithm* alg,const std::string& propertyName,const std::string& propertyValue,int perioidNum) + void SaveNexusProcessed::setOtherProperties(IAlgorithm* alg, const std::string& propertyName, + const std::string& propertyValue, int perioidNum) { - if(!propertyName.compare("Append")) - { if(perioidNum!=1) - { alg->setPropertyValue(propertyName,"1"); - } - else alg->setPropertyValue(propertyName,propertyValue); + if (!propertyName.compare("Append")) + { + if (perioidNum != 1) + { + alg->setPropertyValue(propertyName, "1"); + } + else + alg->setPropertyValue(propertyName, propertyValue); } else - Algorithm::setOtherProperties(alg,propertyName,propertyValue,perioidNum); + Algorithm::setOtherProperties(alg, propertyName, propertyValue, perioidNum); + } + + /** + Overriden process groups. + */ + bool SaveNexusProcessed::processGroups() + { + // Then immediately open the file + auto nexusFile = boost::make_shared(); + + /* Unless we have explicity been asked to append to the file. We should assume that we can remove any existing + files of the same name prior to processing. */ + bool append_to_file = this->getProperty("Append"); + if (!append_to_file) + { + const std::string filename = getPropertyValue("Filename"); + Poco::File file(filename); + if (file.exists()) + { + file.remove(); + } + } + + // Only the input workspace property can take group workspaces. Therefore index = 0. + std::vector & thisGroup = m_groups[0]; + if (!thisGroup.empty()) + { + for (size_t entry = 0; entry < m_groupSize; entry++) + { + Workspace_sptr ws = thisGroup[entry]; + this->doExec(ws, nexusFile, true /*keepFile*/, entry); + std::stringstream buffer; + buffer << "Saving group index " << entry; + m_log.information(buffer.str()); + } + } + + nexusFile->closeNexusFile(); + // We finished successfully. + setExecuted(true); + notificationCenter().postNotification(new FinishedNotification(this, isExecuted())); + + return true; } } // namespace DataHandling diff --git a/Code/Mantid/Framework/DataHandling/src/SavePDFGui.cpp b/Code/Mantid/Framework/DataHandling/src/SavePDFGui.cpp new file mode 100644 index 000000000000..4e04a0b01da9 --- /dev/null +++ b/Code/Mantid/Framework/DataHandling/src/SavePDFGui.cpp @@ -0,0 +1,133 @@ +#include "MantidDataHandling/SavePDFGui.h" +#include "MantidAPI/FileProperty.h" +#include "MantidKernel/MantidVersion.h" +#include +#include + +namespace Mantid +{ +namespace DataHandling +{ + + using Mantid::Kernel::Direction; + using Mantid::API::WorkspaceProperty; + + // Register the algorithm into the AlgorithmFactory + DECLARE_ALGORITHM(SavePDFGui) + + + + //---------------------------------------------------------------------------------------------- + /** Constructor + */ + SavePDFGui::SavePDFGui() + { + } + + //---------------------------------------------------------------------------------------------- + /** Destructor + */ + SavePDFGui::~SavePDFGui() + { + } + + + //---------------------------------------------------------------------------------------------- + + ///Algorithm's name for identification. @see Algorithm::name + const std::string SavePDFGui::name() const + { + return "SavePDFGui"; + } + + /// Algorithm's version for identification. @see Algorithm::version + int SavePDFGui::version() const + { + return 1; + } + + /// Algorithm's category for identification. @see Algorithm::category + const std::string SavePDFGui::category() const + { + return "DataHandling"; + } + + /// Algorithm's summary for use in the GUI and help. @see Algorithm::summary + const std::string SavePDFGui::summary() const + { + return "Save files readable by PDFGui"; + } + + //---------------------------------------------------------------------------------------------- + /** Initialize the algorithm's properties. + */ + void SavePDFGui::init() + { + declareProperty(new WorkspaceProperty<>("InputWorkspace","",Direction::Input), "An input workspace."); + declareProperty(new API::FileProperty("Filename", "", API::FileProperty::Save, ".gr"), + "The filename to use for the saved data"); + } + + /// @copydoc Algorithm::validateInputs + std::map SavePDFGui::validateInputs(){ + std::map result; + + // check for null pointers - this is to protect against workspace groups + API::MatrixWorkspace_const_sptr inputWS = getProperty("InputWorkspace"); + if (!inputWS){ + return result; + } + + const int nHist = static_cast (inputWS->getNumberHistograms()); + if (nHist != 1) + { + result["InputWorkspace"] = "Workspace must contain only one spectrum"; + } + else if (std::string(inputWS->getAxis(0)->unit()->label()) != "Angstrom") + { + result["InputWorkspace"] = "Expected x-units of Angstrom"; + } + + return result; + } + + //---------------------------------------------------------------------------------------------- + /** Execute the algorithm. + */ + void SavePDFGui::exec() + { + API::MatrixWorkspace_const_sptr inputWS = getProperty("InputWorkspace"); + const std::string filename = getProperty("Filename"); + + // --------- open the file + std::ofstream out; + out.open(filename.c_str(), std::ios_base::out); + + // --------- write the header // TODO + + // --------- write the label for the data + out << "##### start data\n"; + //out << "#O0 rg_int sig_rg_int low_int sig_low_int rmax rhofit\n"; // TODO + out << "#S 1 - PDF from Mantid " << Kernel::MantidVersion::version() << "\n"; + //out << "#P0 -22.03808 1.10131 2556.26392 0.03422 1.50 0.5985\n"; // TODO + out << "#L r G(r) dr dG(r)\n"; + + // --------- write the data + auto x = inputWS->readX(0); + auto dx = inputWS->readDx(0); + auto y = inputWS->readY(0); + auto dy = inputWS->readE(0); + const size_t length = x.size(); + for (size_t i = 0; i < length; ++i) + { + out << " " << x[i] << " " << y[i] << " " << dx[i] << " " << dy[i] << "\n"; + } + + // --------- close the file + out.close(); + } + + + +} // namespace DataHandling +} // namespace Mantid diff --git a/Code/Mantid/Framework/DataHandling/src/SaveParameterFile.cpp b/Code/Mantid/Framework/DataHandling/src/SaveParameterFile.cpp index 0a5dfd20dc8b..690eb5a44961 100644 --- a/Code/Mantid/Framework/DataHandling/src/SaveParameterFile.cpp +++ b/Code/Mantid/Framework/DataHandling/src/SaveParameterFile.cpp @@ -6,12 +6,7 @@ #include "MantidGeometry/Instrument/ParameterMap.h" #include - -#include -#include -#include -#include -#include +#include #include @@ -83,115 +78,151 @@ namespace DataHandling const Instrument_const_sptr instrument = ws->getInstrument(); const ParameterMap_sptr params = instrument->getParameterMap(); - //Map of component ids to their respective XML Elements - std::map > compMap; + //maps components to a tuple of parameters' name, type, and value + std::map > > toSave; - //Set up the XML document - XML::AutoPtr xmlDoc = new XML::Document; - XML::AutoPtr rootElem = xmlDoc->createElement("parameter-file"); - rootElem->setAttribute("instrument", instrument->getName()); - rootElem->setAttribute("valid-from", instrument->getValidFromDate().toISO8601String()); - xmlDoc->appendChild(rootElem); + //Set up a progress bar + Progress prog(this, 0.0, 0.3, params->size()); - //Iterate through all the parameters set for the instrument and build an XML - //document out of it. + //Build a list of parameters to save; for(auto paramsIt = params->begin(); paramsIt != params->end(); ++paramsIt) { - //Component data - const ComponentID cID = (*paramsIt).first; - const std::string cFullName = cID->getFullName(); - const IDetector* cDet = dynamic_cast(cID); - const detid_t cDetID = (cDet) ? cDet->getID() : 0; - const std::string cDetIDStr = boost::lexical_cast(cDetID); - - //Parameter data - const std::string pName = (*paramsIt).second->name(); - const std::string pType = (*paramsIt).second->type(); + if(prog.hasCancellationBeenRequested()) + break; + prog.report("Generating parameters"); + const ComponentID cID = (*paramsIt).first; + const std::string pName = (*paramsIt).second->name(); + const std::string pType = (*paramsIt).second->type(); const std::string pValue = (*paramsIt).second->asString(); - //Skip rot and pos according to: http://www.mantidproject.org/IDF#Using_.3Cparameter.3E - if(pName == "pos" || pName == "rot") + if(pName == "x" || pName == "y" || pName == "z" || + pName == "r-position" || pName == "t-position" || pName == "p-position" || + pName == "rotx" || pName == "roty" || pName == "rotz" ) + { + g_log.warning() << "The parameter name '" << pName << "' is reserved and has not been saved. " + << "Please contact the Mantid team for more information."; continue; + } - //If save location parameters is not enabled, skip any location parameters - if(!saveLocationParams) + //If it isn't a position or rotation parameter, we can just add it to the list to save directly and move on. + if(pName != "pos" && pName != "rot") { - if( pName == "x" || pName == "y" || pName == "z" || - pName == "r-position" || pName == "t-position" || pName == "p-position" || - pName == "rotx" || pName == "roty" || pName == "rotz") + if(pType == "fitting") { - continue; + //With fitting parameters we do something special (i.e. silly) + //We create an entire XML element to be inserted into the output, instead of just giving a single fixed value + const FitParameter& fitParam = paramsIt->second->value(); + const std::string fpName = fitParam.getFunction() + ":" + fitParam.getName(); + std::stringstream fpValue; + fpValue << ""; + toSave[cID].push_back(boost::make_tuple(fpName, "fitting", fpValue.str())); } + else + toSave[cID].push_back(boost::make_tuple(pName, pType, pValue)); } + } - //A component-link element - XML::AutoPtr compElem = 0; - - /* If an element already exists for a component with this name, re-use it. - * - * Why are we using an std::map and not simply traversing the DOM? Because - * the interface for doing that is painful and horrible to use, and this is - * probably faster (but negligably so in this case). - * - * And lastly, because Poco::XML::NodeList::length() segfaults. - */ - auto compIt = compMap.find(cID); - if(compIt != compMap.end()) - { - compElem = (*compIt).second; - } + std::vector components; + //If we're saving location parameters we'll check every component to see if its location has been changed + if(saveLocationParams) + { + //Get all the components in the instrument + instrument->getChildren(components, true); + prog.resetNumSteps((int64_t)components.size(), 0.3, 0.6); - //One doesn't already exist? Make a new one. - if(!compElem) + for(auto cIt = components.begin(); cIt != components.end(); ++cIt) { - compElem = xmlDoc->createElement("component-link"); - rootElem->appendChild(compElem); - compMap[cID] = compElem; + if(prog.hasCancellationBeenRequested()) + break; + prog.report("Generating location parameters"); + const IComponent* comp = cIt->get(); + const IComponent* baseComp = comp->getBaseComponent(); + const ComponentID cID = const_cast(comp); + + //Check if the position has been changed by a parameter + //If so, check each axis and add the relevant adjustment parameters to the to-save list. + const V3D basePos = baseComp->getPos(); + const V3D absPos = comp->getPos(); + const V3D posDiff = absPos - basePos; + + const double threshold = 0.0001; + + if(std::abs(posDiff.X()) > threshold) + toSave[cID].push_back(boost::make_tuple("x", "double", Strings::toString(absPos.X()))); + if(std::abs(posDiff.Y()) > threshold) + toSave[cID].push_back(boost::make_tuple("y", "double", Strings::toString(absPos.Y()))); + if(std::abs(posDiff.Z()) > threshold) + toSave[cID].push_back(boost::make_tuple("z", "double", Strings::toString(absPos.Z()))); + + //Check if the rotation has been changed by a parameter + //If so, convert to Euler (XYZ order) and output each component that differs + const Quat baseRot = baseComp->getRotation(); + const Quat absRot = comp->getRotation(); + + if(baseRot != absRot) + { + //Euler rotation components are not independent so write them all out to be safe. + std::vector absEuler = absRot.getEulerAngles("XYZ"); + toSave[cID].push_back(boost::make_tuple("rotx", "double", Strings::toString(absEuler[0]))); + toSave[cID].push_back(boost::make_tuple("roty", "double", Strings::toString(absEuler[1]))); + toSave[cID].push_back(boost::make_tuple("rotz", "double", Strings::toString(absEuler[2]))); + } } + } - //Create the parameter and value elements - XML::AutoPtr paramElem = xmlDoc->createElement("parameter"); - XML::AutoPtr valueElem = xmlDoc->createElement("value"); + //Begin writing the XML manually + std::ofstream file(filename.c_str(), std::ofstream::trunc); + file << "\n"; + file << "getName() << "\""; + file << " valid-from=\"" << instrument->getValidFromDate().toISO8601String() << "\">\n"; - //Set the attributes - compElem->setAttribute("name", cFullName); + prog.resetNumSteps((int64_t)toSave.size(), 0.6, 1.0); + //Iterate through all the parameters we want to save and build an XML document out of them. + for(auto compIt = toSave.begin(); compIt != toSave.end(); ++compIt) + { + if(prog.hasCancellationBeenRequested()) + break; + prog.report("Saving parameters"); + //Component data + const ComponentID cID = compIt->first; + const std::string cFullName = cID->getFullName(); + const IDetector* cDet = dynamic_cast(cID); + const detid_t cDetID = (cDet) ? cDet->getID() : 0; - //If there is a valid detector id, include it - if(cDetID > 0) + file << " \n"; + for(auto paramIt = compIt->second.begin(); paramIt != compIt->second.end(); ++paramIt) { - compElem->setAttribute("id", cDetIDStr); - } + const std::string pName = paramIt->get<0>(); + const std::string pType = paramIt->get<1>(); + const std::string pValue = paramIt->get<2>(); - paramElem->setAttribute("name", pName); - - //For strings, we specify their type. - if(pType == "string") - { - paramElem->setAttribute("type", "string"); + //With fitting parameters, we're actually inserting an entire element, as constructed above + if(pType == "fitting") + { + file << " \n"; + file << " " << pValue << "\n"; + file << " \n"; + } + else + { + file << " \n"; + file << " \n"; + file << " \n"; + } } - - valueElem->setAttribute("val", pValue); - - //Insert the elements into the document - compElem->appendChild(paramElem); - paramElem->appendChild(valueElem); + file << " \n"; } + file << "\n"; - //Output the XMl document to the given file. - XML::DOMWriter writer; - writer.setOptions(XML::XMLWriter::PRETTY_PRINT | XML::XMLWriter::WRITE_XML_DECLARATION); - std::ofstream file(filename.c_str(), std::ofstream::trunc); - try - { - writer.writeNode(file, xmlDoc); - } - catch(Poco::Exception &e) - { - g_log.error() << "Error serializing XML for SaveParameterFile: " << e.displayText() << std::endl; - } file.flush(); file.close(); - } } // namespace Algorithms diff --git a/Code/Mantid/Framework/DataHandling/src/SaveReflTBL.cpp b/Code/Mantid/Framework/DataHandling/src/SaveReflTBL.cpp index 5b623ef210e4..5642859373ec 100644 --- a/Code/Mantid/Framework/DataHandling/src/SaveReflTBL.cpp +++ b/Code/Mantid/Framework/DataHandling/src/SaveReflTBL.cpp @@ -111,7 +111,8 @@ namespace Mantid //now add dq/q and scale from the first row in the group TableRow row = ws->getRow(rowNos[0]); writeVal(row.cell(5),file); - writeVal(row.cell(6),file, false, true); + std::string scaleStr = boost::lexical_cast(row.cell(6)); + writeVal(scaleStr, file, false, true); } //now do the same for the ungrouped @@ -130,7 +131,8 @@ namespace Mantid } //now add dq/q and scale writeVal(row.cell(5),file); - writeVal(row.cell(6),file, false, true); + std::string scaleStr = boost::lexical_cast(row.cell(6)); + writeVal(scaleStr, file, false, true); } file.close(); } diff --git a/Code/Mantid/Framework/DataHandling/src/SaveSPE.cpp b/Code/Mantid/Framework/DataHandling/src/SaveSPE.cpp index 348d66e37474..6aca5b736300 100644 --- a/Code/Mantid/Framework/DataHandling/src/SaveSPE.cpp +++ b/Code/Mantid/Framework/DataHandling/src/SaveSPE.cpp @@ -8,6 +8,7 @@ #include "Poco/File.h" #include #include +#include #include namespace Mantid @@ -23,7 +24,7 @@ namespace Mantid * @param stream :: the file object to write to * @param format :: C string that contains the text to be written to the stream. * @param ... :: Additional arguments to fill format specifiers - * @throws std::runtime_error :: throws when there is a problem writing to disk, ususally disk space or permissions based + * @throws std::runtime_error :: throws when there is a problem writing to disk, usually disk space or permissions based */ #define FPRINTF_WITH_EXCEPTION(stream, format, ... ) if (fprintf(stream, format, ##__VA_ARGS__) <= 0)\ {\ @@ -35,8 +36,8 @@ namespace Mantid using namespace API; ///@cond - const char NUM_FORM[] = "%10.3E"; - const char NUMS_FORM[] = "%10.3E%10.3E%10.3E%10.3E%10.3E%10.3E%10.3E%10.3E\n"; + const char NUM_FORM[] = "%-10.4G"; + const char NUMS_FORM[] = "%-10.4G%-10.4G%-10.4G%-10.4G%-10.4G%-10.4G%-10.4G%-10.4G\n"; static const char Y_HEADER[] = "### S(Phi,w)\n"; static const char E_HEADER[] = "### Errors\n"; ///@endcond @@ -53,7 +54,7 @@ namespace Mantid // Private member functions //--------------------------------------------------- /** - * Initialise the algorithm + * Initialize the algorithm */ void SaveSPE::init() { @@ -219,7 +220,7 @@ namespace Mantid spuriousSpectra.push_back(i); writeMaskFlags(outFile); } - // make regular progress reports and check for cancelling the algorithm + // make regular progress reports and check for canceling the algorithm if ( i % progStep == 0 ) { progress.report(); @@ -227,18 +228,49 @@ namespace Mantid } logMissingMasked(spuriousSpectra, nHist-nMasked, nMasked); } + /** method verifies if a spectra contains any NaN or Inf values and replaces these values with SPE-specified constants + @param inSignal :: the vector of the spectra signals + @param inErr :: the vector of the spectra errors + + @param Signal :: the vector of the verified spectra signals, containing masked values in place of NaN-s and Inf-S + @param Error :: the vector of the verified spectra errors, containing masked values in place of NaN-s and Inf-S of the correspondent signal + + */ + void SaveSPE::check_and_copy_spectra(const MantidVec &inSignal,const MantidVec &inErr,MantidVec &Signal,MantidVec &Error)const + { + if(Signal.size() != inSignal.size()) + { + Signal.resize(inSignal.size()); + Error.resize(inSignal.size()); + } + for(size_t i=0;ireadY(specIn),WS->readE(specIn),m_tSignal,m_tError); FPRINTF_WITH_EXCEPTION(outFile,"%s", Y_HEADER); - writeBins(WS->readY(specIn), outFile); + writeBins(m_tSignal, outFile); FPRINTF_WITH_EXCEPTION(outFile,"%s", E_HEADER); - writeBins(WS->readE(specIn), outFile); + writeBins(m_tError, outFile); } /** Write the mask flags for in a histogram entry * @param outFile :: the file object to write to @@ -251,12 +283,13 @@ namespace Mantid FPRINTF_WITH_EXCEPTION(outFile,"%s", E_HEADER); writeValue(MASK_ERROR, outFile); } - /** Write the the values in the array to the file in the correct format + /** Write the values in the array to the file in the correct format * @param Vs :: the array of values to write (must have length given by m_nbins) * @param outFile :: the file object to write to */ void SaveSPE::writeBins(const MantidVec &Vs, FILE * const outFile) const { + for(size_t j = NUM_PER_LINE-1; j < m_nBins; j+=NUM_PER_LINE) {// output a whole line of numbers at once FPRINTF_WITH_EXCEPTION(outFile,NUMS_FORM, @@ -271,8 +304,8 @@ namespace Mantid FPRINTF_WITH_EXCEPTION(outFile,"\n"); } } - /** Write the the value the file a number of times given by m_nbins - * @param value :: the value that will be writen continuely + /** Write the value the file a number of times given by m_nbins + * @param value :: the value that will be written continually * @param outFile :: the file object to write to */ void SaveSPE::writeValue(const double value, FILE * const outFile) const @@ -295,7 +328,7 @@ namespace Mantid * file * @param inds :: the indices of histograms whose detectors couldn't be found * @param nonMasked :: the number of histograms saved successfully - * @param masked :: the number of histograms for which mask values were writen + * @param masked :: the number of histograms for which mask values were written */ void SaveSPE::logMissingMasked(const std::vector &inds, const size_t nonMasked, const int masked) const { diff --git a/Code/Mantid/Framework/DataHandling/src/SetSampleMaterial.cpp b/Code/Mantid/Framework/DataHandling/src/SetSampleMaterial.cpp index 613d7da35b4e..6b3fd0ebc94a 100644 --- a/Code/Mantid/Framework/DataHandling/src/SetSampleMaterial.cpp +++ b/Code/Mantid/Framework/DataHandling/src/SetSampleMaterial.cpp @@ -60,9 +60,9 @@ namespace Mantid declareProperty("SampleNumberDensity", EMPTY_DBL(), mustBePositive, "Optional: This number density of the sample in number of formulas per cubic angstrom will be used instead of calculated"); declareProperty("ZParameter", EMPTY_DBL(), mustBePositive, - "Number of formulas in the unit cell needed for chemical formulas with more than 1 atom"); + "Number of atoms in the unit cell"); declareProperty("UnitCellVolume", EMPTY_DBL(), mustBePositive, - "Unit cell volume in Angstoms^3 needed for chemical formulas with more than 1 atom"); + "Unit cell volume in Angstoms^3. Will be calculated from the OrientedLattice if not supplied."); declareProperty("CoherentXSection", EMPTY_DBL(), mustBePositive, "Optional: This coherent cross-section for the sample material in barns will be used instead of tabulated"); declareProperty("IncoherentXSection", EMPTY_DBL(), mustBePositive, @@ -244,8 +244,10 @@ namespace Mantid mat.reset(new Material(chemicalSymbol, neutron, rho)); } - // set the material on workspace - expInfo->mutableSample().setMaterial(*mat); + // set the material but leave the geometry unchanged + auto shapeObject = expInfo->sample().getShape(); //copy + shapeObject.setMaterial(*mat); + expInfo->mutableSample().setShape(shapeObject); g_log.notice() << "Sample number density "; if (isEmpty(mat->numberDensity())) { diff --git a/Code/Mantid/Framework/DataHandling/test/LoadEventNexusTest.h b/Code/Mantid/Framework/DataHandling/test/LoadEventNexusTest.h index 9739246443c0..18b9221ff970 100644 --- a/Code/Mantid/Framework/DataHandling/test/LoadEventNexusTest.h +++ b/Code/Mantid/Framework/DataHandling/test/LoadEventNexusTest.h @@ -218,7 +218,35 @@ class LoadEventNexusTest : public CxxTest::TestSuite TSM_ASSERT("The min TOF in the workspace should be equal to or greater than the filtered cut-off", min >= filterStart); } - void test_Load_And_CompressEvents() + void test_partial_spectra_loading() + { + const std::string wsName = "test_partial_spectra_loading"; + std::vector specList; + specList.push_back(13); + specList.push_back(16); + specList.push_back(21); + specList.push_back(28); + + LoadEventNexus ld; + ld.initialize(); + ld.setPropertyValue("OutputWorkspace", wsName); + ld.setPropertyValue("Filename","CNCS_7860_event.nxs"); + ld.setProperty("SpectrumList", specList); + ld.setProperty("LoadLogs", false); // Time-saver + + TS_ASSERT( ld.execute() ); + + auto outWs = AnalysisDataService::Instance().retrieveWS(wsName); + + TSM_ASSERT("The number of spectra in the workspace should be equal to the spectra filtered", outWs->getNumberHistograms()==specList.size()); + TSM_ASSERT("Some spectra were not found in the workspace", outWs->getSpectrum(0)->getSpectrumNo()==13); + TSM_ASSERT("Some spectra were not found in the workspace", outWs->getSpectrum(1)->getSpectrumNo()==16); + TSM_ASSERT("Some spectra were not found in the workspace", outWs->getSpectrum(2)->getSpectrumNo()==21); + TSM_ASSERT("Some spectra were not found in the workspace", outWs->getSpectrum(3)->getSpectrumNo()==28); + + } + + void test_Load_And_CompressEvents() { Mantid::API::FrameworkManager::Instance(); LoadEventNexus ld; diff --git a/Code/Mantid/Framework/DataHandling/test/LoadFITSTest.h b/Code/Mantid/Framework/DataHandling/test/LoadFITSTest.h new file mode 100644 index 000000000000..73d34cf0209f --- /dev/null +++ b/Code/Mantid/Framework/DataHandling/test/LoadFITSTest.h @@ -0,0 +1,61 @@ +#ifndef LOADFITSTEST_H_ +#define LOADFITSTEST_H_ + +#include +#include "MantidDataHandling/LoadFITS.h" + +using namespace Mantid::API; +using namespace Mantid::DataHandling; +using namespace Mantid::Kernel; + +class LoadFITSTest : public CxxTest::TestSuite +{ +public: + void testInit() + { + TS_ASSERT_THROWS_NOTHING(algToBeTested.initialize()); + TS_ASSERT( algToBeTested.isInitialized() ); + + if ( !algToBeTested.isInitialized() ) algToBeTested.initialize(); + + outputSpace="LoadFITSTest"; + algToBeTested.setPropertyValue("OutputWorkspace", outputSpace); + + // Should fail because mandatory parameter has not been set + TS_ASSERT_THROWS(algToBeTested.execute(),std::runtime_error); + + inputFile = "FITS_small_01.fits,FITS_small_02.fits"; + algToBeTested.setPropertyValue("Filename", inputFile); + } + + void testPerformAssertions() + { + TS_ASSERT_THROWS_NOTHING(algToBeTested.execute()); + TS_ASSERT( algToBeTested.isExecuted() ); + // get workspace generated + MatrixWorkspace_sptr output = AnalysisDataService::Instance().retrieveWS(outputSpace); + TS_ASSERT_EQUALS( output->blocksize(), 2); // Number of time bins should equal number of files + TS_ASSERT_EQUALS( output->getNumberHistograms(), SPECTRA_COUNT); // Number of spectra + // Sum the two bins from the last spectra - should be 70400 + double sumY = output->readY(SPECTRA_COUNT-1)[0] + output->readY(SPECTRA_COUNT-1)[1]; + TS_ASSERT_EQUALS(sumY, 70400); + // Check the sum of the error values for the last spectra in each file - should be 375.183 + double sumE = output->readE(SPECTRA_COUNT-1)[0] + output->readE(SPECTRA_COUNT-1)[1]; + TS_ASSERT_LESS_THAN(abs(sumE-375.1830), 0.0001); // Include a small tolerance check with the assert - not exactly 375.183 + } + + void testSingleChunkSize() + { + algToBeTested.setPropertyValue("FileChunkSize", "1"); + testPerformAssertions(); + } + +private: + LoadFITS algToBeTested; + std::string inputFile; + std::string outputSpace; + const static size_t SPECTRA_COUNT = 262144; +}; + + +#endif \ No newline at end of file diff --git a/Code/Mantid/Framework/DataHandling/test/LoadILLReflectometryTest.h b/Code/Mantid/Framework/DataHandling/test/LoadILLReflectometryTest.h index e2211a2e4c06..7d5e1dec52db 100644 --- a/Code/Mantid/Framework/DataHandling/test/LoadILLReflectometryTest.h +++ b/Code/Mantid/Framework/DataHandling/test/LoadILLReflectometryTest.h @@ -21,7 +21,8 @@ class LoadILLReflectometryTest: public CxxTest::TestSuite { } LoadILLReflectometryTest() : - m_dataFile("ILLD17_111686.nxs") { + m_dataFile("ILLD17-161876-Ni.nxs") + { } void test_Init() { @@ -60,14 +61,13 @@ class LoadILLReflectometryTest: public CxxTest::TestSuite { double channelWidth = getPropertyFromRun(output, "channel_width"); TS_ASSERT_EQUALS(channelWidth, 57.0); - + double analyserAngle = getPropertyFromRun(output, "dan.value"); + TS_ASSERT_EQUALS(analyserAngle, 3.1909999847412109); if (!output) return; - // TODO: Check the results - // Remove workspace from the data service. AnalysisDataService::Instance().clear(); } diff --git a/Code/Mantid/Framework/DataHandling/test/LoadISISNexusTest.h b/Code/Mantid/Framework/DataHandling/test/LoadISISNexusTest.h index 7124eec12d54..9335317a294e 100644 --- a/Code/Mantid/Framework/DataHandling/test/LoadISISNexusTest.h +++ b/Code/Mantid/Framework/DataHandling/test/LoadISISNexusTest.h @@ -67,6 +67,77 @@ class LoadISISNexusTest : public CxxTest::TestSuite } public: + + void testExecMonSeparated() + { + Mantid::API::FrameworkManager::Instance(); + LoadISISNexus2 ld; + ld.initialize(); + ld.setPropertyValue("Filename","LOQ49886.nxs"); + ld.setPropertyValue("OutputWorkspace","outWS"); + ld.setPropertyValue("LoadMonitors","1"); // should read "Separate" + TS_ASSERT_THROWS_NOTHING(ld.execute()); + TS_ASSERT(ld.isExecuted()); + + + MatrixWorkspace_sptr ws = AnalysisDataService::Instance().retrieveWS("outWS"); + MatrixWorkspace_sptr mon_ws = AnalysisDataService::Instance().retrieveWS("outWS_monitors"); + + TS_ASSERT_EQUALS(ws->blocksize(),5); + TS_ASSERT_EQUALS(ws->getNumberHistograms(),17790); + + TS_ASSERT_EQUALS(mon_ws->blocksize(),5); + TS_ASSERT_EQUALS(mon_ws->getNumberHistograms(),2); + + // Two monitors which form two first spectra are excluded by load separately + + // spectrum with ID 5 is now spectrum N 3 as 2 monitors + TS_ASSERT_EQUALS(ws->readY(5-2)[1],1.); + TS_ASSERT_EQUALS(ws->getSpectrum(5-2)->getSpectrumNo(),6); + TS_ASSERT_EQUALS(*(ws->getSpectrum(5-2)->getDetectorIDs().begin()), 6); + // spectrum with ID 7 is now spectrum N 4 + TS_ASSERT_EQUALS(ws->readY(6-2)[0],1.); + TS_ASSERT_EQUALS(ws->getSpectrum(6-2)->getSpectrumNo(),7); + TS_ASSERT_EQUALS(*(ws->getSpectrum(6-2)->getDetectorIDs().begin()), 7); + // + TS_ASSERT_EQUALS(ws->readY(8-2)[3],1.); + + TS_ASSERT_EQUALS(mon_ws->readX(0)[0],5.); + TS_ASSERT_EQUALS(mon_ws->readX(0)[1],4005.); + TS_ASSERT_EQUALS(mon_ws->readX(0)[2],8005.); + + // these spectra are not loaded as above so their values are different (occasionally 0) + TS_ASSERT_EQUALS(mon_ws->readY(0)[1],0); + TS_ASSERT_EQUALS(mon_ws->readY(1)[0],0.); + TS_ASSERT_EQUALS(mon_ws->readY(0)[3],0.); + + + + const std::vector< Property* >& logs = mon_ws->run().getLogData(); + TS_ASSERT_EQUALS(logs.size(), 62); + + std::string header = mon_ws->run().getPropertyValueAsType("run_header"); + TS_ASSERT_EQUALS(86, header.size()); + TS_ASSERT_EQUALS("LOQ 49886 Team LOQ Quiet Count, ISIS Off, N 28-APR-2009 09:20:29 0.00", header); + + TimeSeriesProperty* slog = dynamic_cast*>(mon_ws->run().getLogData("icp_event")); + TS_ASSERT(slog); + std::string str = slog->value(); + TS_ASSERT_EQUALS(str.size(),1023); + TS_ASSERT_EQUALS(str.substr(0,37),"2009-Apr-28 09:20:29 CHANGE_PERIOD 1"); + + slog = dynamic_cast*>(mon_ws->run().getLogData("icp_debug")); + TS_ASSERT(slog); + TS_ASSERT_EQUALS(slog->size(),50); + + AnalysisDataService::Instance().remove("outWS"); + AnalysisDataService::Instance().remove("outWS_monitors"); + } + + + + + void testExec() { Mantid::API::FrameworkManager::Instance(); @@ -451,6 +522,119 @@ class LoadISISNexusTest : public CxxTest::TestSuite TS_ASSERT_THROWS_NOTHING( v1.initialize() ); TS_ASSERT_THROWS( v1.execute(), Exception::NotImplementedError) } + void testExecMonExcluded() + { + Mantid::API::FrameworkManager::Instance(); + LoadISISNexus2 ld; + ld.initialize(); + ld.setPropertyValue("Filename","LOQ49886.nxs"); + ld.setPropertyValue("OutputWorkspace","outWS"); + ld.setPropertyValue("LoadMonitors","0"); // should read "exclude" + TS_ASSERT_THROWS_NOTHING(ld.execute()); + TS_ASSERT(ld.isExecuted()); + + + MatrixWorkspace_sptr ws = AnalysisDataService::Instance().retrieveWS("outWS"); + TS_ASSERT_EQUALS(ws->blocksize(),5); + TS_ASSERT_EQUALS(ws->getNumberHistograms(),17790); + + // Two monitors which form two first spectra are excluded by load separately + + // spectrum with ID 5 is now spectrum N 3 as 2 monitors + TS_ASSERT_EQUALS(ws->readY(5-2)[1],1.); + TS_ASSERT_EQUALS(ws->getSpectrum(5-2)->getSpectrumNo(),6); + TS_ASSERT_EQUALS(*(ws->getSpectrum(5-2)->getDetectorIDs().begin()), 6); + // spectrum with ID 7 is now spectrum N 4 + TS_ASSERT_EQUALS(ws->readY(6-2)[0],1.); + TS_ASSERT_EQUALS(ws->getSpectrum(6-2)->getSpectrumNo(),7); + TS_ASSERT_EQUALS(*(ws->getSpectrum(6-2)->getDetectorIDs().begin()), 7); + // + TS_ASSERT_EQUALS(ws->readY(8-2)[3],1.); + + // spectrum with ID 9 is now spectrum N 6 + TS_ASSERT_EQUALS(ws->getSpectrum(8-2)->getSpectrumNo(),9); + TS_ASSERT_EQUALS(*(ws->getSpectrum(8-2)->getDetectorIDs().begin()), 9); + // spectrum with ID 14 is now spectrum N 11 + TS_ASSERT_EQUALS(ws->readY(13-2)[1],1.); + TS_ASSERT_EQUALS(ws->getSpectrum(13-2)->getSpectrumNo(),14); + TS_ASSERT_EQUALS(*(ws->getSpectrum(13-2)->getDetectorIDs().begin()), 14); + // spectrum with ID 18 is now spectrum N 15 + TS_ASSERT_EQUALS(ws->readY(17-2)[1],2.); + TS_ASSERT_EQUALS(ws->getSpectrum(17-2)->getSpectrumNo(),18); + TS_ASSERT_EQUALS(*(ws->getSpectrum(17-2)->getDetectorIDs().begin()), 18); + // spectrum with ID 19 is now spectrum N 16 + TS_ASSERT_EQUALS(ws->readY(18-2)[1],1.); + TS_ASSERT_EQUALS(ws->getSpectrum(18-2)->getSpectrumNo(),19); + TS_ASSERT_EQUALS(*(ws->getSpectrum(18-2)->getDetectorIDs().begin()), 19); + + + TS_ASSERT_EQUALS(ws->readY(33-2)[2],1.); + TS_ASSERT_EQUALS(ws->getSpectrum(33-2)->getSpectrumNo(),34); + TS_ASSERT_EQUALS(*(ws->getSpectrum(33-2)->getDetectorIDs().begin()), 34); + // + TS_ASSERT_EQUALS(ws->readY(34-2)[1],1.); + TS_ASSERT_EQUALS(ws->getSpectrum(34-2)->getSpectrumNo(),35); + TS_ASSERT_EQUALS(*(ws->getSpectrum(34-2)->getDetectorIDs().begin()), 35); + + TS_ASSERT_EQUALS(ws->readY(37-2)[3],1.); + TS_ASSERT_EQUALS(ws->readY(37-2)[4],1.); + TS_ASSERT_EQUALS(ws->getSpectrum(37-2)->getSpectrumNo(),38); + TS_ASSERT_EQUALS(*(ws->getSpectrum(37-2)->getDetectorIDs().begin()), 38); + + + TS_ASSERT_EQUALS(ws->getSpectrum(1234-2)->getDetectorIDs().size(), 1); + TS_ASSERT_EQUALS(*(ws->getSpectrum(1234-2)->getDetectorIDs().begin()), 1235); + + TS_ASSERT_EQUALS(ws->getSpectrum(1234-2)->getSpectrumNo(), 1235 ); + TS_ASSERT(ws->getSpectrum(1234-2)->hasDetectorID(1235) ); + + const std::vector< Property* >& logs = ws->run().getLogData(); + TS_ASSERT_EQUALS(logs.size(), 62); + + std::string header = ws->run().getPropertyValueAsType("run_header"); + TS_ASSERT_EQUALS(86, header.size()); + TS_ASSERT_EQUALS("LOQ 49886 Team LOQ Quiet Count, ISIS Off, N 28-APR-2009 09:20:29 0.00", header); + + TimeSeriesProperty* slog = dynamic_cast*>(ws->run().getLogData("icp_event")); + TS_ASSERT(slog); + std::string str = slog->value(); + TS_ASSERT_EQUALS(str.size(),1023); + TS_ASSERT_EQUALS(str.substr(0,37),"2009-Apr-28 09:20:29 CHANGE_PERIOD 1"); + + slog = dynamic_cast*>(ws->run().getLogData("icp_debug")); + TS_ASSERT(slog); + TS_ASSERT_EQUALS(slog->size(),50); + + TimeSeriesProperty* ilog = dynamic_cast*>(ws->run().getLogData("total_counts")); + TS_ASSERT(ilog); + TS_ASSERT_EQUALS(ilog->size(),172); + + ilog = dynamic_cast*>(ws->run().getLogData("period")); + TS_ASSERT(ilog); + TS_ASSERT_EQUALS(ilog->size(),172); + + TimeSeriesProperty *dlog = dynamic_cast*>(ws->run().getLogData("proton_charge")); + TS_ASSERT(dlog); + TS_ASSERT_EQUALS(dlog->size(),172); + + + TimeSeriesProperty* blog = dynamic_cast*>(ws->run().getLogData("period 1")); + TS_ASSERT(blog); + TS_ASSERT_EQUALS(blog->size(),1); + + blog = dynamic_cast*>(ws->run().getLogData("running")); + TS_ASSERT(blog); + TS_ASSERT_EQUALS(blog->size(),6); + + TS_ASSERT_EQUALS(ws->sample().getName(),"PMMA_SAN25_1.5%_TRANS_150"); + + Property *l_property = ws->run().getLogData( "run_number" ); + TS_ASSERT_EQUALS( l_property->value(), "49886" ); + AnalysisDataService::Instance().remove("outWS"); + } + + + }; //------------------------------------------------------------------------------ diff --git a/Code/Mantid/Framework/DataHandling/test/LoadNXSPETest.h b/Code/Mantid/Framework/DataHandling/test/LoadNXSPETest.h index 01379b78eade..c08f14c79ae1 100644 --- a/Code/Mantid/Framework/DataHandling/test/LoadNXSPETest.h +++ b/Code/Mantid/Framework/DataHandling/test/LoadNXSPETest.h @@ -25,7 +25,7 @@ class LoadNXSPETest : public CxxTest::TestSuite TS_ASSERT( alg.isInitialized() ) } - void xtest_exec() + void test_exec() { // Name of the output workspace. std::string outWSName("LoadNXSPETest_OutputWS"); @@ -33,29 +33,31 @@ class LoadNXSPETest : public CxxTest::TestSuite LoadNXSPE alg; TS_ASSERT_THROWS_NOTHING( alg.initialize() ) TS_ASSERT( alg.isInitialized() ) - TS_ASSERT_THROWS_NOTHING( alg.setPropertyValue("Filename", "/home/andrei/Mantid/Test/Data/CNCS_7850.nxspe") ); + TS_ASSERT_THROWS_NOTHING( alg.setPropertyValue("Filename", "NXSPEData.nxspe") ); TS_ASSERT_THROWS_NOTHING( alg.setPropertyValue("OutputWorkspace", outWSName) ); TS_ASSERT_THROWS_NOTHING( alg.execute(); ); TS_ASSERT( alg.isExecuted() ); -// TS_ASSERT_THROWS_NOTHING( alg.setPropertyValue("Filename", "/home/andrei/Desktop/cncs.nxspe") ); - TS_ASSERT_THROWS_NOTHING( alg.setPropertyValue("Filename", "/home/andrei/Desktop/reduction.py") ); - 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(outWSName) ); TS_ASSERT(ws); if (!ws) return; - // TODO: Check the results - - // Remove workspace from the data service. AnalysisDataService::Instance().remove(outWSName); } + void test_identifier_confidence() + { + const int high_confidence = LoadNXSPE::identiferConfidence("NXSPE"); + const int good_confidence = LoadNXSPE::identiferConfidence("NXSP"); + const int no_confidence = LoadNXSPE::identiferConfidence("NXS"); + + TS_ASSERT(high_confidence > good_confidence); + TS_ASSERT(good_confidence > no_confidence); + } + }; diff --git a/Code/Mantid/Framework/DataHandling/test/LoadNexusMonitorsTest.h b/Code/Mantid/Framework/DataHandling/test/LoadNexusMonitorsTest.h index 35762dab4986..4cfec9b4c694 100644 --- a/Code/Mantid/Framework/DataHandling/test/LoadNexusMonitorsTest.h +++ b/Code/Mantid/Framework/DataHandling/test/LoadNexusMonitorsTest.h @@ -95,6 +95,32 @@ class LoadNexusMonitorsTest : public CxxTest::TestSuite TS_ASSERT( ld.isExecuted() ); } + void testBrokenISISFile() + { + // Just need to make sure it runs. + Mantid::API::FrameworkManager::Instance(); + LoadNexusMonitors ld; + std::string outws_name = "LOQ_49886_monitors"; + ld.initialize(); + ld.setPropertyValue("Filename", "LOQ49886.nxs"); + ld.setPropertyValue("OutputWorkspace", outws_name); + TS_ASSERT_THROWS_NOTHING( ld.execute() ); + TS_ASSERT( ld.isExecuted() ); + + MatrixWorkspace_sptr WS = AnalysisDataService::Instance().retrieveWS(outws_name); + //Valid WS and it is an MatrixWorkspace + TS_ASSERT( WS ); + //Correct number of monitors found + TS_ASSERT_EQUALS( WS->getNumberHistograms(), 2 ); + //Monitors data is correct + TS_ASSERT_EQUALS( WS->readY(0)[0], 0 ); + TS_ASSERT_EQUALS( WS->readY(1)[0], 0 ); + + TS_ASSERT_EQUALS( WS->readX(0)[0], 5.0 ); + TS_ASSERT_EQUALS( WS->readX(1)[5],19995.0 ); + + } + void test_10_monitors() { Poco::Path path(ConfigService::Instance().getTempDir().c_str()); diff --git a/Code/Mantid/Framework/DataHandling/test/LoadReflTBLTest.h b/Code/Mantid/Framework/DataHandling/test/LoadReflTBLTest.h index 306e42e5c92a..48d189156ed6 100644 --- a/Code/Mantid/Framework/DataHandling/test/LoadReflTBLTest.h +++ b/Code/Mantid/Framework/DataHandling/test/LoadReflTBLTest.h @@ -54,7 +54,7 @@ class LoadReflTBLTest : public CxxTest::TestSuite Workspace_sptr output; TS_ASSERT_THROWS_NOTHING(output = AnalysisDataService::Instance().retrieve(m_wsName)); TableWorkspace_sptr outputWS = boost::dynamic_pointer_cast(output); - TS_ASSERT_EQUALS(outputWS->columnCount(),8); + TS_ASSERT_EQUALS(outputWS->columnCount(),9); TS_ASSERT_EQUALS(outputWS->rowCount(),10); //test the first three rows, equivalent to the first two rows of the file. @@ -65,7 +65,7 @@ class LoadReflTBLTest : public CxxTest::TestSuite TS_ASSERT_DELTA(boost::lexical_cast(row.cell(3)),0.01,0.001); TS_ASSERT_DELTA(boost::lexical_cast(row.cell(4)),0.06,0.001); TS_ASSERT_DELTA(boost::lexical_cast(row.cell(5)),0.04,0.001); - TS_ASSERT_DELTA(boost::lexical_cast(row.cell(6)),2,0.01); + TS_ASSERT_DELTA(row.cell(6),2,0.01); TS_ASSERT_EQUALS(row.cell(7),1); row = outputWS->getRow(1); @@ -75,7 +75,7 @@ class LoadReflTBLTest : public CxxTest::TestSuite TS_ASSERT_DELTA(boost::lexical_cast(row.cell(3)),0.01,0.001); TS_ASSERT_DELTA(boost::lexical_cast(row.cell(4)),0.06,0.001); TS_ASSERT_DELTA(boost::lexical_cast(row.cell(5)),0.04,0.001); - TS_ASSERT_DELTA(boost::lexical_cast(row.cell(6)),2,0.01); + TS_ASSERT_DELTA(row.cell(6),2,0.01); TS_ASSERT_EQUALS(row.cell(7),2); row = outputWS->getRow(2); @@ -85,7 +85,7 @@ class LoadReflTBLTest : public CxxTest::TestSuite TS_ASSERT_DELTA(boost::lexical_cast(row.cell(3)),0.035,0.001); TS_ASSERT_DELTA(boost::lexical_cast(row.cell(4)),0.3,0.001); TS_ASSERT_DELTA(boost::lexical_cast(row.cell(5)),0.04,0.001); - TS_ASSERT_DELTA(boost::lexical_cast(row.cell(6)),2,0.01); + TS_ASSERT_DELTA(row.cell(6),2,0.01); TS_ASSERT_EQUALS(row.cell(7),2); cleanupafterwards(); @@ -117,7 +117,7 @@ class LoadReflTBLTest : public CxxTest::TestSuite Workspace_sptr output; TS_ASSERT_THROWS_NOTHING(output = AnalysisDataService::Instance().retrieve(m_wsName)); TableWorkspace_sptr outputWS = boost::dynamic_pointer_cast(output); - TS_ASSERT_EQUALS(outputWS->columnCount(),8); + TS_ASSERT_EQUALS(outputWS->columnCount(),9); TS_ASSERT_EQUALS(outputWS->rowCount(),10); //test the first three rows, equivalent to the first two rows of the file. @@ -128,7 +128,7 @@ class LoadReflTBLTest : public CxxTest::TestSuite TS_ASSERT_DELTA(boost::lexical_cast(row.cell(3)),0.01,0.001); TS_ASSERT_DELTA(boost::lexical_cast(row.cell(4)),0.06,0.001); TS_ASSERT_DELTA(boost::lexical_cast(row.cell(5)),0.04,0.001); - TS_ASSERT_DELTA(boost::lexical_cast(row.cell(6)),2,0.01); + TS_ASSERT_DELTA(row.cell(6),2,0.01); TS_ASSERT_EQUALS(row.cell(7),1); row = outputWS->getRow(1); @@ -138,7 +138,7 @@ class LoadReflTBLTest : public CxxTest::TestSuite TS_ASSERT_DELTA(boost::lexical_cast(row.cell(3)),0.01,0.001); TS_ASSERT_DELTA(boost::lexical_cast(row.cell(4)),0.06,0.001); TS_ASSERT_DELTA(boost::lexical_cast(row.cell(5)),0.04,0.001); - TS_ASSERT_DELTA(boost::lexical_cast(row.cell(6)),2,0.01); + TS_ASSERT_DELTA(row.cell(6),2,0.01); TS_ASSERT_EQUALS(row.cell(7),2); row = outputWS->getRow(2); @@ -148,7 +148,7 @@ class LoadReflTBLTest : public CxxTest::TestSuite TS_ASSERT_DELTA(boost::lexical_cast(row.cell(3)),0.035,0.001); TS_ASSERT_DELTA(boost::lexical_cast(row.cell(4)),0.3,0.001); TS_ASSERT_DELTA(boost::lexical_cast(row.cell(5)),0.04,0.001); - TS_ASSERT_DELTA(boost::lexical_cast(row.cell(6)),2,0.01); + TS_ASSERT_DELTA(row.cell(6),2,0.01); TS_ASSERT_EQUALS(row.cell(7),2); cleanupafterwards(); @@ -244,7 +244,7 @@ class LoadReflTBLTest : public CxxTest::TestSuite TableWorkspace_sptr outputWS = boost::dynamic_pointer_cast(output); //the columns should be there, but no rows - TS_ASSERT_EQUALS(outputWS->columnCount(),8); + TS_ASSERT_EQUALS(outputWS->columnCount(),9); TS_ASSERT_EQUALS(outputWS->rowCount(),0); cleanupafterwards(); @@ -279,7 +279,7 @@ class LoadReflTBLTest : public CxxTest::TestSuite TableWorkspace_sptr outputWS = boost::dynamic_pointer_cast(output); //the columns should be there, but no rows - TS_ASSERT_EQUALS(outputWS->columnCount(),8); + TS_ASSERT_EQUALS(outputWS->columnCount(),9); TS_ASSERT_EQUALS(outputWS->rowCount(),0); cleanupafterwards(); diff --git a/Code/Mantid/Framework/DataHandling/test/MaskDetectorsTest.h b/Code/Mantid/Framework/DataHandling/test/MaskDetectorsTest.h index fdb5612c83de..67f9ae9e8971 100644 --- a/Code/Mantid/Framework/DataHandling/test/MaskDetectorsTest.h +++ b/Code/Mantid/Framework/DataHandling/test/MaskDetectorsTest.h @@ -130,7 +130,7 @@ class MaskDetectorsTest : public CxxTest::TestSuite TS_ASSERT_EQUALS( props[0]->name(), "Workspace" ); TS_ASSERT( props[0]->isDefault() ); - TS_ASSERT( dynamic_cast* >(props[0]) ); + TS_ASSERT( dynamic_cast* >(props[0]) ); TS_ASSERT_EQUALS( props[1]->name(), "SpectraList" ); TS_ASSERT( props[1]->isDefault() ); diff --git a/Code/Mantid/Framework/DataHandling/test/SNSDataArchiveICAT2Test.h b/Code/Mantid/Framework/DataHandling/test/SNSDataArchiveICAT2Test.h deleted file mode 100644 index 429cec0d84f6..000000000000 --- a/Code/Mantid/Framework/DataHandling/test/SNSDataArchiveICAT2Test.h +++ /dev/null @@ -1,50 +0,0 @@ -#ifndef SNSDATAARCHIVEICAT2TEST_H_ -#define SNSDATAARCHIVEICAT2TEST_H_ - -#include - -#include "MantidDataHandling/SNSDataArchiveICAT2.h" -#include "MantidAPI/ArchiveSearchFactory.h" - -using namespace Mantid::DataHandling; -using namespace Mantid::API; - -class SNSDataArchiveICAT2Test : public CxxTest::TestSuite -{ -public: - - void xtestSearch() - { - SNSDataArchiveICAT2 arch; - - // PG3 Test case - std::set filename; - filename.insert("PG3_7390"); - std::vector extension = std::vector(1,"_event.nxs"); - std::string path = arch.getArchivePath(filename, extension); - TS_ASSERT_EQUALS(path, "/SNS/PG3/IPTS-2767/0/7390/NeXus/PG3_7390_histo.nxs"); - - - // BSS Test case - filename.clear(); - filename.insert("BSS_18339"); - path = arch.getArchivePath(filename, extension); - TS_ASSERT_EQUALS(path, "/SNS/BSS/IPTS-6817/0/18339/NeXus/BSS_18339_event.nxs"); - - // Test a non-existent file - filename.clear(); - filename.insert("mybeamline_666"); - extension = std::vector(1, ".nxs"); - path = arch.getArchivePath(filename, extension); - TS_ASSERT(path.empty()); - } - - void testFactory() - { - boost::shared_ptr arch = ArchiveSearchFactory::Instance().create("SNSDataSearchICAT2"); - TS_ASSERT(arch); - } - -}; - -#endif /*SNSDATAARCHIVEICAT2TEST_H_*/ diff --git a/Code/Mantid/Framework/DataHandling/test/SaveNexusProcessedTest.h b/Code/Mantid/Framework/DataHandling/test/SaveNexusProcessedTest.h index 9d33c5f1c20a..587309614d63 100644 --- a/Code/Mantid/Framework/DataHandling/test/SaveNexusProcessedTest.h +++ b/Code/Mantid/Framework/DataHandling/test/SaveNexusProcessedTest.h @@ -393,6 +393,42 @@ class SaveNexusProcessedTest : public CxxTest::TestSuite AnalysisDataService::Instance().remove("testSpace"); } + void testSaveGroupWorkspace() + { + const std::string output_filename = "SaveNexusProcessedTest_GroupWorkspaceFile.nxs"; + + // Clean out any previous instances. + bool doesFileExist = Poco::File(output_filename).exists(); + if (doesFileExist) + { + Poco::File(output_filename).remove(); + } + + const int nEntries = 3; + const int nHist = 1; + const int nBins = 1; + const std::string stem = "test_group_ws"; + Mantid::API::WorkspaceGroup_sptr group_ws = WorkspaceCreationHelper::CreateWorkspaceGroup(nEntries, + nHist, nBins, stem); + + SaveNexusProcessed alg; + alg.setRethrows(true); + alg.setChild(true); + alg.initialize(); + + alg.setProperty("Filename", output_filename); + alg.setProperty("InputWorkspace", group_ws); + alg.execute(); + + doesFileExist = Poco::File(output_filename).exists(); + TSM_ASSERT("File should have been created", doesFileExist); + if (doesFileExist) + { + Poco::File(output_filename).remove(); + } + + } + void testSaveTableVectorColumn() { std::string outputFileName = "SaveNexusProcessedTest_testSaveTableVectorColumn.nxs"; diff --git a/Code/Mantid/Framework/DataHandling/test/SavePDFGuiTest.h b/Code/Mantid/Framework/DataHandling/test/SavePDFGuiTest.h new file mode 100644 index 000000000000..6782e6a6b153 --- /dev/null +++ b/Code/Mantid/Framework/DataHandling/test/SavePDFGuiTest.h @@ -0,0 +1,131 @@ +#ifndef MANTID_DATAHANDLING_SAVEPDFGUITEST_H_ +#define MANTID_DATAHANDLING_SAVEPDFGUITEST_H_ + +#include +#include +#include + +#include "MantidAPI/AlgorithmManager.h" +#include "MantidDataHandling/SavePDFGui.h" +#include "MantidDataHandling/LoadNexusProcessed.h" + +using Mantid::DataHandling::SavePDFGui; +using Mantid::DataHandling::LoadNexusProcessed; +using namespace Mantid::API; + +class SavePDFGuiTest : 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 SavePDFGuiTest *createSuite() { return new SavePDFGuiTest(); } + static void destroySuite( SavePDFGuiTest *suite ) { delete suite; } + + + void test_Init() + { + SavePDFGui alg; + TS_ASSERT_THROWS_NOTHING( alg.initialize() ) + TS_ASSERT( alg.isInitialized() ) + } + + size_t read( std::istream & is, std::vector & buff ) { + is.read( &buff[0], buff.size() ); + return is.gcount(); + } + + size_t countEOL( const std::vector & buff, size_t sz ) { + size_t newlines = 0; + const char * p = &buff[0]; + for ( size_t i = 0; i < sz; i++ ) { + if ( p[i] == '\n' ) { + newlines++; + } + } + return newlines; + } + + size_t countLines(const std::string &filename) + { + const size_t BUFFER_SIZE = 1024 * 1024; + std::vector buffer( BUFFER_SIZE ); + std::ifstream in( filename.c_str() ); + size_t n = 0; + while( size_t cc = read( in, buffer ) ) { + n += countEOL( buffer, cc ); + } + return n; + } + + bool loadWorkspace(const std::string &filename, const std::string wsName) + { + LoadNexusProcessed load; + load.initialize(); + load.setProperty("Filename", filename); + load.setProperty("OutputWorkspace", wsName); + load.execute(); + return load.isExecuted(); + } + + void test_exec() + { + // name of workspace to create and save + const std::string wsName("SavePDFGuiTest_OutputWS"); + // name of the output file + const std::string outFilename("SavePDFGuiTest_Output.gr"); + + // Load a file to save out + TS_ASSERT(loadWorkspace("nom_gr.nxs", wsName)); + + // save the file + SavePDFGui alg; + TS_ASSERT_THROWS_NOTHING( alg.initialize() ) + TS_ASSERT( alg.isInitialized() ) + TS_ASSERT_THROWS_NOTHING( alg.setPropertyValue("InputWorkspace", wsName) ); + TS_ASSERT_THROWS_NOTHING( alg.setPropertyValue("Filename", outFilename) ); + TS_ASSERT_THROWS_NOTHING( alg.execute(); ); + TS_ASSERT( alg.isExecuted() ); + + // do the checks + Poco::File outFile(outFilename); + TS_ASSERT( outFile.isFile()); + TS_ASSERT_EQUALS( countLines(outFilename), 1003); + + // Remove workspace from the data service. + AnalysisDataService::Instance().remove(wsName); + + // remove the output file + outFile.remove(false); + } + + void test_exec_ws_group() + { + // Create a group + const std::string groupName("SavePDFGUIGroup"); + TS_ASSERT(loadWorkspace("nom_gr.nxs", groupName+"_1")); + TS_ASSERT(loadWorkspace("nom_gr.nxs", groupName+"_2")); + + auto grpAlg = AlgorithmManager::Instance().createUnmanaged("GroupWorkspaces"); + grpAlg->initialize(); + grpAlg->setPropertyValue("InputWorkspaces", groupName+"_1,"+groupName+"_2"); + grpAlg->setPropertyValue("OutputWorkspace", groupName); + grpAlg->execute(); + + // name of the output file + const std::string outFilename("SavePDFGUIGroup.gr"); + + // run the algorithm with a group + SavePDFGui alg; + TS_ASSERT_THROWS_NOTHING( alg.initialize() ); + TS_ASSERT_THROWS_NOTHING( alg.setPropertyValue("InputWorkspace", groupName) ); + TS_ASSERT_THROWS_NOTHING( alg.setPropertyValue("Filename","SavePDFGUIGroup.gr") ); + TS_ASSERT_THROWS_NOTHING( alg.execute() ); + TS_ASSERT( alg.isExecuted() ); + + // remove the workspace group + AnalysisDataService::Instance().deepRemoveGroup(groupName); + } +}; + + +#endif /* MANTID_DATAHANDLING_SAVEPDFGUITEST_H_ */ diff --git a/Code/Mantid/Framework/DataHandling/test/SaveParameterFileTest.h b/Code/Mantid/Framework/DataHandling/test/SaveParameterFileTest.h index 4bd4a3291648..77f270f79d90 100644 --- a/Code/Mantid/Framework/DataHandling/test/SaveParameterFileTest.h +++ b/Code/Mantid/Framework/DataHandling/test/SaveParameterFileTest.h @@ -39,6 +39,7 @@ class SaveParameterFileTest : public CxxTest::TestSuite setParam("nickel-holder", "testString1", "hello world"); setParam("nickel-holder", "testString2", "unchanged"); setParamByDetID(1301, "testDouble", 2.17); + setFitParam("nickel-holder", "A", ", BackToBackExponential , S , , , , , sqrt(188.149*centre^4+6520.945*centre^2) , dSpacing , TOF , linear ; TOF ; TOF"); //Create a temporary blank file for us to test with ScopedFileHelper::ScopedFile paramFile("", "__params.xml"); @@ -47,9 +48,10 @@ class SaveParameterFileTest : public CxxTest::TestSuite saveParams(paramFile.getFileName()); //Change some parameters - these changes should not have an effect - setParam("nickel-holder", "testDouble1", 3.14); - setParam("nickel-holder", "testString1", "broken"); - setParamByDetID(1301, "testDouble", 7.89); + setParam("nickel-holder", "testDouble1", 3.14); + setParam("nickel-holder", "testString1", "broken"); + setParamByDetID(1301, "testDouble", 7.89); + setFitParam("nickel-holder", "B", "someString"); //Load the saved parameters back in loadParams(paramFile.getFileName()); @@ -60,6 +62,7 @@ class SaveParameterFileTest : public CxxTest::TestSuite checkParam("nickel-holder", "testString1", "hello world"); checkParam("nickel-holder", "testString2", "unchanged"); checkParamByDetID(1301, "testDouble", 2.17); + checkFitParam("nickel-holder", "A", ", BackToBackExponential , S , , , , , sqrt(188.149*centre^4+6520.945*centre^2) , dSpacing , TOF , linear ; TOF ; TOF"); } void setParam(std::string cName, std::string pName, std::string value) @@ -87,6 +90,16 @@ class SaveParameterFileTest : public CxxTest::TestSuite paramMap.addDouble(comp->getComponentID(), pName, value); } + void setFitParam(std::string cName, std::string pName, std::string value) + { + Instrument_const_sptr inst = m_ws->getInstrument(); + ParameterMap& paramMap = m_ws->instrumentParameters(); + boost::shared_ptr comp = inst->getComponentByName(cName); + auto param = ParameterFactory::create("fitting",pName); + param->fromString(value); + paramMap.add(comp.get(),param); + } + void checkParam(std::string cName, std::string pName, std::string value) { Instrument_const_sptr inst = m_ws->getInstrument(); @@ -116,6 +129,22 @@ class SaveParameterFileTest : public CxxTest::TestSuite TS_ASSERT_DELTA(value, pValue, 0.0001); } + void checkFitParam(std::string cName, std::string pName, std::string value) + { + Instrument_const_sptr inst = m_ws->getInstrument(); + ParameterMap& paramMap = m_ws->instrumentParameters(); + boost::shared_ptr comp = inst->getComponentByName(cName); + auto param = paramMap.get(comp.get(),pName,"fitting"); + const Mantid::Geometry::FitParameter& fitParam = param->value(); + + // Info about fitting parameter is in string value, see FitParameter class + typedef Poco::StringTokenizer tokenizer; + tokenizer values(value, ",", tokenizer::TOK_TRIM); + TS_ASSERT_EQUALS(fitParam.getFormula(), values[7]); + TS_ASSERT_EQUALS(fitParam.getFunction(), values[1]); + TS_ASSERT_EQUALS(fitParam.getResultUnit(), values[9]); + TS_ASSERT_EQUALS(fitParam.getFormulaUnit(), values[8]); + } void loadParams(std::string filename) { diff --git a/Code/Mantid/Framework/DataHandling/test/SaveReflTBLTest.h b/Code/Mantid/Framework/DataHandling/test/SaveReflTBLTest.h index ea927d347441..e9f376d78cfa 100644 --- a/Code/Mantid/Framework/DataHandling/test/SaveReflTBLTest.h +++ b/Code/Mantid/Framework/DataHandling/test/SaveReflTBLTest.h @@ -69,10 +69,10 @@ class SaveReflTBLTest : public CxxTest::TestSuite ITableWorkspace_sptr ws = CreateWorkspace(); TableRow row = ws->appendRow(); - row << "13460" << "0.7" << "13463,13464" << "0.01" << "0.06" << "0.04" << "2" << 4; + row << "13460" << "0.7" << "13463,13464" << "0.01" << "0.06" << "0.04" << 2.0 << 4; row = ws->appendRow(); - row << "13470" << "2.3" << "13463,13464" << "0.035" << "0.3" << "0.04" << "2" << 5; + row << "13470" << "2.3" << "13463,13464" << "0.035" << "0.3" << "0.04" << 2.0 << 5; Mantid::API::IAlgorithm_sptr alg = Mantid::API::AlgorithmManager::Instance().create("SaveReflTBL"); alg->setRethrows(true); @@ -111,7 +111,7 @@ class SaveReflTBLTest : public CxxTest::TestSuite ITableWorkspace_sptr ws = CreateWorkspace(); TableRow row = ws->appendRow(); - row << "13460" << "0.7" << "13463" << "0.01" << "0.06" << "0.04" << "2" << 1; + row << "13460" << "0.7" << "13463" << "0.01" << "0.06" << "0.04" << 2.0 << 1; Mantid::API::IAlgorithm_sptr alg = Mantid::API::AlgorithmManager::Instance().create("SaveReflTBL"); alg->setRethrows(true); @@ -135,7 +135,7 @@ class SaveReflTBLTest : public CxxTest::TestSuite auto colQmin = ws->addColumn("str","Qmin"); auto colQmax = ws->addColumn("str","Qmax"); auto colDqq = ws->addColumn("str","dq/q"); - auto colScale = ws->addColumn("str","Scale"); + auto colScale = ws->addColumn("double","Scale"); colRuns->setPlotType(0); colTheta->setPlotType(0); @@ -146,13 +146,13 @@ class SaveReflTBLTest : public CxxTest::TestSuite colScale->setPlotType(0); TableRow row = ws->appendRow(); - row << "13460" << "0.7" << "13463" << "0.01" << "0.06" << "0.04" << "2"; + row << "13460" << "0.7" << "13463" << "0.01" << "0.06" << "0.04" << 2.0; row = ws->appendRow(); - row << "13462" << "2.3" << "13463" << "0.035" << "0.3" << "0.04" << "2"; + row << "13462" << "2.3" << "13463" << "0.035" << "0.3" << "0.04" << 2.0; row = ws->appendRow(); - row << "13470" << "2.3" << "13463" << "0.035" << "0.3" << "0.04" << "2"; + row << "13470" << "2.3" << "13463" << "0.035" << "0.3" << "0.04" << 2.0; Mantid::API::IAlgorithm_sptr alg = Mantid::API::AlgorithmManager::Instance().create("SaveReflTBL"); alg->setRethrows(true); @@ -214,7 +214,7 @@ class SaveReflTBLTest : public CxxTest::TestSuite auto colQmin = ws->addColumn("str","Qmin"); auto colQmax = ws->addColumn("str","Qmax"); auto colDqq = ws->addColumn("str","dq/q"); - auto colScale = ws->addColumn("str","Scale"); + auto colScale = ws->addColumn("double","Scale"); auto colStitch = ws->addColumn("int","StitchGroup"); colRuns->setPlotType(0); @@ -227,32 +227,32 @@ class SaveReflTBLTest : public CxxTest::TestSuite colStitch->setPlotType(0); TableRow row = ws->appendRow(); - row << "13460" << "0.7" << "13463" << "0.01" << "0.06" << "0.04" << "2" << 1; + row << "13460" << "0.7" << "13463" << "0.01" << "0.06" << "0.04" << 2.0 << 1; row = ws->appendRow(); - row << "13462" << "2.3" << "13463" << "0.035" << "0.3" << "0.04" << "2" << 1; + row << "13462" << "2.3" << "13463" << "0.035" << "0.3" << "0.04" << 2.0 << 1; row = ws->appendRow(); - row << "13470" << "2.3" << "13463" << "0.035" << "0.3" << "0.04" << "2" << 1; + row << "13470" << "2.3" << "13463" << "0.035" << "0.3" << "0.04" << 2.0 << 1; row = ws->appendRow(); - row << "13460" << "0.7" << "13463" << "0.01" << "0.06" << "0.04" << "2" << 2; + row << "13460" << "0.7" << "13463" << "0.01" << "0.06" << "0.04" << 2.0 << 2; row = ws->appendRow(); - row << "13462" << "2.3" << "13463" << "0.035" << "0.3" << "0.04" << "2" << 2; + row << "13462" << "2.3" << "13463" << "0.035" << "0.3" << "0.04" << 2.0 << 2; row = ws->appendRow(); - row << "13470" << "2.3" << "13463" << "0.035" << "0.3" << "0.04" << "2" << 3; + row << "13470" << "2.3" << "13463" << "0.035" << "0.3" << "0.04" << 2.0 << 3; row = ws->appendRow(); - row << "13460" << "0.7" << "13463" << "0.01" << "0.06" << "0.04" << "2" << 0; + row << "13460" << "0.7" << "13463" << "0.01" << "0.06" << "0.04" << 2.0 << 0; //this row's last two cells will show in the tableworkspace, but the first row in stich group 3's will take priority when saving row = ws->appendRow(); - row << "13462" << "2.3" << "13463" << "0.035" << "0.3" << "0.4" << "3" << 3; + row << "13462" << "2.3" << "13463" << "0.035" << "0.3" << "0.4" << 3.0 << 3; row = ws->appendRow(); - row << "13470" << "2.3" << "13463" << "0.035" << "0.3" << "0.04" << "2" << 4; + row << "13470" << "2.3" << "13463" << "0.035" << "0.3" << "0.04" << 2.0 << 4; return ws; } diff --git a/Code/Mantid/Framework/DataHandling/test/XMLlogfileTest.h b/Code/Mantid/Framework/DataHandling/test/XMLInstrumentParameterTest.h similarity index 88% rename from Code/Mantid/Framework/DataHandling/test/XMLlogfileTest.h rename to Code/Mantid/Framework/DataHandling/test/XMLInstrumentParameterTest.h index 96a80167b2a6..47863743e9cd 100644 --- a/Code/Mantid/Framework/DataHandling/test/XMLlogfileTest.h +++ b/Code/Mantid/Framework/DataHandling/test/XMLInstrumentParameterTest.h @@ -3,7 +3,7 @@ #include -#include "MantidGeometry/Instrument/XMLlogfile.h" +#include "MantidGeometry/Instrument/XMLInstrumentParameter.h" #include "MantidDataHandling/LoadRaw3.h" #include "MantidAPI/WorkspaceFactory.h" #include "MantidAPI/AnalysisDataService.h" @@ -19,11 +19,11 @@ using namespace Mantid::DataHandling; using namespace Mantid::DataObjects; using namespace Mantid::Geometry; -class XMLlogfileTest : public CxxTest::TestSuite +class XMLInstrumentParameterTest : public CxxTest::TestSuite { public: - // LoadRaw2 uses XMLlogfile to populate its parameter map. Hence the test here simply + // LoadRaw2 uses XMLInstrumentParameter to populate its parameter map. Hence the test here simply // checks that this is done ok void testParameterMap() { @@ -63,7 +63,7 @@ class XMLlogfileTest : public CxxTest::TestSuite } - // LoadRaw2 uses XMLlogfile to populate its parameter map. Hence the test here simply + // LoadRaw2 uses XMLInstrumentParameter to populate its parameter map. Hence the test here simply // checks that this is done ok void testParsing() { @@ -76,7 +76,7 @@ class XMLlogfileTest : public CxxTest::TestSuite std::string eq; const double angleConvert(1.0); - XMLlogfile testParamEntry("", "1000.0", interpolation, + XMLInstrumentParameter testParamEntry("", "1000.0", interpolation, "", "", "", "bob", "double", "", constraint, penaltyFactor, diff --git a/Code/Mantid/Framework/DataObjects/inc/MantidDataObjects/EventWorkspace.h b/Code/Mantid/Framework/DataObjects/inc/MantidDataObjects/EventWorkspace.h index 50ff948b4a36..01ed2e99ef0f 100644 --- a/Code/Mantid/Framework/DataObjects/inc/MantidDataObjects/EventWorkspace.h +++ b/Code/Mantid/Framework/DataObjects/inc/MantidDataObjects/EventWorkspace.h @@ -152,6 +152,8 @@ class DLLExport EventWorkspace : public API::IEventWorkspace void resizeTo(const std::size_t numSpectra); // Pad pixels in the workspace using the loaded spectra. Requires a non-empty spectra-detector map void padSpectra(); + // Pad pixels in the workspace using specList. Requires a non-empty vector + void padSpectra(const std::vector & specList); // Remove pixels in the workspace that do not contain events. void deleteEmptyLists(); diff --git a/Code/Mantid/Framework/DataObjects/inc/MantidDataObjects/TableColumn.h b/Code/Mantid/Framework/DataObjects/inc/MantidDataObjects/TableColumn.h index 6f5e3951d437..d79d36f12fd4 100644 --- a/Code/Mantid/Framework/DataObjects/inc/MantidDataObjects/TableColumn.h +++ b/Code/Mantid/Framework/DataObjects/inc/MantidDataObjects/TableColumn.h @@ -93,10 +93,10 @@ class TableColumn: public API::Column if((name.find("i")!=std::string::npos)||(name.find("l")!=std::string::npos)|| (name.find("x")!=std::string::npos)){ if(length==4){ - this->m_type=="int"; + this->m_type="int"; } if(length==8){ - this->m_type=="int64"; + this->m_type="int64"; } } if(name.find("f")!=std::string::npos){ @@ -109,11 +109,11 @@ class TableColumn: public API::Column { if(length == 4) { - this->m_type=="uint32_t"; + this->m_type="uint32_t"; } if(length == 8) { - this->m_type=="uint64_t"; + this->m_type="uint64_t"; } } if(this->m_type.empty()){ diff --git a/Code/Mantid/Framework/DataObjects/src/EventWorkspace.cpp b/Code/Mantid/Framework/DataObjects/src/EventWorkspace.cpp index 46dbb2f05bfe..16c277868187 100644 --- a/Code/Mantid/Framework/DataObjects/src/EventWorkspace.cpp +++ b/Code/Mantid/Framework/DataObjects/src/EventWorkspace.cpp @@ -190,6 +190,7 @@ namespace Mantid { if (index >= m_noVectors) throw std::range_error("EventWorkspace::getSpectrum, workspace index out of range"); + invalidateCommonBinsFlag(); return data[index]; } @@ -614,6 +615,29 @@ namespace Mantid } } + /** Expands the workspace to a number of spectra corresponding to the number of + * pixels/detectors contained in specList. + * All events lists will be empty after calling this method. + */ + void EventWorkspace::padSpectra(const std::vector & specList) + { + if (specList.empty()) + { + padSpectra(); + } + else + { + resizeTo(specList.size()); + for (size_t i = 0; i < specList.size(); ++i) + { + // specList ranges from 1, ..., N + // detector ranges from 0, ..., N-1 + getSpectrum(i)->setDetectorID(specList[i]-1); + getSpectrum(i)->setSpectrumNo(specList[i]); + } + } + } + void EventWorkspace::deleteEmptyLists() { // figure out how much data to copy @@ -925,6 +949,7 @@ namespace Mantid size_t howManyCores = 1; // And auto-detect how many threads size_t howManyThreads = 0; +#ifdef _OPENMP if (m_noVectors < num_threads * 10) { // If you have few vectors, sort with 2 cores. @@ -939,6 +964,7 @@ namespace Mantid howManyCores = 4; howManyThreads = num_threads / 4 + 1; } +#endif g_log.debug() << "Performing sort with " << howManyCores << " cores per EventList, in " << howManyThreads << " threads, using a chunk size of " << chunk_size << ".\n"; diff --git a/Code/Mantid/Framework/DataObjects/src/Peak.cpp b/Code/Mantid/Framework/DataObjects/src/Peak.cpp index 8d79736cc78f..78f5e920dfe6 100644 --- a/Code/Mantid/Framework/DataObjects/src/Peak.cpp +++ b/Code/Mantid/Framework/DataObjects/src/Peak.cpp @@ -528,6 +528,7 @@ namespace DataObjects */ bool Peak::findDetector() { + bool found = false; // Scattered beam direction V3D oldDetPos = detPos; V3D beam = detPos - samplePos; @@ -539,13 +540,42 @@ namespace DataObjects IDetector_const_sptr det = tracker.getDetectorResult(); if (det) { - // Set the detector ID, the row, col, etc. - this->setDetectorID(det->getID()); - // The old detector position is not more precise if it comes from FindPeaksMD - detPos = det->getPos(); - return true; + // Set the detector ID, the row, col, etc. + this->setDetectorID(det->getID()); + // The old detector position is not more precise if it comes from FindPeaksMD + detPos = det->getPos(); + found = true; } - return false; + //Use tube-gap parameter in instrument parameter file to find peaks with center in gaps between tubes + else if (m_inst->hasParameter("tube-gap")) + { + std::vector gaps = m_inst->getNumberParameter("tube-gap", true); + if (!gaps.empty()) + { + const double gap = static_cast(gaps.front()); + // try adding and subtracting tube-gap in 3 q dimensions to see if you can find detectors on each side of tube gap + for(int i=0;i<3;i++) + { + V3D gapDir = V3D(0.,0.,0.); + gapDir[i] = gap; + V3D beam1 = beam + gapDir; + tracker.traceFromSample(beam1); + IDetector_const_sptr det1 = tracker.getDetectorResult(); + V3D beam2 = beam - gapDir; + tracker.traceFromSample(beam2); + IDetector_const_sptr det2 = tracker.getDetectorResult(); + if (det1 && det2) + { + // Set the detector ID to one of the neighboring pixels + this->setDetectorID(static_cast(det1->getID()));; + detPos = det1->getPos() ; + found = true; + break; + } + } + } + } + return found; } //---------------------------------------------------------------------------------------------- diff --git a/Code/Mantid/Framework/DataObjects/src/Workspace2D.cpp b/Code/Mantid/Framework/DataObjects/src/Workspace2D.cpp index 89e6c661e960..82047dcd2234 100644 --- a/Code/Mantid/Framework/DataObjects/src/Workspace2D.cpp +++ b/Code/Mantid/Framework/DataObjects/src/Workspace2D.cpp @@ -111,6 +111,7 @@ namespace Mantid ss << "Workspace2D::getSpectrum, histogram number " << index << " out of range " << m_noVectors; throw std::range_error(ss.str()); } + invalidateCommonBinsFlag(); return data[index]; } diff --git a/Code/Mantid/Framework/Geometry/CMakeLists.txt b/Code/Mantid/Framework/Geometry/CMakeLists.txt index 4f6990ac989d..bb1d146e9c8b 100644 --- a/Code/Mantid/Framework/Geometry/CMakeLists.txt +++ b/Code/Mantid/Framework/Geometry/CMakeLists.txt @@ -1,16 +1,31 @@ set ( SRC_FILES src/ComponentParser.cpp + src/Crystal/BraggScatterer.cpp + src/Crystal/BraggScattererFactory.cpp + src/Crystal/BraggScattererInCrystalStructure.cpp + src/Crystal/CenteringGroup.cpp + src/Crystal/CompositeBraggScatterer.cpp src/Crystal/ConventionalCell.cpp src/Crystal/CrystalStructure.cpp + src/Crystal/CyclicGroup.cpp + src/Crystal/Group.cpp src/Crystal/IndexingUtils.cpp + src/Crystal/IsotropicAtomBraggScatterer.cpp src/Crystal/NiggliCell.cpp src/Crystal/OrientedLattice.cpp src/Crystal/PointGroup.cpp + src/Crystal/PointGroupFactory.cpp + src/Crystal/ProductOfCyclicGroups.cpp src/Crystal/ReducedCell.cpp src/Crystal/ReflectionCondition.cpp src/Crystal/ScalarUtils.cpp + src/Crystal/SpaceGroup.cpp + src/Crystal/SpaceGroupFactory.cpp src/Crystal/SymmetryOperation.cpp + src/Crystal/SymmetryOperationFactory.cpp + src/Crystal/SymmetryOperationSymbolParser.cpp src/Crystal/UnitCell.cpp + src/Crystal/V3R.cpp src/IObjComponent.cpp src/Instrument.cpp src/Instrument/CompAssembly.cpp @@ -32,7 +47,7 @@ set ( SRC_FILES src/Instrument/RectangularDetector.cpp src/Instrument/RectangularDetectorPixel.cpp src/Instrument/ReferenceFrame.cpp - src/Instrument/XMLlogfile.cpp + src/Instrument/XMLInstrumentParameter.cpp src/MDGeometry/CompositeImplicitFunction.cpp src/MDGeometry/IMDDimension.cpp src/MDGeometry/IMDDimensionFactory.cpp @@ -88,30 +103,45 @@ set ( SRC_FILES ) set ( OPENCASCADE_SRC - src/Rendering/OCGeometryGenerator.cpp - src/Rendering/OCGeometryHandler.cpp - src/Rendering/OCGeometryRenderer.cpp + src/Rendering/OCGeometryGenerator.cpp + src/Rendering/OCGeometryHandler.cpp + src/Rendering/OCGeometryRenderer.cpp ) set ( SRC_UNITY_IGNORE_FILES src/Instrument/CompAssembly.cpp - src/Instrument/ObjCompAssembly.cpp - src/Rendering/OCGeometryHandler.cpp - src/Rendering/OCGeometryRenderer.cpp - ) + src/Instrument/ObjCompAssembly.cpp + src/Rendering/OCGeometryHandler.cpp + src/Rendering/OCGeometryRenderer.cpp +) set ( INC_FILES inc/MantidGeometry/ComponentParser.h + inc/MantidGeometry/Crystal/BraggScatterer.h + inc/MantidGeometry/Crystal/BraggScattererFactory.h + inc/MantidGeometry/Crystal/BraggScattererInCrystalStructure.h + inc/MantidGeometry/Crystal/CenteringGroup.h + inc/MantidGeometry/Crystal/CompositeBraggScatterer.h inc/MantidGeometry/Crystal/ConventionalCell.h inc/MantidGeometry/Crystal/CrystalStructure.h + inc/MantidGeometry/Crystal/CyclicGroup.h + inc/MantidGeometry/Crystal/Group.h inc/MantidGeometry/Crystal/IndexingUtils.h + inc/MantidGeometry/Crystal/IsotropicAtomBraggScatterer.h inc/MantidGeometry/Crystal/NiggliCell.h inc/MantidGeometry/Crystal/OrientedLattice.h inc/MantidGeometry/Crystal/PointGroup.h + inc/MantidGeometry/Crystal/PointGroupFactory.h + inc/MantidGeometry/Crystal/ProductOfCyclicGroups.h inc/MantidGeometry/Crystal/ReducedCell.h inc/MantidGeometry/Crystal/ReflectionCondition.h inc/MantidGeometry/Crystal/ScalarUtils.h + inc/MantidGeometry/Crystal/SpaceGroup.h + inc/MantidGeometry/Crystal/SpaceGroupFactory.h inc/MantidGeometry/Crystal/SymmetryOperation.h + inc/MantidGeometry/Crystal/SymmetryOperationFactory.h + inc/MantidGeometry/Crystal/SymmetryOperationSymbolParser.h inc/MantidGeometry/Crystal/UnitCell.h + inc/MantidGeometry/Crystal/V3R.h inc/MantidGeometry/DllConfig.h inc/MantidGeometry/ICompAssembly.h inc/MantidGeometry/IComponent.h @@ -140,7 +170,7 @@ set ( INC_FILES inc/MantidGeometry/Instrument/RectangularDetector.h inc/MantidGeometry/Instrument/RectangularDetectorPixel.h inc/MantidGeometry/Instrument/ReferenceFrame.h - inc/MantidGeometry/Instrument/XMLlogfile.h + inc/MantidGeometry/Instrument/XMLInstrumentParameter.h inc/MantidGeometry/MDGeometry/CompositeImplicitFunction.h inc/MantidGeometry/MDGeometry/IMDDimension.h inc/MantidGeometry/MDGeometry/IMDDimensionFactory.h @@ -198,21 +228,28 @@ set ( TEST_FILES AlgebraTest.h BnIdTest.h BoundingBoxTest.h + BraggScattererFactoryTest.h + BraggScattererInCrystalStructureTest.h + BraggScattererTest.h + CenteringGroupTest.h CompAssemblyTest.h ComponentHelperTest.h ComponentParserTest.h ComponentTest.h + CompositeBraggScattererTest.h CompositeImplicitFunctionTest.h ConeTest.h ConventionalCellTest.h ConvexPolygonTest.h CrystalStructureTest.h + CyclicGroupTest.h CylinderTest.h DetectorGroupTest.h DetectorTest.h FitParameterTest.h GeneralTest.h GoniometerTest.h + GroupTest.h IDFObjectTest.h IMDDimensionFactoryTest.h IMDDimensionTest.h @@ -220,6 +257,7 @@ set ( TEST_FILES InstrumentDefinitionParserTest.h InstrumentRayTracerTest.h InstrumentTest.h + IsotropicAtomBraggScattererTest.h LaszloIntersectionTest.h LineIntersectVisitTest.h LineTest.h @@ -234,11 +272,11 @@ set ( TEST_FILES MathSupportTest.h NearestNeighboursFactoryTest.h NearestNeighboursTest.h + NiggliCellTest.h NullImplicitFunctionTest.h ObjCompAssemblyTest.h ObjComponentTest.h ObjectTest.h - NiggliCellTest.h OrientedLatticeTest.h ParCompAssemblyTest.h ParComponentFactoryTest.h @@ -249,8 +287,10 @@ set ( TEST_FILES ParameterMapTest.h ParametrizedComponentTest.h PlaneTest.h + PointGroupFactoryTest.h PointGroupTest.h PolygonEdgeTest.h + ProductOfCyclicGroupsTest.h QuadrilateralTest.h RectangularDetectorPixelTest.h RectangularDetectorTest.h @@ -267,21 +307,26 @@ set ( TEST_FILES RulesUnionTest.h ScalarUtilsTest.h ShapeFactoryTest.h + SpaceGroupFactoryTest.h + SpaceGroupTest.h SphereTest.h SurfaceFactoryTest.h SurfaceTest.h + SymmetryOperationFactoryTest.h + SymmetryOperationSymbolParserTest.h SymmetryOperationTest.h TorusTest.h TrackTest.h TripleTest.h UnitCellTest.h + V3RTest.h Vertex2DListTest.h Vertex2DTest.h - XMLlogfileTest.h + XMLInstrumentParameterTest.h ) set ( GMOCK_TEST_FILES - MDGeometryXMLBuilderTest.h + MDGeometryXMLBuilderTest.h ) diff --git a/Code/Mantid/Framework/Geometry/inc/MantidGeometry/Crystal/BraggScatterer.h b/Code/Mantid/Framework/Geometry/inc/MantidGeometry/Crystal/BraggScatterer.h new file mode 100644 index 000000000000..e4a0e1ae6fc3 --- /dev/null +++ b/Code/Mantid/Framework/Geometry/inc/MantidGeometry/Crystal/BraggScatterer.h @@ -0,0 +1,108 @@ +#ifndef MANTID_GEOMETRY_BRAGGSCATTERER_H_ +#define MANTID_GEOMETRY_BRAGGSCATTERER_H_ + +#include "MantidGeometry/DllConfig.h" +#include "MantidKernel/V3D.h" + + +#include +#include + +#include "MantidKernel/PropertyManager.h" +#include "MantidKernel/TypedValidator.h" + +namespace Mantid +{ +namespace Geometry +{ + +typedef std::complex StructureFactor; + +/** BraggScatterer + + BraggScatterer is a general interface for representing scatterers + in the unit cell of a periodic structure. Since there are many possibilities + of modelling scatterers, BraggScatterer is derived from PropertyManager. + This way, new scatterers with very different parameters can be + added easily. + + New implementations must override the declareProperties method and + define any parameters there. For most applications it should be easier + to inherit from BraggScattererInCrystalStructure, which provides some + default properties that are useful in many cases. CompositeBraggScatterer + is designed to combine several scatterers. + + CompositeBraggScatterer does not declare any properties by itself. For + some properties it makes sense to be equal for all scatterers in the + composite. This behavior can be achieved by calling the method + makePropertyPropagating after it has been declared. Examples are + the UnitCell and SpaceGroup properties in BraggScattererInCrystalStructure. + + Construction of concrete scatterers is done through ScattererFactory. + + @author Michael Wedel, Paul Scherrer Institut - SINQ + @date 20/10/2014 + + Copyright © 2014 PSI-MSS + + 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 . + + File change history is stored at: + Code Documentation is available at: + */ + +class BraggScatterer; + +typedef boost::shared_ptr BraggScatterer_sptr; + +class MANTID_GEOMETRY_DLL BraggScatterer : public Kernel::PropertyManager +{ +public: + BraggScatterer(); + virtual ~BraggScatterer() { } + + void initialize(); + bool isInitialized(); + + virtual std::string name() const = 0; + virtual BraggScatterer_sptr clone() const = 0; + + virtual StructureFactor calculateStructureFactor(const Kernel::V3D &hkl) const = 0; + + bool isPropertyExposedToComposite(const std::string &propertyName) const; + bool isPropertyExposedToComposite(Kernel::Property *property) const; + +protected: + /// Base implementation does nothing, can be re-implemented by subclasses. + void afterPropertySet(const std::string &) { } + + /// Base implementation does nothing - for implementing classes only. + virtual void declareProperties() { } + + void exposePropertyToComposite(const std::string &propertyName); + void unexposePropertyFromComposite(const std::string &propertyName); + + const std::string &getPropagatingGroupName() const; + +private: + std::string m_propagatingGroupName; + bool m_isInitialized; +}; + +} // namespace Geometry +} // namespace Mantid + +#endif /* MANTID_GEOMETRY_BRAGGSCATTERER_H_ */ diff --git a/Code/Mantid/Framework/Geometry/inc/MantidGeometry/Crystal/BraggScattererFactory.h b/Code/Mantid/Framework/Geometry/inc/MantidGeometry/Crystal/BraggScattererFactory.h new file mode 100644 index 000000000000..13e5ad89c58a --- /dev/null +++ b/Code/Mantid/Framework/Geometry/inc/MantidGeometry/Crystal/BraggScattererFactory.h @@ -0,0 +1,103 @@ +#ifndef MANTID_GEOMETRY_BRAGGSCATTERERFACTORY_H_ +#define MANTID_GEOMETRY_BRAGGSCATTERERFACTORY_H_ + +#include "MantidGeometry/DllConfig.h" +#include "MantidKernel/DynamicFactory.h" +#include "MantidKernel/SingletonHolder.h" +#include "MantidGeometry/Crystal/BraggScatterer.h" + +namespace Mantid +{ +namespace Geometry +{ + +/** BraggScattererFactory : + + This class implements a factory for concrete BraggScatterer classes. + When a new scatterer is derived from BraggScatterer, it should be registered + in the factory. Like other factories in Mantid, a macro is provided for + this purpose: + + DECLARE_BRAGGSCATTERER(NewScattererClass) + + At runtime, instances of this class can be created like this: + + BraggScatterer_sptr scatterer = BraggScattererFactory::Instance().createScatterer("NewScattererClass"); + + The returned object is initialized, which is required for using the + Kernel::Property-based system of setting parameters for the scatterer. + To make creation of scatterers more convenient, it's possible to provide + a string with "name=value" pairs, separated by semi-colons, which assigns + property values. This is similar to the way FunctionFactory::createInitialized works: + + BraggScatterer_sptr s = BraggScattererFactory::Instance() + .createScatterer( + "NewScatterer", + "SpaceGroup=F m -3 m; Position=[0.1,0.2,0.3]"); + + If you choose to use the raw create/createUnwrapped methods, you have to + make sure to call BraggScatterer::initialize() on the created instance. + + @author Michael Wedel, Paul Scherrer Institut - SINQ + @date 26/10/2014 + + Copyright © 2014 PSI-MSS + + 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 . + + File change history is stored at: + Code Documentation is available at: + */ +class MANTID_GEOMETRY_DLL BraggScattererFactoryImpl : public Kernel::DynamicFactory +{ +public: + BraggScatterer_sptr createScatterer(const std::string &name, const std::string &properties = ""); + + /// Subscribes a scatterer class into the factory. + template + void subscribeScatterer() + { + Kernel::Instantiator *instantiator = new Kernel::Instantiator; + BraggScatterer_sptr scatterer = instantiator->createInstance(); + + subscribe(scatterer->name(), instantiator); + } + +private: + friend struct Mantid::Kernel::CreateUsingNew; + + BraggScattererFactoryImpl(); +}; + +// This is taken from FuncMinimizerFactory +#ifdef _WIN32 + template class MANTID_GEOMETRY_DLL Mantid::Kernel::SingletonHolder; +#endif + +typedef Mantid::Kernel::SingletonHolder BraggScattererFactory; + + +} // namespace Geometry +} // namespace Mantid + +#define DECLARE_BRAGGSCATTERER(classname) \ + namespace { \ + Mantid::Kernel::RegistrationHelper register_scatterer_##classname( \ + ((Mantid::Geometry::BraggScattererFactory::Instance().subscribeScatterer()) \ + , 0)); \ + } + +#endif /* MANTID_GEOMETRY_BRAGGSCATTERERFACTORY_H_ */ diff --git a/Code/Mantid/Framework/Geometry/inc/MantidGeometry/Crystal/BraggScattererInCrystalStructure.h b/Code/Mantid/Framework/Geometry/inc/MantidGeometry/Crystal/BraggScattererInCrystalStructure.h new file mode 100644 index 000000000000..48fc0f5267bf --- /dev/null +++ b/Code/Mantid/Framework/Geometry/inc/MantidGeometry/Crystal/BraggScattererInCrystalStructure.h @@ -0,0 +1,103 @@ +#ifndef MANTID_GEOMETRY_BRAGGSCATTERERINCRYSTALSTRUCTURE_H_ +#define MANTID_GEOMETRY_BRAGGSCATTERERINCRYSTALSTRUCTURE_H_ + +#include "MantidGeometry/DllConfig.h" +#include "MantidGeometry/Crystal/BraggScatterer.h" +#include "MantidGeometry/Crystal/UnitCell.h" +#include "MantidGeometry/Crystal/SpaceGroup.h" + +namespace Mantid +{ +namespace Geometry +{ + +/** BraggScattererInCrystalStructure + + This class provides an extension of BraggScatterer, suitable + for scatterers that are part of a crystal structure. Information about + the unit cell and space group can be set. The space group information + is used to calculate equivalent positions in the structure. + + Both space group and unit cell are exposed marked as exposed to + BraggScattererComposite, so all members of one composite will + have the same unit cell and space group. + + @author Michael Wedel, Paul Scherrer Institut - SINQ + @date 04/11/2014 + + Copyright © 2014 PSI-MSS + + 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 . + + File change history is stored at: + Code Documentation is available at: + */ + + +class MANTID_GEOMETRY_DLL BraggScattererInCrystalStructure : public BraggScatterer +{ +public: + BraggScattererInCrystalStructure(); + virtual ~BraggScattererInCrystalStructure() { } + + Kernel::V3D getPosition() const; + std::vector getEquivalentPositions() const; + UnitCell getCell() const; + SpaceGroup_const_sptr getSpaceGroup() const; + +protected: + virtual void afterPropertySet(const std::string &propertyName); + + /// This method should be re-implemented by subclasses for additional parameter processing. + virtual void afterScattererPropertySet(const std::string &) { } + + /// This method should be implemented by subclasses for declaring additional properties. + virtual void declareScattererProperties() { } + + virtual void setPosition(const Kernel::V3D &position); + virtual void setCell(const UnitCell &cell); + virtual void setSpaceGroup(const SpaceGroup_const_sptr &spaceGroup); + + virtual void declareProperties(); + + void recalculateEquivalentPositions(); + + Kernel::V3D m_position; + std::vector m_equivalentPositions; + + UnitCell m_cell; + SpaceGroup_const_sptr m_spaceGroup; +}; + +typedef boost::shared_ptr BraggScattererInCrystalStructure_sptr; + +/** + * Helper class for validating unit cell strings. + * + * This validator checks whether a string consists of either 3 or 6 numbers, + * possibly floating point numbers. It's required for the unit cell string + * property. + */ +class MANTID_GEOMETRY_DLL UnitCellStringValidator : public Kernel::TypedValidator +{ +protected: + Kernel::IValidator_sptr clone() const; + virtual std::string checkValidity(const std::string &unitCellString) const; +}; + +} // namespace Geometry +} // namespace Mantid + +#endif /* MANTID_GEOMETRY_BRAGGSCATTERERINCRYSTALSTRUCTURE_H_ */ diff --git a/Code/Mantid/Framework/Geometry/inc/MantidGeometry/Crystal/CenteringGroup.h b/Code/Mantid/Framework/Geometry/inc/MantidGeometry/Crystal/CenteringGroup.h new file mode 100644 index 000000000000..6d4a4862d3eb --- /dev/null +++ b/Code/Mantid/Framework/Geometry/inc/MantidGeometry/Crystal/CenteringGroup.h @@ -0,0 +1,113 @@ +#ifndef MANTID_GEOMETRY_CENTERINGGROUP_H_ +#define MANTID_GEOMETRY_CENTERINGGROUP_H_ + +#include "MantidGeometry/DllConfig.h" +#include "MantidGeometry/Crystal/Group.h" +#include + +#include "MantidKernel/SingletonHolder.h" + + +namespace Mantid +{ +namespace Geometry +{ + +/** CenteringGroup + + This class is mostly a convenience class. It takes a bravais lattice symbol + (P, I, A, B, C, F, R) and forms a group that contains all translations + connected to the centering. This is for example used in the space group + generation process. + + In addition to the inherited interface of Group, CenteringGroup provides + methods that provide some meta information, namely the "name" of the + centering operation. While CenteringGroup::getSymbol() returns a string, + CenteringGroup::getType() returns a value of the enum type + CenteringGroup::CenteringType. + + Important differences occur in the handling of Rhombohedral centering. + CenteringType distinguishes between obverse (Robv) and reverse (Rrev) + setting. These can be given explicitly as strings for construction. When + only "R" is provided, the obverse setting is assumed. + + @author Michael Wedel, Paul Scherrer Institut - SINQ + @date 07/10/2014 + + Copyright © 2014 PSI-MSS + + 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 . + + File change history is stored at: + Code Documentation is available at: + */ +class MANTID_GEOMETRY_DLL CenteringGroup : public Group +{ +public: + enum CenteringType { + P, I, A, B, C, F, Robv, Rrev + }; + + CenteringGroup(const std::string ¢eringSymbol); + virtual ~CenteringGroup() { } + + CenteringType getType() const; + std::string getSymbol() const; + +protected: + CenteringType m_type; + std::string m_symbol; +}; + +typedef boost::shared_ptr CenteringGroup_sptr; +typedef boost::shared_ptr CenteringGroup_const_sptr; + +/// Helper class to keep this out of the interface of CenteringGroup. +class MANTID_GEOMETRY_DLL CenteringGroupCreatorImpl +{ +public: + ~CenteringGroupCreatorImpl() { } + + CenteringGroup::CenteringType getCenteringType(const std::string ¢eringSymbol) const; + + std::vector getSymmetryOperations(CenteringGroup::CenteringType centeringType) const; + +protected: + std::vector getPrimitive() const; + std::vector getBodyCentered() const; + std::vector getACentered() const; + std::vector getBCentered() const; + std::vector getCCentered() const; + std::vector getFCentered() const; + std::vector getRobvCentered() const; + std::vector getRrevCentered() const; + CenteringGroupCreatorImpl(); + + std::map m_centeringSymbolMap; +private: + friend struct Mantid::Kernel::CreateUsingNew; +}; + +#ifdef _WIN32 + template class MANTID_GEOMETRY_DLL Mantid::Kernel::SingletonHolder; +#endif + +typedef Mantid::Kernel::SingletonHolder CenteringGroupCreator; + +} // namespace Geometry +} // namespace Mantid + +#endif /* MANTID_GEOMETRY_CENTERINGGROUP_H_ */ diff --git a/Code/Mantid/Framework/Geometry/inc/MantidGeometry/Crystal/CompositeBraggScatterer.h b/Code/Mantid/Framework/Geometry/inc/MantidGeometry/Crystal/CompositeBraggScatterer.h new file mode 100644 index 000000000000..192f8986c97a --- /dev/null +++ b/Code/Mantid/Framework/Geometry/inc/MantidGeometry/Crystal/CompositeBraggScatterer.h @@ -0,0 +1,97 @@ +#ifndef MANTID_GEOMETRY_COMPOSITEBRAGGSCATTERER_H_ +#define MANTID_GEOMETRY_COMPOSITEBRAGGSCATTERER_H_ + +#include "MantidGeometry/DllConfig.h" +#include "MantidGeometry/Crystal/BraggScatterer.h" + + +namespace Mantid +{ +namespace Geometry +{ + +/** CompositeBraggScatterer + + CompositeBraggScatterer accumulates scatterers, for easier calculation + of structure factors. Scatterers can be added through the method + addScatterer. The supplied scatterer is not stored directly, + it is cloned instead, so there is a new instance. The original instance + is not modified at all. + + For structure factor calculations, all contributions from contained scatterers + are summed. Contained scatterers may be CompositeBraggScatterers themselves, + so it's possible to build up elaborate structures. + + There are two ways of creating instances of CompositeBraggScatterer. The first + possibility is to use BraggScattererFactory, just like for other implementations + of BraggScatterer. Additionally there is a static method CompositeBraggScatterer::create, + which creates a composite scatterer of the supplied vector of scatterers. + + CompositeBraggScatterer does not declare any methods by itself, instead it exposes + some properties of the contained scatterers (those which were marked using + exposePropertyToComposite). When these properties are set, their values + are propagated to all members of the composite. The default behavior when + new properties are declared in subclasses of BraggScatterer is not to expose + them in this way. + + @author Michael Wedel, Paul Scherrer Institut - SINQ + @date 21/10/2014 + + Copyright © 2014 PSI-MSS + + 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 . + + File change history is stored at: + Code Documentation is available at: + */ +class CompositeBraggScatterer; + +typedef boost::shared_ptr CompositeBraggScatterer_sptr; + +class MANTID_GEOMETRY_DLL CompositeBraggScatterer : public BraggScatterer +{ +public: + CompositeBraggScatterer(); + virtual ~CompositeBraggScatterer() { } + + static CompositeBraggScatterer_sptr create(); + static CompositeBraggScatterer_sptr create(const std::vector &scatterers); + + std::string name() const { return "CompositeBraggScatterer"; } + BraggScatterer_sptr clone() const; + + void addScatterer(const BraggScatterer_sptr &scatterer); + size_t nScatterers() const; + BraggScatterer_sptr getScatterer(size_t i) const; + void removeScatterer(size_t i); + + StructureFactor calculateStructureFactor(const Kernel::V3D &hkl) const; + +protected: + void afterPropertySet(const std::string &propertyName); + void propagateProperty(const std::string &propertyName); + void propagatePropertyToScatterer(BraggScatterer_sptr &scatterer, const std::string &propertyName, const std::string &propertyValue); + + void redeclareProperties(); + std::map getPropertyCountMap() const; + + std::vector m_scatterers; +}; + +} +} + +#endif diff --git a/Code/Mantid/Framework/Geometry/inc/MantidGeometry/Crystal/CyclicGroup.h b/Code/Mantid/Framework/Geometry/inc/MantidGeometry/Crystal/CyclicGroup.h new file mode 100644 index 000000000000..68a60fe9fa88 --- /dev/null +++ b/Code/Mantid/Framework/Geometry/inc/MantidGeometry/Crystal/CyclicGroup.h @@ -0,0 +1,101 @@ +#ifndef MANTID_GEOMETRY_CYCLICGROUP_H_ +#define MANTID_GEOMETRY_CYCLICGROUP_H_ + +#include "MantidGeometry/DllConfig.h" +#include "MantidGeometry/Crystal/Group.h" + +#include +#include + +namespace Mantid +{ +namespace Geometry +{ + +/** CyclicGroup : + + A cyclic group G has the property that it can be represented by + powers of one symmetry operation S of order n: + + G = { S^1, S^2, ..., S^n = S^0 = I } + + The operation S^m is defined as carrying out the multiplication + S * S * ... * S. To illustrate this, a four-fold rotation around + the z-axis is considered. The symmetry operation representing the + transformation by this symmetry element is "-y,x,z". This is also the + first member of the resulting group: + + S^1 = S = -y,x,z + + Then, multiplying this by itself: + + S^2 = S * S = -x,-y,z + S^3 = S * S * S = y,-x,z + S^4 = S * S * S * S = x,y,z = I + + Thus, the cyclic group G resulting from the operation "-y,x,z" contains + the following members: + + G = { S^1, S^2, S^3, I } = { -y,x,z; -x,-y,z; y,-x,z; x,y,z } + + This example shows in fact how the point group "4" can be generated as + a cyclic group by the generator S = -y,x,z. Details about this + are given for example in [1]. + + In code, the example is very concise: + + Group_const_sptr pointGroup4 = GroupFactory::create("-y,x,z"); + + This is much more convenient than having to construct a Group, + where all four symmetry operations would have to be supplied. + + Related to this class is ProductOfCyclicGroups, which provides an easy way + to express a group that is the product of multiple cyclic groups + (such as some point groups). + + [1] Shmueli, U. Acta Crystallogr. A 40, 559–567 (1984). + http://dx.doi.org/10.1107/S0108767384001161 + + @author Michael Wedel, Paul Scherrer Institut - SINQ + @date 03/10/2014 + + Copyright © 2014 PSI-MSS + + 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 . + + File change history is stored at: + Code Documentation is available at: + */ +class MANTID_GEOMETRY_DLL CyclicGroup : public Group +{ +public: + CyclicGroup(const std::string &symmetryOperationString); + CyclicGroup(const SymmetryOperation &symmetryOperation); + virtual ~CyclicGroup() { } + +protected: + std::vector generateAllOperations(const SymmetryOperation &operation) const; + +}; + +typedef boost::shared_ptr CyclicGroup_sptr; +typedef boost::shared_ptr CyclicGroup_const_sptr; + + +} // namespace Geometry +} // namespace Mantid + +#endif /* MANTID_GEOMETRY_CYCLICGROUP_H_ */ diff --git a/Code/Mantid/Framework/Geometry/inc/MantidGeometry/Crystal/Group.h b/Code/Mantid/Framework/Geometry/inc/MantidGeometry/Crystal/Group.h new file mode 100644 index 000000000000..72fffc46898c --- /dev/null +++ b/Code/Mantid/Framework/Geometry/inc/MantidGeometry/Crystal/Group.h @@ -0,0 +1,161 @@ +#ifndef MANTID_GEOMETRY_GROUP_H_ +#define MANTID_GEOMETRY_GROUP_H_ + +#include "MantidGeometry/DllConfig.h" +#include "MantidGeometry/Crystal/SymmetryOperation.h" + +#include +#include + +#include +#include + +namespace Mantid +{ +namespace Geometry +{ + +/** Group : + + The class Group represents a set of symmetry operations (or + symmetry group). It can be constructed by providing a vector + of the symmetry operations it consists of. Another possibility + is using a string (see SymmetryOperationFactory for format). + + Upon construction of Group, the vector of symmetry operations + is potentially reduced to a set of unique operations, because + each operation may occur only once. + + The number of symmetry operations in the group determines its + so-called order, it can be queried with the member function + Group::order(). If one needs to process the symmetry operation + themselves, they can be obtained by Group::getSymmetryOperations(). + + A common task is to apply all symmetry operations of a group to + a point (given in the form of a Kernel::V3D-object). The multiplication + operator for carrying out this operation has been overloaded + to perform this task: + + vector coordinates = Group * V3D + + Please note that a set of unique coordinates is produced, which means + that the number of coordinates in the vector may be smaller than the + order of the group, depending on the input. This is because the + components of V3D are mapped onto the interval [0, 1). + + Two groups A and B can be combined by a multiplication operation, provided by + the corresponding overloaded operator: + + Group A, B; + Group C = A * B + + In this operation each element of A is multiplied with each element of B + and from the resulting list a new group is constructed. For better illustration, + an example is provided. Group A has two symmetry operations: identity ("x,y,z") + and inversion ("-x,-y,-z"). Group B also consists of two operations: + identity ("x,y,z") and a rotation around the y-axis ("-x,y,-z"). In terms + of symmetry elements, the groups are defined like this: + + A := { 1, -1 }; B := { 1, 2 [010] } + + The following table shows all multiplications that are carried out and their + results (for multiplication of symmetry operations see SymmetryOperation): + A + | x,y,z -x,-y,-z + --------+------------------------ + x,y,z | x,y,z -x,-y,-z + B | + -x,y,-z | -x,y,-z x,-y,z + + The resulting group contains the three elements of A and B (1, -1, 2 [010]), + but also one new element that is the result of multiplying "x,y,z" and "-x,y,-z", + which is "x,-y,z" - the operation resulting from a mirror plane perpendicular + to the y-axis. In fact, this example demonstrated how the combination of + two crystallographic point groups (see PointGroup documentation and wiki) + "-1" and "2" results in a new point group "2/m". + + Most of the time it's not required to use Group directly, there are several + sub-classes that implement different behavior (CenteringGroup, CyclicGroup, + ProductOfCyclicGroups) and are easier to handle. For construction there is a simple + "factory function", that works for all Group-based classes which provide a + string-based constructor: + + Group_const_sptr group = GroupFactory::create("-x,-y,-z"); + + However, the most useful sub-class is SpaceGroup, which comes with its + own factory. For detailed information about the respective sub-classes, + please consult their documentation. + + @author Michael Wedel, Paul Scherrer Institut - SINQ + @date 03/10/2014 + + Copyright © 2014 PSI-MSS + + 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 . + + File change history is stored at: + Code Documentation is available at: + */ +class MANTID_GEOMETRY_DLL Group +{ +public: + Group(); + Group(const std::string &symmetryOperationString); + Group(const std::vector &symmetryOperations); + Group(const Group &other); + Group &operator =(const Group &other); + + virtual ~Group() { } + + size_t order() const; + std::vector getSymmetryOperations() const; + + Group operator *(const Group &other) const; + + std::vector operator *(const Kernel::V3D &vector) const; + + bool operator ==(const Group &other) const; + bool operator !=(const Group &other) const; + +protected: + void setSymmetryOperations(const std::vector &symmetryOperations); + + std::vector m_allOperations; + std::set m_operationSet; +}; + +typedef boost::shared_ptr Group_sptr; +typedef boost::shared_ptr Group_const_sptr; + +namespace GroupFactory { + /// Creates a Group sub-class of type T if T has a constructor that takes a string. + template + Group_const_sptr create(const std::string &initializationString) + { + return boost::make_shared(initializationString); + } +} + +MANTID_GEOMETRY_DLL Group_const_sptr operator *(const Group_const_sptr &lhs, const Group_const_sptr &rhs); +MANTID_GEOMETRY_DLL std::vector operator *(const Group_const_sptr &lhs, const Kernel::V3D &rhs); +MANTID_GEOMETRY_DLL bool operator ==(const Group_const_sptr &lhs, const Group_const_sptr &rhs); +MANTID_GEOMETRY_DLL bool operator !=(const Group_const_sptr &lhs, const Group_const_sptr &rhs); + + +} // namespace Geometry +} // namespace Mantid + +#endif /* MANTID_GEOMETRY_GROUP_H_ */ diff --git a/Code/Mantid/Framework/Geometry/inc/MantidGeometry/Crystal/IsotropicAtomBraggScatterer.h b/Code/Mantid/Framework/Geometry/inc/MantidGeometry/Crystal/IsotropicAtomBraggScatterer.h new file mode 100644 index 000000000000..aee5d4f00d9d --- /dev/null +++ b/Code/Mantid/Framework/Geometry/inc/MantidGeometry/Crystal/IsotropicAtomBraggScatterer.h @@ -0,0 +1,137 @@ +#ifndef MANTID_GEOMETRY_ISOTROPICATOMBRAGGSCATTERER_H_ +#define MANTID_GEOMETRY_ISOTROPICATOMBRAGGSCATTERER_H_ + +#include "MantidGeometry/Crystal/BraggScattererInCrystalStructure.h" +#include "MantidGeometry/Crystal/UnitCell.h" +#include "MantidKernel/NeutronAtom.h" + +namespace Mantid +{ +namespace Geometry +{ + +/** IsotropicAtomBraggScatterer + + IsotropicAtomBraggScatterer calculates the structure factor for + a given HKL using the following equation, which gives the + structure factor for the j-th atom in the unit cell: + + F(hkl)_j = b_j * o_j * DWF_j(hkl) * exp[i * 2pi * (h*x_j + k*y_j + l*z_j)] + + Since there are many terms in that equation, further explanation + is required. The j-th atom in a unit cell occupies a certain position, + here denoted by the fractional coordinates (x, y, z). With this information, + an important calculation can be already carried out, calculation of the + so called "phase". This term is easier seen when the complex part is written + using trigonometric functions: + + phi = 2pi * (h*x_j + k*y_j + l*z_j) + exp[i * phi] = cos(phi) + i * sin(phi) + + The magnitude of the complex number is determined first of all by the + scattering length, b_j (which is element specific and tabulated, in + Mantid this is in PhysicalConstants::NeutronAtom). It is multiplied + by the occupancy o_j, which is a number on the interval [0, 1], where 0 + is a bit meaningless, since it means "no atoms on this position" and + 1 represents a fully occupied position in the crystal lattice. This number + can be used to model statistically distributed defects. + + DWF_j denotes the Debye-Waller-factor, which models the diminishing + scattering power of atoms that are displaced from their position + (either due to temperature or other effects). It is defined like this: + + DWF_j(hkl) = exp[-2.0 * pi^2 * U * 1/d(hkl)^2] + + Here, U is given in Angstrom^2 (for a discussion of terms regarding + atomic displacement parameters, please see [1]), it is often of the + order 0.05. d(hkl) is alculated using the unit cell. The model used + in this class is isotropic (hence the class name), which may be insufficient + depending on the crystal structure, but as a first approximation it is + often enough. + + This class is designed to handle atoms in a unit cell. When a position is set, + the internally stored space group is used to generate all positions that are + symmetrically equivalent. In the structure factor calculation method + all contributions are summed. + + Easiest is demonstration by example. Copper crystallizes in the space group + Fm-3m, Cu atoms occupy the position (0,0,0) and, because of the F-centering, + also 3 additional positions. + + BraggScatterer_sptr cu = BraggScattererFactory::Instance().createScatterer( + "IsotropicAtomBraggScatterer", + "Element=Cu; SpaceGroup=F m -3 m") + cu->setProperty("UnitCell", unitCellToStr(cellCu)); + + StructureFactor F = cu->calculateStructureFactor(V3D(1, 1, 1)); + + The structure factor F contains contributions from all 4 copper atoms in the cell. + This is convenient especially for general positions. The general position + of Fm-3m for example has 192 equivalents. + + [1] http://ww1.iucr.org/comm/cnom/adp/finrep/finrep.html + + @author Michael Wedel, Paul Scherrer Institut - SINQ + @date 21/10/2014 + + Copyright © 2014 PSI-MSS + + 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 . + + File change history is stored at: + Code Documentation is available at: + */ +class IsotropicAtomBraggScatterer; + +typedef boost::shared_ptr IsotropicAtomBraggScatterer_sptr; + +class MANTID_GEOMETRY_DLL IsotropicAtomBraggScatterer : public BraggScattererInCrystalStructure +{ +public: + IsotropicAtomBraggScatterer(); + virtual ~IsotropicAtomBraggScatterer() { } + + std::string name() const { return "IsotropicAtomBraggScatterer"; } + BraggScatterer_sptr clone() const; + + std::string getElement() const; + PhysicalConstants::NeutronAtom getNeutronAtom() const; + + double getOccupancy() const; + double getU() const; + + StructureFactor calculateStructureFactor(const Kernel::V3D &hkl) const; + +protected: + void setElement(const std::string &element); + + void declareScattererProperties(); + void afterScattererPropertySet(const std::string &propertyName); + + double getDebyeWallerFactor(const Kernel::V3D &hkl) const; + double getScatteringLength() const; + + PhysicalConstants::NeutronAtom m_atom; + std::string m_label; +}; + +typedef boost::shared_ptr IsotropicAtomBraggScatterer_sptr; + + +} // namespace Geometry +} // namespace Mantid + +#endif /* MANTID_GEOMETRY_ISOTROPICATOMBRAGGSCATTERER_H_ */ diff --git a/Code/Mantid/Framework/Geometry/inc/MantidGeometry/Crystal/PointGroup.h b/Code/Mantid/Framework/Geometry/inc/MantidGeometry/Crystal/PointGroup.h index 8148492506f7..51d9bf485ecb 100644 --- a/Code/Mantid/Framework/Geometry/inc/MantidGeometry/Crystal/PointGroup.h +++ b/Code/Mantid/Framework/Geometry/inc/MantidGeometry/Crystal/PointGroup.h @@ -37,29 +37,36 @@ namespace Geometry virtual ~PointGroup() {} /// Name of the point group - virtual std::string getName() = 0; - /// Return true if the hkls are in same group - virtual bool isEquivalent(Kernel::V3D hkl, Kernel::V3D hkl2) = 0; + virtual std::string getName() const = 0; + /// Hermann-Mauguin symbol + std::string getSymbol() const; + virtual CrystalSystem crystalSystem() const = 0; + /// Return true if the hkls are in same group + virtual bool isEquivalent(const Kernel::V3D &hkl, const Kernel::V3D &hkl2) const = 0; + /// Returns a vector with all equivalent hkls std::vector getEquivalents(const Kernel::V3D &hkl) const; /// Returns the same hkl for all equivalent hkls Kernel::V3D getReflectionFamily(const Kernel::V3D &hkl) const; + /// In this method symmetry operations should be defined. It's called by the factory after construction of the object. + virtual void init() = 0; + protected: - PointGroup(); + PointGroup(const std::string &symbolHM); - void addSymmetryOperation(const SymmetryOperation_const_sptr &symmetryOperation); - std::vector getSymmetryOperations() const; + void setSymmetryOperations(const std::vector &generators); + void addSymmetryOperation(const SymmetryOperation &symmetryOperation); + std::vector getSymmetryOperations() const; - std::vector generateTransformationMatrices(const std::vector &symmetryOperations); - void setTransformationMatrices(const std::vector &matrices); + std::vector generateSymmetryOperations(const std::vector &symmetryOperations); std::set getEquivalentSet(const Kernel::V3D &hkl) const; - std::vector m_symmetryOperations; - std::vector m_transformationMatrices; + std::vector m_symmetryOperations; + std::string m_symbolHM; }; //------------------------------------------------------------------------ @@ -69,10 +76,12 @@ namespace Geometry public: PointGroupLaue1(); /// Name of the point group - virtual std::string getName(); + virtual std::string getName() const; /// Return true if the hkls are equivalent. - virtual bool isEquivalent(Kernel::V3D hkl, Kernel::V3D hkl2); + virtual bool isEquivalent(const Kernel::V3D &hkl, const Kernel::V3D &hkl2) const; virtual PointGroup::CrystalSystem crystalSystem() const; + + virtual void init(); }; //------------------------------------------------------------------------ @@ -82,10 +91,12 @@ namespace Geometry public: PointGroupLaue2(); /// Name of the point group - virtual std::string getName(); + virtual std::string getName() const; /// Return true if the hkls are equivalent. - virtual bool isEquivalent(Kernel::V3D hkl, Kernel::V3D hkl2); + virtual bool isEquivalent(const Kernel::V3D &hkl, const Kernel::V3D &hkl2) const; virtual PointGroup::CrystalSystem crystalSystem() const; + + virtual void init(); }; //------------------------------------------------------------------------ @@ -95,10 +106,12 @@ namespace Geometry public: PointGroupLaue3(); /// Name of the point group - virtual std::string getName(); + virtual std::string getName() const; /// Return true if the hkls are equivalent. - virtual bool isEquivalent(Kernel::V3D hkl, Kernel::V3D hkl2); + virtual bool isEquivalent(const Kernel::V3D &hkl, const Kernel::V3D &hkl2) const; virtual PointGroup::CrystalSystem crystalSystem() const; + + virtual void init(); }; //------------------------------------------------------------------------ @@ -108,10 +121,12 @@ namespace Geometry public: PointGroupLaue4(); /// Name of the point group - virtual std::string getName(); + virtual std::string getName() const; /// Return true if the hkls are equivalent. - virtual bool isEquivalent(Kernel::V3D hkl, Kernel::V3D hkl2); + virtual bool isEquivalent(const Kernel::V3D &hkl, const Kernel::V3D &hkl2) const; virtual PointGroup::CrystalSystem crystalSystem() const; + + virtual void init(); }; //------------------------------------------------------------------------ @@ -121,10 +136,12 @@ namespace Geometry public: PointGroupLaue5(); /// Name of the point group - virtual std::string getName(); + virtual std::string getName() const; /// Return true if the hkls are equivalent. - virtual bool isEquivalent(Kernel::V3D hkl, Kernel::V3D hkl2); + virtual bool isEquivalent(const Kernel::V3D &hkl, const Kernel::V3D &hkl2) const; virtual PointGroup::CrystalSystem crystalSystem() const; + + virtual void init(); }; //------------------------------------------------------------------------ @@ -134,10 +151,12 @@ namespace Geometry public: PointGroupLaue6(); /// Name of the point group - virtual std::string getName(); + virtual std::string getName() const; /// Return true if the hkls are equivalent. - virtual bool isEquivalent(Kernel::V3D hkl, Kernel::V3D hkl2); + virtual bool isEquivalent(const Kernel::V3D &hkl, const Kernel::V3D &hkl2) const; virtual PointGroup::CrystalSystem crystalSystem() const; + + virtual void init(); }; //------------------------------------------------------------------------ @@ -147,10 +166,12 @@ namespace Geometry public: PointGroupLaue7(); /// Name of the point group - virtual std::string getName(); + virtual std::string getName() const; /// Return true if the hkls are equivalent. - virtual bool isEquivalent(Kernel::V3D hkl, Kernel::V3D hkl2); + virtual bool isEquivalent(const Kernel::V3D &hkl, const Kernel::V3D &hkl2) const; virtual PointGroup::CrystalSystem crystalSystem() const; + + virtual void init(); }; //------------------------------------------------------------------------ @@ -160,10 +181,12 @@ namespace Geometry public: PointGroupLaue8(); /// Name of the point group - virtual std::string getName(); + virtual std::string getName() const; /// Return true if the hkls are equivalent. - virtual bool isEquivalent(Kernel::V3D hkl, Kernel::V3D hkl2); + virtual bool isEquivalent(const Kernel::V3D &hkl, const Kernel::V3D &hkl2) const; virtual PointGroup::CrystalSystem crystalSystem() const; + + virtual void init(); }; //------------------------------------------------------------------------ @@ -173,10 +196,12 @@ namespace Geometry public: PointGroupLaue9(); /// Name of the point group - virtual std::string getName(); + virtual std::string getName() const; /// Return true if the hkls are equivalent. - virtual bool isEquivalent(Kernel::V3D hkl, Kernel::V3D hkl2); + virtual bool isEquivalent(const Kernel::V3D &hkl, const Kernel::V3D &hkl2) const; virtual PointGroup::CrystalSystem crystalSystem() const; + + virtual void init(); }; //------------------------------------------------------------------------ @@ -186,10 +211,12 @@ namespace Geometry public: PointGroupLaue10(); /// Name of the point group - virtual std::string getName(); + virtual std::string getName() const; /// Return true if the hkls are equivalent. - virtual bool isEquivalent(Kernel::V3D hkl, Kernel::V3D hkl2); + virtual bool isEquivalent(const Kernel::V3D &hkl, const Kernel::V3D &hkl2) const; virtual PointGroup::CrystalSystem crystalSystem() const; + + virtual void init(); }; //------------------------------------------------------------------------ @@ -199,10 +226,12 @@ namespace Geometry public: PointGroupLaue11(); /// Name of the point group - virtual std::string getName(); + virtual std::string getName() const; /// Return true if the hkls are equivalent. - virtual bool isEquivalent(Kernel::V3D hkl, Kernel::V3D hkl2); + virtual bool isEquivalent(const Kernel::V3D &hkl, const Kernel::V3D &hkl2) const; virtual PointGroup::CrystalSystem crystalSystem() const; + + virtual void init(); }; //------------------------------------------------------------------------ @@ -212,10 +241,12 @@ namespace Geometry public: PointGroupLaue12(); /// Name of the point group - virtual std::string getName(); + virtual std::string getName() const; /// Return true if the hkls are equivalent. - virtual bool isEquivalent(Kernel::V3D hkl, Kernel::V3D hkl2); + virtual bool isEquivalent(const Kernel::V3D &hkl, const Kernel::V3D &hkl2) const; virtual PointGroup::CrystalSystem crystalSystem() const; + + virtual void init(); }; //------------------------------------------------------------------------ @@ -225,10 +256,12 @@ namespace Geometry public: PointGroupLaue13(); /// Name of the point group - virtual std::string getName(); + virtual std::string getName() const; /// Return true if the hkls are equivalent. - virtual bool isEquivalent(Kernel::V3D hkl, Kernel::V3D hkl2); + virtual bool isEquivalent(const Kernel::V3D &hkl, const Kernel::V3D &hkl2) const; virtual PointGroup::CrystalSystem crystalSystem() const; + + virtual void init(); }; diff --git a/Code/Mantid/Framework/Geometry/inc/MantidGeometry/Crystal/PointGroupFactory.h b/Code/Mantid/Framework/Geometry/inc/MantidGeometry/Crystal/PointGroupFactory.h new file mode 100644 index 000000000000..d926a68dbce4 --- /dev/null +++ b/Code/Mantid/Framework/Geometry/inc/MantidGeometry/Crystal/PointGroupFactory.h @@ -0,0 +1,102 @@ +#ifndef MANTID_GEOMETRY_POINTGROUPFACTORY_H_ +#define MANTID_GEOMETRY_POINTGROUPFACTORY_H_ + +#include "MantidGeometry/DllConfig.h" +#include "MantidKernel/DynamicFactory.h" +#include "MantidKernel/SingletonHolder.h" +#include "MantidGeometry/Crystal/PointGroup.h" + +namespace Mantid +{ +namespace Geometry +{ + /** PointGroupFactory + + A factory for point groups. Point group objects can be constructed by + supplying the Hermann-Mauguin-symbol like this: + + PointGroup_sptr cubic = PointGroupFactory::Instance().createPointgroup("m-3m"); + + Furthermore it's possible to query available point groups, either all available + groups or only point groups belonging to a certain crystal system. + + @author Michael Wedel, Paul Scherrer Institut - SINQ + @date 09/09/2014 + + Copyright © 2014 PSI-MSS + + 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 . + + File change history is stored at: + Code Documentation is available at: + */ + class MANTID_GEOMETRY_DLL PointGroupFactoryImpl : public Kernel::DynamicFactory + { + public: + PointGroup_sptr createPointGroup(const std::string &hmSymbol) const; + + std::vector getAllPointGroupSymbols() const; + std::vector getPointGroupSymbols(const PointGroup::CrystalSystem &crystalSystem) const; + + /// Subscribes a point group into the factory + template + void subscribePointGroup() + { + Kernel::Instantiator *instantiator = new Kernel::Instantiator; + PointGroup_sptr temporaryPointgroup = instantiator->createInstance(); + std::string hmSymbol = temporaryPointgroup->getSymbol(); + + subscribe(hmSymbol, instantiator); + + addToCrystalSystemMap(temporaryPointgroup->crystalSystem(), hmSymbol); + } + + /// Unsubscribes a point group from the factory + void unsubscribePointGroup(const std::string &hmSymbol) + { + unsubscribe(hmSymbol); + removeFromCrystalSystemMap(hmSymbol); + } + + private: + friend struct Mantid::Kernel::CreateUsingNew; + + PointGroupFactoryImpl(); + void addToCrystalSystemMap(const PointGroup::CrystalSystem &crystalSystem, const std::string &hmSymbol); + void removeFromCrystalSystemMap(const std::string &hmSymbol); + + std::map m_crystalSystemMap; + }; + +// This is taken from FuncMinimizerFactory +#ifdef _WIN32 + template class MANTID_GEOMETRY_DLL Mantid::Kernel::SingletonHolder; +#endif + +typedef Mantid::Kernel::SingletonHolder PointGroupFactory; + + +} // namespace Geometry +} // namespace Mantid + +#define DECLARE_POINTGROUP(classname) \ + namespace { \ + Mantid::Kernel::RegistrationHelper register_pointgroup_##classname( \ + ((Mantid::Geometry::PointGroupFactory::Instance().subscribePointGroup()) \ + , 0)); \ + } + +#endif /* MANTID_GEOMETRY_POINTGROUPFACTORY_H_ */ diff --git a/Code/Mantid/Framework/Geometry/inc/MantidGeometry/Crystal/ProductOfCyclicGroups.h b/Code/Mantid/Framework/Geometry/inc/MantidGeometry/Crystal/ProductOfCyclicGroups.h new file mode 100644 index 000000000000..6c244d42af47 --- /dev/null +++ b/Code/Mantid/Framework/Geometry/inc/MantidGeometry/Crystal/ProductOfCyclicGroups.h @@ -0,0 +1,80 @@ +#ifndef MANTID_GEOMETRY_PRODUCTGROUP_H_ +#define MANTID_GEOMETRY_PRODUCTGROUP_H_ + +#include "MantidGeometry/DllConfig.h" +#include "MantidGeometry/Crystal/Group.h" + +namespace Mantid +{ +namespace Geometry +{ + +/** ProductOfCyclicGroups : + + ProductOfCyclicGroups expands a bit on the explanations given in + CyclicGroup. As shown for example in [1], some point groups + cannot be expressed solely as a cyclic group. Instead it's + necessary to multiply two or three cyclic groups to obtain all + symmetry operations of that group. + + For this purpose, ProductOfCyclicGroups was created. It takes a set of + n symmetry operations, each of which is seen as a generator of + a cyclic group C_i. The resulting n groups ("factor groups") are + multiplied to form a product group G: + + G = C_1 * C_2 * ... * C_n + + Where C_i is generated by the symmetry operation S_i. The notation + in code to generate even large groups from a few generators + becomes very short using this class: + + Group_const_sptr pointGroup422 = GroupFactory::create("-y,x,z; x,-y,-z"); + + This is for example used in SpaceGroupFactory to create space groups + from a small set of generators supplied in the International Tables + for Crystallography A. + + [1] Shmueli, U. Acta Crystallogr. A 40, 559–567 (1984). + http://dx.doi.org/10.1107/S0108767384001161 + + @author Michael Wedel, Paul Scherrer Institut - SINQ + @date 08/10/2014 + + Copyright © 2014 PSI-MSS + + 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 . + + File change history is stored at: + Code Documentation is available at: + */ +class MANTID_GEOMETRY_DLL ProductOfCyclicGroups : public Group +{ +public: + ProductOfCyclicGroups(const std::string &generators); + ProductOfCyclicGroups(const std::vector &factorGroups); + virtual ~ProductOfCyclicGroups() { } + +protected: + Group_const_sptr getGeneratedGroup(const std::string &generators) const; + std::vector getFactorGroups(const std::vector &symmetryOperations) const; + Group_const_sptr getProductOfCyclicGroups(const std::vector &factorGroups) const; +}; + + +} // namespace Geometry +} // namespace Mantid + +#endif /* MANTID_GEOMETRY_PRODUCTGROUP_H_ */ diff --git a/Code/Mantid/Framework/Geometry/inc/MantidGeometry/Crystal/SpaceGroup.h b/Code/Mantid/Framework/Geometry/inc/MantidGeometry/Crystal/SpaceGroup.h new file mode 100644 index 000000000000..3b0887bdcd0c --- /dev/null +++ b/Code/Mantid/Framework/Geometry/inc/MantidGeometry/Crystal/SpaceGroup.h @@ -0,0 +1,96 @@ +#ifndef MANTID_GEOMETRY_SPACEGROUP_H_ +#define MANTID_GEOMETRY_SPACEGROUP_H_ + +#include "MantidGeometry/DllConfig.h" +#include "MantidGeometry/Crystal/Group.h" +#include "MantidGeometry/Crystal/SymmetryOperation.h" +#include "MantidKernel/V3D.h" + +#include + +namespace Mantid +{ +namespace Geometry +{ + +/** SpaceGroup : + + A class for representing space groups, inheriting from Group. + + SpaceGroup-objects represent a space group, which is a set + of symmetry operations. Along with storing the operations themselves, + which is realized through inheriting from Group, SpaceGroup also + stores a number (space group number according to the International + Tables for Crystallography A) and a Hermann-Mauguin-symbol. + + SpaceGroup may for example be used to generate all equivalent positions + within the unit cell: + + SpaceGroup_const_sptr someGroup; + + V3D position(0.13, 0.54, 0.38); + std::vector equivalents = someGroup->getEquivalentPositions(position); + + The class should not be instantiated directly, see SpaceGroupFactory instead. + + @author Michael Wedel, Paul Scherrer Institut - SINQ + @date 03/10/2014 + + Copyright © 2014 PSI-MSS + + 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 . + + File change history is stored at: + Code Documentation is available at: + */ +class MANTID_GEOMETRY_DLL SpaceGroup : public Group +{ +public: + SpaceGroup(size_t itNumber, const std::string &hmSymbol, const Group &group); + + SpaceGroup(const SpaceGroup &other); + SpaceGroup &operator =(const SpaceGroup &other); + + virtual ~SpaceGroup() { } + + size_t number() const; + std::string hmSymbol() const; + + template + std::vector getEquivalentPositions(const T &position) const + { + const std::vector &symmetryOperations = getSymmetryOperations(); + + std::set equivalents; + for(auto it = symmetryOperations.begin(); it != symmetryOperations.end(); ++it) { + equivalents.insert(Geometry::getWrappedVector((*it) * position)); + } + + return std::vector(equivalents.begin(), equivalents.end()); + } + +protected: + size_t m_number; + std::string m_hmSymbol; +}; + +typedef boost::shared_ptr SpaceGroup_sptr; +typedef boost::shared_ptr SpaceGroup_const_sptr; + +} // namespace Geometry +} // namespace Mantid + +#endif /* MANTID_GEOMETRY_SPACEGROUP_H_ */ diff --git a/Code/Mantid/Framework/Geometry/inc/MantidGeometry/Crystal/SpaceGroupFactory.h b/Code/Mantid/Framework/Geometry/inc/MantidGeometry/Crystal/SpaceGroupFactory.h new file mode 100644 index 000000000000..21c6bce2eb8c --- /dev/null +++ b/Code/Mantid/Framework/Geometry/inc/MantidGeometry/Crystal/SpaceGroupFactory.h @@ -0,0 +1,130 @@ +#ifndef MANTID_GEOMETRY_SPACEGROUPFACTORY_H_ +#define MANTID_GEOMETRY_SPACEGROUPFACTORY_H_ + +#include "MantidGeometry/DllConfig.h" +#include "MantidKernel/SingletonHolder.h" +#include "MantidGeometry/Crystal/SpaceGroup.h" +#include "MantidKernel/RegistrationHelper.h" + +#include + +namespace Mantid +{ +namespace Geometry +{ + +/** SpaceGroupFactory + + Factory for SpaceGroups. When a space group is subscribed, it + creates a prototype object and stores that. All space group + creations through the factory are just copy-constructions. + + Space groups can be subscribed using one of two available methods, + either by supplying ALL symmetry operations (this is called a "tabulated" + space group) or a set of generators (from International Tables for + Crystallography A). + + @author Michael Wedel, Paul Scherrer Institut - SINQ + @date 08/10/2014 + + Copyright © 2014 PSI-MSS + + 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 . + + File change history is stored at: + Code Documentation is available at: +*/ +class MANTID_GEOMETRY_DLL SpaceGroupFactoryImpl +{ +public: + virtual ~SpaceGroupFactoryImpl() { } + + SpaceGroup_const_sptr createSpaceGroup(const std::string &hmSymbol) const; + + bool isSubscribed(const std::string &hmSymbol) const; + bool isSubscribed(size_t number) const; + + std::vector subscribedSpaceGroupSymbols() const; + std::vector subscribedSpaceGroupSymbols(size_t number) const; + std::vector subscribedSpaceGroupNumbers() const; + + void unsubscribeSpaceGroup(const std::string &hmSymbol); + + void subscribeGeneratedSpaceGroup(size_t number, const std::string &hmSymbol, const std::string &generators); + void subscribeTabulatedSpaceGroup(size_t number, const std::string &hmSymbol, const std::string &symmetryOperations); + +protected: + void throwIfSubscribed(const std::string &hmSymbol); + + std::string getCenteringString(const std::string &hmSymbol) const; + Group_const_sptr getGeneratedGroup(const std::string &generators, const std::string ¢eringSymbol) const; + Group_const_sptr getTabulatedGroup(const std::string &symmetryOperations) const; + + SpaceGroup_const_sptr getPrototype(Group_const_sptr generatingGroup, size_t number, const std::string &hmSymbol) const; + + void subscribe(const SpaceGroup_const_sptr &prototype); + + SpaceGroup_const_sptr constructFromPrototype(const SpaceGroup_const_sptr prototype) const; + + std::multimap m_numberMap; + std::map m_prototypes; + + SpaceGroupFactoryImpl(); + +private: + friend struct Mantid::Kernel::CreateUsingNew; +}; + +// This is taken from FuncMinimizerFactory +#ifdef _WIN32 + template class MANTID_GEOMETRY_DLL Mantid::Kernel::SingletonHolder; +#endif + +typedef Mantid::Kernel::SingletonHolder SpaceGroupFactory; + + +} // namespace Geometry +} // namespace Mantid + +/* Macros for compile time space group registration + * + * The macros are a bit different than in other factories, + * because there is no identifier that can be used to generate + * a unique name for each RegistrationHelper instance. + * + * Instead, the __COUNTER__ macro is used, which is available + * in many compilers and is incremented every time it's called. + * + * Solution was found here: http://stackoverflow.com/a/1295338 + */ +#define SPGF_CONCAT_IMPL(x, y) x##y +#define SPGF_CONCAT(x, y) SPGF_CONCAT_IMPL(x, y) + +#define DECLARE_GENERATED_SPACE_GROUP(number,hmSymbol,generators) \ + namespace { \ + Mantid::Kernel::RegistrationHelper SPGF_CONCAT(register_spacegroup_, __COUNTER__)( \ +((Mantid::Geometry::SpaceGroupFactory::Instance().subscribeGeneratedSpaceGroup(number, hmSymbol, generators)) \ + , 0)); \ + } + +#define DECLARE_TABULATED_SPACE_GROUP(number,hmSymbol,symmetryOperations) \ + namespace { \ +Mantid::Kernel::RegistrationHelper SPGF_CONCAT(register_spacegroup_, __COUNTER__)( \ +((Mantid::Geometry::SpaceGroupFactory::Instance().subscribeTabulatedSpaceGroup(number, hmSymbol, symmetryOperations)) \ +, 0)); \ +} + +#endif /* MANTID_GEOMETRY_SPACEGROUPFACTORY_H_ */ diff --git a/Code/Mantid/Framework/Geometry/inc/MantidGeometry/Crystal/SymmetryOperation.h b/Code/Mantid/Framework/Geometry/inc/MantidGeometry/Crystal/SymmetryOperation.h index 9ca28e271d02..b2618a9c4baa 100644 --- a/Code/Mantid/Framework/Geometry/inc/MantidGeometry/Crystal/SymmetryOperation.h +++ b/Code/Mantid/Framework/Geometry/inc/MantidGeometry/Crystal/SymmetryOperation.h @@ -3,6 +3,7 @@ #include "MantidGeometry/DllConfig.h" #include "MantidKernel/Matrix.h" +#include "MantidGeometry/Crystal/V3R.h" #include @@ -13,35 +14,69 @@ namespace Geometry /** SymmetryOperation : - Crystallographic symmetry operations that involve rotations, (roto-)inversions - and mirror-planes in three dimensions can be represented by 3x3 integer - matrices. + Crystallographic symmetry operations are composed of a rotational component, + which is represented by a matrix and a translational part, which is + described by a vector. - In this interface, each symmetry operation has an "order", which is an + In this interface, each symmetry operation has a so-called order, which is an unsigned integer describing the number of times a symmetry operation has to be applied to an object until it is identical. Furthermore, each symmetry operation has a string-identifier. It contains the - symbol of the operation and the relevant direction, i.e. direction of a rotation - axis or direction perpendicular to a mirror plane. Examples are "2 [100]" for - a 2-fold rotation around the x-axis or "m [001]" for a mirror plane perpendicular - to the z-axis. For hexagonal coordinate systems the symmetry operations differ, - so their symbols are marked with an additional "h" at the end. One example is - "2 [100]h" which denotes a 2-fold axis in x-direction of a hexagonal coordinate - system. The matrices and identifiers are taken from [1]. + Jones faithful representation of the operation, as it is commonly used in + many crystallographic programs and of course the International Tables + for Crystallography, where the symmetry operations and their representations + may be found [1]. - Using the symmetry operations in code is easy. All that is required is constructing - an instance of the desired operation and calling its templated apply-method: + The Jones faithful notation is a very concise way of describing matrix/vector pairs. + The matrix/vector pair of a two-fold rotation axis along z is for example: - SymOpMirrorPlaneZ symOp; - V3D mirrored = symOp.apply(V3D(1, 1, 1)); + Matrix Vector + -1 0 0 0 + 0 -1 0 0 + 0 0 1 0 - Because the symmetry operation is using Kernel::IntMatrix internally, it can be - used on any object for which Kernel::IntMatrix implements a multiplication-operator. + This is described by the symbol '-x,-y,z'. If it were a 2_1 screw axis in the same + direction, the matrix/vector pair would look like this: - While all the operations could be represented by just one class (SymmetryOperation) - with the correct parameters set, having one class for each operation provides more - semantics in the code using these operations. + Matrix Vector + -1 0 0 0 + 0 -1 0 0 + 0 0 1 1/2 + + And this is represented by the string '-x,-y,z+1/2'. In hexagonal systems there + are often operations involving 1/3 or 2/3, so the translational part is kept as + a vector of rational numbers in order to carry out precise calculations. For details, + see the class V3R. + + Using the symmetry operations in code is easy, since SymmetryOperationSymbolParser is + automatically called by the string-based constructor of SymmetryOperation and the multiplication + operator is overloaded: + + SymmetryOperation inversion("-x,-y,-z"); + V3D hklPrime = inversion * V3D(1, 1, -1); // results in -1, -1, 1 + + The operator is templated and works for any object Kernel::IntMatrix can be + multiplied with and V3R can be added to (for example V3R, V3D). + + A special case is the multiplication of several symmetry operations, which can + be used to generate new operations: + + SymmetryOperation inversion("-x,-y,-z"); + SymmetryOperation identity = inversion * inversion; + + Please note that the components of the vector are wrapped to + the interval (0, 1] when two symmetry operations are combined. + + Constructing a SymmetryOperation object from a string is heavy, because the string + has to be parsed every time. It's preferable to use the available factory: + + SymmetryOperation inversion = SymmetryOperationFactory::Instance().createSymOp("-x,-y,-z"); + + It stores a prototype of the created operation and copy constructs a new + instance on subsequent calls with the same string. + + SymmetryOperation-objects are for example used in PointGroup. References: [1] International Tables for Crystallography, Volume A, Fourth edition, pp 797-798. @@ -70,134 +105,62 @@ namespace Geometry File change history is stored at: Code Documentation is available at: */ +class SymmetryOperation; + class MANTID_GEOMETRY_DLL SymmetryOperation { public: + SymmetryOperation(); + SymmetryOperation(const std::string &identifier); + + SymmetryOperation(const SymmetryOperation &other); + SymmetryOperation &operator =(const SymmetryOperation &other); + virtual ~SymmetryOperation() { } + const Kernel::IntMatrix &matrix() const; + const V3R &vector() const; + size_t order() const; std::string identifier() const; + bool isIdentity() const; + bool hasTranslation() const; + + /// Returns the transformed vector. template - T apply(const T &operand) const + T operator *(const T &operand) const { - return m_matrix * operand; - } - -protected: - SymmetryOperation(size_t order, Kernel::IntMatrix matrix, std::string identifier); - void setMatrixFromArray(int array[]); - - size_t m_order; - Kernel::IntMatrix m_matrix; - std::string m_identifier; -}; - -typedef boost::shared_ptr SymmetryOperation_sptr; -typedef boost::shared_ptr SymmetryOperation_const_sptr; - -// Identity -class MANTID_GEOMETRY_DLL SymOpIdentity : public SymmetryOperation -{ -public: - SymOpIdentity(); -}; - -// Inversion -class MANTID_GEOMETRY_DLL SymOpInversion : public SymmetryOperation -{ -public: - SymOpInversion(); -}; - -// Rotations 2-fold -// x-axis -class MANTID_GEOMETRY_DLL SymOpRotationTwoFoldX : public SymmetryOperation -{ -public: - SymOpRotationTwoFoldX(); -}; - -// y-axis -class MANTID_GEOMETRY_DLL SymOpRotationTwoFoldY : public SymmetryOperation -{ -public: - SymOpRotationTwoFoldY(); -}; - -// z-axis -class MANTID_GEOMETRY_DLL SymOpRotationTwoFoldZ : public SymmetryOperation -{ -public: - SymOpRotationTwoFoldZ(); -}; + if(!hasTranslation()) { + return m_matrix * operand; + } -// x-axis -class MANTID_GEOMETRY_DLL SymOpRotationTwoFoldXHexagonal : public SymmetryOperation -{ -public: - SymOpRotationTwoFoldXHexagonal(); -}; + return (m_matrix * operand) + m_vector; + } -// 210, hexagonal -class MANTID_GEOMETRY_DLL SymOpRotationTwoFold210Hexagonal : public SymmetryOperation -{ -public: - SymOpRotationTwoFold210Hexagonal(); -}; + SymmetryOperation operator *(const SymmetryOperation &operand) const; + SymmetryOperation inverse() const; -// Rotations 4-fold -// z-axis -class MANTID_GEOMETRY_DLL SymOpRotationFourFoldZ : public SymmetryOperation -{ -public: - SymOpRotationFourFoldZ(); -}; + bool operator !=(const SymmetryOperation &other) const; + bool operator ==(const SymmetryOperation &other) const; + bool operator <(const SymmetryOperation &other) const; -// Rotations 3-fold -// z-axis, hexagonal -class MANTID_GEOMETRY_DLL SymOpRotationThreeFoldZHexagonal : public SymmetryOperation -{ -public: - SymOpRotationThreeFoldZHexagonal(); -}; +protected: + SymmetryOperation(const Kernel::IntMatrix &matrix, const V3R &vector); -// 111 -class MANTID_GEOMETRY_DLL SymOpRotationThreeFold111 : public SymmetryOperation -{ -public: - SymOpRotationThreeFold111(); -}; + void init(const Kernel::IntMatrix &matrix, const V3R &vector); -// Rotations 6-fold -// z-axis, hexagonal -class MANTID_GEOMETRY_DLL SymOpRotationSixFoldZHexagonal : public SymmetryOperation -{ -public: - SymOpRotationSixFoldZHexagonal(); -}; + size_t getOrderFromMatrix(const Kernel::IntMatrix &matrix) const; -// Mirror planes -// y-axis -class MANTID_GEOMETRY_DLL SymOpMirrorPlaneY : public SymmetryOperation -{ -public: - SymOpMirrorPlaneY(); -}; -// z-axis -class MANTID_GEOMETRY_DLL SymOpMirrorPlaneZ : public SymmetryOperation -{ -public: - SymOpMirrorPlaneZ(); + size_t m_order; + Kernel::IntMatrix m_matrix; + V3R m_vector; + std::string m_identifier; }; -// 210, hexagonal -class MANTID_GEOMETRY_DLL SymOpMirrorPlane210Hexagonal : public SymmetryOperation -{ -public: - SymOpMirrorPlane210Hexagonal(); -}; +MANTID_GEOMETRY_DLL V3R getWrappedVector(const V3R &vector); +MANTID_GEOMETRY_DLL Kernel::V3D getWrappedVector(const Kernel::V3D &vector); } // namespace Geometry diff --git a/Code/Mantid/Framework/Geometry/inc/MantidGeometry/Crystal/SymmetryOperationFactory.h b/Code/Mantid/Framework/Geometry/inc/MantidGeometry/Crystal/SymmetryOperationFactory.h new file mode 100644 index 000000000000..fe4095486338 --- /dev/null +++ b/Code/Mantid/Framework/Geometry/inc/MantidGeometry/Crystal/SymmetryOperationFactory.h @@ -0,0 +1,102 @@ +#ifndef MANTID_GEOMETRY_SYMMETRYOPERATIONFACTORY_H_ +#define MANTID_GEOMETRY_SYMMETRYOPERATIONFACTORY_H_ + +#include "MantidGeometry/DllConfig.h" +#include "MantidKernel/SingletonHolder.h" +#include "MantidGeometry/Crystal/SymmetryOperation.h" +#include "MantidGeometry/Crystal/SymmetryOperationSymbolParser.h" +#include "MantidKernel/RegistrationHelper.h" + +#include +#include +#include + +namespace Mantid +{ +namespace Geometry +{ + /** SymmetryOperationFactory + + A factory for symmetry operations. Symmetry operations are stored + with respect to their identifier (see SymmetryOperation for details). + + Creation of symmetry operations is then performed like this: + + SymmetryOperations inversion = SymmetryOperationFactory::Instance().createSymOp("x,y,z"); + + Creating a symmetry operation object automatically registers the object + as a prototype and subsequent creations are much more efficient because + the symbol does not need to be parsed. + + Available symmetry operations may be queried with SymmetryOperation::subscribedSymbols. + + @author Michael Wedel, Paul Scherrer Institut - SINQ + @date 10/09/2014 + + Copyright © 2014 PSI-MSS + + 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 . + + File change history is stored at: + Code Documentation is available at: + */ + class MANTID_GEOMETRY_DLL SymmetryOperationFactoryImpl + { + public: + SymmetryOperation createSymOp(const std::string &identifier); + std::vector createSymOps(const std::string &identifiers); + std::vector createSymOps(const std::vector &identifiers); + + void subscribeSymOp(const std::string &identifier); + void unsubscribeSymOp(const std::string &identifier); + + bool isSubscribed(const std::string &identifier) const; + + std::vector subscribedSymbols() const; + + protected: + void subscribe(const std::string &alias, const SymmetryOperation &prototype); + + std::map m_prototypes; + + private: + friend struct Mantid::Kernel::CreateUsingNew; + + + SymmetryOperationFactoryImpl(); + + + }; + +// This is taken from FuncMinimizerFactory +#ifdef _WIN32 + template class MANTID_GEOMETRY_DLL Mantid::Kernel::SingletonHolder; +#endif + +typedef Mantid::Kernel::SingletonHolder SymmetryOperationFactory; + + +} // namespace Geometry +} // namespace Mantid + +#define DECLARE_SYMMETRY_OPERATION(operation,name) \ + namespace { \ + Mantid::Kernel::RegistrationHelper register_symop_##name( \ + ((Mantid::Geometry::SymmetryOperationFactory::Instance().subscribeSymOp(operation)) \ + , 0)); \ + } + +#endif /* MANTID_GEOMETRY_SYMMETRYOPERATIONFACTORY_H_ */ diff --git a/Code/Mantid/Framework/Geometry/inc/MantidGeometry/Crystal/SymmetryOperationSymbolParser.h b/Code/Mantid/Framework/Geometry/inc/MantidGeometry/Crystal/SymmetryOperationSymbolParser.h new file mode 100644 index 000000000000..e4b4f24cece0 --- /dev/null +++ b/Code/Mantid/Framework/Geometry/inc/MantidGeometry/Crystal/SymmetryOperationSymbolParser.h @@ -0,0 +1,102 @@ +#ifndef MANTID_GEOMETRY_SYMMETRYOPERATIONSYMBOLPARSER_H_ +#define MANTID_GEOMETRY_SYMMETRYOPERATIONSYMBOLPARSER_H_ + +#include "MantidGeometry/DllConfig.h" +#include "MantidGeometry/Crystal/SymmetryOperation.h" +#include + + +namespace Mantid +{ +namespace Geometry +{ + + /** SymmetryOperationSymbolParser : + + This is a parser for symmetry operation symbols in the Jones + faithful representation. It creates matrix and a vector component + from the given symbol. First an example with no translational component, + the inversion: + + -x,-y,-z + + Parsing this symbol returns the following matrix/vector pair: + + Matrix Vector + -1 0 0 0 + 0 -1 0 0 + 0 0 -1 0 + + Translational components, as required for screw axes and glide planes + are given as rational numbers, such as in this 2_1 screw axis around z: + + -x,-y,z+1/2 + + Which returns the following matrix/vector pair: + + Matrix Vector + -1 0 0 0 + 0 -1 0 0 + 0 0 1 1/2 + + From these components, a SymmetryOperation object can be constructed. + See the documentation for SymmetryOperation and SymmetryOperationFactory. + + @author Michael Wedel, Paul Scherrer Institut - SINQ + @date 30/09/2014 + + Copyright © 2014 PSI-MSS + + 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 . + + File change history is stored at: + Code Documentation is available at: + */ + + class MANTID_GEOMETRY_DLL SymmetryOperationSymbolParser + { + public: + ~SymmetryOperationSymbolParser() { } + + static std::pair parseIdentifier(const std::string &identifier); + static std::string getNormalizedIdentifier(const std::pair &data); + static std::string getNormalizedIdentifier(const Kernel::IntMatrix &matrix, const V3R &vector); + + protected: + SymmetryOperationSymbolParser(); + + static std::pair parseComponents(const std::vector &components); + static std::string getCleanComponentString(const std::string &componentString); + static std::pair, RationalNumber> parseComponent(const std::string &component); + + static void processMatrixRowToken(const std::string &matrixToken, std::vector &matrixRow); + static void addToVector(std::vector &vector, const std::vector &add); + static std::vector getVectorForSymbol(const char symbol, const char sign = '+'); + static int getFactorForSign(const char sign); + + static void processVectorComponentToken(const std::string &rationalNumberToken, RationalNumber &vectorComponent); + + static bool isValidMatrixRow(const std::vector &matrixRow); + + static bool regexMembersInitialized(); + static void initializeRegexMembers(); + }; + + +} // namespace Geometry +} // namespace Mantid + +#endif /* MANTID_GEOMETRY_SYMMETRYOPERATIONSYMBOLPARSER_H_ */ diff --git a/Code/Mantid/Framework/Geometry/inc/MantidGeometry/Crystal/UnitCell.h b/Code/Mantid/Framework/Geometry/inc/MantidGeometry/Crystal/UnitCell.h index 248cdc134ffa..018163d8f50c 100644 --- a/Code/Mantid/Framework/Geometry/inc/MantidGeometry/Crystal/UnitCell.h +++ b/Code/Mantid/Framework/Geometry/inc/MantidGeometry/Crystal/UnitCell.h @@ -178,6 +178,10 @@ namespace Geometry }; MANTID_GEOMETRY_DLL std::ostream& operator<<(std::ostream &out, const UnitCell& unitCell); + + MANTID_GEOMETRY_DLL UnitCell strToUnitCell(const std::string &unitCellString); + MANTID_GEOMETRY_DLL std::string unitCellToStr(const UnitCell &unitCell); + } // namespace Mantid } // namespace Geometry diff --git a/Code/Mantid/Framework/Geometry/inc/MantidGeometry/Crystal/V3R.h b/Code/Mantid/Framework/Geometry/inc/MantidGeometry/Crystal/V3R.h new file mode 100644 index 000000000000..ca6daf13b13d --- /dev/null +++ b/Code/Mantid/Framework/Geometry/inc/MantidGeometry/Crystal/V3R.h @@ -0,0 +1,135 @@ +#ifndef MANTID_GEOMETRY_V3R_H_ +#define MANTID_GEOMETRY_V3R_H_ + +#include "MantidGeometry/DllConfig.h" + +#include "MantidKernel/V3D.h" +#include "MantidKernel/Matrix.h" + +#include + +namespace Mantid +{ +namespace Geometry +{ + +/** V3R : + + In crystallography, many operations use rational numbers like 1/2, 1/4 + or 2/3. Floating point numbers can approximate these, but calculations + involving these approximations are never exact. + + V3R is a vector with three rational components, implemented using + boost::rational. This way, crystallographic calculations involving + fractional vectors may be carried out exactly (for example symmetry + operations with a translational component). + + @author Michael Wedel, Paul Scherrer Institut - SINQ + @date 26/09/2014 + + Copyright © 2014 PSI-MSS + + 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 . + + File change history is stored at: + Code Documentation is available at: + */ +typedef boost::rational RationalNumber; + +class MANTID_GEOMETRY_DLL V3R +{ +public: + V3R(); + V3R(const RationalNumber &x, const RationalNumber &y, const RationalNumber &z); + V3R(const std::vector &vector); + + V3R(const V3R &other); + V3R &operator =(const V3R &other); + + ~V3R(); + + const RationalNumber& x() const; + void setX(const RationalNumber &newX); + + const RationalNumber& y() const; + void setY(const RationalNumber &newY); + + const RationalNumber& z() const; + void setZ(const RationalNumber &newZ); + + RationalNumber& operator [](size_t index); + const RationalNumber& operator [](size_t index) const; + + // Operations with other vectors of rational numbers + V3R operator +(const V3R &other) const; + V3R &operator +=(const V3R &other); + + V3R operator -() const; + V3R operator -(const V3R &other) const; + V3R &operator -=(const V3R &other); + + // Operations with integers + V3R operator +(int other) const; + V3R &operator +=(int other); + + V3R operator -(int other) const; + V3R &operator -=(int other); + + V3R operator *(int other) const; + V3R &operator *=(int other); + + V3R operator /(int other) const; + V3R &operator /=(int other); + + // Operations with rational numbers + V3R operator +(const RationalNumber &other) const; + V3R &operator +=(const RationalNumber &other); + + V3R operator -(const RationalNumber &other) const; + V3R &operator -=(const RationalNumber &other); + + V3R operator *(const RationalNumber &other) const; + V3R &operator *=(const RationalNumber &other); + + V3R operator /(const RationalNumber &other) const; + V3R &operator /=(const RationalNumber &other); + + // Operations with V3D + operator Kernel::V3D() const; + Kernel::V3D operator +(const Kernel::V3D &other) const; + Kernel::V3D operator -(const Kernel::V3D &other) const; + + // Comparison operators + bool operator ==(const V3R &other) const; + bool operator !=(const V3R &other) const; + bool operator <(const V3R &other) const; + + bool operator ==(int other) const; + bool operator !=(int other) const; + +protected: + RationalNumber m_x; + RationalNumber m_y; + RationalNumber m_z; + +}; + +MANTID_GEOMETRY_DLL V3R operator *(const Kernel::IntMatrix &lhs, const V3R &rhs); + +} // namespace Geometry +} // namespace Mantid + +#endif /* MANTID_GEOMETRY_V3R_H_ */ diff --git a/Code/Mantid/Framework/Geometry/inc/MantidGeometry/Instrument.h b/Code/Mantid/Framework/Geometry/inc/MantidGeometry/Instrument.h index d4ba268778db..d27293759d60 100644 --- a/Code/Mantid/Framework/Geometry/inc/MantidGeometry/Instrument.h +++ b/Code/Mantid/Framework/Geometry/inc/MantidGeometry/Instrument.h @@ -25,11 +25,11 @@ namespace Mantid //------------------------------------------------------------------ // Forward declarations //------------------------------------------------------------------ - class XMLlogfile; + class XMLInstrumentParameter; class ParameterMap; class ReferenceFrame; /// Convenience typedef - typedef std::map, boost::shared_ptr > InstrumentParameterCache; + typedef std::map, boost::shared_ptr > InstrumentParameterCache; /** Base Instrument Class. diff --git a/Code/Mantid/Framework/Geometry/inc/MantidGeometry/Instrument/InstrumentDefinitionParser.h b/Code/Mantid/Framework/Geometry/inc/MantidGeometry/Instrument/InstrumentDefinitionParser.h index b8821e77bf92..e02f557fe3c6 100644 --- a/Code/Mantid/Framework/Geometry/inc/MantidGeometry/Instrument/InstrumentDefinitionParser.h +++ b/Code/Mantid/Framework/Geometry/inc/MantidGeometry/Instrument/InstrumentDefinitionParser.h @@ -78,7 +78,7 @@ namespace Geometry boost::shared_ptr parseXML(Kernel::ProgressBase * prog); /// Add/overwrite any parameters specified in instrument with param values specified in XML elements - void setComponentLinks(boost::shared_ptr& instrument, Poco::XML::Element* pElem); + void setComponentLinks(boost::shared_ptr& instrument, Poco::XML::Element* pElem, Kernel::ProgressBase* progress = NULL); std::string getMangledName(); diff --git a/Code/Mantid/Framework/Geometry/inc/MantidGeometry/Instrument/ParameterMap.h b/Code/Mantid/Framework/Geometry/inc/MantidGeometry/Instrument/ParameterMap.h index bd9fcf4e26e1..238d434d893c 100644 --- a/Code/Mantid/Framework/Geometry/inc/MantidGeometry/Instrument/ParameterMap.h +++ b/Code/Mantid/Framework/Geometry/inc/MantidGeometry/Instrument/ParameterMap.h @@ -10,12 +10,7 @@ #include "MantidGeometry/Objects/BoundingBox.h" #include "MantidKernel/Cache.h" -#ifndef HAS_UNORDERED_MAP_H #include -#else -#include -#endif - #include #include @@ -59,34 +54,19 @@ namespace Geometry File change history is stored at: . Code Documentation is available at: */ -#ifndef HAS_UNORDERED_MAP_H - /// Parameter map iterator typedef + /// Parameter map iterator typedef typedef std::multimap >::iterator component_map_it; typedef std::multimap >::const_iterator component_map_cit; -#else - /// Parameter map iterator typedef - typedef std::tr1::unordered_multimap >::iterator component_map_it; - typedef std::tr1::unordered_multimap >::const_iterator component_map_cit; -#endif class MANTID_GEOMETRY_DLL ParameterMap { public: -#ifndef HAS_UNORDERED_MAP_H /// Parameter map typedef typedef std::multimap > pmap; /// Parameter map iterator typedef typedef std::multimap >::iterator pmap_it; /// Parameter map iterator typedef typedef std::multimap >::const_iterator pmap_cit; -#else - /// Parameter map typedef - typedef std::tr1::unordered_multimap > pmap; - /// Parameter map iterator typedef - typedef std::tr1::unordered_multimap >::iterator pmap_it; - /// Parameter map iterator typedef - typedef std::tr1::unordered_multimap >::const_iterator pmap_cit; -#endif /// Default constructor ParameterMap(); /// Returns true if the map is empty, false otherwise diff --git a/Code/Mantid/Framework/Geometry/inc/MantidGeometry/Instrument/XMLlogfile.h b/Code/Mantid/Framework/Geometry/inc/MantidGeometry/Instrument/XMLInstrumentParameter.h similarity index 82% rename from Code/Mantid/Framework/Geometry/inc/MantidGeometry/Instrument/XMLlogfile.h rename to Code/Mantid/Framework/Geometry/inc/MantidGeometry/Instrument/XMLInstrumentParameter.h index d71a0da1a979..7759da933220 100644 --- a/Code/Mantid/Framework/Geometry/inc/MantidGeometry/Instrument/XMLlogfile.h +++ b/Code/Mantid/Framework/Geometry/inc/MantidGeometry/Instrument/XMLInstrumentParameter.h @@ -1,5 +1,5 @@ -#ifndef MANTID_GEOMETRY_XMLLOGFILE_H_ -#define MANTID_GEOMETRY_XMLLOGFILE_H_ +#ifndef MANTID_GEOMETRY_XMLINSTRUMENTPARAMETER_H_ +#define MANTID_GEOMETRY_XMLINSTRUMENTPARAMETER_H_ //---------------------------------------------------------------------- // Includes @@ -24,8 +24,10 @@ namespace Mantid class IComponent; /** - This class links parameters defined in ISIS log files to components of the instrument tree - defined in the instrument definition. + This class is used to store information about parameters in XML instrument definition files and + instrument parameter files, so that such parameters can be added to a workspace when appropriate. + For example log file parameters make reference to log file entry values in raw data, and such + parameters needs raw data to be loaded first. @author Anders Markvardsen, ISIS, RAL @date 12/1/2009 @@ -49,11 +51,11 @@ namespace Mantid File change history is stored at: */ - class MANTID_GEOMETRY_DLL XMLlogfile + class MANTID_GEOMETRY_DLL XMLInstrumentParameter { public: /// Default constructor - XMLlogfile(const std::string& logfileID, const std::string& value, const boost::shared_ptr& interpolation, + XMLInstrumentParameter(const std::string& logfileID, const std::string& value, const boost::shared_ptr& interpolation, const std::string& formula, const std::string& formulaUnit, const std::string& resultUnit, const std::string& paramName, const std::string& type, const std::string& tie, const std::vector& constraint, std::string& penaltyFactor, @@ -61,9 +63,9 @@ namespace Mantid const std::string& eq, const Geometry::IComponent* comp, double angleConvertConst); /// Destructor - ~XMLlogfile() {} + ~XMLInstrumentParameter() {} - // log file XML attributes from instrument definition file + // XML attributes from instrument definition file or instrument parameter file const std::string m_logfileID; ///< logfile id const std::string m_value; ///< rather then extracting value from logfile, specify a value directly const std::string m_paramName; ///< parameter name @@ -91,5 +93,5 @@ namespace Mantid } // namespace Geometry } // namespace Mantid -#endif /*MANTID_GEOMETRY_XMLLOGFILE_H_*/ +#endif /*MANTID_GEOMETRY_XMLINSTRUMENTPARAMETER_H_*/ diff --git a/Code/Mantid/Framework/Geometry/inc/MantidGeometry/Objects/Object.h b/Code/Mantid/Framework/Geometry/inc/MantidGeometry/Objects/Object.h index 208f7b00663b..48e07ce48eeb 100644 --- a/Code/Mantid/Framework/Geometry/inc/MantidGeometry/Objects/Object.h +++ b/Code/Mantid/Framework/Geometry/inc/MantidGeometry/Objects/Object.h @@ -5,19 +5,19 @@ // Includes //---------------------------------------------------------------------- #include "MantidGeometry/DllConfig.h" -#include "MantidKernel/V3D.h" +#include "MantidKernel/Material.h" #include "MantidKernel/Quat.h" +#include "MantidKernel/V3D.h" #include "BoundingBox.h" #include namespace Mantid { - + //---------------------------------------------------------------------- + // Forward declarations + //---------------------------------------------------------------------- namespace Geometry { - //---------------------------------------------------------------------- - // Forward declarations - //---------------------------------------------------------------------- class Rule; class CompGrp; class Surface; @@ -76,6 +76,9 @@ namespace Mantid void setName(const int nx) { ObjName=nx; } ///< Set Name int getName() const { return ObjName; } ///< Get Name + void setMaterial(const Kernel::Material & material); + const Kernel::Material & material() const; + /// Return whether this object has a valid shape bool hasValidShape() const; int setObject(const int ON,const std::string& Ln); @@ -132,7 +135,7 @@ namespace Mantid const BoundingBox & getBoundingBox() const; /// Define axis-aligned bounding box void defineBoundingBox(const double& xmax,const double& ymax,const double& zmax,const double& xmin,const double& ymin,const double& zmin); - /// Set a null bounding box for this object + /// Set a null bounding box for this object void setNullBoundingBox(); // find internal point to object int getPointInObject(Kernel::V3D& point) const; @@ -176,11 +179,11 @@ namespace Mantid double getTriangleSolidAngle(const Kernel::V3D& a, const Kernel::V3D& b, const Kernel::V3D& c, const Kernel::V3D& observer) const; double CuboidSolidAngle(const Kernel::V3D observer, const std::vector vectors) const; double SphereSolidAngle(const Kernel::V3D observer, const std::vector vectors, const double radius) const; - double CylinderSolidAngle(const Kernel::V3D & observer, const Mantid::Kernel::V3D & centre, - const Mantid::Kernel::V3D & axis, + double CylinderSolidAngle(const Kernel::V3D & observer, const Mantid::Kernel::V3D & centre, + const Mantid::Kernel::V3D & axis, const double radius, const double height) const; - double ConeSolidAngle(const Kernel::V3D & observer, const Mantid::Kernel::V3D & centre, - const Mantid::Kernel::V3D & axis, + double ConeSolidAngle(const Kernel::V3D & observer, const Mantid::Kernel::V3D & centre, + const Mantid::Kernel::V3D & axis, const double radius, const double height) const; /// Geometry Handle for rendering @@ -200,6 +203,8 @@ namespace Mantid double* getTriangleVertices() const; /// original shape xml used to generate this object. std::string m_shapeXML; + /// material composition + Kernel::Material m_material; protected: std::vector SurList; ///< Full surfaces (make a map including complementary object ?) diff --git a/Code/Mantid/Framework/Geometry/inc/MantidGeometry/Objects/Track.h b/Code/Mantid/Framework/Geometry/inc/MantidGeometry/Objects/Track.h index df549d77b1c1..a1a1d3448b76 100644 --- a/Code/Mantid/Framework/Geometry/inc/MantidGeometry/Objects/Track.h +++ b/Code/Mantid/Framework/Geometry/inc/MantidGeometry/Objects/Track.h @@ -6,6 +6,7 @@ //---------------------------------------------------------------------- #include "MantidGeometry/DllConfig.h" #include "MantidGeometry/IComponent.h" +#include "MantidGeometry/Objects/Object.h" #include "MantidKernel/Tolerance.h" #include @@ -51,23 +52,18 @@ namespace Mantid */ struct MANTID_GEOMETRY_DLL Link { - /** - * Default constructor - */ - inline Link() : entryPoint(),exitPoint(),distFromStart(), - distInsideObject(), componentID(NULL) - {} - /** * Constuctor * @param entry :: Kernel::V3D point to start * @param exit :: Kernel::V3D point to end track * @param totalDistance :: Total distance from start of track + * @param obj :: A reference to the object that was intersected * @param compID :: An optional component identifier for the physical object hit. (Default=NULL) */ - inline Link(const Kernel::V3D& entry,const Kernel::V3D& exit, const double totalDistance, const ComponentID compID = NULL) : - entryPoint(entry),exitPoint(exit),distFromStart(totalDistance), distInsideObject(entryPoint.distance(exitPoint)), - componentID(compID) + inline Link(const Kernel::V3D& entry,const Kernel::V3D& exit, const double totalDistance, + const Object & obj, const ComponentID compID = NULL) : + entryPoint(entry),exitPoint(exit),distFromStart(totalDistance), distInsideObject(entryPoint.distance(exitPoint)), + object(&obj), componentID(compID) {} /// Less than operator inline bool operator<(const Link& other) const { return distFromStart < other.distFromStart; } @@ -76,20 +72,21 @@ namespace Mantid /** @name Attributes. */ //@{ - Kernel::V3D entryPoint; ///< Entry point - Kernel::V3D exitPoint; ///< Exit point + Kernel::V3D entryPoint; ///< Entry point + Kernel::V3D exitPoint; ///< Exit point double distFromStart; ///< Total distance from track beginning double distInsideObject; ///< Total distance covered inside object + const Object * object; ///< The object that was intersected ComponentID componentID; ///< ComponentID of the intersected component //@} - + }; /** * Stores a point of intersection along a track. The component intersected * is linked using its ComponentID. * - * Ordering for IntersectionPoint is special since we need that when dist is close + * Ordering for IntersectionPoint is special since we need that when dist is close * that the +/- flag is taken into * account. */ @@ -97,22 +94,25 @@ namespace Mantid { /** * Constuctor - * @param flag :: Indicates the direction of travel of the track with respect + * @param flag :: Indicates the direction of travel of the track with respect * to the object: +1 is entering, -1 is leaving. * @param end :: The end point for this partial segment * @param distFromStartOfTrack :: Total distance from start of track * @param compID :: An optional unique ID marking the component intersected. (Default=NULL) + * @param obj :: A reference to the object that was intersected */ inline IntersectionPoint(const int flag, const Kernel::V3D& end, - const double distFromStartOfTrack, const ComponentID compID = NULL) : - directionFlag(flag),endPoint(end),distFromStart(distFromStartOfTrack), componentID(compID) + const double distFromStartOfTrack, const Object & obj, + const ComponentID compID = NULL) : + directionFlag(flag),endPoint(end),distFromStart(distFromStartOfTrack), + object(&obj), componentID(compID) {} /** * A IntersectionPoint is less-than another if either * (a) the difference in distances is greater than the tolerance and this distance is less than the other or * (b) the distance is less than the other and this point is defined as an exit point - * + * * @param other :: IntersectionPoint object to compare * @return True if the object is considered less than, otherwise false. */ @@ -127,6 +127,7 @@ namespace Mantid int directionFlag; ///< Directional flag Kernel::V3D endPoint; ///< Point double distFromStart; ///< Total distance from track begin + const Object * object; ///< The object that was intersected ComponentID componentID; ///< Unique component ID //@} }; @@ -155,10 +156,12 @@ namespace Mantid /// Destructor ~Track(); /// Adds a point of intersection to the track - void addPoint(const int directionFlag, const Kernel::V3D& endPoint, const ComponentID compID = NULL); + void addPoint(const int directionFlag, const Kernel::V3D& endPoint, + const Object & obj, const ComponentID compID = NULL); /// Adds a link to the track - int addLink(const Kernel::V3D& firstPoint,const Kernel::V3D& secondPoint, - const double distanceAlongTrack, const ComponentID compID = NULL); + int addLink(const Kernel::V3D& firstPoint,const Kernel::V3D& secondPoint, + const double distanceAlongTrack, const Object & obj, + const ComponentID compID = NULL); /// Remove touching Links that have identical components void removeCojoins(); /// Construct links between added points @@ -175,10 +178,10 @@ namespace Mantid /// Returns an interator to the start of the set of links LType::const_iterator begin() const { return m_links.begin(); } /// Returns an interator to one-past-the-end of the set of links - LType::const_iterator end() const { return m_links.end(); } + LType::const_iterator end() const { return m_links.end(); } /// Returns the number of links - int count() const { return static_cast(m_links.size()); } - /// Is the link complete? + int count() const { return static_cast(m_links.size()); } + /// Is the link complete? int nonComplete() const; private: diff --git a/Code/Mantid/Framework/Geometry/inc/MantidGeometry/Surfaces/Line.h b/Code/Mantid/Framework/Geometry/inc/MantidGeometry/Surfaces/Line.h index e5f8957178be..45952481c5df 100644 --- a/Code/Mantid/Framework/Geometry/inc/MantidGeometry/Surfaces/Line.h +++ b/Code/Mantid/Framework/Geometry/inc/MantidGeometry/Surfaces/Line.h @@ -62,7 +62,7 @@ namespace Mantid Kernel::V3D Direct; ///< Direction of outer surface (Unit Vector) int lambdaPair(const int ix,const std::pair, - std::complex >& SQ,std::vector& PntOut) const; + std::complex >& SQ,std::list& PntOut) const; public: @@ -86,10 +86,10 @@ namespace Mantid int setLine(const Kernel::V3D&,const Kernel::V3D&); ///< input Origin + direction - int intersect(std::vector&,const Quadratic&) const; - int intersect(std::vector&,const Cylinder&) const; - int intersect(std::vector&,const Plane&) const; - int intersect(std::vector&,const Sphere&) const; + int intersect(std::list&,const Quadratic&) const; + int intersect(std::list&,const Cylinder&) const; + int intersect(std::list&,const Plane&) const; + int intersect(std::list&,const Sphere&) const; }; diff --git a/Code/Mantid/Framework/Geometry/inc/MantidGeometry/Surfaces/LineIntersectVisit.h b/Code/Mantid/Framework/Geometry/inc/MantidGeometry/Surfaces/LineIntersectVisit.h index dba93f49362a..f225702a7c68 100644 --- a/Code/Mantid/Framework/Geometry/inc/MantidGeometry/Surfaces/LineIntersectVisit.h +++ b/Code/Mantid/Framework/Geometry/inc/MantidGeometry/Surfaces/LineIntersectVisit.h @@ -4,7 +4,7 @@ #include "MantidGeometry/Surfaces/BaseVisit.h" #include "MantidGeometry/Surfaces/Line.h" #include "MantidKernel/V3D.h" -#include +#include namespace Mantid { @@ -56,8 +56,8 @@ namespace Mantid private: Line ATrack; ///< The line - std::vector PtOut; ///< The intersection point - std::vector DOut; ///< The distance + std::list PtOut; ///< The intersection point + std::list DOut; ///< The distance void procTrack(); @@ -66,7 +66,7 @@ namespace Mantid LineIntersectVisit(const Kernel::V3D&, const Kernel::V3D&); /// Destructor - virtual ~LineIntersectVisit() {}; + virtual ~LineIntersectVisit() {} void Accept(const Surface&); void Accept(const Quadratic&); @@ -78,10 +78,10 @@ namespace Mantid // Accessor /// Get the distance - const std::vector& getDistance() const + const std::list& getDistance() const { return DOut; } /// Get the intersection points - const std::vector& getPoints() const + const std::list& getPoints() const { return PtOut; } /// Get the number of intersection points unsigned long getNPoints() const { return (unsigned long)PtOut.size(); } diff --git a/Code/Mantid/Framework/Geometry/inc/MantidGeometry/Surfaces/Plane.h b/Code/Mantid/Framework/Geometry/inc/MantidGeometry/Surfaces/Plane.h index 8e4c34e0d412..cdb7e3c93834 100644 --- a/Code/Mantid/Framework/Geometry/inc/MantidGeometry/Surfaces/Plane.h +++ b/Code/Mantid/Framework/Geometry/inc/MantidGeometry/Surfaces/Plane.h @@ -82,7 +82,7 @@ namespace Mantid double distance(const Kernel::V3D&) const; ///< distance from a point double getDistance() const { return Dist; } ///< Distance from origin - Kernel::V3D getNormal() const { return NormV; } ///< Normal to plane (+ve surface) + const Kernel::V3D & getNormal() const { return NormV; } ///< Normal to plane (+ve surface) void rotate(const Kernel::Matrix&); void displace(const Kernel::V3D&); diff --git a/Code/Mantid/Framework/Geometry/src/Crystal/BraggScatterer.cpp b/Code/Mantid/Framework/Geometry/src/Crystal/BraggScatterer.cpp new file mode 100644 index 000000000000..7c33c0300218 --- /dev/null +++ b/Code/Mantid/Framework/Geometry/src/Crystal/BraggScatterer.cpp @@ -0,0 +1,80 @@ +#include "MantidGeometry/Crystal/BraggScatterer.h" + + +namespace Mantid +{ +namespace Geometry +{ + +using namespace Kernel; + +/// Default constructor. +BraggScatterer::BraggScatterer() : + PropertyManager(), + m_propagatingGroupName("PropagatingProperty"), + m_isInitialized(false) +{ +} + +/// Initialization method that calls declareProperties() and sets initialized state to true. +void BraggScatterer::initialize() +{ + declareProperties(); + + m_isInitialized = true; +} + +/// Returns whether the instance has been initialized. +bool BraggScatterer::isInitialized() +{ + return m_isInitialized; +} + +/// Checks whether a property with the given name is exposed to BraggScattererComposite. +bool BraggScatterer::isPropertyExposedToComposite(const std::string &propertyName) const +{ + Property *property = getProperty(propertyName); + + return isPropertyExposedToComposite(property); +} + +/// Checks if a property is exposed to BraggScattererComposite or throws std::invalid_argument if a null-pointer is supplied. +bool BraggScatterer::isPropertyExposedToComposite(Property *property) const +{ + if(!property) { + throw std::invalid_argument("Cannot determine propagation behavior of null-property."); + } + + return property->getGroup() == getPropagatingGroupName(); +} + +/** + * Exposes the property with the supplied name to BraggScattererComposite + * + * When a property is marked to be exposed to BraggScattererComposite, the composite + * also declares this property and tries to propagate the value assigned to the + * composite's property to all its members. + * + * @param propertyName :: Name of the parameter that should be exposed. + */ +void BraggScatterer::exposePropertyToComposite(const std::string &propertyName) +{ + setPropertyGroup(propertyName, m_propagatingGroupName); +} + +/// Removes exposure to composite for specified property. +void BraggScatterer::unexposePropertyFromComposite(const std::string &propertyName) +{ + setPropertyGroup(propertyName, ""); +} + +/// Returns the group name that is used to mark properties that are propagated. +const std::string &BraggScatterer::getPropagatingGroupName() const +{ + return m_propagatingGroupName; +} + + + +} // namespace Geometry +} // namespace Mantid diff --git a/Code/Mantid/Framework/Geometry/src/Crystal/BraggScattererFactory.cpp b/Code/Mantid/Framework/Geometry/src/Crystal/BraggScattererFactory.cpp new file mode 100644 index 000000000000..66c9df3c48cf --- /dev/null +++ b/Code/Mantid/Framework/Geometry/src/Crystal/BraggScattererFactory.cpp @@ -0,0 +1,43 @@ +#include "MantidGeometry/Crystal/BraggScattererFactory.h" +#include "MantidKernel/LibraryManager.h" + +namespace Mantid +{ +namespace Geometry +{ + +/** + * Creates an initialized instance of the desired scatterer class + * + * This method tries to construct an instance of the class specified by the "name"-parameter. + * If it is not found, an exception is thrown (see DynamicFactory::create). Otherwise, + * the object is initialized. If the second argument is not empty, it is expected + * to contain a semi-colon separated list of "name=value"-pairs. These pairs need to be + * valid input for assigning properties of the created scatterer. See the example in + * the general class documentation. + * + * @param name :: Class name to construct. + * @param properties :: Semi-colon separated "name=value"-pairs. + * @return Initialized scatterer object. + */ +BraggScatterer_sptr BraggScattererFactoryImpl::createScatterer(const std::string &name, const std::string &properties) +{ + BraggScatterer_sptr scatterer = create(name); + scatterer->initialize(); + + if(!properties.empty()) { + scatterer->setProperties(properties); + } + + return scatterer; +} + +/// Private constructor. +BraggScattererFactoryImpl::BraggScattererFactoryImpl() +{ + Kernel::LibraryManager::Instance(); +} + + +} // namespace Geometry +} // namespace Mantid diff --git a/Code/Mantid/Framework/Geometry/src/Crystal/BraggScattererInCrystalStructure.cpp b/Code/Mantid/Framework/Geometry/src/Crystal/BraggScattererInCrystalStructure.cpp new file mode 100644 index 000000000000..029245e4aa3a --- /dev/null +++ b/Code/Mantid/Framework/Geometry/src/Crystal/BraggScattererInCrystalStructure.cpp @@ -0,0 +1,151 @@ +#include "MantidGeometry/Crystal/BraggScattererInCrystalStructure.h" +#include + +#include +#include +#include "MantidKernel/ListValidator.h" +#include "MantidGeometry/Crystal/SpaceGroupFactory.h" + +namespace Mantid +{ +namespace Geometry +{ + +using namespace Kernel; + +/// Default constructor. +BraggScattererInCrystalStructure::BraggScattererInCrystalStructure() : + BraggScatterer(), + m_position(), + m_cell(UnitCell(1, 1, 1, 90, 90, 90)), + m_spaceGroup() +{ +} + +/// Sets the position of the scatterer to the supplied coordinates - vector is wrapped to [0, 1) and equivalent positions are recalculated. +void BraggScattererInCrystalStructure::setPosition(const Kernel::V3D &position) +{ + m_position = getWrappedVector(position); + + recalculateEquivalentPositions(); +} + +/// Returns the position of the scatterer. +Kernel::V3D BraggScattererInCrystalStructure::getPosition() const +{ + return m_position; +} + +/// Returns all equivalent positions of the scatterer according to the assigned space group. +std::vector BraggScattererInCrystalStructure::getEquivalentPositions() const +{ + return m_equivalentPositions; +} + +/// Returns the cell which is currently set. +UnitCell BraggScattererInCrystalStructure::getCell() const +{ + return m_cell; +} + +/// Returns the assigned space group. +SpaceGroup_const_sptr BraggScattererInCrystalStructure::getSpaceGroup() const +{ + return m_spaceGroup; +} + +/// Assigns a unit cell, which may be required for certain calculations. +void BraggScattererInCrystalStructure::setCell(const UnitCell &cell) +{ + m_cell = cell; +} + +/// Sets the space group, which is required for calculation of equivalent positions. +void BraggScattererInCrystalStructure::setSpaceGroup(const SpaceGroup_const_sptr &spaceGroup) +{ + m_spaceGroup = spaceGroup; + + recalculateEquivalentPositions(); +} + +/// Declares basic properties, should not be overridden by subclasses, use declareScattererProperties instead. +void BraggScattererInCrystalStructure::declareProperties() +{ + /* This is required for default behavior. It's not possible to call it + * from the constructure, because it's not guaranteed that the space group + * factory has been filled at the time the ScattererFactory is filled. + */ + setSpaceGroup(SpaceGroupFactory::Instance().createSpaceGroup("P 1")); + + declareProperty(new Kernel::PropertyWithValue("Position", V3D(0.0, 0.0, 0.0)), "Position of the scatterer"); + + IValidator_sptr unitCellStringValidator = boost::make_shared(); + declareProperty(new Kernel::PropertyWithValue("UnitCell", "1.0 1.0 1.0 90.0 90.0 90.0", unitCellStringValidator), "Unit cell."); + exposePropertyToComposite("UnitCell"); + + IValidator_sptr spaceGroupValidator = boost::make_shared >(SpaceGroupFactory::Instance().subscribedSpaceGroupSymbols()); + declareProperty(new Kernel::PropertyWithValue("SpaceGroup", "P 1", spaceGroupValidator), "Space group."); + exposePropertyToComposite("SpaceGroup"); + + + declareScattererProperties(); +} + +/** + * Additional property processing + * + * Takes care of handling new property values, for example for construction of a space group + * from string and so on. + * + * Please note that derived classes should not re-implement this method, as + * the processing for the base properties is absolutely necessary. Instead, all deriving + * classes should override the method afterScattererPropertySet, which is called + * from this method. + */ +void BraggScattererInCrystalStructure::afterPropertySet(const std::string &propertyName) +{ + if(propertyName == "Position") { + PropertyWithValue *position = dynamic_cast *>(getPointerToProperty("Position")); + setPosition((*position)()); + } else if(propertyName == "SpaceGroup") { + setSpaceGroup(SpaceGroupFactory::Instance().createSpaceGroup(getProperty("SpaceGroup"))); + } else if(propertyName == "UnitCell") { + setCell(strToUnitCell(getProperty("UnitCell"))); + } + + afterScattererPropertySet(propertyName); +} + +/// Uses the stored space group to calculate all equivalent positions or if present. +void BraggScattererInCrystalStructure::recalculateEquivalentPositions() +{ + m_equivalentPositions.clear(); + + if(m_spaceGroup) { + m_equivalentPositions = m_spaceGroup * m_position; + } else { + m_equivalentPositions.push_back(m_position); + } +} + + +/// Return a clone of the validator. +IValidator_sptr UnitCellStringValidator::clone() const +{ + return boost::make_shared(*this); +} + +/// Check if the string is valid input for Geometry::strToUnitCell. +std::string UnitCellStringValidator::checkValidity(const std::string &unitCellString) const +{ + boost::regex unitCellRegex("((\\d+(\\.\\d+){0,1}\\s+){2}|(\\d+(\\.\\d+){0,1}\\s+){5})(\\d+(\\.\\d+){0,1}\\s*)"); + + if(!boost::regex_match(unitCellString, unitCellRegex)) { + return "Unit cell string is invalid: " + unitCellString; + } + + return ""; +} + +} // namespace Geometry +} // namespace Mantid diff --git a/Code/Mantid/Framework/Geometry/src/Crystal/CenteringGroup.cpp b/Code/Mantid/Framework/Geometry/src/Crystal/CenteringGroup.cpp new file mode 100644 index 000000000000..e8d2ba62de0b --- /dev/null +++ b/Code/Mantid/Framework/Geometry/src/Crystal/CenteringGroup.cpp @@ -0,0 +1,137 @@ +#include "MantidGeometry/Crystal/CenteringGroup.h" +#include "MantidGeometry/Crystal/SymmetryOperationFactory.h" + +#include + +namespace Mantid +{ +namespace Geometry +{ + +/// String-based constructor which accepts centering symbols such as P, I or F. +CenteringGroup::CenteringGroup(const std::string ¢eringSymbol) : + Group(), + m_type(), + m_symbol() +{ + m_type = CenteringGroupCreator::Instance().getCenteringType(centeringSymbol); + m_symbol = centeringSymbol.substr(0, 1); + + setSymmetryOperations(CenteringGroupCreator::Instance().getSymmetryOperations(m_type)); +} + +/// Returns the centering type of the group (distinguishes between Rhombohedral obverse and reverse). +CenteringGroup::CenteringType CenteringGroup::getType() const +{ + return m_type; +} + +/// Returns the centering symbol, does not distinguish between Rhombohedral obverse and reverse. +std::string CenteringGroup::getSymbol() const +{ + return m_symbol; +} + + +/// Returns centering type enum value if centering symbol exists, throws std::invalid_argument exception otherwise. +CenteringGroup::CenteringType CenteringGroupCreatorImpl::getCenteringType(const std::string ¢eringSymbol) const +{ + auto it = m_centeringSymbolMap.find(centeringSymbol); + + if(it == m_centeringSymbolMap.end()) { + throw std::invalid_argument("Centering does not exist: " + centeringSymbol); + } + + return it->second; +} + +/// Returns a vector of symmetry operations for the given centering type or throws std::invalid_argument if an invalid value is supplied. +std::vector CenteringGroupCreatorImpl::getSymmetryOperations(CenteringGroup::CenteringType centeringType) const +{ + switch(centeringType) { + case CenteringGroup::P: + return getPrimitive(); + case CenteringGroup::I: + return getBodyCentered(); + case CenteringGroup::A: + return getACentered(); + case CenteringGroup::B: + return getBCentered(); + case CenteringGroup::C: + return getCCentered(); + case CenteringGroup::F: + return getFCentered(); + case CenteringGroup::Robv: + return getRobvCentered(); + case CenteringGroup::Rrev: + return getRrevCentered(); + default: + throw std::invalid_argument("Unknown centering type."); + } +} + +/// Returns symmetry operations for P-centering. +std::vector CenteringGroupCreatorImpl::getPrimitive() const +{ + return SymmetryOperationFactory::Instance().createSymOps("x,y,z"); +} + +/// Returns symmetry operations for I-centering. +std::vector CenteringGroupCreatorImpl::getBodyCentered() const +{ + return SymmetryOperationFactory::Instance().createSymOps("x,y,z; x+1/2,y+1/2,z+1/2"); +} + +/// Returns symmetry operations for A-centering. +std::vector CenteringGroupCreatorImpl::getACentered() const +{ + return SymmetryOperationFactory::Instance().createSymOps("x,y,z; x,y+1/2,z+1/2"); +} + +/// Returns symmetry operations for B-centering. +std::vector CenteringGroupCreatorImpl::getBCentered() const +{ + return SymmetryOperationFactory::Instance().createSymOps("x,y,z; x+1/2,y,z+1/2"); +} + +/// Returns symmetry operations for C-centering. +std::vector CenteringGroupCreatorImpl::getCCentered() const +{ + return SymmetryOperationFactory::Instance().createSymOps("x,y,z; x+1/2,y+1/2,z"); +} + +/// Returns symmetry operations for F-centering. +std::vector CenteringGroupCreatorImpl::getFCentered() const +{ + return SymmetryOperationFactory::Instance().createSymOps("x,y,z; x,y+1/2,z+1/2; x+1/2,y,z+1/2; x+1/2,y+1/2,z"); +} + +/// Returns symmetry operations for R-centering, obverse setting. +std::vector CenteringGroupCreatorImpl::getRobvCentered() const +{ + return SymmetryOperationFactory::Instance().createSymOps("x,y,z; x+1/3,y+2/3,z+2/3; x+2/3,y+1/3,z+1/3"); +} + +/// Returns symmetry operations for R-centering, reverse setting. +std::vector CenteringGroupCreatorImpl::getRrevCentered() const +{ + return SymmetryOperationFactory::Instance().createSymOps("x,y,z; x+1/3,y+2/3,z+1/3; x+2/3,y+1/3,z+2/3"); +} + +CenteringGroupCreatorImpl::CenteringGroupCreatorImpl() : + m_centeringSymbolMap() +{ + m_centeringSymbolMap.insert(std::make_pair("P", CenteringGroup::P)); + m_centeringSymbolMap.insert(std::make_pair("I", CenteringGroup::I)); + m_centeringSymbolMap.insert(std::make_pair("A", CenteringGroup::A)); + m_centeringSymbolMap.insert(std::make_pair("B", CenteringGroup::B)); + m_centeringSymbolMap.insert(std::make_pair("C", CenteringGroup::C)); + m_centeringSymbolMap.insert(std::make_pair("F", CenteringGroup::F)); + m_centeringSymbolMap.insert(std::make_pair("R", CenteringGroup::Robv)); + m_centeringSymbolMap.insert(std::make_pair("Robv", CenteringGroup::Robv)); + m_centeringSymbolMap.insert(std::make_pair("Rrev", CenteringGroup::Rrev)); +} + + +} // namespace Geometry +} // namespace Mantid diff --git a/Code/Mantid/Framework/Geometry/src/Crystal/CompositeBraggScatterer.cpp b/Code/Mantid/Framework/Geometry/src/Crystal/CompositeBraggScatterer.cpp new file mode 100644 index 000000000000..c19d8a1e668d --- /dev/null +++ b/Code/Mantid/Framework/Geometry/src/Crystal/CompositeBraggScatterer.cpp @@ -0,0 +1,190 @@ +#include "MantidGeometry/Crystal/CompositeBraggScatterer.h" +#include "MantidGeometry/Crystal/BraggScattererFactory.h" +#include + +namespace Mantid +{ +namespace Geometry +{ + +using namespace Kernel; + +/// Default constructor. +CompositeBraggScatterer::CompositeBraggScatterer() : + BraggScatterer(), + m_scatterers() +{ +} + +/// Static method that creates a new instance of CompositeBraggScatterer and returns it (wrapped by a smart pointer). +CompositeBraggScatterer_sptr CompositeBraggScatterer::create() +{ + CompositeBraggScatterer_sptr compositeScatterer = boost::make_shared(); + compositeScatterer->initialize(); + + return compositeScatterer; +} + +/// Creates and empty CompositeBraggScatterer and adds all scatterers contained in the supplied vector. +CompositeBraggScatterer_sptr CompositeBraggScatterer::create(const std::vector &scatterers) +{ + CompositeBraggScatterer_sptr collection = CompositeBraggScatterer::create(); + + for(auto it = scatterers.begin(); it != scatterers.end(); ++it) { + collection->addScatterer(*it); + } + + return collection; +} + +/// Recursively clones all contained scatterers and returns the resulting composite. +BraggScatterer_sptr CompositeBraggScatterer::clone() const +{ + CompositeBraggScatterer_sptr clone = boost::make_shared(); + clone->initialize(); + + for(auto it = m_scatterers.begin(); it != m_scatterers.end(); ++it) { + clone->addScatterer(*it); + } + + clone->setProperties(this->asString(false, ';')); + + return clone; +} + +/// Clones the supplied scatterer, assigns the internal space group and unit cell to the clone and adds it to the composite. +void CompositeBraggScatterer::addScatterer(const BraggScatterer_sptr &scatterer) +{ + if(!scatterer) { + throw std::invalid_argument("Cannot process null-scatterer."); + } + + BraggScatterer_sptr localScatterer = scatterer->clone(); + + m_scatterers.push_back(localScatterer); + + redeclareProperties(); +} + +/// Returns the number of scatterers contained in the composite. +size_t CompositeBraggScatterer::nScatterers() const +{ + return m_scatterers.size(); +} + +/// Returns the i-th scatterer or throws an std::out_of_range exception. +BraggScatterer_sptr CompositeBraggScatterer::getScatterer(size_t i) const +{ + if(i >= nScatterers()) { + throw std::out_of_range("Index is out of range."); + } + + return m_scatterers[i]; +} + +/// Removes the i-th scatterer from the composite or throws an std::out_of_range exception. +void CompositeBraggScatterer::removeScatterer(size_t i) +{ + if(i >= nScatterers()) { + throw std::out_of_range("Index is out of range."); + } + + m_scatterers.erase(m_scatterers.begin() + i); + + redeclareProperties(); +} + +/// Calculates the structure factor for the given HKL by summing all contributions from contained scatterers. +StructureFactor CompositeBraggScatterer::calculateStructureFactor(const Kernel::V3D &hkl) const +{ + StructureFactor sum(0.0, 0.0); + + for(auto it = m_scatterers.begin(); it != m_scatterers.end(); ++it) { + sum += (*it)->calculateStructureFactor(hkl); + } + + return sum; +} + +/// Makes sure that space group and unit cell are propagated to all stored scatterers. +void CompositeBraggScatterer::afterPropertySet(const std::string &propertyName) +{ + propagateProperty(propertyName); +} + +/// Propagates the given property to all contained scatterers that have this property. +void CompositeBraggScatterer::propagateProperty(const std::string &propertyName) +{ + std::string propertyValue = getPropertyValue(propertyName); + + for(auto it = m_scatterers.begin(); it != m_scatterers.end(); ++it) { + propagatePropertyToScatterer(*it, propertyName, propertyValue); + } +} + +void CompositeBraggScatterer::propagatePropertyToScatterer(BraggScatterer_sptr &scatterer, const std::string &propertyName, const std::string &propertyValue) +{ + try { + scatterer->setPropertyValue(propertyName, propertyValue); + } catch(Kernel::Exception::NotFoundError) { + // do nothing. + } +} + +/** + * Synchronize properties with scatterer members + * + * This method synchronizes the properties of CompositeBraggScatterer with the properties + * of the contained BraggScatterer instances. It adds new properties if required + * and removed properties that are no longer used (for example because the member that + * introduced the property has been removed). + */ +void CompositeBraggScatterer::redeclareProperties() +{ + std::map propertyUseCount = getPropertyCountMap(); + + for(auto it = m_scatterers.begin(); it != m_scatterers.end(); ++it) { + // Check if any of the declared properties is in this scatterer (and set value if that's the case) + for(auto prop = propertyUseCount.begin(); prop != propertyUseCount.end(); ++prop) { + if((*it)->existsProperty(prop->first)) { + prop->second += 1; + + propagatePropertyToScatterer(*it, prop->first, getPropertyValue(prop->first)); + } + } + + // Use the properties of this scatterer which have been marked as exposed to composite + std::vector properties = (*it)->getPropertiesInGroup(getPropagatingGroupName()); + for(auto prop = properties.begin(); prop != properties.end(); ++prop) { + std::string propertyName = (*prop)->name(); + if(!existsProperty(propertyName)) { + declareProperty((*prop)->clone()); + } + } + } + + // Remove unused properties + for(auto it = propertyUseCount.begin(); it != propertyUseCount.end(); ++it) { + if(it->second == 0) { + removeProperty(it->first); + } + } +} + +/// Returns a map with all declared property names and 0. +std::map CompositeBraggScatterer::getPropertyCountMap() const +{ + std::map propertyUseCount; + + std::vector compositeProperties = getProperties(); + for(auto it = compositeProperties.begin(); it != compositeProperties.end(); ++it) { + propertyUseCount.insert(std::make_pair((*it)->name(), 0)); + } + + return propertyUseCount; +} + +DECLARE_BRAGGSCATTERER(CompositeBraggScatterer) + +} // namespace Geometry +} // namespace Mantid diff --git a/Code/Mantid/Framework/Geometry/src/Crystal/CyclicGroup.cpp b/Code/Mantid/Framework/Geometry/src/Crystal/CyclicGroup.cpp new file mode 100644 index 000000000000..b65c308663c2 --- /dev/null +++ b/Code/Mantid/Framework/Geometry/src/Crystal/CyclicGroup.cpp @@ -0,0 +1,38 @@ +#include "MantidGeometry/Crystal/CyclicGroup.h" +#include "MantidGeometry/Crystal/SymmetryOperationFactory.h" +#include + +namespace Mantid +{ +namespace Geometry +{ + +/// Construct cyclic group from one symmetry operation by applying it to itself until identity is obtained. +CyclicGroup::CyclicGroup(const std::string &symmetryOperationString) : + Group(generateAllOperations(SymmetryOperationFactory::Instance().createSymOp(symmetryOperationString))) +{ + +} + +/// Construct CyclicGroup from a SymmetryOperation object. +CyclicGroup::CyclicGroup(const SymmetryOperation &symmetryOperation) : + Group(generateAllOperations(symmetryOperation)) +{ +} + +/// Returns a vector with all symmetry operations that are part of the cyclic group defined by the generating operation. +std::vector CyclicGroup::generateAllOperations(const SymmetryOperation &operation) const +{ + std::vector symOps(1, operation); + + for(size_t i = 1; i < operation.order(); ++i) { + symOps.push_back(operation * symOps.back()); + } + + return symOps; +} + + + +} // namespace Geometry +} // namespace Mantid diff --git a/Code/Mantid/Framework/Geometry/src/Crystal/Group.cpp b/Code/Mantid/Framework/Geometry/src/Crystal/Group.cpp new file mode 100644 index 000000000000..411b3428553e --- /dev/null +++ b/Code/Mantid/Framework/Geometry/src/Crystal/Group.cpp @@ -0,0 +1,160 @@ +#include "MantidGeometry/Crystal/Group.h" +#include "MantidGeometry/Crystal/SymmetryOperationFactory.h" +#include + +namespace Mantid +{ +namespace Geometry +{ + +/// Default constructor. Creates a group with one symmetry operation (identity). +Group::Group() : + m_allOperations(), + m_operationSet() +{ + std::vector operation(1); + setSymmetryOperations(operation); +} + +/// Uses SymmetryOperationFactory to create a vector of symmetry operations from the string. +Group::Group(const std::string &symmetryOperationString) : + m_allOperations(), + m_operationSet() +{ + setSymmetryOperations(SymmetryOperationFactory::Instance().createSymOps(symmetryOperationString)); +} + +/// Constructs a group from the symmetry operations in the vector, duplicates are removed. +Group::Group(const std::vector &symmetryOperations) : + m_allOperations(), + m_operationSet() +{ + setSymmetryOperations(symmetryOperations); +} + +/// Copy constructor. +Group::Group(const Group &other) : + m_allOperations(other.m_allOperations), + m_operationSet(other.m_operationSet) +{ + +} + +/// Assignment operator. +Group &Group::operator =(const Group &other) +{ + m_allOperations = other.m_allOperations; + m_operationSet = other.m_operationSet; + + return *this; +} + +/// Returns the order of the group, which is the number of symmetry operations. +size_t Group::order() const +{ + return m_allOperations.size(); +} + +/// Returns a vector with all symmetry operations. +std::vector Group::getSymmetryOperations() const +{ + return m_allOperations; +} + +/** + * Multiplication operator of two groups. + * + * Multiplies each element of this group with each element of the other + * group, as described in the class documentation. + * + * @param other :: A group. + * @return The product resulting from the group multiplication. + */ +Group Group::operator *(const Group &other) const +{ + std::vector result; + result.reserve(order() * other.order()); + + for(auto selfOp = m_allOperations.begin(); selfOp != m_allOperations.end(); ++selfOp) { + for(auto otherOp = other.m_allOperations.begin(); otherOp != other.m_allOperations.end(); ++otherOp) { + result.push_back((*selfOp) * (*otherOp)); + } + } + + return Group(result); +} + +/// Returns a unique set of Kernel::V3D resulting from applying all symmetry operations, vectors are wrapped to [0, 1). +std::vector Group::operator *(const Kernel::V3D &vector) const +{ + std::set result; + + for(auto op = m_allOperations.begin(); op != m_allOperations.end(); ++op) { + result.insert(Geometry::getWrappedVector((*op) * vector)); + } + + return std::vector(result.begin(), result.end()); +} + +/// Returns true if both groups contain the same set of symmetry operations. +bool Group::operator ==(const Group &other) const +{ + return m_operationSet == other.m_operationSet; +} + +/// Returns true if groups are different from eachother. +bool Group::operator !=(const Group &other) const +{ + return !(this->operator ==(other)); +} + +/// Assigns symmetry operations, throws std::invalid_argument if vector is empty. +void Group::setSymmetryOperations(const std::vector &symmetryOperations) +{ + if(symmetryOperations.size() < 1) { + throw std::invalid_argument("Group needs at least one element."); + } + + m_operationSet = std::set(symmetryOperations.begin(), symmetryOperations.end()); + m_allOperations = std::vector(m_operationSet.begin(), m_operationSet.end()); +} + +/// Convenience operator* for directly multiplying groups using shared pointers. +Group_const_sptr operator *(const Group_const_sptr &lhs, const Group_const_sptr &rhs) +{ + if(!lhs || !rhs) { + throw std::invalid_argument("One of the operands is null. Aborting."); + } + + return boost::make_shared((*lhs) * (*rhs)); +} + +/// Convenience operator* for getting a vector of V3D using shared pointers. +std::vector operator *(const Group_const_sptr &lhs, const Kernel::V3D &rhs) +{ + if(!lhs) { + throw std::invalid_argument("Cannot use null pointer for multiplication."); + } + + return (*lhs) * rhs; +} + +/// Equality operator for shared pointers. +bool operator ==(const Group_const_sptr &lhs, const Group_const_sptr &rhs) +{ + if(!lhs || !rhs) { + throw std::invalid_argument("One of the operands is null. Aborting."); + } + + return (*lhs) == (*rhs); +} + +/// Inequality operator for shared pointers. +bool operator !=(const Group_const_sptr &lhs, const Group_const_sptr &rhs) +{ + return !(operator ==(lhs, rhs)); +} + + +} // namespace Geometry +} // namespace Mantid diff --git a/Code/Mantid/Framework/Geometry/src/Crystal/IsotropicAtomBraggScatterer.cpp b/Code/Mantid/Framework/Geometry/src/Crystal/IsotropicAtomBraggScatterer.cpp new file mode 100644 index 000000000000..1dd91a09625c --- /dev/null +++ b/Code/Mantid/Framework/Geometry/src/Crystal/IsotropicAtomBraggScatterer.cpp @@ -0,0 +1,144 @@ +#include "MantidGeometry/Crystal/IsotropicAtomBraggScatterer.h" +#include "MantidKernel/Atom.h" +#include + +#include "MantidKernel/BoundedValidator.h" +#include "MantidKernel/MandatoryValidator.h" + +#include "MantidGeometry/Crystal/BraggScattererFactory.h" + +namespace Mantid +{ +namespace Geometry +{ + +using namespace Kernel; + +/// Constructor which takes an element symbol, fractional coordinates, isotropic atomic displacement parameter and occupancy. +IsotropicAtomBraggScatterer::IsotropicAtomBraggScatterer() : + BraggScattererInCrystalStructure(), + m_atom(), + m_label() +{ +} + +/// Clones the instance. +BraggScatterer_sptr IsotropicAtomBraggScatterer::clone() const +{ + IsotropicAtomBraggScatterer_sptr clone = boost::make_shared(); + clone->initialize(); + clone->setProperties(this->asString(false, ';')); + + return clone; +} + +/// Tries to obtain element specific data for the given symbol using PhysicalConstants::getAtom. +void IsotropicAtomBraggScatterer::setElement(const std::string &element) +{ + PhysicalConstants::Atom atom = PhysicalConstants::getAtom(element); + + m_atom = atom.neutron; + m_label = atom.symbol; +} + +/// Returns the string representation of the contained element. +std::string IsotropicAtomBraggScatterer::getElement() const +{ + return m_label; +} + +/// Returns the internally stored NeutronAtom that holds element specific data. +PhysicalConstants::NeutronAtom IsotropicAtomBraggScatterer::getNeutronAtom() const +{ + return m_atom; +} + +/// Returns the occupancy. +double IsotropicAtomBraggScatterer::getOccupancy() const +{ + return getProperty("Occupancy"); +} + +/// Returns the isotropic atomic displacement parameter. +double IsotropicAtomBraggScatterer::getU() const +{ + return getProperty("U"); +} + +/** + * Calculates the structure factor + * + * This method calculates the structure factor, taking into account contributions from all + * atoms on the stored position _and all symmetrically equivalent_. + * For details, please refer to the class documentation in the header file. + * + * @param hkl :: HKL for which the structure factor should be calculated + * @return Structure factor (complex). + */ +StructureFactor IsotropicAtomBraggScatterer::calculateStructureFactor(const V3D &hkl) const +{ + double amplitude = getOccupancy() * getDebyeWallerFactor(hkl) * getScatteringLength(); + + StructureFactor sum(0.0, 0.0); + + std::vector equivalentPositions = getEquivalentPositions(); + for(auto pos = equivalentPositions.begin(); pos != equivalentPositions.end(); ++pos) { + double phase = 2.0 * M_PI * (*pos).scalar_prod(hkl); + sum += amplitude * StructureFactor(cos(phase), sin(phase)); + } + + return sum; +} + +/** + * Declares properties of this scatterer model + * + * In addition to the properties of BraggScatterer, this class implements three more properties, + * as described in the general class documentation, with some restrictions on allowed + * values: + * - U must be 0 or greater + * - Occupancy must be on the interval [0,1] + * - Element must be present. + */ +void IsotropicAtomBraggScatterer::declareScattererProperties() +{ + // Default behavior requires this. + setElement("H"); + + boost::shared_ptr > uValidator = boost::make_shared >(); + uValidator->setLower(0.0); + + declareProperty(new PropertyWithValue("U", 0.0, uValidator), "Isotropic atomic displacement in Angstrom^2"); + + IValidator_sptr occValidator = boost::make_shared >(0.0, 1.0); + declareProperty(new PropertyWithValue("Occupancy", 1.0, occValidator), "Site occupancy, values on interval [0,1]."); + + declareProperty(new PropertyWithValue("Element", "H", boost::make_shared >())); +} + +/// After setting the element as a string, the corresponding +void IsotropicAtomBraggScatterer::afterScattererPropertySet(const std::string &propertyName) +{ + if(propertyName == "Element") { + setElement(getPropertyValue(propertyName)); + } +} + +/// Returns the Debye-Waller factor, using an isotropic atomic displacement and the stored unit cell. +double IsotropicAtomBraggScatterer::getDebyeWallerFactor(const V3D &hkl) const +{ + V3D dstar = getCell().getB() * hkl; + + return exp(-2.0 * M_PI * M_PI * getU() * dstar.norm2()); +} + +/// Returns the scattering length of the stored element. +double IsotropicAtomBraggScatterer::getScatteringLength() const +{ + return m_atom.coh_scatt_length_real; +} + +DECLARE_BRAGGSCATTERER(IsotropicAtomBraggScatterer) + +} // namespace Geometry +} // namespace Mantid diff --git a/Code/Mantid/Framework/Geometry/src/Crystal/PointGroup.cpp b/Code/Mantid/Framework/Geometry/src/Crystal/PointGroup.cpp index c243de7813e7..5c1049de42ca 100644 --- a/Code/Mantid/Framework/Geometry/src/Crystal/PointGroup.cpp +++ b/Code/Mantid/Framework/Geometry/src/Crystal/PointGroup.cpp @@ -3,6 +3,10 @@ #include #include +#include + +#include "MantidGeometry/Crystal/PointGroupFactory.h" +#include "MantidGeometry/Crystal/SymmetryOperationFactory.h" namespace Mantid { @@ -51,12 +55,18 @@ namespace Geometry } /// Protected constructor - can not be used directly. - PointGroup::PointGroup() : + PointGroup::PointGroup(const std::string &symbolHM) : m_symmetryOperations(), - m_transformationMatrices() + m_symbolHM(symbolHM) { } + /// Hermann-Mauguin symbol + std::string PointGroup::getSymbol() const + { + return m_symbolHM; + } + /** * Generates a set of hkls * @@ -76,33 +86,44 @@ namespace Geometry std::set equivalents; equivalents.insert(hkl); - for(std::vector::const_iterator m = m_transformationMatrices.begin(); - m != m_transformationMatrices.end(); ++m) { - equivalents.insert((*m) * hkl); + for(auto op = m_symmetryOperations.begin(); + op != m_symmetryOperations.end(); ++op) { + equivalents.insert((*op) * hkl); } return equivalents; } + /// Sets the point group's symmetry operations. + void PointGroup::setSymmetryOperations(const std::vector &generators) + { + m_symmetryOperations.clear(); + + std::vector allSymmetryOperations = generateSymmetryOperations(generators); + for(auto it = allSymmetryOperations.begin(); it != allSymmetryOperations.end(); ++it) { + addSymmetryOperation(*it); + } + } + /// Adds a symmetry operation to the point group. - void PointGroup::addSymmetryOperation(const SymmetryOperation_const_sptr &symmetryOperation) + void PointGroup::addSymmetryOperation(const SymmetryOperation &symmetryOperation) { m_symmetryOperations.push_back(symmetryOperation); } /// Returns all symmetry operations stored in the point group. - std::vector PointGroup::getSymmetryOperations() const + std::vector PointGroup::getSymmetryOperations() const { return m_symmetryOperations; } /** - * Returns all transformation matrices generated by a list of symmetry operations + * Returns all symmetry operations generated by a list of symmetry operations * * This method takes a vector of symmetry operations and returns the resulting set of - * transformation matrices. It does so by applying the first symmetry operation (order - 1) times - * to an identity matrix which results in a list of (order - 1) matrices. Then it applies - * the second operation to all these matrices, and so on. + * symmetry operations. It does so by applying the first symmetry operation (order - 1) times + * to an identity operation which results in a list of (order - 1) matrices. Then it multiplies + * the second operation to all these operations, and so on. * * Using this method, all point groups can be described using a maximum of four * symmetry operations. m-3m for example, which is defined in PointGroupLaue13, @@ -117,50 +138,42 @@ namespace Geometry * @param symmetryOperations * @return */ - std::vector PointGroup::generateTransformationMatrices(const std::vector &symmetryOperations) + std::vector PointGroup::generateSymmetryOperations(const std::vector &symmetryOperations) { - std::vector matrices; - matrices.push_back(IntMatrix(3,3,true)); + SymmetryOperation identity; - for(std::vector::const_iterator symOp = symmetryOperations.begin(); + std::vector allSymmetryOperations; + allSymmetryOperations.push_back(identity); + + for(std::vector::const_iterator symOp = symmetryOperations.begin(); symOp != symmetryOperations.end(); ++symOp) { - std::vector currentMatrices(matrices); + std::vector currentMatrices(allSymmetryOperations); - for(std::vector::const_iterator currentMatrix = currentMatrices.begin(); + for(std::vector::const_iterator currentMatrix = currentMatrices.begin(); currentMatrix != currentMatrices.end(); ++currentMatrix) { - IntMatrix transformed = *currentMatrix; - for(size_t i = 0; i < (*symOp)->order() - 1; ++i) { - transformed = (*symOp)->apply(transformed); - matrices.push_back(transformed); + SymmetryOperation transformed = *currentMatrix; + for(size_t i = 0; i < (*symOp).order() - 1; ++i) { + transformed = (*symOp) * transformed; + allSymmetryOperations.push_back(transformed); } } } - return matrices; + return allSymmetryOperations; } - /// Sets the transformation matrices. - void PointGroup::setTransformationMatrices(const std::vector &matrices) - { - m_transformationMatrices = matrices; - } + PointGroupLaue1::PointGroupLaue1() : + PointGroup("-1") + { } - - PointGroupLaue1::PointGroupLaue1() - { - addSymmetryOperation(boost::make_shared()); - - setTransformationMatrices(generateTransformationMatrices(getSymmetryOperations())); - } - - std::string PointGroupLaue1::getName() + std::string PointGroupLaue1::getName() const { return "-1 (Triclinic)"; } - bool PointGroupLaue1::isEquivalent(V3D hkl, V3D hkl2) + bool PointGroupLaue1::isEquivalent(const V3D &hkl, const V3D &hkl2) const { double h=hkl[0]; double k=hkl[1]; @@ -174,20 +187,24 @@ namespace Geometry return Triclinic; } - PointGroupLaue2::PointGroupLaue2() + void PointGroupLaue1::init() { - addSymmetryOperation(boost::make_shared()); - addSymmetryOperation(boost::make_shared()); + std::vector generatingSymmetryOperations; + generatingSymmetryOperations.push_back(SymmetryOperationFactory::Instance().createSymOp("-x,-y,-z")); - setTransformationMatrices(generateTransformationMatrices(getSymmetryOperations())); + setSymmetryOperations(generatingSymmetryOperations); } - std::string PointGroupLaue2::getName() + PointGroupLaue2::PointGroupLaue2() : + PointGroup("2/m") + { } + + std::string PointGroupLaue2::getName() const { return "1 2/m 1 (Monoclinic, unique axis b)"; } - bool PointGroupLaue2::isEquivalent(V3D hkl, V3D hkl2) + bool PointGroupLaue2::isEquivalent(const V3D &hkl, const V3D &hkl2) const { double h=hkl[0]; double k=hkl[1]; @@ -201,20 +218,25 @@ namespace Geometry return Monoclinic; } - PointGroupLaue3::PointGroupLaue3() + void PointGroupLaue2::init() { - addSymmetryOperation(boost::make_shared()); - addSymmetryOperation(boost::make_shared()); + std::vector generatingSymmetryOperations; + generatingSymmetryOperations.push_back(SymmetryOperationFactory::Instance().createSymOp("-x,y,-z")); + generatingSymmetryOperations.push_back(SymmetryOperationFactory::Instance().createSymOp("x,-y,z")); - setTransformationMatrices(generateTransformationMatrices(getSymmetryOperations())); + setSymmetryOperations(generatingSymmetryOperations); } - std::string PointGroupLaue3::getName() + PointGroupLaue3::PointGroupLaue3() : + PointGroup("112/m") + { } + + std::string PointGroupLaue3::getName() const { return "1 1 2/m (Monoclinic, unique axis c)"; } - bool PointGroupLaue3::isEquivalent(V3D hkl, V3D hkl2) + bool PointGroupLaue3::isEquivalent(const V3D &hkl, const V3D &hkl2) const { double h=hkl[0]; double k=hkl[1]; @@ -228,21 +250,25 @@ namespace Geometry return Monoclinic; } - PointGroupLaue4::PointGroupLaue4() + void PointGroupLaue3::init() { - addSymmetryOperation(boost::make_shared()); - addSymmetryOperation(boost::make_shared()); - addSymmetryOperation(boost::make_shared()); + std::vector generatingSymmetryOperations; + generatingSymmetryOperations.push_back(SymmetryOperationFactory::Instance().createSymOp("-x,-y,z")); + generatingSymmetryOperations.push_back(SymmetryOperationFactory::Instance().createSymOp("x,y,-z")); - setTransformationMatrices(generateTransformationMatrices(getSymmetryOperations())); + setSymmetryOperations(generatingSymmetryOperations); } - std::string PointGroupLaue4::getName() + PointGroupLaue4::PointGroupLaue4() : + PointGroup("mmm") + { } + + std::string PointGroupLaue4::getName() const { return "mmm (Orthorombic)"; } - bool PointGroupLaue4::isEquivalent(V3D hkl, V3D hkl2) + bool PointGroupLaue4::isEquivalent(const V3D &hkl, const V3D &hkl2) const { double h=hkl[0]; double k=hkl[1]; @@ -258,20 +284,26 @@ namespace Geometry return Orthorhombic; } - PointGroupLaue5::PointGroupLaue5() + void PointGroupLaue4::init() { - addSymmetryOperation(boost::make_shared()); - addSymmetryOperation(boost::make_shared()); + std::vector generatingSymmetryOperations; + generatingSymmetryOperations.push_back(SymmetryOperationFactory::Instance().createSymOp("x,-y,-z")); + generatingSymmetryOperations.push_back(SymmetryOperationFactory::Instance().createSymOp("-x,y,-z")); + generatingSymmetryOperations.push_back(SymmetryOperationFactory::Instance().createSymOp("x,y,-z")); - setTransformationMatrices(generateTransformationMatrices(getSymmetryOperations())); + setSymmetryOperations(generatingSymmetryOperations); } - std::string PointGroupLaue5::getName() + PointGroupLaue5::PointGroupLaue5() : + PointGroup("4/m") + { } + + std::string PointGroupLaue5::getName() const { return "4/m (Tetragonal)"; } - bool PointGroupLaue5::isEquivalent(V3D hkl, V3D hkl2) + bool PointGroupLaue5::isEquivalent(const V3D &hkl, const V3D &hkl2) const { double h=hkl[0]; double k=hkl[1]; @@ -287,21 +319,25 @@ namespace Geometry return Tetragonal; } - PointGroupLaue6::PointGroupLaue6() + void PointGroupLaue5::init() { - addSymmetryOperation(boost::make_shared()); - addSymmetryOperation(boost::make_shared()); - addSymmetryOperation(boost::make_shared()); + std::vector generatingSymmetryOperations; + generatingSymmetryOperations.push_back(SymmetryOperationFactory::Instance().createSymOp("-y,x,z")); + generatingSymmetryOperations.push_back(SymmetryOperationFactory::Instance().createSymOp("x,y,-z")); - setTransformationMatrices(generateTransformationMatrices(getSymmetryOperations())); + setSymmetryOperations(generatingSymmetryOperations); } - std::string PointGroupLaue6::getName() + PointGroupLaue6::PointGroupLaue6() : + PointGroup("4/mmm") + { } + + std::string PointGroupLaue6::getName() const { return "4/mmm (Tetragonal)"; } - bool PointGroupLaue6::isEquivalent(V3D hkl, V3D hkl2) + bool PointGroupLaue6::isEquivalent(const V3D &hkl, const V3D &hkl2) const { double h=hkl[0]; double k=hkl[1]; @@ -320,20 +356,26 @@ namespace Geometry return Tetragonal; } - PointGroupLaue7::PointGroupLaue7() + void PointGroupLaue6::init() { - addSymmetryOperation(boost::make_shared()); - addSymmetryOperation(boost::make_shared()); + std::vector generatingSymmetryOperations; + generatingSymmetryOperations.push_back(SymmetryOperationFactory::Instance().createSymOp("-y,x,z")); + generatingSymmetryOperations.push_back(SymmetryOperationFactory::Instance().createSymOp("x,y,-z")); + generatingSymmetryOperations.push_back(SymmetryOperationFactory::Instance().createSymOp("x,-y,-z")); - setTransformationMatrices(generateTransformationMatrices(getSymmetryOperations())); + setSymmetryOperations(generatingSymmetryOperations); } - std::string PointGroupLaue7::getName() + PointGroupLaue7::PointGroupLaue7() : + PointGroup("-3") + { } + + std::string PointGroupLaue7::getName() const { return "-3 (Trigonal - Hexagonal)"; } - bool PointGroupLaue7::isEquivalent(V3D hkl, V3D hkl2) + bool PointGroupLaue7::isEquivalent(const V3D &hkl, const V3D &hkl2) const { double h=hkl[0]; double k=hkl[1]; @@ -348,21 +390,25 @@ namespace Geometry return Trigonal; } - PointGroupLaue8::PointGroupLaue8() + void PointGroupLaue7::init() { - addSymmetryOperation(boost::make_shared()); - addSymmetryOperation(boost::make_shared()); - addSymmetryOperation(boost::make_shared()); + std::vector generatingSymmetryOperations; + generatingSymmetryOperations.push_back(SymmetryOperationFactory::Instance().createSymOp("-y,x-y,z")); + generatingSymmetryOperations.push_back(SymmetryOperationFactory::Instance().createSymOp("-x,-y,-z")); - setTransformationMatrices(generateTransformationMatrices(getSymmetryOperations())); + setSymmetryOperations(generatingSymmetryOperations); } - std::string PointGroupLaue8::getName() + PointGroupLaue8::PointGroupLaue8() : + PointGroup("-3m1") + { } + + std::string PointGroupLaue8::getName() const { return "-3m1 (Trigonal - Rhombohedral)"; } - bool PointGroupLaue8::isEquivalent(V3D hkl, V3D hkl2) + bool PointGroupLaue8::isEquivalent(const V3D &hkl, const V3D &hkl2) const { double h=hkl[0]; double k=hkl[1]; @@ -379,21 +425,26 @@ namespace Geometry return Trigonal; } - PointGroupLaue9::PointGroupLaue9() + void PointGroupLaue8::init() { - addSymmetryOperation(boost::make_shared()); - addSymmetryOperation(boost::make_shared()); - addSymmetryOperation(boost::make_shared()); + std::vector generatingSymmetryOperations; + generatingSymmetryOperations.push_back(SymmetryOperationFactory::Instance().createSymOp("-y,x-y,z")); + generatingSymmetryOperations.push_back(SymmetryOperationFactory::Instance().createSymOp("-x,-y,-z")); + generatingSymmetryOperations.push_back(SymmetryOperationFactory::Instance().createSymOp("-x,y-x,z")); - setTransformationMatrices(generateTransformationMatrices(getSymmetryOperations())); + setSymmetryOperations(generatingSymmetryOperations); } - std::string PointGroupLaue9::getName() + PointGroupLaue9::PointGroupLaue9() : + PointGroup("-31m") + { } + + std::string PointGroupLaue9::getName() const { return "-31m (Trigonal - Rhombohedral)"; } - bool PointGroupLaue9::isEquivalent(V3D hkl, V3D hkl2) + bool PointGroupLaue9::isEquivalent(const V3D &hkl, const V3D &hkl2) const { double h=hkl[0]; double k=hkl[1]; @@ -410,20 +461,26 @@ namespace Geometry return Trigonal; } - PointGroupLaue10::PointGroupLaue10() + void PointGroupLaue9::init() { - addSymmetryOperation(boost::make_shared()); - addSymmetryOperation(boost::make_shared()); + std::vector generatingSymmetryOperations; + generatingSymmetryOperations.push_back(SymmetryOperationFactory::Instance().createSymOp("-y,x-y,z")); + generatingSymmetryOperations.push_back(SymmetryOperationFactory::Instance().createSymOp("-x,-y,-z")); + generatingSymmetryOperations.push_back(SymmetryOperationFactory::Instance().createSymOp("-x,y-x,z")); - setTransformationMatrices(generateTransformationMatrices(getSymmetryOperations())); + setSymmetryOperations(generatingSymmetryOperations); } - std::string PointGroupLaue10::getName() + PointGroupLaue10::PointGroupLaue10() : + PointGroup("6/m") + { } + + std::string PointGroupLaue10::getName() const { return "6/m (Hexagonal)"; } - bool PointGroupLaue10::isEquivalent(V3D hkl, V3D hkl2) + bool PointGroupLaue10::isEquivalent(const V3D &hkl, const V3D &hkl2) const { double h=hkl[0]; double k=hkl[1]; @@ -440,21 +497,25 @@ namespace Geometry return Hexagonal; } - PointGroupLaue11::PointGroupLaue11() + void PointGroupLaue10::init() { - addSymmetryOperation(boost::make_shared()); - addSymmetryOperation(boost::make_shared()); - addSymmetryOperation(boost::make_shared()); + std::vector generatingSymmetryOperations; + generatingSymmetryOperations.push_back(SymmetryOperationFactory::Instance().createSymOp("x-y,x,z")); + generatingSymmetryOperations.push_back(SymmetryOperationFactory::Instance().createSymOp("-x,-y,-z")); - setTransformationMatrices(generateTransformationMatrices(getSymmetryOperations())); + setSymmetryOperations(generatingSymmetryOperations); } - std::string PointGroupLaue11::getName() + PointGroupLaue11::PointGroupLaue11() : + PointGroup("6/mmm") + { } + + std::string PointGroupLaue11::getName() const { return "6/mmm (Hexagonal)"; } - bool PointGroupLaue11::isEquivalent(V3D hkl, V3D hkl2) + bool PointGroupLaue11::isEquivalent(const V3D &hkl, const V3D &hkl2) const { double h=hkl[0]; double k=hkl[1]; @@ -475,22 +536,26 @@ namespace Geometry return Hexagonal; } - PointGroupLaue12::PointGroupLaue12() + void PointGroupLaue11::init() { - addSymmetryOperation(boost::make_shared()); - addSymmetryOperation(boost::make_shared()); - addSymmetryOperation(boost::make_shared()); - addSymmetryOperation(boost::make_shared()); + std::vector generatingSymmetryOperations; + generatingSymmetryOperations.push_back(SymmetryOperationFactory::Instance().createSymOp("x-y,x,z")); + generatingSymmetryOperations.push_back(SymmetryOperationFactory::Instance().createSymOp("x-y,-y,-z")); + generatingSymmetryOperations.push_back(SymmetryOperationFactory::Instance().createSymOp("x,y,-z")); - setTransformationMatrices(generateTransformationMatrices(getSymmetryOperations())); + setSymmetryOperations(generatingSymmetryOperations); } - std::string PointGroupLaue12::getName() + PointGroupLaue12::PointGroupLaue12() : + PointGroup("m-3") + { } + + std::string PointGroupLaue12::getName() const { return "m-3 (Cubic)"; } - bool PointGroupLaue12::isEquivalent(V3D hkl, V3D hkl2) + bool PointGroupLaue12::isEquivalent(const V3D &hkl, const V3D &hkl2) const { double h=hkl[0]; double k=hkl[1]; @@ -511,22 +576,27 @@ namespace Geometry return Cubic; } - PointGroupLaue13::PointGroupLaue13() + void PointGroupLaue12::init() { - addSymmetryOperation(boost::make_shared()); - addSymmetryOperation(boost::make_shared()); - addSymmetryOperation(boost::make_shared()); - addSymmetryOperation(boost::make_shared()); + std::vector generatingSymmetryOperations; + generatingSymmetryOperations.push_back(SymmetryOperationFactory::Instance().createSymOp("z,x,y")); + generatingSymmetryOperations.push_back(SymmetryOperationFactory::Instance().createSymOp("-x,-y,z")); + generatingSymmetryOperations.push_back(SymmetryOperationFactory::Instance().createSymOp("x,-y,z")); + generatingSymmetryOperations.push_back(SymmetryOperationFactory::Instance().createSymOp("-x,-y,-z")); - setTransformationMatrices(generateTransformationMatrices(getSymmetryOperations())); + setSymmetryOperations(generatingSymmetryOperations); } - std::string PointGroupLaue13::getName() + PointGroupLaue13::PointGroupLaue13() : + PointGroup("m-3m") + { } + + std::string PointGroupLaue13::getName() const { return "m-3m (Cubic)"; } - bool PointGroupLaue13::isEquivalent(V3D hkl, V3D hkl2) + bool PointGroupLaue13::isEquivalent(const V3D &hkl, const V3D &hkl2) const { double h=hkl[0]; double k=hkl[1]; @@ -555,23 +625,27 @@ namespace Geometry return Cubic; } + void PointGroupLaue13::init() + { + std::vector generatingSymmetryOperations; + generatingSymmetryOperations.push_back(SymmetryOperationFactory::Instance().createSymOp("z,x,y")); + generatingSymmetryOperations.push_back(SymmetryOperationFactory::Instance().createSymOp("-y,x,z")); + generatingSymmetryOperations.push_back(SymmetryOperationFactory::Instance().createSymOp("x,-y,z")); + generatingSymmetryOperations.push_back(SymmetryOperationFactory::Instance().createSymOp("-x,-y,-z")); + + setSymmetryOperations(generatingSymmetryOperations); + } + /** @return a vector with all possible PointGroup objects */ std::vector getAllPointGroups() { + std::vector allSymbols = PointGroupFactory::Instance().getAllPointGroupSymbols(); + std::vector out; - out.push_back( boost::make_shared() ); - out.push_back( boost::make_shared() ); - out.push_back( boost::make_shared() ); - out.push_back( boost::make_shared() ); - out.push_back( boost::make_shared() ); - out.push_back( boost::make_shared() ); - out.push_back( boost::make_shared() ); - out.push_back( boost::make_shared() ); - out.push_back( boost::make_shared() ); - out.push_back( boost::make_shared() ); - out.push_back( boost::make_shared() ); - out.push_back( boost::make_shared() ); - out.push_back( boost::make_shared() ); + for(auto it = allSymbols.begin(); it != allSymbols.end(); ++it) { + out.push_back(PointGroupFactory::Instance().createPointGroup(*it)); + } + return out; } @@ -587,7 +661,19 @@ namespace Geometry return map; } - + DECLARE_POINTGROUP(PointGroupLaue1) + DECLARE_POINTGROUP(PointGroupLaue2) + DECLARE_POINTGROUP(PointGroupLaue3) + DECLARE_POINTGROUP(PointGroupLaue4) + DECLARE_POINTGROUP(PointGroupLaue5) + DECLARE_POINTGROUP(PointGroupLaue6) + DECLARE_POINTGROUP(PointGroupLaue7) + DECLARE_POINTGROUP(PointGroupLaue8) + DECLARE_POINTGROUP(PointGroupLaue9) + DECLARE_POINTGROUP(PointGroupLaue10) + DECLARE_POINTGROUP(PointGroupLaue11) + DECLARE_POINTGROUP(PointGroupLaue12) + DECLARE_POINTGROUP(PointGroupLaue13) } // namespace Mantid } // namespace Geometry diff --git a/Code/Mantid/Framework/Geometry/src/Crystal/PointGroupFactory.cpp b/Code/Mantid/Framework/Geometry/src/Crystal/PointGroupFactory.cpp new file mode 100644 index 000000000000..c3adf455d6f3 --- /dev/null +++ b/Code/Mantid/Framework/Geometry/src/Crystal/PointGroupFactory.cpp @@ -0,0 +1,68 @@ +#include "MantidGeometry/Crystal/PointGroupFactory.h" + +#include "MantidKernel/LibraryManager.h" + +namespace Mantid +{ +namespace Geometry +{ + +/// Creates a PointGroup object from its Hermann-Mauguin symbol. +PointGroup_sptr PointGroupFactoryImpl::createPointGroup(const std::string &hmSymbol) const +{ + PointGroup_sptr pointGroup = create(hmSymbol); + pointGroup->init(); + + return pointGroup; +} + +/// Returns the Hermann-Mauguin symbols of all registered point groups. +std::vector PointGroupFactoryImpl::getAllPointGroupSymbols() const +{ + std::vector pointGroups; + + for(auto it = m_crystalSystemMap.begin(); it != m_crystalSystemMap.end(); ++it) { + pointGroups.push_back(it->first); + } + + return pointGroups; +} + +/// Returns the Hermann-Mauguin symbols of all point groups that belong to a certain crystal system. +std::vector PointGroupFactoryImpl::getPointGroupSymbols(const PointGroup::CrystalSystem &crystalSystem) const +{ + std::vector pointGroups; + + for(auto it = m_crystalSystemMap.begin(); it != m_crystalSystemMap.end(); ++it) { + if(it->second == crystalSystem) { + pointGroups.push_back(it->first); + } + } + + return pointGroups; +} + +/// Private default constructor. +PointGroupFactoryImpl::PointGroupFactoryImpl() : Kernel::DynamicFactory(), + m_crystalSystemMap() +{ + Kernel::LibraryManager::Instance(); +} + +/// Adds a point group to a map that stores pairs of Hermann-Mauguin symbol and crystal system. +void PointGroupFactoryImpl::addToCrystalSystemMap(const PointGroup::CrystalSystem &crystalSystem, const std::string &hmSymbol) +{ + m_crystalSystemMap.insert(std::make_pair(hmSymbol, crystalSystem)); +} + +/// Removes point group from internal crystal system map. +void PointGroupFactoryImpl::removeFromCrystalSystemMap(const std::string &hmSymbol) +{ + auto it = m_crystalSystemMap.find(hmSymbol); + m_crystalSystemMap.erase(it); +} + + + +} // namespace Geometry +} // namespace Mantid diff --git a/Code/Mantid/Framework/Geometry/src/Crystal/ProductOfCyclicGroups.cpp b/Code/Mantid/Framework/Geometry/src/Crystal/ProductOfCyclicGroups.cpp new file mode 100644 index 000000000000..0cafb2407b35 --- /dev/null +++ b/Code/Mantid/Framework/Geometry/src/Crystal/ProductOfCyclicGroups.cpp @@ -0,0 +1,58 @@ +#include "MantidGeometry/Crystal/ProductOfCyclicGroups.h" + +#include "MantidGeometry/Crystal/SymmetryOperationFactory.h" +#include "MantidGeometry/Crystal/CyclicGroup.h" + +namespace Mantid +{ +namespace Geometry +{ + +/// String constructor with semicolon-separated symmetry operations +ProductOfCyclicGroups::ProductOfCyclicGroups(const std::string &generators) : + Group(*(getGeneratedGroup(generators))) +{ +} + +/// Constructor which directly takes a list of factor groups to form the product +ProductOfCyclicGroups::ProductOfCyclicGroups(const std::vector &factorGroups) : + Group(*(getProductOfCyclicGroups(factorGroups))) +{ +} + +/// Generates symmetry operations from the string, creates a CyclicGroup from each operation and multiplies them to form a factor group. +Group_const_sptr ProductOfCyclicGroups::getGeneratedGroup(const std::string &generators) const +{ + std::vector operations = SymmetryOperationFactory::Instance().createSymOps(generators); + std::vector factorGroups = getFactorGroups(operations); + + return getProductOfCyclicGroups(factorGroups); +} + +/// Returns a vector of cyclic groups for the given vector of symmetry operations +std::vector ProductOfCyclicGroups::getFactorGroups(const std::vector &symmetryOperations) const +{ + std::vector groups; + + for(auto it = symmetryOperations.begin(); it != symmetryOperations.end(); ++it) { + groups.push_back(GroupFactory::create((*it).identifier())); + } + + return groups; +} + +/// Multiplies all supplied groups and returns the result +Group_const_sptr ProductOfCyclicGroups::getProductOfCyclicGroups(const std::vector &factorGroups) const +{ + Group_const_sptr productGroup = boost::make_shared(*(factorGroups.front())); + + for(size_t i = 1; i < factorGroups.size(); ++i) { + productGroup = productGroup * factorGroups[i]; + } + + return productGroup; +} + + +} // namespace Geometry +} // namespace Mantid diff --git a/Code/Mantid/Framework/Geometry/src/Crystal/SpaceGroup.cpp b/Code/Mantid/Framework/Geometry/src/Crystal/SpaceGroup.cpp new file mode 100644 index 000000000000..62ecbfd55647 --- /dev/null +++ b/Code/Mantid/Framework/Geometry/src/Crystal/SpaceGroup.cpp @@ -0,0 +1,58 @@ +#include "MantidGeometry/Crystal/SpaceGroup.h" + +namespace Mantid +{ +namespace Geometry +{ + +/** + * Constructor + * + * This constructor creates a space group with the symmetry operations contained + * in the Group-parameter and assigns the given number and symbol. + * + * @param itNumber :: Space group number according to International Tables for Crystallography A + * @param hmSymbol :: Herman-Mauguin symbol for the space group + * @param group :: Group that contains all symmetry operations (including centering). + */ +SpaceGroup::SpaceGroup(size_t itNumber, const std::string &hmSymbol, const Group &group) : + Group(group), + m_number(itNumber), + m_hmSymbol(hmSymbol) +{ +} + +/// Copy constructor +SpaceGroup::SpaceGroup(const SpaceGroup &other) : + Group(other), + m_number(other.m_number), + m_hmSymbol(other.m_hmSymbol) +{ + +} + +/// Assignment operator, utilizes Group's assignment operator +SpaceGroup &SpaceGroup::operator =(const SpaceGroup &other) +{ + Group::operator =(other); + + m_number = other.m_number; + m_hmSymbol = other.m_hmSymbol; + + return *this; +} + +/// Returns the stored space group number +size_t SpaceGroup::number() const +{ + return m_number; +} + +/// Returns the stored Hermann-Mauguin symbol +std::string SpaceGroup::hmSymbol() const +{ + return m_hmSymbol; +} + +} // namespace Geometry +} // namespace Mantid diff --git a/Code/Mantid/Framework/Geometry/src/Crystal/SpaceGroupFactory.cpp b/Code/Mantid/Framework/Geometry/src/Crystal/SpaceGroupFactory.cpp new file mode 100644 index 000000000000..96091872d9f6 --- /dev/null +++ b/Code/Mantid/Framework/Geometry/src/Crystal/SpaceGroupFactory.cpp @@ -0,0 +1,236 @@ +#include "MantidGeometry/Crystal/SpaceGroupFactory.h" +#include "MantidGeometry/Crystal/SymmetryOperationFactory.h" + +#include "MantidGeometry/Crystal/ProductOfCyclicGroups.h" +#include "MantidGeometry/Crystal/CenteringGroup.h" + +#include "MantidKernel/LibraryManager.h" + +#include + +namespace Mantid +{ +namespace Geometry +{ + +/// Creates a space group given the Hermann-Mauguin symbol, throws std::invalid_argument if symbol is not registered. +SpaceGroup_const_sptr SpaceGroupFactoryImpl::createSpaceGroup(const std::string &hmSymbol) const +{ + if(!isSubscribed(hmSymbol)) { + throw std::invalid_argument("Space group with symbol '" + hmSymbol + "' is not registered."); + } + + return constructFromPrototype(m_prototypes.find(hmSymbol)->second); +} + +/// Returns true if space group with given symbol is subscribed. +bool SpaceGroupFactoryImpl::isSubscribed(const std::string &hmSymbol) const +{ + return m_prototypes.find(hmSymbol) != m_prototypes.end(); +} + +/// Returns true if space group with given number is subscribed. +bool SpaceGroupFactoryImpl::isSubscribed(size_t number) const +{ + return m_numberMap.find(number) != m_numberMap.end(); +} + +/// Returns a vector with all subscribed space group symbols. +std::vector SpaceGroupFactoryImpl::subscribedSpaceGroupSymbols() const +{ + std::vector symbols; + symbols.reserve(m_prototypes.size()); + + for(auto it = m_prototypes.begin(); it != m_prototypes.end(); ++it) { + symbols.push_back(it->first); + } + + return symbols; +} + +/// Returns a vector with all symbols that correspond to a space group number +std::vector SpaceGroupFactoryImpl::subscribedSpaceGroupSymbols(size_t number) const +{ + std::vector symbols; + + auto keyPair = m_numberMap.equal_range(number); + + for(auto it = keyPair.first; it != keyPair.second; ++it) { + symbols.push_back(it->second); + } + + return symbols; +} + +/// Returns a vector with all subscribed space group numbers. +std::vector SpaceGroupFactoryImpl::subscribedSpaceGroupNumbers() const +{ + std::vector numbers; + numbers.reserve(m_numberMap.size()); + + for(auto it = m_numberMap.begin(); it != m_numberMap.end(); it = m_numberMap.upper_bound(it->first)) { + numbers.push_back(it->first); + } + + return numbers; +} + +/// Unsubscribes the space group with the given Hermann-Mauguin symbol, but throws std::invalid_argument if symbol is not registered. +void SpaceGroupFactoryImpl::unsubscribeSpaceGroup(const std::string &hmSymbol) +{ + if(!isSubscribed(hmSymbol)) { + throw std::invalid_argument("Cannot unsubscribe space group that is not registered."); + } + + auto eraseSymbol = m_prototypes.find(hmSymbol); + SpaceGroup_const_sptr spaceGroup = eraseSymbol->second; + + auto eraseNumber = m_numberMap.find(spaceGroup->number()); + m_numberMap.erase(eraseNumber); + m_prototypes.erase(eraseSymbol); +} + +/** + * Subscribes a space group into the factory using generators + * + * With this method one can register a space group that is generated by an algorithm + * based on the instructions in [1]. Currently it's important that the Herrman- + * Mauguin symbol starts with an upper case letter, because that is used to generate + * centering translations (it should be upper case anyway). + * + * The method will throw an exception if the number or symbol is already registered. + * + * [1] Shmueli, U. Acta Crystallogr. A 40, 559–567 (1984). + * http://dx.doi.org/10.1107/S0108767384001161 + * + * @param number :: Space group number according to International Tables for Crystallography A + * @param hmSymbol :: Herrman-Mauguin symbol with upper case first letter (centering). + * @param generators :: + */ +void SpaceGroupFactoryImpl::subscribeGeneratedSpaceGroup(size_t number, const std::string &hmSymbol, const std::string &generators) +{ + throwIfSubscribed(hmSymbol); + + // Generate factor group and centering group + std::string centeringSymbol = getCenteringString(hmSymbol); + Group_const_sptr generatingGroup = getGeneratedGroup(generators, centeringSymbol); + + SpaceGroup_const_sptr prototype = getPrototype(generatingGroup, number, hmSymbol); + subscribe(prototype); +} + +/// Subscribes a "tabulated space group" into the factory where all symmetry operations need to be supplied, including centering. +void SpaceGroupFactoryImpl::subscribeTabulatedSpaceGroup(size_t number, const std::string &hmSymbol, const std::string &symmetryOperations) +{ + throwIfSubscribed(hmSymbol); + + // Generate a group using the supplied symmetry operations + Group_const_sptr generatingGroup = getTabulatedGroup(symmetryOperations); + + SpaceGroup_const_sptr prototype = getPrototype(generatingGroup, number, hmSymbol); + subscribe(prototype); +} + +/// Creatings a prototype instance of SpaceGroup using the supplied parameters. +SpaceGroup_const_sptr SpaceGroupFactoryImpl::getPrototype(Group_const_sptr generatingGroup, size_t number, const std::string &hmSymbol) const +{ + if(!generatingGroup) { + throw std::runtime_error("Could not create Group from supplied symmetry operations."); + } + + return boost::make_shared(number, hmSymbol, *generatingGroup); +} + +/// Returns a copy-constructed instance of the supplied space group prototype object. +SpaceGroup_const_sptr SpaceGroupFactoryImpl::constructFromPrototype(const SpaceGroup_const_sptr prototype) const +{ + return boost::make_shared(*prototype); +} + +/// Throws std::invalid_argument if a space group with the given Hermann-Mauguin symbol is already registered in the factory. +void SpaceGroupFactoryImpl::throwIfSubscribed(const std::string &hmSymbol) +{ + if(isSubscribed(hmSymbol)) { + throw std::invalid_argument("Space group with this symbol is already registered."); + } +} + +/// Stores the given prototype in the space group factory. +void SpaceGroupFactoryImpl::subscribe(const SpaceGroup_const_sptr &prototype) +{ + m_numberMap.insert(std::make_pair(prototype->number(), prototype->hmSymbol())); + m_prototypes.insert(std::make_pair(prototype->hmSymbol(), prototype)); +} + +/// Returns a group with the given symmetry operations. +Group_const_sptr SpaceGroupFactoryImpl::getTabulatedGroup(const std::string &symmetryOperations) const +{ + return GroupFactory::create(symmetryOperations); +} + +std::string SpaceGroupFactoryImpl::getCenteringString(const std::string &hmSymbol) const +{ + return hmSymbol.substr(0, 1); +} + +/** + * Returns a group constructed from a generator string and a centering symbol + * + * Generators have to be provided as a semicolon separated list of symmetry operations + * in x,y,z format, for example "-x,-y,-z; -x,y,z; -y,x,z". A ProductOfCyclicGroups using this + * string is constructed. Centering symbol has to be supported by CenteringGroup. The + * group is then calculated as the product of these two groups. + * + * @param generators :: Semicolon separated list of symmetry operations. + * @param centeringSymbol :: Symbol for the lattice centering (see CenteringGroup). + * @return Resulting group. + */ +Group_const_sptr SpaceGroupFactoryImpl::getGeneratedGroup(const std::string &generators, const std::string ¢eringSymbol) const +{ + Group_const_sptr baseGroup = GroupFactory::create(generators); + Group_const_sptr centeringGroup = GroupFactory::create(centeringSymbol); + + return baseGroup * centeringGroup; +} + +/// Constructor cannot be called, since SingletonHolder is used. +SpaceGroupFactoryImpl::SpaceGroupFactoryImpl() : + m_numberMap(), + m_prototypes() +{ + Kernel::LibraryManager::Instance(); +} + +/* Space groups according to International Tables for Crystallography, + * using the generators specified there. + * + * When two origin choices are possible, only the first is given. + */ +// Triclinic +DECLARE_TABULATED_SPACE_GROUP(1, "P 1", "x,y,z") +DECLARE_GENERATED_SPACE_GROUP(2, "P -1", "-x,-y,-z") + +// Monoclinic +DECLARE_GENERATED_SPACE_GROUP(3, "P 1 2 1", "-x,y,-z") +DECLARE_GENERATED_SPACE_GROUP(4, "P 1 21 1", "-x,y+1/2,-z") +DECLARE_GENERATED_SPACE_GROUP(5, "C 1 2 1", "-x,y,-z") +DECLARE_GENERATED_SPACE_GROUP(6, "P 1 m 1", "x,-y,z") +DECLARE_GENERATED_SPACE_GROUP(7, "P 1 c 1", "x,-y,z+1/2") +DECLARE_GENERATED_SPACE_GROUP(8, "C 1 m 1", "x,-y,z") +DECLARE_GENERATED_SPACE_GROUP(9, "C 1 c 1", "x,-y,z+1/2") +DECLARE_GENERATED_SPACE_GROUP(10, "P 1 2/m 1", "-x,y,-z; -x,-y,-z") +DECLARE_GENERATED_SPACE_GROUP(11, "P 1 21/m 1", "-x,y+1/2,-z; -x,-y,-z") +DECLARE_GENERATED_SPACE_GROUP(12, "C 1 2/m 1", "-x,y,-z; -x,-y,-z") +DECLARE_GENERATED_SPACE_GROUP(13, "P 1 2/c 1", "-x,y,-z+1/2; -x,-y,-z") +DECLARE_GENERATED_SPACE_GROUP(14, "P 1 21/c 1", "-x,y+1/2,-z+1/2; -x,-y,-z") +DECLARE_GENERATED_SPACE_GROUP(15, "C 1 2/c 1", "-x,y,-z+1/2; -x,-y,-z") + +DECLARE_GENERATED_SPACE_GROUP(194, "P 63/m m c", "-y,x-y,z; -x,-y,z+1/2; y,x,-z; -x,-y,-z") + +DECLARE_GENERATED_SPACE_GROUP(221, "P m -3 m", "-x,-y,z; -x,y,-z; z,x,y; y,x,-z; -x,-y,-z") +DECLARE_GENERATED_SPACE_GROUP(225, "F m -3 m", "-x,-y,z; -x,y,-z; z,x,y; y,x,-z; -x,-y,-z") +DECLARE_GENERATED_SPACE_GROUP(227, "F d -3 m", "-x,-y+1/2,z+1/2; -x+1/2,y+1/2,-z; z,x,y; y+3/4,x+1/4,-z+3/4; -x+1/4,-y+1/4,-z+1/4") +DECLARE_GENERATED_SPACE_GROUP(229, "I m -3 m", "-x,-y,z; -x,y,-z; z,x,y; y,x,-z; -x,-y,-z") + +} // namespace Geometry +} // namespace Mantid diff --git a/Code/Mantid/Framework/Geometry/src/Crystal/SymmetryOperation.cpp b/Code/Mantid/Framework/Geometry/src/Crystal/SymmetryOperation.cpp index 820c8757f7e0..4307621bc88b 100644 --- a/Code/Mantid/Framework/Geometry/src/Crystal/SymmetryOperation.cpp +++ b/Code/Mantid/Framework/Geometry/src/Crystal/SymmetryOperation.cpp @@ -1,220 +1,253 @@ #include "MantidGeometry/Crystal/SymmetryOperation.h" +#include "MantidGeometry/Crystal/SymmetryOperationSymbolParser.h" +#include + +#include namespace Mantid { namespace Geometry { -/** - * The constructor of SymmetryOperation - * - * Since the SymmetryOperation base-class is not intended to be used directly, the - * only constructor is protected. This way, it can be called by the inheriting classes - * with the correct parameters, but no "anonymous" symmetry operation is possible. - * - * Three parameters are required. The "order", as described in the header file specifies - * how often the operation has to be applied to an object in sequence until it is - * identical with itself. The matrix-parameter is the transformation matrix that - * represents the operation and identifier is a string that follows a certain convention, - * also described in the header file. It must match the following regular expression: - * - * ^-?((1)|((2|3|4|6|m) \\[(-?\\d{1}){3}\\]h?))$ - * - * @param order :: Order of the symmetry operation. - * @param matrix :: Integer matrix with dimensions 3x3, defines symmetry operation. - * @param identifier :: Identifier string for symmetry operation. - */ -SymmetryOperation::SymmetryOperation(size_t order, Kernel::IntMatrix matrix, std::string identifier) : - m_order(order), - m_matrix(matrix), - m_identifier(identifier) +/// Default constructor, results in identity. +SymmetryOperation::SymmetryOperation() : + m_order(1), + m_matrix(Kernel::IntMatrix(3, 3, true)), + m_vector(), + m_identifier() { + m_identifier = SymmetryOperationSymbolParser::getNormalizedIdentifier(m_matrix, m_vector); } /** - * Returns the order of the symmetry operation + * Construct a symmetry operation from a Jones faithful representation * - * @return Order of the symmetry operation - */ -size_t SymmetryOperation::order() const -{ - return m_order; -} - -/** - * Returns the string-identifier for this symmetry operation + * This method invokes SymmetryOperationSymbolParser and tries to parse the supplied string. + * Please not that parsing this string is not very efficient. If you have to create the same + * operations very often, use SymmetryOperationFactory, which works with the copy constructor + * - it's orders of magnitude faster. * - * @return Identifier of the symmetry operation + * @param identifier :: Jones faithful representation of a symmetry operation */ -std::string SymmetryOperation::identifier() const +SymmetryOperation::SymmetryOperation(const std::string &identifier) { - return m_identifier; + const std::pair parsedSymbol = SymmetryOperationSymbolParser::parseIdentifier(identifier); + init(parsedSymbol.first, parsedSymbol.second); } -/** - * Takes a flat int-array and assigns its 9 elements to the internal matrix. - * - * @param array :: int-array containing the transformation matrix. - */ -void SymmetryOperation::setMatrixFromArray(int array[]) +/// Constructs a symmetry operation from a matrix component and a vector, derives order and identifier from matrix and vector. +SymmetryOperation::SymmetryOperation(const Kernel::IntMatrix &matrix, const V3R &vector) { - for(size_t row = 0; row < 3; ++row) { - for(size_t col = 0; col < 3; ++col) { - m_matrix[row][col] = array[row * 3 + col]; - } - } + init(matrix, vector); } -/// Identity -SymOpIdentity::SymOpIdentity() : - SymmetryOperation(1, Kernel::IntMatrix(3, 3, true), "1") +/// Copy-constructor +SymmetryOperation::SymmetryOperation(const SymmetryOperation &other) : + m_order(other.m_order), + m_matrix(other.m_matrix), + m_vector(other.m_vector), + m_identifier(other.m_identifier) { } -/// Inversion -SymOpInversion::SymOpInversion() : - SymmetryOperation(2, Kernel::IntMatrix(3, 3, true), "-1") +/// Assignment operator +SymmetryOperation &SymmetryOperation::operator =(const SymmetryOperation &other) { - m_matrix *= -1; + m_order = other.m_order; + m_matrix = other.m_matrix; + m_vector = other.m_vector; + m_identifier = other.m_identifier; + + return *this; } -/* 2-fold rotation axes */ -/// 2-fold rotation around x-axis -SymOpRotationTwoFoldX::SymOpRotationTwoFoldX() : - SymmetryOperation(2, Kernel::IntMatrix(3, 3), "2 [100]") +/// Initialize from matrix and vector. +void SymmetryOperation::init(const Kernel::IntMatrix &matrix, const V3R &vector) { - int rotTwoFoldX[] = {1, 0, 0, - 0, -1, 0, - 0, 0, -1}; + m_matrix = matrix; + m_vector = getWrappedVector(vector); - setMatrixFromArray(rotTwoFoldX); + m_order = getOrderFromMatrix(m_matrix); + m_identifier = SymmetryOperationSymbolParser::getNormalizedIdentifier(m_matrix, m_vector); } -/// 2-fold rotation around y-axis -SymOpRotationTwoFoldY::SymOpRotationTwoFoldY() : - SymmetryOperation(2, Kernel::IntMatrix(3, 3), "2 [010]") +/// Returns a const reference to the internally stored matrix +const Kernel::IntMatrix &SymmetryOperation::matrix() const { - int rotTwoFoldY[] = {-1, 0, 0, - 0, 1, 0, - 0, 0, -1}; - - setMatrixFromArray(rotTwoFoldY); + return m_matrix; } -/// 2-fold rotation around z-axis -SymOpRotationTwoFoldZ::SymOpRotationTwoFoldZ() : - SymmetryOperation(2, Kernel::IntMatrix(3, 3), "2 [001]") +/// Returns a const reference to the internall stored vector +const V3R &SymmetryOperation::vector() const { - int rotTwoFoldZ[] = {-1, 0, 0, - 0, -1, 0, - 0, 0, 1}; - - setMatrixFromArray(rotTwoFoldZ); + return m_vector; } -/// 2-fold rotation around x-axis, hexagonal coordinate system -SymOpRotationTwoFoldXHexagonal::SymOpRotationTwoFoldXHexagonal() : - SymmetryOperation(2, Kernel::IntMatrix(3, 3), "2 [100]h") +/** + * Returns the order of the symmetry operation + * + * @return Order of the symmetry operation + */ +size_t SymmetryOperation::order() const { - int rotTwoFoldXHexagonal[] = {1, -1, 0, - 0, -1, 0, - 0, 0, -1}; - - setMatrixFromArray(rotTwoFoldXHexagonal); + return m_order; } -/// 2-fold rotation around [210]-axis, hexagonal coordinate system -SymOpRotationTwoFold210Hexagonal::SymOpRotationTwoFold210Hexagonal() : - SymmetryOperation(2, Kernel::IntMatrix(3, 3), "2 [210]h") +/** + * Returns the string-identifier for this symmetry operation + * + * @return Identifier of the symmetry operation + */ +std::string SymmetryOperation::identifier() const { - int rotTwoFold210Hexagonal[] = { 1, 0, 0, - 1, -1, 0, - 0, 0, -1}; + return m_identifier; +} - setMatrixFromArray(rotTwoFold210Hexagonal); +/// Returns true if this is the identity operation. +bool SymmetryOperation::isIdentity() const +{ + return !hasTranslation() && m_matrix == Kernel::IntMatrix(3, 3, true); } -/* 4-fold rotation axes */ -/// 4-fold rotation around z-axis -SymOpRotationFourFoldZ::SymOpRotationFourFoldZ() : - SymmetryOperation(4, Kernel::IntMatrix(3, 3), "4 [001]") +/// Returns true if the operation has a translational component. +bool SymmetryOperation::hasTranslation() const { - int rotFourFoldZ[] = { 0, -1, 0, - 1, 0, 0, - 0, 0, 1}; + return m_vector != 0; +} - setMatrixFromArray(rotFourFoldZ); +/** + * Multiplication operator for combining symmetry operations + * + * This operator constructs from S1 (this) and S2 (other) a new symmetry operation SymOp' with + * + * SymOp'(M', v') + * + * where + * M' = M1 * M2 + * + * and + * v' = (M1 * v2) + v1 + * + * and the components of v' are on the interval (0, 1]. + * + * @param operand + * @return + */ +SymmetryOperation SymmetryOperation::operator *(const SymmetryOperation &operand) const +{ + return SymmetryOperation(m_matrix * operand.m_matrix, getWrappedVector((m_matrix * operand.m_vector) + m_vector) ); } -/* 3-fold rotation axes */ -/// 3-fold rotation around z-axis, hexagonal coordinate system -SymOpRotationThreeFoldZHexagonal::SymOpRotationThreeFoldZHexagonal() : - SymmetryOperation(3, Kernel::IntMatrix(3, 3), "3 [001]h") +/// Returns the inverse of the symmetry operation. +SymmetryOperation SymmetryOperation::inverse() const { - int rotThreeFoldZHexagonal[] = { 0, -1, 0, - 1, -1, 0, - 0, 0, 1}; + Kernel::IntMatrix matrix(m_matrix); + matrix.Invert(); - setMatrixFromArray(rotThreeFoldZHexagonal); + return SymmetryOperation(matrix, -(matrix * m_vector)); } -/// 3-fold rotation around [111]-axis -SymOpRotationThreeFold111::SymOpRotationThreeFold111() : - SymmetryOperation(3, Kernel::IntMatrix(3, 3), "3 [111]") -{ - int rotThreeFold111[] = { 0, 0, 1, - 1, 0, 0, - 0, 1, 0}; - setMatrixFromArray(rotThreeFold111); +/// Returns true if matrix and vector are equal +bool SymmetryOperation::operator ==(const SymmetryOperation &other) const +{ + return m_matrix == other.m_matrix && m_vector == other.m_vector; } -/* 6-fold rotation axes */ -/// 6-fold rotation around z-axis, hexagonal coordinate system -SymOpRotationSixFoldZHexagonal::SymOpRotationSixFoldZHexagonal() : - SymmetryOperation(6, Kernel::IntMatrix(3, 3), "6 [001]h") +/// Returns true if SymmetryOperation is "smaller" than other, determined by using the identifier strings. +bool SymmetryOperation::operator <(const SymmetryOperation &other) const { - int rotSixFoldZHexagonal[] = { 1, -1, 0, - 1, 0, 0, - 0, 0, 1}; + return m_identifier < other.m_identifier; +} - setMatrixFromArray(rotSixFoldZHexagonal); +/// Returns true if operatios are not equal +bool SymmetryOperation::operator !=(const SymmetryOperation &other) const +{ + return !(this->operator ==(other)); } -/* Mirror planes */ -/// Mirror plane perpendicular to y-axis -SymOpMirrorPlaneY::SymOpMirrorPlaneY() : - SymmetryOperation(2, Kernel::IntMatrix(3, 3), "m [010]") +/// Returns the order of the symmetry operation based on the matrix. From "Introduction to Crystal Growth and Characterization, Benz and Neumann, Wiley, 2014, p. 51." +size_t SymmetryOperation::getOrderFromMatrix(const Kernel::IntMatrix &matrix) const { - int mirrorPlaneY[] = {1, 0, 0, - 0, -1, 0, - 0, 0, 1}; + int trace = matrix.Trace(); + int determinant = matrix.determinant(); - setMatrixFromArray(mirrorPlaneY); + if(determinant == 1) { + switch(trace) { + case 3: + return 1; + case 2: + return 6; + case 1: + return 4; + case 0: + return 3; + case -1: + return 2; + default: + break; + } + } else if(determinant == -1) { + switch(trace) { + case -3: + return 2; + case -2: + return 6; + case -1: + return 4; + case 0: + return 6; + case 1: + return 2; + default: + break; + } + } + + throw std::runtime_error("There is something wrong with supplied matrix."); } -/// Mirror plane perpendicular to z-axis -SymOpMirrorPlaneZ::SymOpMirrorPlaneZ() : - SymmetryOperation(2, Kernel::IntMatrix(3, 3), "m [001]") -{ - int mirrorPlaneZ[] = {1, 0, 0, - 0, 1, 0, - 0, 0, -1}; +/** + * Wraps a V3R to the interval (0, 1] + * + * For certain crystallographic calculations it is necessary to constrain fractional + * coordinates to the unit cell, for example to generate all atomic positions + * in the cell. In this context, the fractional coordinate -0.45 is equal to + * "0.55 of the next cell", so it's transformed to 0.55. + * + * @param vector :: Input vector with arbitrary numbers. + * @return Vector with components on the interval (0, 1] + */ +V3R getWrappedVector(const V3R &vector) +{ + V3R wrappedVector(vector); + for(size_t i = 0; i < 3; ++i) { + if(wrappedVector[i] < 0) { + wrappedVector[i] += (abs(vector[i].numerator() / vector[i].denominator()) + 1); + } else if(wrappedVector[i] >= 1) { + wrappedVector[i] -= (vector[i].numerator() / vector[i].denominator()); + } + } - setMatrixFromArray(mirrorPlaneZ); + return wrappedVector; } -/// Mirror plane perpendicular to [210]-axis -SymOpMirrorPlane210Hexagonal::SymOpMirrorPlane210Hexagonal() : - SymmetryOperation(2, Kernel::IntMatrix(3, 3), "m [210]h") +/// Returns a V3D with components on the interval (0, 1], as the version for V3R. +Kernel::V3D getWrappedVector(const Kernel::V3D &vector) { - int mirrorPlane210Hexagonal[] = {-1, 0, 0, - -1, 1, 0, - 0, 0, 1}; + Kernel::V3D wrappedVector(vector); + for(size_t i = 0; i < 3; ++i) { + if(wrappedVector[i] < 0) { + wrappedVector[i] = fmod(vector[i], 1.0) + 1.0; + } else if(wrappedVector[i] >= 1) { + wrappedVector[i] = fmod(vector[i], 1.0); + } + } - setMatrixFromArray(mirrorPlane210Hexagonal); + return wrappedVector; } + } // namespace Geometry } // namespace Mantid diff --git a/Code/Mantid/Framework/Geometry/src/Crystal/SymmetryOperationFactory.cpp b/Code/Mantid/Framework/Geometry/src/Crystal/SymmetryOperationFactory.cpp new file mode 100644 index 000000000000..f8a911561d77 --- /dev/null +++ b/Code/Mantid/Framework/Geometry/src/Crystal/SymmetryOperationFactory.cpp @@ -0,0 +1,94 @@ +#include "MantidGeometry/Crystal/SymmetryOperationFactory.h" +#include "MantidKernel/LibraryManager.h" +#include "MantidKernel/Exception.h" + +#include +#include + +namespace Mantid +{ +namespace Geometry +{ + +/// Creates a SymmetryOperation object from its identifier. +SymmetryOperation SymmetryOperationFactoryImpl::createSymOp(const std::string &identifier) +{ + if(!isSubscribed(identifier)) { + subscribeSymOp(identifier); + } + + return SymmetryOperation(m_prototypes[identifier]); +} + +/// Creates all symmetry operations in string (separated by semicolon). +std::vector SymmetryOperationFactoryImpl::createSymOps(const std::string &identifiers) +{ + std::vector symOpStrings; + boost::split(symOpStrings, identifiers, boost::is_any_of(";")); + + return createSymOps(symOpStrings); +} + +/// Creates all symmetry operations with the given strings (whitespaces at beginning and end are removed). +std::vector SymmetryOperationFactoryImpl::createSymOps(const std::vector &identifiers) +{ + std::vector symOps; + for(auto it = identifiers.begin(); it != identifiers.end(); ++it) { + symOps.push_back(createSymOp(boost::trim_copy(*it))); + } + + return symOps; +} + +/// Subscribes a symmetry operation into the factory +void SymmetryOperationFactoryImpl::subscribeSymOp(const std::string &identifier) +{ + SymmetryOperation prototype(identifier); + + subscribe(identifier, prototype); +} + +/// Unsubscribes a symmetry operation from the factory +void SymmetryOperationFactoryImpl::unsubscribeSymOp(const std::string &identifier) +{ + if(isSubscribed(identifier)) { + m_prototypes.erase(identifier); + } +} + +/// Returns true if identifier already has a prototype in the factory. +bool SymmetryOperationFactoryImpl::isSubscribed(const std::string &identifier) const +{ + return m_prototypes.find(identifier) != m_prototypes.end(); +} + +/// Returns all symbols in the factory. +std::vector SymmetryOperationFactoryImpl::subscribedSymbols() const +{ + std::vector symbols; + symbols.reserve(m_prototypes.size()); + + for(auto it = m_prototypes.begin(); it != m_prototypes.end(); ++it) { + symbols.push_back(it->first); + } + + return symbols; +} + +/// Subscribes symmetry operation into factory, using the supplied alias as key. +void SymmetryOperationFactoryImpl::subscribe(const std::string &alias, const SymmetryOperation &prototype) +{ + if(!isSubscribed(alias)) { + m_prototypes.insert(std::make_pair(alias, prototype)); + } +} + +/// Private default constructor. +SymmetryOperationFactoryImpl::SymmetryOperationFactoryImpl() : + m_prototypes() +{ + Kernel::LibraryManager::Instance(); +} + +} // namespace Geometry +} // namespace Mantid diff --git a/Code/Mantid/Framework/Geometry/src/Crystal/SymmetryOperationSymbolParser.cpp b/Code/Mantid/Framework/Geometry/src/Crystal/SymmetryOperationSymbolParser.cpp new file mode 100644 index 000000000000..783a117bb8f4 --- /dev/null +++ b/Code/Mantid/Framework/Geometry/src/Crystal/SymmetryOperationSymbolParser.cpp @@ -0,0 +1,296 @@ +#include "MantidGeometry/Crystal/SymmetryOperationSymbolParser.h" +#include "MantidKernel/Exception.h" + +#include +#include + +namespace Mantid +{ +namespace Geometry +{ + +/// Default constructor +SymmetryOperationSymbolParser::SymmetryOperationSymbolParser() +{ + +} + +/** + * Tries to parse the given symbol + * + * This method tries to parse a given symbol and returns the matrix/vector pair resulting from + * the parsing process. It takes a string representing a symmetry operation in the format: + * x+a/b, -y-c/d, e/f-z + * where x, y and z are the literals 'x', 'y' and 'z', while a-f are integers, representing + * rational numbers. The latter don't need to be present, a string "x,y,z" is valid. Leading plus-signs + * may be included if desired, so that "+x,+y,+z" is also valid. + * + * If there is a problem, a Kernel::Exception::ParseError exception is thrown. + * + * See also SymmetryOperationSymbolParser::getNormalizedIdentifier, which performs the opposite operation. + * + * @param identifier :: Symbol representing a symmetry operation + * @return Pair of Kernel::IntMatrix and V3R, representing the symmetry operation. + */ +std::pair SymmetryOperationSymbolParser::parseIdentifier(const std::string &identifier) +{ + std::vector components; + boost::split(components, identifier, boost::is_any_of(",")); + + try { + std::pair matrixVector = parseComponents(components); + + return matrixVector; + } catch(const std::runtime_error &e1) { + throw Kernel::Exception::ParseError("Error in parsing symbol " + identifier + ":\n" + std::string(e1.what()), "", 0); + } catch(const boost::bad_lexical_cast &e2) { + throw Kernel::Exception::ParseError("Error in parsing symbol " + identifier + ":\n" + std::string(e2.what()), "", 0); + } +} + +/// Returns a Jones faithful representation of the symmetry operation characterized by the supplied matrix/column pair. +std::string SymmetryOperationSymbolParser::getNormalizedIdentifier(const std::pair &data) +{ + return getNormalizedIdentifier(data.first, data.second); +} + +/** + * Returns the Jones faithful representation of a symmetry operation + * + * This method generates a Jones faithful string for the given matrix and vector. + * The string is generated bases on some rules: + * + * - No spaces: + * 'x + 1/2' -> 'x+1/2' + * - Matrix components occur before vector components: + * '1/2+x' -> 'x+1/2' + * - No leading '+' signs: + * '+x' -> 'x' + * - If more than one matrix element is present, they are ordered x, y, z: + * 'y-x' -> '-x+y' + * + * If the matrix is not 3x3, an std::runtime_error exception is thrown. + * + * @param matrix + * @param vector + * @return + */ +std::string SymmetryOperationSymbolParser::getNormalizedIdentifier(const Kernel::IntMatrix &matrix, const V3R &vector) +{ + if(matrix.numCols() != 3 || matrix.numRows() != 3) { + throw std::runtime_error("Matrix is not a 3x3 matrix."); + } + + std::vector symbols; + symbols.push_back("x"); + symbols.push_back("y"); + symbols.push_back("z"); + + std::vector components; + + for(size_t r = 0; r < 3; ++r) { + std::ostringstream currentComponent; + + for(size_t c = 0; c < 3; ++c) { + if(matrix[r][c] != 0) { + if(matrix[r][c] < 0) { + currentComponent << "-"; + } else { + if(currentComponent.str().size() > 0) { + currentComponent << "+"; + } + } + + currentComponent << symbols[c]; + } + } + + if(vector[r] != 0) { + if(vector[r] > 0) { + currentComponent << "+"; + } + currentComponent << vector[r]; + } + + components.push_back(currentComponent.str()); + } + + return boost::join(components, ","); +} + +/// Tries to parse the three components of the symbol, throws std::runtime_error if number of components is not three. +std::pair SymmetryOperationSymbolParser::parseComponents(const std::vector &components) +{ + if(components.size() != 3) { + throw std::runtime_error("Failed to parse identifier [" + boost::join(components, ", ") + "]: Wrong number of components."); + } + + Kernel::IntMatrix matrix(3, 3); + V3R vector; + + // Each part of the symbol contains one row of the resulting matrix and the magnitude of the translation vector. + for(size_t i = 0; i < 3; ++i) { + std::pair, RationalNumber> currentComponent = parseComponent(getCleanComponentString(components[i])); + + matrix.setRow(i, currentComponent.first); + vector[i] = currentComponent.second; + } + + return std::make_pair(matrix, vector); +} + +/// Strips all spaces from a string, also in the middle. +std::string SymmetryOperationSymbolParser::getCleanComponentString(const std::string &componentString) +{ + return boost::algorithm::erase_all_copy(componentString, " "); +} + +/// Tries to parse a single component of the total symbol, throws std::runtime_error if the string can not be parsed. +std::pair, RationalNumber> SymmetryOperationSymbolParser::parseComponent(const std::string &component) +{ + std::vector matrixRow(3, 0); + RationalNumber vectorComponent; + + size_t totalMatchedLength = 0; + + // Regular expressions for different token types + boost::regex tokenRegex("[+\\-]?((x|y|z)|(\\d/\\d))", boost::regex::icase); + boost::regex matrixRowRegex("^[+\\-]?(x|y|z)", boost::regex::icase); + boost::regex vectorComponentRegex("^[+\\-]?(\\d/\\d)", boost::regex::icase); + + + // Check how many tokens this string is composed of and iterate through them + boost::sregex_iterator iter(component.begin(), component.end(), tokenRegex); + boost::sregex_iterator end; + for(; iter != end; ++iter) { + std::string currentString = iter->str(); + totalMatchedLength += currentString.size(); + + // Try to handle the current token as either a matrix row (x, y, z) or a vector component (a/b) + if(boost::regex_match(currentString, matrixRowRegex)) { + processMatrixRowToken(currentString, matrixRow); + } else if(boost::regex_match(currentString, vectorComponentRegex)) { + processVectorComponentToken(currentString, vectorComponent); + } else { + throw std::runtime_error("Failed to parse input: " + component); + } + } + + // If the combined length of the matched sub strings is less than the total string length, there was some garbage inbetween. + if(totalMatchedLength < component.size()) { + throw std::runtime_error("Failed to parse component string " + component + ": Could not parse entire string."); + } + + // The matrix may be invalid, this happens when something like x+x+y+z is specified. + if(!isValidMatrixRow(matrixRow)) { + throw std::runtime_error("Failed to parse component string " + component + ": Matrix row is invalid (all 0 or an abs(element) > 1)."); + } + + return std::make_pair(matrixRow, vectorComponent); +} + +/// Try to generate a matrix row from the token and add it to the supplied vector, throws std::runtime_error if it fails to parse the input. +void SymmetryOperationSymbolParser::processMatrixRowToken(const std::string &matrixToken, std::vector &matrixRow) +{ + switch(matrixToken.size()) { + case 1: + addToVector(matrixRow, getVectorForSymbol(matrixToken[0])); + break; + case 2: + addToVector(matrixRow, getVectorForSymbol(matrixToken[1], matrixToken[0])); + break; + default: + throw std::runtime_error("Failed to parse matrix row token " + matrixToken); + } +} + +/// Add a vector to another vector (element wise), throws std::runtime_error if sizes don't match. +void SymmetryOperationSymbolParser::addToVector(std::vector &vector, const std::vector &add) +{ + if(vector.size() != add.size()) { + throw std::runtime_error("Vectors do not have matching sizes, can not add."); + } + + for(size_t i = 0; i < vector.size(); ++i) { + vector[i] += add[i]; + } +} + +/// Returns the vector corresponding to the given symbol (x: (1, 0, 0); y: (0, 1, 0); z: (0, 0, 1)) and adds + or -. +std::vector SymmetryOperationSymbolParser::getVectorForSymbol(const char symbol, const char sign) +{ + int factor = getFactorForSign(sign); + + std::vector symbolVector(3, 0); + + switch(symbol) { + case 'x': + symbolVector[0] = factor * 1; + break; + case 'y': + symbolVector[1] = factor * 1; + break; + case 'z': + symbolVector[2] = factor * 1; + break; + default: + throw std::runtime_error("Failed to parse matrix row token " + std::string(1, symbol) + " with sign " + std::string(1, sign)); + } + + return symbolVector; +} + +/// Returns a multiplication factor for the given sign ('-': -1, '+': 1). +int SymmetryOperationSymbolParser::getFactorForSign(const char sign) +{ + switch(sign) { + case '+': + return 1; + case '-': + return -1; + default: + throw std::runtime_error("Failed to parse sign " + std::string(1, sign)); + } +} + +/// Tries to create a RationalNumber from the input and adds it to the supplied RationalNumber. +void SymmetryOperationSymbolParser::processVectorComponentToken(const std::string &rationalNumberToken, RationalNumber &vectorComponent) +{ + std::vector components; + boost::split(components, rationalNumberToken, boost::is_any_of("/")); + + switch(components.size()) { + case 1: + vectorComponent += boost::lexical_cast(components.front()); + break; + case 2: + if(!(components.front()).empty() && !(components.back()).empty()) { + vectorComponent += RationalNumber( + boost::lexical_cast(components.front()), + boost::lexical_cast(components.back()) + ); + break; + } + default: + throw std::runtime_error("Failed to parse vector token " + rationalNumberToken); + } +} + +/// Checks if there are either 1 or 2 zeros in a given matrix row and all non-zero elements are 1 or -1. +bool SymmetryOperationSymbolParser::isValidMatrixRow(const std::vector &matrixRow) +{ + int nulls = 0; + + for(auto it = matrixRow.begin(); it != matrixRow.end(); ++it) { + if(abs(*it) > 1) { + return false; + } else if(*it == 0) { + ++nulls; + } + } + + return nulls > 0 && nulls < 3; +} + +} // namespace Geometry +} // namespace Mantid diff --git a/Code/Mantid/Framework/Geometry/src/Crystal/UnitCell.cpp b/Code/Mantid/Framework/Geometry/src/Crystal/UnitCell.cpp index a85f910dd106..313e47f991f1 100644 --- a/Code/Mantid/Framework/Geometry/src/Crystal/UnitCell.cpp +++ b/Code/Mantid/Framework/Geometry/src/Crystal/UnitCell.cpp @@ -7,6 +7,9 @@ #include #include +#include +#include + namespace Mantid { namespace Geometry @@ -733,6 +736,37 @@ namespace Geometry return out; } + std::string unitCellToStr(const UnitCell &unitCell) + { + std::ostringstream stream; + stream << std::setprecision(9); + + stream << unitCell.a() << " " << unitCell.b() << " " << unitCell.c() << " " << unitCell.alpha() << " " << unitCell.beta() << " " << unitCell.gamma(); + + return stream.str(); + } + + UnitCell strToUnitCell(const std::string &unitCellString) + { + boost::char_separator separator(" "); + boost::tokenizer > cellTokens(unitCellString, separator); + + std::vector components; + + for(boost::tokenizer>::iterator token = cellTokens.begin(); token != cellTokens.end(); ++token) { + components.push_back(boost::lexical_cast(*token)); + } + + switch(components.size()) { + case 3: + return UnitCell(components[0], components[1], components[2]); + case 6: + return UnitCell(components[0], components[1], components[2], components[3], components[4], components[5]); + default: + throw std::runtime_error("Failed to parse unit cell input string: " + unitCellString); + } + } + } // namespace Mantid } // namespace Geometry diff --git a/Code/Mantid/Framework/Geometry/src/Crystal/V3R.cpp b/Code/Mantid/Framework/Geometry/src/Crystal/V3R.cpp new file mode 100644 index 000000000000..7b9880b9502f --- /dev/null +++ b/Code/Mantid/Framework/Geometry/src/Crystal/V3R.cpp @@ -0,0 +1,372 @@ +#include "MantidGeometry/Crystal/V3R.h" +#include "MantidKernel/Exception.h" + +namespace Mantid +{ +namespace Geometry +{ + +/// Default constructor, all elements 0 +V3R::V3R() : + m_x(0), m_y(0), m_z(0) +{ +} + +/// Constructor from three RationalNumbers, which may also be integers +V3R::V3R(const RationalNumber &x, const RationalNumber &y, const RationalNumber &z) : + m_x(x), m_y(y), m_z(z) +{ +} + +/// Constructor from an appropriately sized integer vector +V3R::V3R(const std::vector &vector) +{ + if(vector.size() != 3) { + throw Kernel::Exception::MisMatch(vector.size(),3,"V3R(const std::vector &vector)"); + } + + m_x = vector[0]; + m_y = vector[1]; + m_z = vector[2]; +} + +/// Copy constructor +V3R::V3R(const V3R &other) : + m_x(other.m_x), m_y(other.m_y), m_z(other.m_z) +{ +} + +/// Assigment operator +V3R &V3R::operator =(const V3R &other) +{ + m_x = other.m_x; + m_y = other.m_y; + m_z = other.m_z; + + return *this; +} + +/// Destructor +V3R::~V3R() +{ +} + +/// Returns the x-component of the vector +const RationalNumber &V3R::x() const +{ + return m_x; +} + +/// Assigns a new value to the x-component +void V3R::setX(const RationalNumber &newX) +{ + m_x = newX; +} + +/// Returns the y-component of the vector +const RationalNumber &V3R::y() const +{ + return m_y; +} + +/// Assigns a new value to the y-component +void V3R::setY(const RationalNumber &newY) +{ + m_y = newY; +} + +/// Returns the z-component of the vector +const RationalNumber &V3R::z() const +{ + return m_z; +} + +/// Assigns a new value to the z-component +void V3R::setZ(const RationalNumber &newZ) +{ + m_z = newZ; +} + +/// Array-style non-const access to the components. Throws Kernel::Exception::IndexError if index is out of range. +RationalNumber &V3R::operator [](size_t index) +{ + switch(index) { + case 0: return m_x; + case 1: return m_y; + case 2: return m_z; + default: + throw Kernel::Exception::IndexError(index, 2, "V3R::operator [] index out of range."); + } +} + +/// Array-style const access to the components. Throws Kernel::Exception::IndexError if index is out of range. +const RationalNumber &V3R::operator [](size_t index) const +{ + switch(index) { + case 0: return m_x; + case 1: return m_y; + case 2: return m_z; + default: + throw Kernel::Exception::IndexError(index, 2, "V3R::operator [] index out of range."); + } +} + +// Operations with other vectors +/// Performs the operation v1 + v2, which sums the vectors component-wise. +V3R V3R::operator +(const V3R &other) const +{ + V3R result(*this); + return result += other; +} + +/// Performs the operation v1 += v2 in place, which adds the components of v2 to the components of v1. +V3R &V3R::operator +=(const V3R &other) +{ + m_x += other.m_x; + m_y += other.m_y; + m_z += other.m_z; + + return *this; +} + +/// Negates all components of the vector +V3R V3R::operator -() const +{ + return V3R(-m_x, -m_y, -m_z); +} + +/// Performs the operation v1 - v2, which subtracts the vectors component-wise. +V3R V3R::operator -(const V3R &other) const +{ + V3R result(*this); + return result -= other; +} + +/// Performs the operation v1 -= v2 in place, which subtracts the components of v2 from the components of v1. +V3R &V3R::operator -=(const V3R &other) +{ + m_x -= other.m_x; + m_y -= other.m_y; + m_z -= other.m_z; + + return *this; +} + +// Operations with int +/// Performs the operation v' = v1 + i, which adds the integer i to each component of v1. +V3R V3R::operator +(int other) const +{ + V3R result(*this); + return result += other; +} + +/// Performs the operation v1 += i in place, which adds the integer i to each component of v1. +V3R &V3R::operator +=(int other) +{ + m_x += other; + m_y += other; + m_z += other; + + return *this; +} + +/// Performs the operation v' = v1 - i, which subtracts the integer i from each component of v1. +V3R V3R::operator -(int other) const +{ + V3R result(*this); + return result -= other; +} + +/// Performs the operation v1 -= i in place, which subtracts the integer i from each component of v1. +V3R &V3R::operator -=(int other) +{ + m_x -= other; + m_y -= other; + m_z -= other; + + return *this; +} + +/// Performs the operation v' = v1 * i, which multiplies each component of v1 with the integer i. +V3R V3R::operator *(int other) const +{ + V3R result(*this); + return result *= other; +} + +/// Performs the operation v1 *= i in place, which multiplies each component of v1 with the integer i. +V3R &V3R::operator *=(int other) +{ + m_x *= other; + m_y *= other; + m_z *= other; + + return *this; +} + +/// Performs the operation v' = v1 / i, which divides each component of v1 by the integer i. +V3R V3R::operator /(int other) const +{ + V3R result(*this); + return result /= other; +} + +/// Performs the operation v1 /= i in place, which divides each component of v1 by the integer i. +V3R &V3R::operator /=(int other) +{ + m_x /= other; + m_y /= other; + m_z /= other; + + return *this; +} + +// Operations with rational numbers +/// Performs the operation v' = v1 + r, which adds the RationalNumber r to each component of v1. +V3R V3R::operator +(const RationalNumber &other) const +{ + V3R result(*this); + return result += other; +} + +/// Performs the operation v1 += r in place, which adds the RationalNumber r to each component of v1. +V3R &V3R::operator +=(const RationalNumber &other) +{ + m_x += other; + m_y += other; + m_z += other; + + return *this; +} + +/// Performs the operation v' = v1 - r, which subtracts the RationalNumber r from each component of v1. +V3R V3R::operator -(const RationalNumber &other) const +{ + V3R result(*this); + return result -= other; +} + +/// Performs the operation v1 -= r, which subtracts the RationalNumber r from each component of v1. +V3R &V3R::operator -=(const RationalNumber &other) +{ + m_x -= other; + m_y -= other; + m_z -= other; + + return *this; +} + +/// Performs the operation v' = v1 * r, which multiplies each component of v1 with the RationalNumber r. +V3R V3R::operator *(const RationalNumber &other) const +{ + V3R result(*this); + return result *= other; +} + +/// Performs the operation v1 *= r in place, which multiplies each component of v1 with the RationalNumber r. +V3R &V3R::operator *=(const RationalNumber &other) +{ + m_x *= other; + m_y *= other; + m_z *= other; + + return *this; +} + +/// Performs the operation v' = v1 / r, which divides each component of v1 by the RationalNumber r. +V3R V3R::operator /(const RationalNumber &other) const +{ + V3R result(*this); + return result /= other; +} + +/// Performs the operation v1 /= r in place, which divides each component of v1 by the RationalNumber r. +V3R &V3R::operator /=(const RationalNumber &other) +{ + m_x /= other; + m_y /= other; + m_z /= other; + + return *this; +} + +/// Returns an instance of Kernel::V3D with floating point approximations of the components. +V3R::operator Kernel::V3D() const +{ + return Kernel::V3D(boost::rational_cast(m_x), + boost::rational_cast(m_y), + boost::rational_cast(m_z)); +} + +/// Returns the result of the operation d3' = r3 + d3, which is again a Kernel::V3D. +Kernel::V3D V3R::operator +(const Kernel::V3D &other) const +{ + return other + static_cast(*this); +} + +/// Returns the result of the operation d3' = r3 - d3, which is again a Kernel::V3D. +Kernel::V3D V3R::operator -(const Kernel::V3D &other) const +{ + return static_cast(*this) - other; +} + +/// Returns true if all components of the compared vectors are equal, false otherwise. +bool V3R::operator ==(const V3R &other) const +{ + return m_x == other.m_x && m_y == other.m_y && m_z == other.m_z; +} + +/// Returns true if the compared vectors are not equal. +bool V3R::operator !=(const V3R &other) const +{ + return !(this->operator==(other)); +} + +/// Compares x of both vectors first, if those are equal the function compares y and finally z. +bool V3R::operator <(const V3R &other) const +{ + if(m_x != other.m_x) { + return m_x < other.m_x; + } + + if(m_y != other.m_y) { + return m_y < other.m_y; + } + + return m_z < other.m_z; +} + +/// Returns true if all components are equal to the integer used for comparison. Useful for checking against 0. +bool V3R::operator ==(int other) const +{ + return m_x == other && m_y == other && m_z == other; +} + +/// Returns true if any component is different from the integer. +bool V3R::operator !=(int other) const +{ + return !(this->operator ==(other)); +} + +/// Performs a matrix multiplication v' = M * v, throws Kernel::Exception::MisMatch if M does not have exactly 3 columns. +V3R operator *(const Kernel::IntMatrix &lhs, const V3R &rhs) +{ + size_t rows = lhs.numRows(); + size_t cols = lhs.numCols(); + + if (cols != 3) { + throw Kernel::Exception::MisMatch(cols,3,"operator*(IntMatrix, V3R)"); + } + + V3R result; + for(size_t r = 0; r < rows; ++r) { + for(size_t c = 0; c < cols; ++c) { + result[r]+=lhs[r][c]*rhs[c]; + } + } + + return result; +} + +} // namespace Geometry +} // namespace Mantid diff --git a/Code/Mantid/Framework/Geometry/src/Instrument/InstrumentDefinitionParser.cpp b/Code/Mantid/Framework/Geometry/src/Instrument/InstrumentDefinitionParser.cpp index 5145c5cd5645..fec46c2cbd2b 100644 --- a/Code/Mantid/Framework/Geometry/src/Instrument/InstrumentDefinitionParser.cpp +++ b/Code/Mantid/Framework/Geometry/src/Instrument/InstrumentDefinitionParser.cpp @@ -3,7 +3,7 @@ #include "MantidGeometry/Instrument/ObjCompAssembly.h" #include "MantidGeometry/Instrument/ReferenceFrame.h" #include "MantidGeometry/Instrument/RectangularDetector.h" -#include "MantidGeometry/Instrument/XMLlogfile.h" +#include "MantidGeometry/Instrument/XMLInstrumentParameter.h" #include "MantidGeometry/Objects/ShapeFactory.h" #include "MantidGeometry/Rendering/vtkGeometryCacheReader.h" #include "MantidGeometry/Rendering/vtkGeometryCacheWriter.h" @@ -1909,7 +1909,7 @@ namespace Geometry } auto cacheKey = std::make_pair(paramName, comp); - auto cacheValue = boost::shared_ptr(new XMLlogfile(logfileID, value, interpolation, formula, formulaUnit, resultUnit, + auto cacheValue = boost::shared_ptr(new XMLInstrumentParameter(logfileID, value, interpolation, formula, formulaUnit, resultUnit, paramName, type, tie, constraint, penaltyFactor, fittingFunction, extractSingleValueAs, eq, comp, m_angleConvertConst)); auto inserted = logfileCache.insert(std::make_pair(cacheKey,cacheValue)); @@ -1929,13 +1929,10 @@ namespace Geometry * * @param instrument :: Instrument * @param pRootElem :: Associated Poco::XML element that may contain \ elements + * @param progress :: Optional progress object for reporting progress to an algorithm */ - void InstrumentDefinitionParser::setComponentLinks(boost::shared_ptr& instrument, Poco::XML::Element* pRootElem) + void InstrumentDefinitionParser::setComponentLinks(boost::shared_ptr& instrument, Poco::XML::Element* pRootElem, Kernel::ProgressBase* progress) { - Poco::AutoPtr pNL_link = pRootElem->getElementsByTagName("component-link"); - unsigned long numberLinks = pNL_link->length(); - - // check if any logfile cache units set. As of this writing the only unit to check is if "angle=radian" std::map& units = instrument->getLogfileUnit(); std::map::iterator unit_it; @@ -1944,82 +1941,99 @@ namespace Geometry if ( unit_it->second == "radian" ) m_angleConvertConst = 180.0/M_PI; + const std::string elemName = "component-link"; + Poco::AutoPtr pNL_link = pRootElem->getElementsByTagName(elemName); + unsigned long numberLinks = pNL_link->length(); - // Loop over all component-link elements of pRootElem - for (unsigned long iLink = 0; iLink < numberLinks; iLink++) - { - Element* pLinkElem = static_cast(pNL_link->item(iLink)); - std::string id = pLinkElem->getAttribute("id"); - std::string name = pLinkElem->getAttribute("name"); - std::vector > sharedIComp; + if(progress) + progress->resetNumSteps((int64_t)numberLinks, 0.0, 0.95); - //If available, use the detector id as it's the most specific. - if(id.length() > 0) + Node* curNode = pRootElem->firstChild(); + while(curNode) + { + if(curNode->nodeType() == Node::ELEMENT_NODE && curNode->nodeName() == elemName) { - int detid; - std::stringstream(id) >> detid; - boost::shared_ptr detector = instrument->getDetector((detid_t) detid); + Element* curElem = static_cast(curNode); - //If we didn't find anything with the detector id, explain why to the user, and throw an exception. - if(!detector) + if(progress) { - g_log.error() << "Error whilst loading parameters. No detector found with id '" << detid << "'" << std::endl; - g_log.error() << "Please check that your detectors' ids are correct." << std::endl; - throw Kernel::Exception::InstrumentDefinitionError("Invalid detector id in component-link tag."); + if(progress->hasCancellationBeenRequested()) + return; + progress->report("Loading parameters"); } - sharedIComp.push_back(detector); + std::string id = curElem->getAttribute("id"); + std::string name = curElem->getAttribute("name"); + std::vector > sharedIComp; - //If the user also supplied a name, make sure it's consistent with the detector id. - if(name.length() > 0) + //If available, use the detector id as it's the most specific. + if(id.length() > 0) { - auto comp = boost::dynamic_pointer_cast(detector); - if(comp) + int detid; + std::stringstream(id) >> detid; + boost::shared_ptr detector = instrument->getDetector((detid_t) detid); + + //If we didn't find anything with the detector id, explain why to the user, and throw an exception. + if(!detector) { - bool consistent = (comp->getFullName() == name || comp->getName() == name); - if(!consistent) + g_log.error() << "Error whilst loading parameters. No detector found with id '" << detid << "'" << std::endl; + g_log.error() << "Please check that your detectors' ids are correct." << std::endl; + throw Kernel::Exception::InstrumentDefinitionError("Invalid detector id in component-link tag."); + } + + sharedIComp.push_back(detector); + + //If the user also supplied a name, make sure it's consistent with the detector id. + if(name.length() > 0) + { + auto comp = boost::dynamic_pointer_cast(detector); + if(comp) { - g_log.warning() << "Error whilst loading parameters. Name '" << name << "' does not match id '" << detid << "'." << std::endl; - g_log.warning() << "Parameters have been applied to detector with id '" << detid << "'. Please check the name is correct." << std::endl; + bool consistent = (comp->getFullName() == name || comp->getName() == name); + if(!consistent) + { + g_log.warning() << "Error whilst loading parameters. Name '" << name << "' does not match id '" << detid << "'." << std::endl; + g_log.warning() << "Parameters have been applied to detector with id '" << detid << "'. Please check the name is correct." << std::endl; + } } } } - } - else - { - //No detector id given, fall back to using the name - - if( name.find('/',0) == std::string::npos ) - { // Simple name, look for all components of that name. - sharedIComp = instrument->getAllComponentsWithName(name); - } else - { // Pathname given. Assume it is unique. - boost::shared_ptr shared = instrument->getComponentByName(name); - sharedIComp.push_back( shared ); - } - } - - for (size_t i = 0; i < sharedIComp.size(); i++) - { - boost::shared_ptr sharedComp = boost::dynamic_pointer_cast(sharedIComp[i]); - if ( sharedComp ) { - //Not empty Component - if (sharedComp->isParametrized()) - { - setLogfile(sharedComp->base(), pLinkElem, instrument->getLogfileCache()); + //No detector id given, fall back to using the name + + if( name.find('/',0) == std::string::npos ) + { // Simple name, look for all components of that name. + sharedIComp = instrument->getAllComponentsWithName(name); } else + { // Pathname given. Assume it is unique. + boost::shared_ptr shared = instrument->getComponentByName(name); + sharedIComp.push_back( shared ); + } + } + + for (size_t i = 0; i < sharedIComp.size(); i++) + { + boost::shared_ptr sharedComp = boost::dynamic_pointer_cast(sharedIComp[i]); + if ( sharedComp ) { - setLogfile(sharedIComp[i].get(), pLinkElem, instrument->getLogfileCache()); + //Not empty Component + if (sharedComp->isParametrized()) + { + setLogfile(sharedComp->base(), curElem, instrument->getLogfileCache()); + } + else + { + setLogfile(sharedIComp[i].get(), curElem, instrument->getLogfileCache()); + } } } } + curNode = curNode->nextSibling(); } } - /** Check that the cache file does actually exist and that it was modified last after the last modification to the xml def file. i.e. the vtp file contains the most recent set of changes. diff --git a/Code/Mantid/Framework/Geometry/src/Instrument/ObjComponent.cpp b/Code/Mantid/Framework/Geometry/src/Instrument/ObjComponent.cpp index 45e17b2cb93f..6eb8f985a0a8 100644 --- a/Code/Mantid/Framework/Geometry/src/Instrument/ObjComponent.cpp +++ b/Code/Mantid/Framework/Geometry/src/Instrument/ObjComponent.cpp @@ -72,8 +72,8 @@ namespace Mantid m_shape = newShape; } - /** - * Return the material of the component. Currently + /** + * Return the material of the component. Currently * unaffected by parametrization */ const Kernel::Material_const_sptr ObjComponent::material() const @@ -132,7 +132,7 @@ namespace Mantid //use the scale factor out *= getScaleFactor(); out += this->getPos(); - track.addLink(in,out,out.distance(track.startPoint()),this->getComponentID()); + track.addLink(in,out,out.distance(track.startPoint()), *(this->shape()), this->getComponentID()); } return intercepts; @@ -160,18 +160,18 @@ namespace Mantid } } - + /** * Given an input estimate of the axis aligned (AA) bounding box (BB), return an improved set of values. * The AA BB is determined in the frame of the object and the initial estimate will be transformed there. * The returned BB will be the frame of the ObjComponent and may not be optimal. * @param absoluteBB :: [InOut] The bounding box for this object component will be stored here. - * if BB alignment is different from axis alignment, the system of coordinates to alighn is taken fron + * if BB alignment is different from axis alignment, the system of coordinates to alighn is taken fron * the absoluteBB */ void ObjComponent::getBoundingBox(BoundingBox& absoluteBB) const { - + // Start with the box in the shape's coordinates const Object_const_sptr s = shape(); if ( ! s ){ @@ -200,22 +200,22 @@ namespace Mantid // Rotate (this->getRotation()).rotateBB(absoluteBB.xMin(),absoluteBB.yMin(),absoluteBB.zMin(), absoluteBB.xMax(),absoluteBB.yMax(),absoluteBB.zMax()); - - + + // Shift const V3D localPos = this->getPos(); - absoluteBB.xMin() += localPos.X(); + absoluteBB.xMin() += localPos.X(); absoluteBB.xMax() += localPos.X(); - absoluteBB.yMin() += localPos.Y(); + absoluteBB.yMin() += localPos.Y(); absoluteBB.yMax() += localPos.Y(); - absoluteBB.zMin() += localPos.Z(); + absoluteBB.zMin() += localPos.Z(); absoluteBB.zMax() += localPos.Z(); if(!Coord_system.empty()){ absoluteBB.realign(&Coord_system); - } + } } - + /** * Gets the Height of the object by querying the underlying BoundingBox. * @return height of object @@ -235,7 +235,7 @@ namespace Mantid const BoundingBox & bbox = shape()->getBoundingBox(); return ( bbox.xMax() - bbox.xMin() ) / getScaleFactor().X(); } - + /** * Gets the Depth of the object by querying the underlying BoundingBox. * @return depth of object diff --git a/Code/Mantid/Framework/Geometry/src/Instrument/ParameterMap.cpp b/Code/Mantid/Framework/Geometry/src/Instrument/ParameterMap.cpp index 8ad7623a149d..9741362db103 100644 --- a/Code/Mantid/Framework/Geometry/src/Instrument/ParameterMap.cpp +++ b/Code/Mantid/Framework/Geometry/src/Instrument/ParameterMap.cpp @@ -131,10 +131,10 @@ namespace Mantid * @return true if the objects are considered not equal, false otherwise */ bool ParameterMap::operator!=(const ParameterMap & rhs) const - { - return !(this->operator==(rhs)); + { + return !(this->operator==(rhs)); } - + /** * Compares the values in this object with that given for equality * The order of the values in the map is not important. @@ -144,10 +144,10 @@ namespace Mantid bool ParameterMap::operator==(const ParameterMap & rhs) const { if(this == &rhs) return true; // True for the same object - + // Quick size check if(this->size() != rhs.size()) return false; - + // The map is unordered and the key is only valid at runtime. The // asString method turns the ComponentIDs to full-qualified name identifiers // so we will use the same approach to compare them @@ -175,7 +175,7 @@ namespace Mantid return true; } - + /** * Output information that helps understanding the mismatch between two parameter maps. * To loop through the difference between two very large parameter map can take time, in which @@ -187,15 +187,15 @@ namespace Mantid const std::string ParameterMap::diff(const ParameterMap & rhs, const bool & firstDiffOnly) const { if(this == &rhs) return std::string(""); // True for the same object - + // Quick size check - if(this->size() != rhs.size()) + if(this->size() != rhs.size()) { - return std::string("Number of parameters does not match: ") + + return std::string("Number of parameters does not match: ") + boost::lexical_cast(this->size()) + " not equal to " + boost::lexical_cast(rhs.size()); } - + // Run this same loops as in operator== // The map is unordered and the key is only valid at runtime. The // asString method turns the ComponentIDs to full-qualified name identifiers @@ -221,7 +221,7 @@ namespace Mantid } } - if(!match) + if(!match) { // output some information that helps with understanding the mismatch strOutput << "Parameter mismatch LHS=RHS for LHS parameter in component with name: " << fullName @@ -306,7 +306,7 @@ namespace Mantid if( name == pos() || name == rot() ) clearPositionSensitiveCaches(); } } - + /** * Add a value into the map * @param type :: A string denoting the type, e.g. double, string, fitting @@ -314,7 +314,7 @@ namespace Mantid * @param name :: The name of the parameter * @param value :: The parameter's value */ - void ParameterMap::add(const std::string& type,const IComponent* comp,const std::string& name, + void ParameterMap::add(const std::string& type,const IComponent* comp,const std::string& name, const std::string& value) { auto param = ParameterFactory::create(type,name); @@ -331,7 +331,7 @@ namespace Mantid // can not add null pointer if(!par)return; - PARALLEL_CRITICAL(parameter_add) + PARALLEL_CRITICAL(m_mapAccess) { auto existing_par = positionOf(comp,par->name().c_str(),""); // As this is only an add method it should really throw if it already exists. @@ -350,13 +350,13 @@ namespace Mantid } /** Create or adjust "pos" parameter for a component - * Assumed that name either equals "x", "y" or "z" otherwise this + * Assumed that name either equals "x", "y" or "z" otherwise this * method will not add or modify "pos" parameter * @param comp :: Component * @param name :: name of the parameter * @param value :: value */ - void ParameterMap::addPositionCoordinate(const IComponent* comp, const std::string& name, + void ParameterMap::addPositionCoordinate(const IComponent* comp, const std::string& name, const double value) { Parameter_sptr param = get(comp,pos()); @@ -393,7 +393,7 @@ namespace Mantid } /** Create or adjust "rot" parameter for a component - * Assumed that name either equals "rotx", "roty" or "rotz" otherwise this + * Assumed that name either equals "rotx", "roty" or "rotz" otherwise this * method will not add/modify "rot" parameter * @param comp :: Component * @param name :: Parameter name @@ -420,7 +420,7 @@ namespace Mantid rotZ = paramRotZ->value(); else rotZ = 0.0; - + // adjust rotation Quat quat; @@ -452,7 +452,7 @@ namespace Mantid addQuat(comp, rot(), quat); } - /** + /** * Adds a double value to the parameter map. * @param comp :: Component to which the new parameter is related * @param name :: Name for the new parameter @@ -474,7 +474,7 @@ namespace Mantid add(pDouble(),comp,name,value); } - /** + /** * Adds an int value to the parameter map. * @param comp :: Component to which the new parameter is related * @param name :: Name for the new parameter @@ -496,7 +496,7 @@ namespace Mantid add(pInt(),comp,name,value); } - /** + /** * Adds a bool value to the parameter map. * @param comp :: Component to which the new parameter is related * @param name :: Name for the new parameter @@ -517,7 +517,7 @@ namespace Mantid add(pBool(),comp,name,value); } - /** + /** * Adds a std::string value to the parameter map. * @param comp :: Component to which the new parameter is related * @param name :: Name for the new parameter @@ -528,7 +528,7 @@ namespace Mantid add(pString(),comp,name,value); } - /** + /** * Adds a V3D value to the parameter map. * @param comp :: Component to which the new parameter is related * @param name :: Name for the new parameter @@ -552,7 +552,7 @@ namespace Mantid clearPositionSensitiveCaches(); } - /** + /** * Adds a Quat value to the parameter map. * @param comp :: Component to which the new parameter is related * @param name :: Name for the new parameter @@ -625,7 +625,7 @@ namespace Mantid } return false; } - else + else return false; } @@ -654,7 +654,7 @@ namespace Mantid Parameter_sptr result; if(!comp) return result; - PARALLEL_CRITICAL(ParameterMap_get) + PARALLEL_CRITICAL(m_mapAccess) { auto itr = positionOf(comp,name, type); if (itr != m_map.end()) @@ -662,8 +662,8 @@ namespace Mantid } return result; } - - /**Return an iterator pointing to a named parameter of a given type. + + /**Return an iterator pointing to a named parameter of a given type. * @param comp :: Component to which parameter is related * @param name :: Parameter name * @param type :: An optional type string. If empty, any type is returned @@ -692,11 +692,11 @@ namespace Mantid } } } - } + } return result; } - /**Return a const iterator pointing to a named parameter of a given type. + /**Return a const iterator pointing to a named parameter of a given type. * @param comp :: Component to which parameter is related * @param name :: Parameter name * @param type :: An optional type string. If empty, any type is returned @@ -725,7 +725,7 @@ namespace Mantid } } } - } + } return result; } @@ -739,7 +739,7 @@ namespace Mantid Parameter_sptr ParameterMap::getByType(const IComponent* comp, const std::string& type) const { Parameter_sptr result = Parameter_sptr(); - PARALLEL_CRITICAL(ParameterMap_get) + PARALLEL_CRITICAL(m_mapAccess) { if( !m_map.empty() ) { @@ -763,7 +763,7 @@ namespace Mantid } // found->firdst } // it_found != m_map.end() } //!m_map.empty() - } // PARALLEL_CRITICAL(ParameterMap_get) + } // PARALLEL_CRITICAL(m_map_access) return result; } @@ -789,7 +789,7 @@ namespace Mantid } - /** + /** * Find a parameter by name, recursively going up the component tree * to higher parents. * @param comp :: The component to start the search with @@ -797,13 +797,13 @@ namespace Mantid * @param type :: An optional type string * @returns the first matching parameter. */ - Parameter_sptr ParameterMap::getRecursive(const IComponent* comp,const std::string& name, + Parameter_sptr ParameterMap::getRecursive(const IComponent* comp,const std::string& name, const std::string & type) const { return getRecursive(comp, name.c_str(), type.c_str()); } - /** + /** * Find a parameter by name, recursively going up the component tree * to higher parents. * @param comp :: The component to start the search with @@ -811,7 +811,7 @@ namespace Mantid * @param type :: An optional type string * @returns the first matching parameter. */ - Parameter_sptr ParameterMap::getRecursive(const IComponent* comp, const char* name, + Parameter_sptr ParameterMap::getRecursive(const IComponent* comp, const char* name, const char * type) const { Parameter_sptr result = this->get(comp->getComponentID(), name, type); @@ -827,7 +827,7 @@ namespace Mantid return result; } - /** + /** * Return the value of a parameter as a string * @param comp :: Component to which parameter is related * @param name :: Parameter name @@ -849,7 +849,7 @@ namespace Mantid return param->asString(); } - /** + /** * Returns a set with all the parameter names for the given component * @param comp :: A pointer to the component of interest * @returns A set of names of parameters for the given component @@ -864,17 +864,16 @@ namespace Mantid return paramNames; } - pmap_cit it_begin = m_map.lower_bound(id); - pmap_cit it_end = m_map.upper_bound(id); - - for(pmap_cit it = it_begin; it != it_end; ++it) + pmap_cit itr = m_map.lower_bound(id); + pmap_cit itr_end = m_map.upper_bound(id); + for(pmap_cit it = itr; it != itr_end; ++it) { paramNames.insert(it->second->name()); } return paramNames; - } - + } + /** * Return a string representation of the parameter map. The format is either: * |detID:id-value;param-type;param-name;param-value| for a detector or @@ -914,10 +913,10 @@ namespace Mantid m_cacheRotMap.clear(); m_boundingBoxMap.clear(); } - + ///Sets a cached location on the location cache /// @param comp :: The Component to set the location of - /// @param location :: The location + /// @param location :: The location void ParameterMap::setCachedLocation(const IComponent* comp, const V3D& location) const { // Call to setCachedLocation is a write so not thread-safe @@ -943,7 +942,7 @@ namespace Mantid ///Sets a cached rotation on the rotation cache /// @param comp :: The Component to set the rotation of - /// @param rotation :: The rotation as a quaternion + /// @param rotation :: The rotation as a quaternion void ParameterMap::setCachedRotation(const IComponent* comp, const Quat& rotation) const { // Call to setCachedRotation is a write so not thread-safe @@ -996,7 +995,7 @@ namespace Mantid * @param oldPMap :: Old map corresponding to the Old component */ void ParameterMap::copyFromParameterMap(const IComponent* oldComp, - const IComponent* newComp, const ParameterMap *oldPMap) + const IComponent* newComp, const ParameterMap *oldPMap) { std::set oldParameterNames = oldPMap->names(oldComp); @@ -1008,7 +1007,7 @@ namespace Mantid m_map.insert(std::make_pair(newComp->getComponentID(),thisParameter)); } } - + //-------------------------------------------------------------------------------------------- /** Save the object to an open NeXus file. * @param file :: open NeXus file @@ -1029,4 +1028,3 @@ namespace Mantid } // Namespace Geometry } // Namespace Mantid - diff --git a/Code/Mantid/Framework/Geometry/src/Instrument/RectangularDetector.cpp b/Code/Mantid/Framework/Geometry/src/Instrument/RectangularDetector.cpp index 8dfdbc9f571f..f3239590c994 100644 --- a/Code/Mantid/Framework/Geometry/src/Instrument/RectangularDetector.cpp +++ b/Code/Mantid/Framework/Geometry/src/Instrument/RectangularDetector.cpp @@ -8,7 +8,7 @@ #include "MantidKernel/Exception.h" #include #include -#include +#include #include "MantidGeometry/Instrument/RectangularDetectorPixel.h" namespace Mantid @@ -44,7 +44,7 @@ RectangularDetector::RectangularDetector(const RectangularDetector* base, const /** Valued constructor * @param n :: name of the assembly * @param reference :: the parent Component - * + * * If the reference is an object of class Component, * normal parenting apply. If the reference object is * an assembly itself, then in addition to parenting @@ -63,7 +63,7 @@ RectangularDetector::RectangularDetector(const std::string& n, IComponent* refer */ RectangularDetector::~RectangularDetector() { - + } /** Clone method @@ -406,7 +406,7 @@ void RectangularDetector::initialize(boost::shared_ptr shape, //Calculate its id and set it. int id; id = this->getDetectorIDAtXY(ix, iy); - + //minimum rectangular detector id if(id shape, m_minDetId=minDetId; m_maxDetId=maxDetId; - + } //------------------------------------------------------------------------------------------------- @@ -544,8 +544,8 @@ void RectangularDetector::testIntersectionWithChildren(Track & testRay, std::deq if (yIndex >= ypixels()) return; // TODO: Do I need to put something smart here for the first 3 parameters? - testRay.addLink(intersec, intersec, 0.0, - getAtXY(xIndex, yIndex)->getComponentID()); + auto comp = getAtXY(xIndex, yIndex); + testRay.addLink(intersec, intersec, 0.0, *(comp->shape()), comp->getComponentID()); } diff --git a/Code/Mantid/Framework/Geometry/src/Instrument/XMLlogfile.cpp b/Code/Mantid/Framework/Geometry/src/Instrument/XMLInstrumentParameter.cpp similarity index 94% rename from Code/Mantid/Framework/Geometry/src/Instrument/XMLlogfile.cpp rename to Code/Mantid/Framework/Geometry/src/Instrument/XMLInstrumentParameter.cpp index 4840b6a452e5..6f46e05ea75e 100644 --- a/Code/Mantid/Framework/Geometry/src/Instrument/XMLlogfile.cpp +++ b/Code/Mantid/Framework/Geometry/src/Instrument/XMLInstrumentParameter.cpp @@ -1,7 +1,7 @@ //---------------------------------------------------------------------- // Includes //---------------------------------------------------------------------- -#include "MantidGeometry/Instrument/XMLlogfile.h" +#include "MantidGeometry/Instrument/XMLInstrumentParameter.h" #include "MantidGeometry/IComponent.h" #include "MantidGeometry/muParser_Silent.h" #include "MantidKernel/TimeSeriesProperty.h" @@ -16,7 +16,7 @@ namespace Mantid { namespace { - Kernel::Logger g_log("XMLlogfile"); + Kernel::Logger g_log("XMLInstrumentParameter"); } using namespace Kernel; @@ -40,7 +40,7 @@ namespace Mantid * @param fitFunc :: What fit function this applies to * @param angleConvertConst :: angle conversion constant????? */ - XMLlogfile::XMLlogfile(const std::string& logfileID, const std::string& value, const boost::shared_ptr& interpolation, + XMLInstrumentParameter::XMLInstrumentParameter(const std::string& logfileID, const std::string& value, const boost::shared_ptr& interpolation, const std::string& formula, const std::string& formulaUnit, const std::string& resultUnit, const std::string& paramName, const std::string& type, const std::string& tie, const std::vector& constraint, std::string& penaltyFactor, @@ -65,7 +65,7 @@ namespace Mantid * * @throw InstrumentDefinitionError Thrown if issues with the content of XML instrument definition file */ - double XMLlogfile::createParamValue(TimeSeriesProperty* logData) const + double XMLInstrumentParameter::createParamValue(TimeSeriesProperty* logData) const { // If this parameter is a or return 0.0. Such parameter types are // associated with 'fitting' parameters. In some sense this method should never be called @@ -80,7 +80,7 @@ namespace Mantid if ( m_type == "string" ) { - g_log.error() << "XMLlogfile::createParamValue has been called with a 'string' parameters.\n" + g_log.error() << "XMLInstrumentParameter::createParamValue has been called with a 'string' parameters.\n" << "Return meaningless zere value."; return 0.0; } diff --git a/Code/Mantid/Framework/Geometry/src/Objects/Object.cpp b/Code/Mantid/Framework/Geometry/src/Objects/Object.cpp index a863dc39f482..221750d9bb4f 100644 --- a/Code/Mantid/Framework/Geometry/src/Objects/Object.cpp +++ b/Code/Mantid/Framework/Geometry/src/Objects/Object.cpp @@ -4,7 +4,6 @@ #include "MantidKernel/MultiThreaded.h" #include "MantidGeometry/Objects/Rules.h" #include "MantidGeometry/Objects/Track.h" -#include "MantidGeometry/Objects/BoundingBox.h" #include "MantidGeometry/Surfaces/Surface.h" #include "MantidGeometry/Surfaces/LineIntersectVisit.h" @@ -36,7 +35,8 @@ namespace Mantid ObjName(0), TopRule(0), m_boundingBox(), AABBxMax(0), AABByMax(0), AABBzMax(0), AABBxMin(0), AABByMin(0), AABBzMin(0), boolBounded(false), handle(), bGeometryCaching(false), vtkCacheReader(boost::shared_ptr()), - vtkCacheWriter(boost::shared_ptr()) + vtkCacheWriter(boost::shared_ptr()), + m_material() // empty by default { handle = boost::shared_ptr(new CacheGeometryHandler(this)); } @@ -49,7 +49,7 @@ namespace Mantid ObjName(0), TopRule(0), m_boundingBox(), AABBxMax(0), AABByMax(0), AABBzMax(0), AABBxMin(0), AABByMin(0), AABBzMin(0), boolBounded(false), handle(), bGeometryCaching(false), vtkCacheReader(boost::shared_ptr()), vtkCacheWriter(boost::shared_ptr< - vtkGeometryCacheWriter>()), m_shapeXML(shapeXML) + vtkGeometryCacheWriter>()), m_shapeXML(shapeXML), m_material() // empty by default { handle = boost::shared_ptr(new CacheGeometryHandler(this)); } @@ -60,11 +60,11 @@ namespace Mantid */ Object::Object(const Object& A) : ObjName(A.ObjName), TopRule((A.TopRule) ? A.TopRule->clone() : NULL), m_boundingBox(A.m_boundingBox), - AABBxMax(A.AABBxMax), AABByMax(A.AABByMax), AABBzMax(A.AABBzMax), AABBxMin(A.AABBxMin), + AABBxMax(A.AABBxMax), AABByMax(A.AABByMax), AABBzMax(A.AABBzMax), AABBxMin(A.AABBxMin), AABByMin(A.AABByMin), AABBzMin(A.AABBzMin), boolBounded(A.boolBounded), handle(A.handle->clone()), bGeometryCaching(A.bGeometryCaching), vtkCacheReader(A.vtkCacheReader), vtkCacheWriter(A.vtkCacheWriter), - m_shapeXML(A.m_shapeXML) + m_shapeXML(A.m_shapeXML), m_material(A.m_material) { if (TopRule) createSurfaceList(); } @@ -93,6 +93,7 @@ namespace Mantid vtkCacheReader = A.vtkCacheReader; vtkCacheWriter = A.vtkCacheWriter; m_shapeXML = A.m_shapeXML; + m_material = A.m_material; if (TopRule) createSurfaceList(); } @@ -108,9 +109,25 @@ namespace Mantid delete TopRule; } + /** + * @param material The new Material that the object is composed from + */ + void Object::setMaterial(const Kernel::Material &material) + { + m_material = material; + } + + /** + * @return The Material that the object is composed from + */ + const Kernel::Material &Object::material() const + { + return m_material; + } + /** * Returns whether this object has a valid shape - * @returns True if the surface list is populated and there is a + * @returns True if the surface list is populated and there is a * defined TopRule, false otherwise. */ bool Object::hasValidShape() const @@ -262,7 +279,7 @@ namespace Mantid * @retval 1000+ keyNumber :: Error with keyNumber * @retval 0 :: successfully populated all the whole Object. */ - int Object::populate(const std::map& Smap) + int Object::populate(const std::map& Smap) { std::deque Rst; Rst.push_back(TopRule); @@ -624,7 +641,7 @@ namespace Mantid /** * Takes the complement of a group */ - void Object::makeComplement() + void Object::makeComplement() { Rule* NCG = procComp(TopRule); TopRule = NCG; @@ -793,16 +810,18 @@ namespace Mantid { (*vc)->acceptVisitor(LI); } - const std::vector& IPts(LI.getPoints()); - const std::vector& dPts(LI.getDistance()); + const auto& IPts(LI.getPoints()); + const auto& dPts(LI.getDistance()); - for (unsigned int i = 0; i < IPts.size(); i++) + auto ditr = dPts.begin(); + auto itrEnd = IPts.end(); + for (auto iitr = IPts.begin(); iitr != itrEnd; ++iitr, ++ditr) { - if (dPts[i] > 0.0) // only interested in forward going points + if (*ditr > 0.0) // only interested in forward going points { // Is the point and enterance/exit Point - const int flag = calcValidType(IPts[i], UT.direction()); - UT.addPoint(flag, IPts[i]); + const int flag = calcValidType(*iitr, UT.direction()); + UT.addPoint(flag, *iitr, *this); } } UT.buildLink(); @@ -1265,12 +1284,12 @@ namespace Mantid double Object::CylinderSolidAngle(const V3D & observer, const Mantid::Kernel::V3D & centre, const Mantid::Kernel::V3D & axis, const double radius, const double height) const { - // The cylinder is triangulated along its axis EXCLUDING the end caps so that stacked cylinders - // give the correct value of solid angle (i.e shadowing is losely taken into account by this + // The cylinder is triangulated along its axis EXCLUDING the end caps so that stacked cylinders + // give the correct value of solid angle (i.e shadowing is losely taken into account by this //method) - // Any triangle that has a normal facing away from the observer gives a negative solid + // Any triangle that has a normal facing away from the observer gives a negative solid //angle and is excluded - // For simplicity the triangulation points are constructed such that the cone axis + // For simplicity the triangulation points are constructed such that the cone axis // points up the +Z axis and then rotated into their final position Kernel::V3D axis_direction = axis; axis_direction.normalize(); @@ -1495,7 +1514,7 @@ namespace Mantid */ const BoundingBox & Object::getBoundingBox() const { - // This member function is const given that from a user's perspective it is perfecly reasonable + // This member function is const given that from a user's perspective it is perfecly reasonable // to call it on a const object. We need to call a non-const function in places to update the cache, // which is where the const_cast comes in to play. @@ -1507,10 +1526,10 @@ namespace Mantid else if( m_boundingBox.isNull() ) { // First up, construct the trial set of elements from the object's bounding box - const double big(1e10); + const double big(1e10); double minX(-big), maxX(big), minY(-big), maxY(big), minZ(-big), maxZ(big); TopRule->getBoundingBox(maxX, maxY, maxZ, minX, minY, minZ); - //If the object is not axis aligned then the bounding box will be poor, in particular the minima are left at the trial start so return + //If the object is not axis aligned then the bounding box will be poor, in particular the minima are left at the trial start so return // a null object here if (minX < -100 || maxX > 100 || minY < -100 || maxY > 100 || minZ < -100 || maxZ > 100) { diff --git a/Code/Mantid/Framework/Geometry/src/Objects/RuleItems.cpp b/Code/Mantid/Framework/Geometry/src/Objects/RuleItems.cpp index b78500bee17f..97a69ac7534f 100644 --- a/Code/Mantid/Framework/Geometry/src/Objects/RuleItems.cpp +++ b/Code/Mantid/Framework/Geometry/src/Objects/RuleItems.cpp @@ -292,9 +292,11 @@ Intersection::isValid(const Kernel::V3D& Vec) const @retval 0 :: Vec is outside object. */ { - if (!A || !B) - return false; - return (A->isValid(Vec) && B->isValid(Vec)) ? true : false; + if(A && B) + { + return (A->isValid(Vec) && B->isValid(Vec)); + } + return false; } bool @@ -849,9 +851,10 @@ SurfPoint::isValid(const Kernel::V3D& Pt) const */ { if (key) - return (key->side(Pt)*sign)>=0 ? true : false; - else - return false; + { + return (key->side(Pt)*sign)>=0; + } + return false; } bool diff --git a/Code/Mantid/Framework/Geometry/src/Objects/Track.cpp b/Code/Mantid/Framework/Geometry/src/Objects/Track.cpp index 05e1a0533268..9fc1a56a65a8 100644 --- a/Code/Mantid/Framework/Geometry/src/Objects/Track.cpp +++ b/Code/Mantid/Framework/Geometry/src/Objects/Track.cpp @@ -26,7 +26,7 @@ namespace Mantid * Constructor * @param startPt :: Initial point * @param unitVector :: Directional vector. It must be unit vector. - */ + */ Track::Track(const V3D& startPt, const V3D& unitVector) : m_startPoint(startPt),m_unitVector(unitVector) {} @@ -34,7 +34,7 @@ namespace Mantid /** * Copy Constructor * @param other :: Track to initialise this copy with. - */ + */ Track::Track(const Track& other) : m_startPoint(other.m_startPoint),m_unitVector(other.m_unitVector), m_links(other.m_links),m_surfPoints(other.m_surfPoints) {} @@ -43,7 +43,7 @@ namespace Mantid * Assignment operator * @param other :: The track to copy from * @return *this - */ + */ Track& Track::operator=(const Track& other) { if (this != &other) @@ -63,7 +63,7 @@ namespace Mantid {} /** - * Resets the track starting point and direction. + * Resets the track starting point and direction. * @param startPoint :: The new starting point * @param direction :: The new direction. Must be a unit vector! */ @@ -153,11 +153,14 @@ namespace Mantid * @param directionFlag :: A flag indicating if the direction of travel is entering/leaving * an object. +1 is entering, -1 is leaving. * @param endPoint :: Point of intersection + * @param obj :: A reference to the object that was intersected * @param compID :: ID of the component that this link is about (Default=NULL) */ - void Track::addPoint(const int directionFlag, const V3D& endPoint, const ComponentID compID) + void Track::addPoint(const int directionFlag, const V3D& endPoint, const Object & obj, + const ComponentID compID) { - IntersectionPoint newPoint(directionFlag, endPoint, endPoint.distance(m_startPoint), compID); + IntersectionPoint newPoint(directionFlag, endPoint, endPoint.distance(m_startPoint), + obj, compID); PType::iterator lowestPtr = std::lower_bound(m_surfPoints.begin(), m_surfPoints.end(), newPoint); m_surfPoints.insert(lowestPtr, newPoint); } @@ -167,14 +170,15 @@ namespace Mantid * @param firstPoint :: first Point * @param secondPoint :: second Point * @param distanceAlongTrack :: Distance along track + * @param obj :: A reference to the object that was intersected * @param compID :: ID of the component that this link is about (Default=NULL) * @retval Index of link within the track */ int Track::addLink(const V3D& firstPoint, const V3D& secondPoint, - const double distanceAlongTrack, const ComponentID compID) + const double distanceAlongTrack, const Object &obj, const ComponentID compID) { // Process First Point - Link newLink(firstPoint,secondPoint,distanceAlongTrack,compID); + Link newLink(firstPoint,secondPoint,distanceAlongTrack,obj,compID); int index(0); if( m_links.empty() ) { @@ -193,7 +197,7 @@ namespace Mantid /** * Builds a set of linking track components. - * This version deals with touching surfaces + * This version deals with touching surfaces */ void Track::buildLink() { @@ -213,7 +217,7 @@ namespace Mantid { if (ac->directionFlag==-1) { - addLink(m_startPoint,ac->endPoint,ac->distFromStart,ac->componentID); // from the void + addLink(m_startPoint,ac->endPoint,ac->distFromStart,*ac->object,ac->componentID); // from the void workPt = ac->endPoint; } ++ac; @@ -221,7 +225,7 @@ namespace Mantid { ++bc; } - } + } //have we now passed over all of the potential intersections without actually hitting the object if (ac == m_surfPoints.end()) @@ -231,7 +235,7 @@ namespace Mantid return; } - workPt = ac->endPoint; + workPt = ac->endPoint; while(bc != m_surfPoints.end()) // Since bc > ac { if (ac->directionFlag==1 && bc->directionFlag==-1) @@ -240,19 +244,19 @@ namespace Mantid if (fabs(ac->distFromStart - bc->distFromStart)>Tolerance) { // track leave ac into bc. - addLink(ac->endPoint,bc->endPoint,bc->distFromStart,ac->componentID); + addLink(ac->endPoint,bc->endPoint,bc->distFromStart,*ac->object,ac->componentID); } // Points with intermediate void else { - addLink(workPt,ac->endPoint,ac->distFromStart,ac->componentID); + addLink(workPt,ac->endPoint,ac->distFromStart,*ac->object,ac->componentID); } workPt = bc->endPoint; // ADDING to ac twice: since processing pairs ++ac; ++ac; - ++bc; // can I do this past the end ? + ++bc; // can I do this past the end ? if (bc!=m_surfPoints.end()) { ++bc; @@ -263,9 +267,9 @@ namespace Mantid ++ac; ++bc; } - } + } - m_surfPoints.clear(); // While vector + m_surfPoints.clear(); // While vector return; } diff --git a/Code/Mantid/Framework/Geometry/src/Surfaces/Line.cpp b/Code/Mantid/Framework/Geometry/src/Surfaces/Line.cpp index 69e2dbbc1e1d..c4c424e9fb55 100644 --- a/Code/Mantid/Framework/Geometry/src/Surfaces/Line.cpp +++ b/Code/Mantid/Framework/Geometry/src/Surfaces/Line.cpp @@ -136,9 +136,9 @@ namespace Mantid } int - Line::lambdaPair(const int ix,const std::pair< + Line::lambdaPair(const int ix, const std::pair< std::complex,std::complex >& SQ, - std::vector& PntOut) const + std::list &PntOut) const /** Helper function to decide which roots to take. The assumption is that lambda has been solved by quadratic @@ -190,7 +190,7 @@ namespace Mantid } int - Line::intersect(std::vector& VecOut, + Line::intersect(std::list &VecOut, const Quadratic& Sur) const /** For the line that intersects the surfaces @@ -220,7 +220,7 @@ namespace Mantid } int - Line::intersect(std::vector& PntOut ,const Plane& Pln) const + Line::intersect(std::list& PntOut ,const Plane& Pln) const /** For the line that intersects the cylinder generate add the point to the VecOut, return number of points @@ -244,7 +244,7 @@ namespace Mantid } int - Line::intersect(std::vector& PntOut ,const Cylinder& Cyl) const + Line::intersect(std::list &PntOut , const Cylinder& Cyl) const /** For the line that intersects the cylinder generate add the point to the VecOut, return number of points @@ -273,7 +273,7 @@ namespace Mantid } int - Line::intersect(std::vector& PntOut ,const Sphere& Sph) const + Line::intersect(std::list &PntOut , const Sphere& Sph) const /** For the line that intersects the cylinder generate add the point to the VecOut, return number of points diff --git a/Code/Mantid/Framework/Geometry/src/Surfaces/Plane.cpp b/Code/Mantid/Framework/Geometry/src/Surfaces/Plane.cpp index 95962e6acb5e..4e5004b92152 100644 --- a/Code/Mantid/Framework/Geometry/src/Surfaces/Plane.cpp +++ b/Code/Mantid/Framework/Geometry/src/Surfaces/Plane.cpp @@ -220,8 +220,7 @@ Plane::side(const Kernel::V3D& A) const @retval 0 :: A is on the plane itself (within tolerence) */ { - double Dp=NormV.scalar_prod(A); - Dp-=Dist; + double Dp=NormV.scalar_prod(A)-Dist; if (Tolerance0) ? 1 : -1; return 0; diff --git a/Code/Mantid/Framework/Geometry/src/Surfaces/Sphere.cpp b/Code/Mantid/Framework/Geometry/src/Surfaces/Sphere.cpp index 476bf61dc33c..16dbd702f15a 100644 --- a/Code/Mantid/Framework/Geometry/src/Surfaces/Sphere.cpp +++ b/Code/Mantid/Framework/Geometry/src/Surfaces/Sphere.cpp @@ -19,17 +19,17 @@ namespace Mantid Sphere::Sphere() : Quadratic(), Centre(0,0,0),Radius(0.0) /** - Default constructor - make sphere at the origin radius zero + Default constructor + make sphere at the origin radius zero */ { setBaseEqn(); } - Sphere::Sphere(const Sphere &A) : + Sphere::Sphere(const Sphere &A) : Quadratic(A),Centre(A.Centre),Radius(A.Radius) /** - Default Copy constructor + Default Copy constructor @param A :: Sphere to copy */ { } @@ -37,7 +37,7 @@ namespace Mantid Sphere* Sphere::clone() const /** - Makes a clone (implicit virtual copy constructor) + Makes a clone (implicit virtual copy constructor) @return new (*this) */ { @@ -45,7 +45,7 @@ namespace Mantid } Sphere& - Sphere::operator=(const Sphere &A) + Sphere::operator=(const Sphere &A) /** Default Assignment operator @param A :: Sphere to copy @@ -69,19 +69,19 @@ namespace Mantid int Sphere::setSurface(const std::string& Pstr) - /** - Processes a standard MCNPX cone string + /** + Processes a standard MCNPX cone string Recall that cones can only be specified on an axis - Valid input is: - - so radius + Valid input is: + - so radius - s cen_x cen_y cen_z radius - sx - cen_x radius - @return : 0 on success, neg of failure + @return : 0 on success, neg of failure */ { std::string Line=Pstr; std::string item; - if (!Mantid::Kernel::Strings::section(Line,item) || + if (!Mantid::Kernel::Strings::section(Line,item) || tolower(item[0])!='s' || item.length()>2) return -1; @@ -115,24 +115,25 @@ namespace Mantid Radius=R; setBaseEqn(); return 0; - } + } int Sphere::side(const Kernel::V3D& Pt) const /** - Calculate where the point Pt is relative to the + Calculate where the point Pt is relative to the sphere. @param Pt :: Point to test @retval -1 :: Pt within sphere @retval 0 :: point on the surface (within CTolerance) - @retval 1 :: Pt outside the sphere + @retval 1 :: Pt outside the sphere */ { - const double displace = centreToPoint(Pt) - Radius; //MG: Surface test - This does not use onSurface since it would double the amount of // computation if the object is not on the surface which is most likely - if( std::abs(displace) < Tolerance ) + const double xdiff(Pt.X()-Centre.X()), ydiff(Pt.Y()-Centre.Y()), zdiff(Pt.Z()-Centre.Z()); + const double displace = sqrt(xdiff*xdiff + ydiff*ydiff + zdiff*zdiff) - Radius; + if( fabs(displace) < Tolerance ) { return 0; } @@ -157,9 +158,9 @@ namespace Mantid double Sphere::distance(const Kernel::V3D& Pt) const - /** - Determine the shortest distance from the Surface - to the Point. + /** + Determine the shortest distance from the Surface + to the Point. @param Pt :: Point to calculate distance from @return distance (Positive only) */ @@ -170,7 +171,7 @@ namespace Mantid void - Sphere::displace(const Kernel::V3D& Pt) + Sphere::displace(const Kernel::V3D& Pt) /** Apply a shift of the centre @param Pt :: distance to add to the centre @@ -182,7 +183,7 @@ namespace Mantid } void - Sphere::rotate(const Kernel::Matrix& MA) + Sphere::rotate(const Kernel::Matrix& MA) /** Apply a Rotation matrix @param MA :: matrix to rotate by @@ -197,13 +198,13 @@ namespace Mantid { /** Compute the distance between the given point and the centre of the sphere - @param pt :: The chosen point + @param pt :: The chosen point */ const Kernel::V3D displace_vec = pt - Centre; return displace_vec.norm(); } - void + void Sphere::setCentre(const Kernel::V3D& A) /** Set the centre point @@ -215,7 +216,7 @@ namespace Mantid return; } - void + void Sphere::setBaseEqn() /** Sets an equation of type (general sphere) @@ -224,7 +225,7 @@ namespace Mantid { BaseEqn[0]=1.0; // A x^2 BaseEqn[1]=1.0; // B y^2 - BaseEqn[2]=1.0; // C z^2 + BaseEqn[2]=1.0; // C z^2 BaseEqn[3]=0.0; // D xy BaseEqn[4]=0.0; // E xz BaseEqn[5]=0.0; // F yz @@ -236,12 +237,12 @@ namespace Mantid } - void + void Sphere::write(std::ostream& OX) const - /** - Object of write is to output a MCNPX plane info - @param OX :: Output stream (required for multiple std::endl) - \todo (Needs precision) + /** + Object of write is to output a MCNPX plane info + @param OX :: Output stream (required for multiple std::endl) + \todo (Needs precision) */ { std::ostringstream cx; diff --git a/Code/Mantid/Framework/Geometry/test/BraggScattererFactoryTest.h b/Code/Mantid/Framework/Geometry/test/BraggScattererFactoryTest.h new file mode 100644 index 000000000000..a8c28f9913ac --- /dev/null +++ b/Code/Mantid/Framework/Geometry/test/BraggScattererFactoryTest.h @@ -0,0 +1,57 @@ +#ifndef MANTID_GEOMETRY_BRAGGSCATTERERFACTORYTEST_H_ +#define MANTID_GEOMETRY_BRAGGSCATTERERFACTORYTEST_H_ + +#include +#include + +#include "MantidGeometry/Crystal/BraggScattererFactory.h" + +using namespace Mantid::Geometry; +using namespace Mantid::Kernel; + +class BraggScattererFactoryTest : 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 BraggScattererFactoryTest *createSuite() { return new BraggScattererFactoryTest(); } + static void destroySuite( BraggScattererFactoryTest *suite ) { delete suite; } + + + void testSubscribeCreateUnsubscribeGetKeys() + { + std::vector registered = BraggScattererFactory::Instance().getKeys(); + TS_ASSERT_EQUALS(std::find(registered.begin(), registered.end(), "MockScatterer"), registered.end()); + TS_ASSERT_THROWS_ANYTHING(BraggScattererFactory::Instance().createScatterer("MockScatterer")); + + BraggScattererFactory::Instance().subscribeScatterer(); + + registered = BraggScattererFactory::Instance().getKeys(); + TS_ASSERT_DIFFERS(std::find(registered.begin(), registered.end(), "MockScatterer"), registered.end()); + TS_ASSERT_THROWS_NOTHING(BraggScattererFactory::Instance().createScatterer("MockScatterer")); + + BraggScatterer_sptr scatterer = BraggScattererFactory::Instance().createScatterer("MockScatterer"); + TS_ASSERT(scatterer->isInitialized()); + + BraggScattererFactory::Instance().unsubscribe("MockScatterer"); + registered = BraggScattererFactory::Instance().getKeys(); + TS_ASSERT_EQUALS(std::find(registered.begin(), registered.end(), "MockScatterer"), registered.end()); + TS_ASSERT_THROWS_ANYTHING(BraggScattererFactory::Instance().createScatterer("MockScatterer")); + } + +private: + class MockScatterer : public BraggScatterer + { + public: + MockScatterer() : BraggScatterer() {} + ~MockScatterer() { } + + std::string name() const { return "MockScatterer"; } + + MOCK_CONST_METHOD0(clone, BraggScatterer_sptr()); + MOCK_CONST_METHOD1(calculateStructureFactor, StructureFactor(const V3D &)); + }; +}; + + +#endif /* MANTID_GEOMETRY_BRAGGSCATTERERFACTORYTEST_H_ */ diff --git a/Code/Mantid/Framework/Geometry/test/BraggScattererInCrystalStructureTest.h b/Code/Mantid/Framework/Geometry/test/BraggScattererInCrystalStructureTest.h new file mode 100644 index 000000000000..5c9bf1ef3a03 --- /dev/null +++ b/Code/Mantid/Framework/Geometry/test/BraggScattererInCrystalStructureTest.h @@ -0,0 +1,154 @@ +#ifndef MANTID_GEOMETRY_BRAGGSCATTERERINCRYSTALSTRUCTURETEST_H_ +#define MANTID_GEOMETRY_BRAGGSCATTERERINCRYSTALSTRUCTURETEST_H_ + +#include +#include + +#include "MantidGeometry/Crystal/BraggScattererInCrystalStructure.h" +#include "MantidGeometry/Crystal/SpaceGroupFactory.h" + +using namespace Mantid::Geometry; +using namespace Mantid::Kernel; + +class BraggScattererInCrystalStructureTest : 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 BraggScattererInCrystalStructureTest *createSuite() { return new BraggScattererInCrystalStructureTest(); } + static void destroySuite( BraggScattererInCrystalStructureTest *suite ) { delete suite; } + + + void testInitialization() + { + BraggScattererInCrystalStructure_sptr scatterer = getDefaultScatterer(); + + TS_ASSERT(!scatterer->isInitialized()); + TS_ASSERT_THROWS_NOTHING(scatterer->initialize()); + TS_ASSERT(scatterer->isInitialized()); + + TS_ASSERT(scatterer->existsProperty("Position")); + TS_ASSERT(scatterer->existsProperty("UnitCell")); + TS_ASSERT(scatterer->existsProperty("SpaceGroup")); + } + + void testAfterScattererPropertySet() + { + //BraggScattererInCrystalStructure_sptr scatterer = getInitializedScatterer(); + //MockBraggScatterer *mockScatterer = dynamic_cast(scatterer.get()); + //EXPECT_CALL(mockScatterer, afterScattererPropertySet) + } + + void testGetSetPosition() + { + BraggScattererInCrystalStructure_sptr scatterer = getInitializedScatterer(); + + V3D goodPosition(0.2, 0.4, 0.3); + TS_ASSERT_THROWS_NOTHING(scatterer->setProperty("Position", goodPosition)); + + V3D testPos; + TS_ASSERT_THROWS_NOTHING(testPos = scatterer->getPosition()); + TS_ASSERT_EQUALS(testPos, goodPosition); + + V3D badPosition(1.2, 4.3, -6.2); + TS_ASSERT_THROWS_NOTHING(scatterer->setProperty("Position", badPosition)); + TS_ASSERT_THROWS_NOTHING(testPos = scatterer->getPosition()); + TS_ASSERT_DIFFERS(testPos, badPosition); + TS_ASSERT_EQUALS(testPos, V3D(0.2, 0.3, 0.8)); + } + + void testGetSetCell() + { + BraggScattererInCrystalStructure_sptr scatterer = getInitializedScatterer(); + + UnitCell cell(5.43, 5.43, 5.43); + + TS_ASSERT_THROWS_NOTHING(scatterer->setProperty("UnitCell", unitCellToStr(cell))); + TS_ASSERT_EQUALS(scatterer->getCell().getG(), cell.getG()); + } + + void testGetSetSpaceGroup() + { + BraggScattererInCrystalStructure_sptr scatterer = getInitializedScatterer(); + + SpaceGroup_const_sptr testGroup = SpaceGroupFactory::Instance().createSpaceGroup("P m -3 m"); + + TS_ASSERT_THROWS_NOTHING(scatterer->setProperty("SpaceGroup", "P m -3 m")); + TS_ASSERT_EQUALS(scatterer->getSpaceGroup()->hmSymbol(), testGroup->hmSymbol()); + } + + void testEquivalentPositions() + { + BraggScattererInCrystalStructure_sptr scatterer = getInitializedScatterer(); + + V3D generalPosition(0.3, 0.32, 0.45); + + // No space group set - no equivalent positions + scatterer->setProperty("Position", generalPosition); + TS_ASSERT_EQUALS(scatterer->getEquivalentPositions().size(), 1); + TS_ASSERT_EQUALS(scatterer->getEquivalentPositions().front(), generalPosition); + + // Assigning a space group must cause recalculation of equivalent positions + SpaceGroup_const_sptr testGroup = SpaceGroupFactory::Instance().createSpaceGroup("P m -3 m"); + scatterer->setProperty("SpaceGroup", "P m -3 m"); + + TS_ASSERT_EQUALS(scatterer->getEquivalentPositions().size(), testGroup->order()); + + // Re-setting the position also recalculates + V3D specialPosition(0.0, 0.0, 0.0); + + scatterer->setProperty("Position", specialPosition); + // Pm-3m does not contain translations, so (0,0,0) is not transformed by any symmetry operation of the group + TS_ASSERT_EQUALS(scatterer->getEquivalentPositions().size(), 1); + TS_ASSERT_EQUALS(scatterer->getEquivalentPositions().front(), specialPosition); + } + + void testUnitCellStringValidator() + { + IValidator_sptr validator = boost::make_shared(); + + // non-working examples + TS_ASSERT_DIFFERS(validator->isValid("1.0"), ""); + TS_ASSERT_DIFFERS(validator->isValid("1.0 1.0"), ""); + TS_ASSERT_DIFFERS(validator->isValid("1.0 1.0 1.0 1.0"), ""); + TS_ASSERT_DIFFERS(validator->isValid("1.0 1.0 1.0 1.0 1.0"), ""); + TS_ASSERT_DIFFERS(validator->isValid("1.0.3 1.0 1.0"), ""); + + // Working examples + TS_ASSERT_EQUALS(validator->isValid("1.0 1.0 1.0"), ""); + TS_ASSERT_EQUALS(validator->isValid("1.0 1.0 1.0 90.0 90.0 90.0"), ""); + TS_ASSERT_EQUALS(validator->isValid("1 2 3 90 90 90"), ""); + TS_ASSERT_EQUALS(validator->isValid("1.1 2.2 3.2 90 90 90"), ""); + TS_ASSERT_EQUALS(validator->isValid("1.0 1.0 1.0 90.0 90.0 90.0 "), ""); + } + +private: + BraggScattererInCrystalStructure_sptr getDefaultScatterer() + { + return boost::make_shared(); + } + + BraggScattererInCrystalStructure_sptr getInitializedScatterer() + { + BraggScattererInCrystalStructure_sptr raw = getDefaultScatterer(); + raw->initialize(); + + return raw; + } + + class MockBraggScatterer : public BraggScattererInCrystalStructure + { + public: + MockBraggScatterer() : BraggScattererInCrystalStructure() { } + ~MockBraggScatterer() { } + + MOCK_CONST_METHOD0(name, std::string()); + MOCK_CONST_METHOD0(clone, BraggScatterer_sptr()); + MOCK_CONST_METHOD1(calculateStructureFactor, StructureFactor(const V3D&)); + MOCK_METHOD1(afterScattererPropertySet, void(const std::string &)); + }; + +}; + + +#endif /* MANTID_GEOMETRY_BRAGGSCATTERERINCRYSTALSTRUCTURETEST_H_ */ diff --git a/Code/Mantid/Framework/Geometry/test/BraggScattererTest.h b/Code/Mantid/Framework/Geometry/test/BraggScattererTest.h new file mode 100644 index 000000000000..584d3de1f580 --- /dev/null +++ b/Code/Mantid/Framework/Geometry/test/BraggScattererTest.h @@ -0,0 +1,62 @@ +#ifndef MANTID_GEOMETRY_BRAGGSCATTERERTEST_H_ +#define MANTID_GEOMETRY_BRAGGSCATTERERTEST_H_ + +#include +#include + +#include "MantidGeometry/Crystal/BraggScatterer.h" + +using namespace Mantid::Geometry; +using namespace Mantid::Kernel; + +class BraggScattererTest : 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 BraggScattererTest *createSuite() { return new BraggScattererTest(); } + static void destroySuite( BraggScattererTest *suite ) { delete suite; } + + void testConstruction() + { + TS_ASSERT_THROWS_NOTHING(MockBraggScatterer scatterer); + } + + void testInitialization() + { + BraggScatterer_sptr scatterer = getDefaultScatterer(); + + TS_ASSERT(!scatterer->isInitialized()); + TS_ASSERT_THROWS_NOTHING(scatterer->initialize()); + TS_ASSERT(scatterer->isInitialized()); + } + +private: + BraggScatterer_sptr getDefaultScatterer() + { + return boost::make_shared(); + } + + BraggScatterer_sptr getInitializedScatterer() + { + BraggScatterer_sptr raw = getDefaultScatterer(); + raw->initialize(); + + return raw; + } + + class MockBraggScatterer : public BraggScatterer + { + public: + MockBraggScatterer() : BraggScatterer() { } + ~MockBraggScatterer() { } + + MOCK_CONST_METHOD0(name, std::string()); + MOCK_CONST_METHOD0(clone, BraggScatterer_sptr()); + MOCK_CONST_METHOD1(calculateStructureFactor, StructureFactor(const V3D&)); + MOCK_METHOD1(afterScattererPropertySet, void(const std::string &)); + }; +}; + + +#endif /* MANTID_GEOMETRY_BRAGGSCATTERERTEST_H_ */ diff --git a/Code/Mantid/Framework/Geometry/test/CenteringGroupTest.h b/Code/Mantid/Framework/Geometry/test/CenteringGroupTest.h new file mode 100644 index 000000000000..092ce9dcc004 --- /dev/null +++ b/Code/Mantid/Framework/Geometry/test/CenteringGroupTest.h @@ -0,0 +1,65 @@ +#ifndef MANTID_GEOMETRY_CENTERINGGROUPTEST_H_ +#define MANTID_GEOMETRY_CENTERINGGROUPTEST_H_ + +#include + +#include "MantidGeometry/Crystal/CenteringGroup.h" +#include "MantidGeometry/Crystal/SymmetryOperationFactory.h" + +using namespace Mantid::Geometry; + +class CenteringGroupTest : 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 CenteringGroupTest *createSuite() { return new CenteringGroupTest(); } + static void destroySuite( CenteringGroupTest *suite ) { delete suite; } + + void testValidCenterings() + { + testCenteringGroup("P", CenteringGroup::P, "P", SymmetryOperationFactory::Instance().createSymOps("x,y,z")); + testCenteringGroup("I", CenteringGroup::I, "I", SymmetryOperationFactory::Instance().createSymOps("x,y,z; x+1/2,y+1/2,z+1/2")); + testCenteringGroup("A", CenteringGroup::A, "A", SymmetryOperationFactory::Instance().createSymOps("x,y,z; x,y+1/2,z+1/2")); + testCenteringGroup("B", CenteringGroup::B, "B", SymmetryOperationFactory::Instance().createSymOps("x,y,z; x+1/2,y,z+1/2")); + testCenteringGroup("C", CenteringGroup::C, "C", SymmetryOperationFactory::Instance().createSymOps("x,y,z; x+1/2,y+1/2,z")); + testCenteringGroup("F", CenteringGroup::F, "F", SymmetryOperationFactory::Instance().createSymOps("x,y,z; x,y+1/2,z+1/2; x+1/2,y,z+1/2; x+1/2,y+1/2,z")); + testCenteringGroup("R", CenteringGroup::Robv, "R", SymmetryOperationFactory::Instance().createSymOps("x,y,z; x+1/3,y+2/3,z+2/3; x+2/3,y+1/3,z+1/3")); + testCenteringGroup("Robv", CenteringGroup::Robv, "R", SymmetryOperationFactory::Instance().createSymOps("x,y,z; x+1/3,y+2/3,z+2/3; x+2/3,y+1/3,z+1/3")); + testCenteringGroup("Rrev", CenteringGroup::Rrev, "R", SymmetryOperationFactory::Instance().createSymOps("x,y,z; x+1/3,y+2/3,z+1/3; x+2/3,y+1/3,z+2/3")); + } + + void testInvalidCentering() + { + TS_ASSERT_THROWS(CenteringGroup group("G"), std::invalid_argument); + TS_ASSERT_THROWS(CenteringGroup group("f"), std::invalid_argument); + } + +private: + void testCenteringGroup(const std::string &symbol, CenteringGroup::CenteringType expectedCenteringType, const std::string &expectedSymbol, const std::vector &expectedOperations) + { + TSM_ASSERT_THROWS_NOTHING("Exception when trying to create " + symbol, CenteringGroup rawGroup(symbol)); + + Group_const_sptr group = GroupFactory::create(symbol); + std::vector ops = group->getSymmetryOperations(); + TSM_ASSERT_EQUALS("Unexpected number of operations for " + symbol, ops.size(), expectedOperations.size()); + + for(auto it = expectedOperations.begin(); it != expectedOperations.end(); ++it) { + TSM_ASSERT("Operation " + (*it).identifier() + " not found in " + symbol, symOpExistsInCollection(*it, ops)); + } + + CenteringGroup_const_sptr centeringGroup = boost::dynamic_pointer_cast(group); + TSM_ASSERT("Could not cast to pointer in " + symbol, centeringGroup); + TSM_ASSERT_EQUALS("CenteringType did not match for " + symbol, centeringGroup->getType(), expectedCenteringType); + TSM_ASSERT_EQUALS("CenteringString did not match for " + symbol, centeringGroup->getSymbol(), expectedSymbol); + } + + + bool symOpExistsInCollection(const SymmetryOperation &op, const std::vector &collection) + { + return std::find(collection.begin(), collection.end(), op) != collection.end(); + } +}; + + +#endif /* MANTID_GEOMETRY_CENTERINGGROUPTEST_H_ */ diff --git a/Code/Mantid/Framework/Geometry/test/CompositeBraggScattererTest.h b/Code/Mantid/Framework/Geometry/test/CompositeBraggScattererTest.h new file mode 100644 index 000000000000..dd5009871e40 --- /dev/null +++ b/Code/Mantid/Framework/Geometry/test/CompositeBraggScattererTest.h @@ -0,0 +1,220 @@ +#ifndef MANTID_GEOMETRY_BRAGGSCATTERERCOLLECTIONTEST_H_ +#define MANTID_GEOMETRY_BRAGGSCATTERERCOLLECTIONTEST_H_ + +#include + +#include "MantidGeometry/Crystal/CompositeBraggScatterer.h" +#include "MantidGeometry/Crystal/UnitCell.h" +#include "MantidKernel/V3D.h" +#include "MantidGeometry/Crystal/SpaceGroupFactory.h" + +#include "MantidGeometry/Crystal/IsotropicAtomBraggScatterer.h" +#include + +using namespace Mantid::Geometry; +using namespace Mantid::Kernel; + + +class CompositeBraggScattererTest : 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 CompositeBraggScattererTest *createSuite() { return new CompositeBraggScattererTest(); } + static void destroySuite( CompositeBraggScattererTest *suite ) { delete suite; } + + + void testConstructor() + { + TS_ASSERT_THROWS_NOTHING(CompositeBraggScatterer scatterers); + } + + void testCreate() + { + TS_ASSERT_THROWS_NOTHING(CompositeBraggScatterer_sptr scatterer = CompositeBraggScatterer::create()); + + std::vector scatterers; + scatterers.push_back(getInitializedScatterer("Si", V3D(0.35, 0, 0))); + scatterers.push_back(getInitializedScatterer("Si", V3D(0.25, 0.25, 0.25))); + + CompositeBraggScatterer_sptr scatterer = CompositeBraggScatterer::create(scatterers); + TS_ASSERT_EQUALS(scatterer->nScatterers(), 2); + TS_ASSERT_EQUALS(boost::dynamic_pointer_cast(scatterer->getScatterer(0))->getPosition(), V3D(0.35, 0, 0)); + TS_ASSERT_EQUALS(boost::dynamic_pointer_cast(scatterer->getScatterer(1))->getPosition(), V3D(0.25, 0.25, 0.25)); + } + + void testClone() + { + CompositeBraggScatterer_sptr scatterer = getCompositeScatterer(); + BraggScatterer_sptr clone = scatterer->clone(); + + CompositeBraggScatterer_sptr collectionClone = boost::dynamic_pointer_cast(clone); + + TS_ASSERT(collectionClone); + TS_ASSERT_EQUALS(collectionClone->nScatterers(), 2); + TS_ASSERT_EQUALS(boost::dynamic_pointer_cast(collectionClone->getScatterer(0))->getPosition(), V3D(0.35, 0, 0)); + TS_ASSERT_EQUALS(boost::dynamic_pointer_cast(collectionClone->getScatterer(1))->getPosition(), V3D(0.25, 0.25, 0.25)); + } + + void testAddGetScatterer() + { + UnitCell cell(5.43, 5.43, 5.43); + SpaceGroup_const_sptr spaceGroup = SpaceGroupFactory::Instance().createSpaceGroup("P 1 2/m 1"); + + CompositeBraggScatterer_sptr scatterer = CompositeBraggScatterer::create(); + TS_ASSERT_EQUALS(scatterer->propertyCount(), 0); + + IsotropicAtomBraggScatterer_sptr siOne = getInitializedScatterer("Si", V3D(0, 0, 0)); + TS_ASSERT_DIFFERS(siOne->getSpaceGroup()->hmSymbol(), spaceGroup->hmSymbol()); + + size_t oldCount = scatterer->nScatterers(); + scatterer->addScatterer(siOne); + TS_ASSERT_EQUALS(scatterer->propertyCount(), 2); + + TS_ASSERT_EQUALS(scatterer->nScatterers(), oldCount + 1); + + // Properties are propagated. + scatterer->setProperty("UnitCell", unitCellToStr(cell)); + scatterer->setProperty("SpaceGroup", spaceGroup->hmSymbol()); + + // The scatterer is cloned, so the new space group is not in siOne + TS_ASSERT_EQUALS(boost::dynamic_pointer_cast(scatterer->getScatterer(0))->getSpaceGroup()->hmSymbol(), spaceGroup->hmSymbol()); + TS_ASSERT_DIFFERS(siOne->getSpaceGroup()->hmSymbol(), spaceGroup->hmSymbol()); + + TS_ASSERT_THROWS(scatterer->getScatterer(2), std::out_of_range); + } + + void testRemoveScatterer() + { + CompositeBraggScatterer_sptr scattererCollection = getCompositeScatterer(); + size_t oldCount = scattererCollection->nScatterers(); + + TS_ASSERT_THROWS_NOTHING(scattererCollection->getScatterer(oldCount - 1)); + TS_ASSERT_THROWS_NOTHING(scattererCollection->removeScatterer(0)); + + TS_ASSERT_EQUALS(scattererCollection->nScatterers(), oldCount - 1); + + TS_ASSERT_THROWS(scattererCollection->getScatterer(oldCount - 1), std::out_of_range); + TS_ASSERT_THROWS(scattererCollection->removeScatterer(10), std::out_of_range); + + scattererCollection->removeScatterer(0); + + // Unused properties are removed, so when there are no scatterers, there are no properties. + TS_ASSERT_EQUALS(scattererCollection->propertyCount(), 0); + } + + void testStructureFactorCalculation() + { + /* To check that structure factor calculation is correct also for + * oblique cells with low symmetry, this hypothetical Si with monoclinic + * cell and one atom in a general position is used. + * + * For comparison, a shelxl .ins file was prepared with the structure and + * squared structure factor amplitudes were calculated using the LIST 4 option. + */ + UnitCell cell(5.43, 6.43, 7.43, 90.0, 103.0, 90.0); + SpaceGroup_const_sptr spaceGroup = SpaceGroupFactory::Instance().createSpaceGroup("P 1 2/m 1"); + + CompositeBraggScatterer_sptr coll = CompositeBraggScatterer::create(); + coll->addScatterer(getInitializedScatterer("Si", V3D(0.2, 0.3, 0.4), 0.01267)); + + coll->setProperty("SpaceGroup", spaceGroup->hmSymbol()); + coll->setProperty("UnitCell", unitCellToStr(cell)); + + // Load reference data, obtained with SHELXL-2014. + std::map referenceData = getCalculatedStructureFactors(); + + for(auto it = referenceData.begin(); it != referenceData.end(); ++it) { + double ampl = std::abs(coll->calculateStructureFactor(it->first)); + double sqAmpl = ampl * ampl; + + // F^2 is calculated to two decimal places, so the maximum deviation is 5e-3, + TS_ASSERT_DELTA(sqAmpl, it->second, 5.1e-3); + } + } + +private: + IsotropicAtomBraggScatterer_sptr getInitializedScatterer(const std::string &element, const V3D &position, double U = 0.0, double occ = 1.0) + { + IsotropicAtomBraggScatterer_sptr scatterer = boost::make_shared(); + scatterer->initialize(); + scatterer->setProperty("Element", element); + scatterer->setProperty("Position", position); + scatterer->setProperty("U", U); + scatterer->setProperty("Occupancy", occ); + + return scatterer; + } + + CompositeBraggScatterer_sptr getCompositeScatterer() + { + std::vector scatterers; + scatterers.push_back(getInitializedScatterer("Si", V3D(0.35, 0, 0))); + scatterers.push_back(getInitializedScatterer("Si", V3D(0.25, 0.25, 0.25))); + + return CompositeBraggScatterer::create(scatterers); + } + + std::map getCalculatedStructureFactors() + { + std::map fSquaredCalc; + fSquaredCalc.insert(std::make_pair(V3D(2, 0, 0), 167.84)); + fSquaredCalc.insert(std::make_pair(V3D(3, 0, 0), 153.50)); + fSquaredCalc.insert(std::make_pair(V3D(4, 0, 0), 19.76)); + fSquaredCalc.insert(std::make_pair(V3D(5, 0, 0), 176.21)); + fSquaredCalc.insert(std::make_pair(V3D(1, 1, 0), 2.44)); + fSquaredCalc.insert(std::make_pair(V3D(2, 1, 0), 15.83)); + fSquaredCalc.insert(std::make_pair(V3D(3, 1, 0), 14.48)); + fSquaredCalc.insert(std::make_pair(V3D(4, 1, 0), 1.86)); + fSquaredCalc.insert(std::make_pair(V3D(5, 1, 0), 16.62)); + fSquaredCalc.insert(std::make_pair(V3D(2, 2, 0), 104.66)); + fSquaredCalc.insert(std::make_pair(V3D(3, 2, 0), 95.72)); + fSquaredCalc.insert(std::make_pair(V3D(4, 2, 0), 12.32)); + fSquaredCalc.insert(std::make_pair(V3D(5, 2, 0), 109.88)); + fSquaredCalc.insert(std::make_pair(V3D(3, 3, 0), 90.10)); + fSquaredCalc.insert(std::make_pair(V3D(4, 3, 0), 11.60)); + fSquaredCalc.insert(std::make_pair(V3D(5, 3, 0), 103.43)); + fSquaredCalc.insert(std::make_pair(V3D(4, 4, 0), 1.55)); + fSquaredCalc.insert(std::make_pair(V3D(5, 4, 0), 13.86)); + fSquaredCalc.insert(std::make_pair(V3D(5, 5, 0), 130.22)); + fSquaredCalc.insert(std::make_pair(V3D(1, 1, 1), 16.45)); + fSquaredCalc.insert(std::make_pair(V3D(2, 1, 1), 2.26)); + fSquaredCalc.insert(std::make_pair(V3D(3, 1, 1), 21.53)); + fSquaredCalc.insert(std::make_pair(V3D(4, 1, 1), 1.80)); + fSquaredCalc.insert(std::make_pair(V3D(5, 1, 1), 10.47)); + fSquaredCalc.insert(std::make_pair(V3D(2, 2, 1), 14.95)); + fSquaredCalc.insert(std::make_pair(V3D(3, 2, 1), 142.33)); + fSquaredCalc.insert(std::make_pair(V3D(4, 2, 1), 11.92)); + fSquaredCalc.insert(std::make_pair(V3D(5, 2, 1), 69.17)); + fSquaredCalc.insert(std::make_pair(V3D(3, 3, 1), 133.97)); + fSquaredCalc.insert(std::make_pair(V3D(4, 3, 1), 11.22)); + fSquaredCalc.insert(std::make_pair(V3D(5, 3, 1), 65.11)); + fSquaredCalc.insert(std::make_pair(V3D(4, 4, 1), 1.50)); + fSquaredCalc.insert(std::make_pair(V3D(5, 4, 1), 8.73)); + fSquaredCalc.insert(std::make_pair(V3D(5, 5, 1), 81.98)); + fSquaredCalc.insert(std::make_pair(V3D(2, 2, 2), 14.36)); + fSquaredCalc.insert(std::make_pair(V3D(3, 2, 2), 88.94)); + fSquaredCalc.insert(std::make_pair(V3D(4, 2, 2), 77.57)); + fSquaredCalc.insert(std::make_pair(V3D(5, 2, 2), 9.52)); + fSquaredCalc.insert(std::make_pair(V3D(3, 3, 2), 83.72)); + fSquaredCalc.insert(std::make_pair(V3D(4, 3, 2), 73.02)); + fSquaredCalc.insert(std::make_pair(V3D(5, 3, 2), 8.96)); + fSquaredCalc.insert(std::make_pair(V3D(4, 4, 2), 9.79)); + fSquaredCalc.insert(std::make_pair(V3D(5, 4, 2), 1.20)); + fSquaredCalc.insert(std::make_pair(V3D(5, 5, 2), 11.29)); + fSquaredCalc.insert(std::make_pair(V3D(3, 3, 3), 11.44)); + fSquaredCalc.insert(std::make_pair(V3D(4, 3, 3), 103.89)); + fSquaredCalc.insert(std::make_pair(V3D(5, 3, 3), 8.30)); + fSquaredCalc.insert(std::make_pair(V3D(4, 4, 3), 13.93)); + fSquaredCalc.insert(std::make_pair(V3D(5, 4, 3), 1.11)); + fSquaredCalc.insert(std::make_pair(V3D(5, 5, 3), 10.45)); + fSquaredCalc.insert(std::make_pair(V3D(4, 4, 4), 8.33)); + fSquaredCalc.insert(std::make_pair(V3D(5, 4, 4), 6.93)); + fSquaredCalc.insert(std::make_pair(V3D(5, 5, 4), 65.05)); + fSquaredCalc.insert(std::make_pair(V3D(5, 5, 5), 88.57)); + return fSquaredCalc; + } +}; + + +#endif /* MANTID_GEOMETRY_BRAGGSCATTERERCOLLECTIONTEST_H_ */ diff --git a/Code/Mantid/Framework/Geometry/test/CrystalStructureTest.h b/Code/Mantid/Framework/Geometry/test/CrystalStructureTest.h index 5af8f60a7199..c54b2e355bee 100644 --- a/Code/Mantid/Framework/Geometry/test/CrystalStructureTest.h +++ b/Code/Mantid/Framework/Geometry/test/CrystalStructureTest.h @@ -4,6 +4,7 @@ #include #include "MantidGeometry/Crystal/CrystalStructure.h" +#include "MantidGeometry/Crystal/PointGroupFactory.h" using namespace Mantid::Geometry; using namespace Mantid::Kernel; @@ -18,7 +19,7 @@ class CrystalStructureTest : public CxxTest::TestSuite CrystalStructureTest() : m_CsCl(4.126, 4.126, 4.126), - m_pg(new PointGroupLaue13), + m_pg(PointGroupFactory::Instance().createPointGroup("m-3m")), m_centering(new ReflectionConditionPrimitive) { } @@ -129,7 +130,7 @@ class CrystalStructureTest : public CxxTest::TestSuite double dMax = 4.0; // make a structure with P-1 - CrystalStructure structure(m_CsCl); + CrystalStructure structure(m_CsCl, PointGroupFactory::Instance().createPointGroup("-1")); std::vector unique = structure.getUniqueHKLs(dMin, dMax); std::vector peaks = structure.getHKLs(dMin, dMax); diff --git a/Code/Mantid/Framework/Geometry/test/CyclicGroupTest.h b/Code/Mantid/Framework/Geometry/test/CyclicGroupTest.h new file mode 100644 index 000000000000..5d40bfb3142c --- /dev/null +++ b/Code/Mantid/Framework/Geometry/test/CyclicGroupTest.h @@ -0,0 +1,61 @@ +#ifndef MANTID_GEOMETRY_CYCLICGROUPTEST_H_ +#define MANTID_GEOMETRY_CYCLICGROUPTEST_H_ + +#include + +#include "MantidGeometry/Crystal/CyclicGroup.h" +#include "MantidGeometry/Crystal/SymmetryOperationFactory.h" + +#include + +using namespace Mantid::Geometry; +using namespace Mantid::Kernel; + +class CyclicGroupTest : 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 CyclicGroupTest *createSuite() { return new CyclicGroupTest(); } + static void destroySuite( CyclicGroupTest *suite ) { delete suite; } + + + void testConstructor() + { + CyclicGroup_const_sptr group = boost::make_shared(SymmetryOperationFactory::Instance().createSymOp("-x,-y,-z")); + + TS_ASSERT_EQUALS(group->order(), 2); + } + + void testCreate() + { + Group_const_sptr group = GroupFactory::create("-x,-y,-z"); + TS_ASSERT(boost::dynamic_pointer_cast(group)); + + TS_ASSERT_EQUALS(group->order(), 2); + } + + void testMultiplication() + { + /* Even though this is part of Group, it's a good example and basically + * the method used to generate point groups. + */ + + Group_const_sptr groupOne = GroupFactory::create("-x,-y,z"); + Group_const_sptr groupTwo = GroupFactory::create("x,-y,-z"); + + // This is in fact point group 222 + Group_const_sptr groupThree = groupOne * groupTwo; + + TS_ASSERT_EQUALS(groupThree->order(), 4); + + Group_const_sptr groupFour = GroupFactory::create("-x,-y,-z"); + + // Which becomes mmm, if inversion is added. + Group_const_sptr groupFive = groupFour * groupThree; + TS_ASSERT_EQUALS(groupFive->order(), 8); + } +}; + + +#endif /* MANTID_GEOMETRY_CYCLICGROUPTEST_H_ */ diff --git a/Code/Mantid/Framework/Geometry/test/GroupTest.h b/Code/Mantid/Framework/Geometry/test/GroupTest.h new file mode 100644 index 000000000000..75cfb8a0a1fa --- /dev/null +++ b/Code/Mantid/Framework/Geometry/test/GroupTest.h @@ -0,0 +1,195 @@ +#ifndef MANTID_GEOMETRY_GROUPTEST_H_ +#define MANTID_GEOMETRY_GROUPTEST_H_ + +#include + +#include "MantidGeometry/Crystal/Group.h" +#include "MantidGeometry/Crystal/SymmetryOperationFactory.h" +#include + +using namespace Mantid::Geometry; + +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 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 groupOps = group.getSymmetryOperations(); + TS_ASSERT_EQUALS(groupOps.size(), 2); + + std::vector empty; + TS_ASSERT_THROWS(Group group(empty), std::invalid_argument); + } + + void testCopyConstructor() + { + std::vector 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 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 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 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 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 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 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 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 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(inversion); + Group_const_sptr two = boost::make_shared(twoFoldY); + + Group_const_sptr three = one * two; + TS_ASSERT_EQUALS(three->order(), 4); + + SymmetryOperation mirrorY = SymmetryOperationFactory::Instance().createSymOp("x,-y,z"); + std::vector 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); + TS_ASSERT_THROWS(null == null, std::invalid_argument); + TS_ASSERT_THROWS(null != null, 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/InstrumentTest.h b/Code/Mantid/Framework/Geometry/test/InstrumentTest.h index 6c32e7b6157b..9868d858e838 100644 --- a/Code/Mantid/Framework/Geometry/test/InstrumentTest.h +++ b/Code/Mantid/Framework/Geometry/test/InstrumentTest.h @@ -45,7 +45,7 @@ class InstrumentTest : public CxxTest::TestSuite instrument.markAsMonitor(det3); //instrument.setDefaultViewAxis("X-"); - instrument.getLogfileCache().insert(std::make_pair(std::make_pair("apple",det3),boost::shared_ptr())); + instrument.getLogfileCache().insert(std::make_pair(std::make_pair("apple",det3),boost::shared_ptr())); instrument.getLogfileUnit()["banana"] = "yellow"; } diff --git a/Code/Mantid/Framework/Geometry/test/IsotropicAtomBraggScattererTest.h b/Code/Mantid/Framework/Geometry/test/IsotropicAtomBraggScattererTest.h new file mode 100644 index 000000000000..8a17e6a3271d --- /dev/null +++ b/Code/Mantid/Framework/Geometry/test/IsotropicAtomBraggScattererTest.h @@ -0,0 +1,210 @@ +#ifndef MANTID_GEOMETRY_ISOTROPICATOMBRAGGSCATTERERTEST_H_ +#define MANTID_GEOMETRY_ISOTROPICATOMBRAGGSCATTERERTEST_H_ + +#include + +#include "MantidGeometry/Crystal/IsotropicAtomBraggScatterer.h" +#include "MantidGeometry/Crystal/SpaceGroupFactory.h" + +using namespace Mantid::Geometry; +using namespace Mantid::Kernel; + +class IsotropicAtomBraggScattererTest : 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 IsotropicAtomBraggScattererTest *createSuite() { return new IsotropicAtomBraggScattererTest(); } + static void destroySuite( IsotropicAtomBraggScattererTest *suite ) { delete suite; } + + + void testConstructor() + { + TS_ASSERT_THROWS_NOTHING(IsotropicAtomBraggScatterer scatterer); + } + + void testProperties() + { + IsotropicAtomBraggScatterer_sptr scatterer = boost::make_shared(); + + TS_ASSERT_THROWS_NOTHING(scatterer->initialize()); + + TS_ASSERT(scatterer->existsProperty("Position")); + TS_ASSERT(scatterer->existsProperty("SpaceGroup")); + TS_ASSERT(scatterer->existsProperty("UnitCell")); + TS_ASSERT(scatterer->existsProperty("U")); + TS_ASSERT(scatterer->existsProperty("Element")); + TS_ASSERT(scatterer->existsProperty("Occupancy")); + + } + + void testGetSetElement() + { + IsotropicAtomBraggScatterer_sptr scatterer = getInitializedScatterer(); + + TS_ASSERT_THROWS_NOTHING(scatterer->setProperty("Element", "Si")); + TS_ASSERT_EQUALS(scatterer->getElement(), "Si"); + TS_ASSERT_EQUALS(scatterer->getNeutronAtom().z_number, 14); + + TS_ASSERT_THROWS_ANYTHING(scatterer->setProperty("Element","Random")); + } + + void testGetSetOccupancy() + { + IsotropicAtomBraggScatterer_sptr scatterer = getInitializedScatterer(); + + TS_ASSERT_THROWS_NOTHING(scatterer->setProperty("Occupancy", 0.3)); + TS_ASSERT_EQUALS(scatterer->getOccupancy(), 0.3); + TS_ASSERT_THROWS_NOTHING(scatterer->setProperty("Occupancy", 0.0)); + TS_ASSERT_THROWS_NOTHING(scatterer->setProperty("Occupancy", 1.0)); + + TS_ASSERT_THROWS(scatterer->setProperty("Occupancy", -0.3), std::invalid_argument); + TS_ASSERT_THROWS(scatterer->setProperty("Occupancy", 1.3), std::invalid_argument); + } + + void testGetSetU() + { + IsotropicAtomBraggScatterer_sptr scatterer = getInitializedScatterer(); + + TS_ASSERT_THROWS_NOTHING(scatterer->setProperty("U", 0.0)); + TS_ASSERT_THROWS_NOTHING(scatterer->setProperty("U", 1.0)); + TS_ASSERT_EQUALS(scatterer->getU(), 1.0); + + TS_ASSERT_THROWS_NOTHING(scatterer->setProperty("U", 1.23e12)); + TS_ASSERT_THROWS_NOTHING(scatterer->setProperty("U", 1.23e-2)); + + TS_ASSERT_THROWS(scatterer->setProperty("U", -0.2), std::invalid_argument); + } + + void testCreate() + { + IsotropicAtomBraggScatterer_sptr isotropic = getInitializedScatterer("Si", V3D(0.3, 0.1, 0.12), 1.0, 0.5); + + TS_ASSERT(isotropic); + TS_ASSERT_EQUALS(isotropic->getElement(), "Si"); + TS_ASSERT_EQUALS(isotropic->getOccupancy(), 0.5); + TS_ASSERT_EQUALS(isotropic->getU(), 1.0); + TS_ASSERT_EQUALS(isotropic->getPosition(), V3D(0.3, 0.1, 0.12)); + } + + void testClone() + { + UnitCell cell(5.43, 5.43, 5.43); + SpaceGroup_const_sptr spaceGroup = SpaceGroupFactory::Instance().createSpaceGroup("P m -3 m"); + + IsotropicAtomBraggScatterer_sptr scatterer = getInitializedScatterer("H", V3D(1.0, 0, 0), 0.0); + scatterer->setProperty("U", 3.04); + scatterer->setProperty("Occupancy", 0.5); + scatterer->setProperty("UnitCell", unitCellToStr(cell)); + scatterer->setProperty("SpaceGroup", spaceGroup->hmSymbol()); + + BraggScatterer_sptr baseclone = scatterer->clone(); + BraggScattererInCrystalStructure_sptr clone = boost::dynamic_pointer_cast(baseclone); + + TS_ASSERT(clone) + + TS_ASSERT_EQUALS(clone->getPosition(), scatterer->getPosition()); + TS_ASSERT_EQUALS(clone->getCell().getG(), scatterer->getCell().getG()); + TS_ASSERT_EQUALS(clone->getSpaceGroup()->hmSymbol(), scatterer->getSpaceGroup()->hmSymbol()); + + IsotropicAtomBraggScatterer_sptr scattererClone = boost::dynamic_pointer_cast(clone); + TS_ASSERT(scattererClone); + + TS_ASSERT_EQUALS(scattererClone->getU(), scatterer->getU()); + TS_ASSERT_EQUALS(scattererClone->getOccupancy(), scatterer->getOccupancy()); + } + + void testCalculateStructureFactor() + { + IsotropicAtomBraggScatterer_sptr scatterer = getInitializedScatterer("Si", V3D(0.0, 0.0, 0.0), 0.0); + + double bSi = scatterer->getNeutronAtom().coh_scatt_length_real; + + V3D hkl(1, 0, 0); + + // There's only one atom in (0,0,0) and U is 0 - rigid scatterer + StructureFactor structureFactor = scatterer->calculateStructureFactor(hkl); + + /* Phase is (1,0,0) * (0,0,0) = (1*0 + 0*0 + 0*0) = 0 + * cos(phase) = 1.0 + * sin(phase) = 0.0 + */ + TS_ASSERT_EQUALS(structureFactor.real(), bSi); + TS_ASSERT_EQUALS(structureFactor.imag(), 0.0); + + // For using U, the cell needs to be set, because 1/d is required + UnitCell cell(5.43, 5.43, 5.43); + scatterer->setProperty("UnitCell", unitCellToStr(cell)); + scatterer->setProperty("U", 0.05); + + structureFactor = scatterer->calculateStructureFactor(hkl); + /* Real part is reduced by exp(-U * 2*pi^2 * 1/d^2) + * d = 5.43, d^2 = 29.4849, 1/d^2 = 0.033916... + * exp(-0.05 * 2 * pi^2 * 1/29.4849) = 0.96708... + */ + TS_ASSERT_EQUALS(structureFactor.real(), bSi * 0.96708061593352515459); + + // Occupancy goes in directly + scatterer->setProperty("Occupancy", 0.5); + structureFactor = scatterer->calculateStructureFactor(hkl); + TS_ASSERT_EQUALS(structureFactor.real(), bSi * 0.5 * 0.96708061593352515459); + + // Set a space group with F-centering + SpaceGroup_const_sptr spaceGroup = SpaceGroupFactory::Instance().createSpaceGroup("F m -3 m"); + scatterer->setProperty("SpaceGroup", spaceGroup->hmSymbol()); + + /* Now there are 4 equivalent positions, the contributions cancel out for (1, 0, 0) + * scalar products are: + * (1,0,0) * (0,0,0) = (1*0 + 1*0 + 1*0) = 0 cos(0) = 1, sin(0) = 0 + * (1,0,0) * (0,0.5,0.5) = (1*0 + 0*0.5 + 0*0.5) = 0 cos(0) = 1, sin(0) = 0 + * (1,0,0) * (0.5,0,0.5) = (1*0.5 + 0*0 + 0*0.5) = 0.5 cos(pi) = -1, sin(pi) = 0 + * (1,0,0) * (0.5,0.5,0) = (1*0.5 + 0*0.5 + 0*0) = 0.5 cos(pi) = -1, sin(pi) = 0 + * + * That means 1 * real + 1 * real + (-1 * real) + (-1 * real) = 0 + */ + structureFactor = scatterer->calculateStructureFactor(hkl); + + // It's not always exactly 0 (floating point math), but should not be less than 0 + TS_ASSERT_LESS_THAN(structureFactor.real(), 1e-9); + TS_ASSERT_LESS_THAN_EQUALS(0, structureFactor.real()); + + // For (1, 1, 1), the value is defined + hkl = V3D(1, 1, 1); + structureFactor = scatterer->calculateStructureFactor(hkl); + + /* scalar products are: + * (1,1,1) * (0,0,0) = (1*0 + 1*0 + 1*0) = 0 cos(0) = 1, sin(0) = 0 + * (1,1,1) * (0,0.5,0.5) = (1*0 + 1*0.5 + 1*0.5) = 1 cos(2pi) = 1, sin(2pi) = 0 + * (1,1,1) * (0.5,0,0.5) = (1*0.5 + 1*0 + 1*0.5) = 1 cos(2pi) = 1, sin(2pi) = 0 + * (1,1,1) * (0.5,0.5,0) = (1*0.5 + 1*0.5 + 1*0) = 1 cos(2pi) = 1, sin(2pi) = 0 + * + * That means 4 * real * debye waller * occupation. d = 3.13... + */ + TS_ASSERT_DELTA(structureFactor.real(), 4.0 * bSi * 0.90445723107190849637 * 0.5, 5e-16) + } + +private: + IsotropicAtomBraggScatterer_sptr getInitializedScatterer() + { + IsotropicAtomBraggScatterer_sptr scatterer = boost::make_shared(); + scatterer->initialize(); + + return scatterer; + } + + IsotropicAtomBraggScatterer_sptr getInitializedScatterer(const std::string &element, const V3D &position, double U = 0.0, double occ = 1.0) + { + IsotropicAtomBraggScatterer_sptr scatterer = getInitializedScatterer(); + + scatterer->setProperty("Element", element); + scatterer->setProperty("Position", position); + scatterer->setProperty("U", U); + scatterer->setProperty("Occupancy", occ); + + return scatterer; + } + +}; + + +#endif /* MANTID_GEOMETRY_ISOTROPICATOMBRAGGSCATTERERTEST_H_ */ diff --git a/Code/Mantid/Framework/Geometry/test/LineIntersectVisitTest.h b/Code/Mantid/Framework/Geometry/test/LineIntersectVisitTest.h index 448aafecbc6e..24765b26c270 100644 --- a/Code/Mantid/Framework/Geometry/test/LineIntersectVisitTest.h +++ b/Code/Mantid/Framework/Geometry/test/LineIntersectVisitTest.h @@ -20,8 +20,8 @@ class LineIntersectVisitTest: public CxxTest::TestSuite{ void testConstructor(){ LineIntersectVisit A(V3D(-1.0,-1.0,-1.0),V3D(1.0,0.0,0.0)); TS_ASSERT_EQUALS(A.getNPoints(),0); - TS_ASSERT_EQUALS(A.getPoints(),std::vector()); - TS_ASSERT_EQUALS(A.getDistance(),std::vector()); + TS_ASSERT_EQUALS(A.getPoints(),std::list()); + TS_ASSERT_EQUALS(A.getDistance(),std::list()); } void testAcceptPlane(){ @@ -31,10 +31,10 @@ class LineIntersectVisitTest: public CxxTest::TestSuite{ TS_ASSERT_EQUALS(extractString(B),"-1 px 0\n"); A.Accept(B); TS_ASSERT_EQUALS(A.getNPoints(),1); - std::vector Pnts; + std::list Pnts; Pnts.push_back(V3D(0.0,-1.0,-1.0)); TS_ASSERT_EQUALS(A.getPoints(),Pnts); - std::vector Dist; + std::list Dist; Dist.push_back(1.0); TS_ASSERT_EQUALS(A.getDistance(),Dist); } @@ -45,14 +45,13 @@ class LineIntersectVisitTest: public CxxTest::TestSuite{ Sphere B; B.setSurface("s 0.0 0.0 0.0 2"); A.Accept(B); - std::vector pntOut; + std::list pntOut; // changed for forward going only intercepts on quadratice surfaces //pntOut.push_back(V3D(-2.0,0.0,0.0)); pntOut.push_back(V3D(2.0,0.0,0.0)); TS_ASSERT_EQUALS(A.getNPoints(),1); TS_ASSERT_EQUALS(A.getPoints(),pntOut); - std::vector Dist; - //Dist.push_back(2.0); + std::list Dist; Dist.push_back(2.0); TS_ASSERT_EQUALS(A.getDistance(),Dist); } @@ -67,19 +66,13 @@ class LineIntersectVisitTest: public CxxTest::TestSuite{ A.Accept(B); // change for forward only intercept TS_ASSERT_EQUALS(A.getNPoints(),1); - std::vector pntOut; - pntOut=A.getPoints(); - //TS_ASSERT_DELTA(pntOut[0].X(),-1,0.0000001); - //TS_ASSERT_DELTA(pntOut[0].Y(),0.0,0.0000001); - //TS_ASSERT_DELTA(pntOut[0].Z(),0.0,0.0000001); - TS_ASSERT_DELTA(pntOut[0].X(),1,0.0000001); - TS_ASSERT_DELTA(pntOut[0].Y(),0.0,0.0000001); - TS_ASSERT_DELTA(pntOut[0].Z(),0.0,0.0000001); + const auto &pntOut = A.getPoints(); + TS_ASSERT_DELTA(pntOut.front().X(),1,0.0000001); + TS_ASSERT_DELTA(pntOut.front().Y(),0.0,0.0000001); + TS_ASSERT_DELTA(pntOut.front().Z(),0.0,0.0000001); - std::vector Dist; - Dist=A.getDistance(); - TS_ASSERT_DELTA(Dist[0],1.0,0.0000001); - //TS_ASSERT_DELTA(Dist[1],1.0,0.0000001); + const auto &Dist = A.getDistance(); + TS_ASSERT_DELTA(Dist.front(),1.0,0.0000001); } void testAcceptCylinder(){ @@ -92,13 +85,13 @@ class LineIntersectVisitTest: public CxxTest::TestSuite{ TS_ASSERT_EQUALS(B.getNormal(),V3D(0,1,0)); A.Accept(B); - std::vector pntOut; + std::list pntOut; // forward only //pntOut.push_back(V3D(-1.0,0.0,0.0)); pntOut.push_back(V3D(1.0,0.0,0.0)); TS_ASSERT_EQUALS(A.getNPoints(),1); TS_ASSERT_EQUALS(A.getPoints(),pntOut); - std::vector Dist; + std::list Dist; //Dist.push_back(1.0); Dist.push_back(1.0); TS_ASSERT_EQUALS(A.getDistance(),Dist); @@ -106,14 +99,12 @@ class LineIntersectVisitTest: public CxxTest::TestSuite{ LineIntersectVisit C(V3D(1.1,0.0,0.0),V3D(-1.0,0.0,0.0)); C.Accept(B); TS_ASSERT_EQUALS(C.getNPoints(),2); - std::vector pntOut2; + std::list pntOut2; pntOut2.push_back(V3D(-1.0,0.0,0.0)); pntOut2.push_back(V3D(1.0,0.0,0.0)); TS_ASSERT_EQUALS(C.getPoints(),pntOut2); } - void testAcceptGeneral(){ - } private: std::string extractString(const Surface& pv) diff --git a/Code/Mantid/Framework/Geometry/test/LineTest.h b/Code/Mantid/Framework/Geometry/test/LineTest.h index b0a2f59dc0f6..2b2d4fcf56ba 100644 --- a/Code/Mantid/Framework/Geometry/test/LineTest.h +++ b/Code/Mantid/Framework/Geometry/test/LineTest.h @@ -142,13 +142,12 @@ class LineTest: public CxxTest::TestSuite TS_ASSERT_EQUALS(B.getRadius(),1); TS_ASSERT_EQUALS(B.getNormal(),V3D(0,1,0)); - std::vector pntOut; + std::list pntOut; A.intersect(pntOut,B); // forward only solution for cylinders - TS_ASSERT_EQUALS(pntOut.size(),1); - //TS_ASSERT_EQUALS(pntOut[0],V3D(-1.0,0.0,0.0)); - TS_ASSERT_EQUALS(pntOut[0],V3D(1.0,0.0,0.0)); + TS_ASSERT_EQUALS(pntOut.size(),1); + TS_ASSERT_EQUALS(pntOut.front(),V3D(1.0,0.0,0.0)); } //A Line with equation equivalent to x axis will cut A Cylinder with 1 radius with center at 0,0,0 y axis normal @@ -164,12 +163,13 @@ class LineTest: public CxxTest::TestSuite TS_ASSERT_EQUALS(B.getRadius(),1); TS_ASSERT_EQUALS(B.getNormal(),V3D(0,1,0)); - std::vector pntOut; + std::list pntOut; A.intersect(pntOut,B); - TS_ASSERT_EQUALS(pntOut.size(),2); - TS_ASSERT_EQUALS(pntOut[0],V3D(1.0,0.0,0.0)); - TS_ASSERT_EQUALS(pntOut[1],V3D(-1.0,0.0,0.0)); + TS_ASSERT_EQUALS(pntOut.size(),2); + auto itr = pntOut.begin(); + TS_ASSERT_EQUALS(*(itr++), V3D(1.0,0.0,0.0)); + TS_ASSERT_EQUALS(*itr,V3D(-1.0,0.0,0.0)); } //A Line with equation equivalent to x axis will cut a plane YZ with equation x=5 will cut at one point 5,0,0 @@ -181,11 +181,11 @@ class LineTest: public CxxTest::TestSuite Plane B; TS_ASSERT_EQUALS(B.setSurface("px 5 0 0"),0); - std::vector pntOut; + std::list pntOut; A.intersect(pntOut,B); - TS_ASSERT_EQUALS(pntOut.size(),1); - TS_ASSERT_EQUALS(pntOut[0],V3D(5.0,0.0,0.0)); + TS_ASSERT_EQUALS(pntOut.size(),1); + TS_ASSERT_EQUALS(pntOut.front(),V3D(5.0,0.0,0.0)); } //A Line with equation equivalent to x axis will cut A sphere with 2 radius with center at 0,0,0 @@ -197,12 +197,11 @@ class LineTest: public CxxTest::TestSuite Sphere B; B.setSurface("s 0.0 0.0 0.0 2"); - std::vector pntOut; + std::list pntOut; A.intersect(pntOut,B); // forward only solutions - TS_ASSERT_EQUALS(pntOut.size(),1); - //TS_ASSERT_EQUALS(pntOut[0],V3D(-2.0,0.0,0.0)); - TS_ASSERT_EQUALS(pntOut[0],V3D(2.0,0.0,0.0)); + TS_ASSERT_EQUALS(pntOut.size(),1); + TS_ASSERT_EQUALS(pntOut.front(),V3D(2.0,0.0,0.0)); } //A Line with equation equivalent to x axis starting at -10 will cut A sphere with 2 radius with center at 0,0,0 @@ -214,11 +213,12 @@ class LineTest: public CxxTest::TestSuite Sphere B; B.setSurface("s 0.0 0.0 0.0 2"); - std::vector pntOut; + std::list pntOut; A.intersect(pntOut,B); - TS_ASSERT_EQUALS(pntOut.size(),2); - TS_ASSERT_EQUALS(pntOut[0],V3D(2.0,0.0,0.0)); - TS_ASSERT_EQUALS(pntOut[1],V3D(-2.0,0.0,0.0)); + TS_ASSERT_EQUALS(pntOut.size(),2); + auto itr = pntOut.begin(); + TS_ASSERT_EQUALS(*(itr++), V3D(2.0,0.0,0.0)); + TS_ASSERT_EQUALS(*itr, V3D(-2.0,0.0,0.0)); } }; diff --git a/Code/Mantid/Framework/Geometry/test/ObjectTest.h b/Code/Mantid/Framework/Geometry/test/ObjectTest.h index bc51c9c2d46c..a36c79899c87 100644 --- a/Code/Mantid/Framework/Geometry/test/ObjectTest.h +++ b/Code/Mantid/Framework/Geometry/test/ObjectTest.h @@ -11,18 +11,18 @@ #include -#include "MantidKernel/V3D.h" -#include "MantidGeometry/Objects/Object.h" -#include "MantidGeometry/Surfaces/Cylinder.h" -#include "MantidGeometry/Surfaces/Sphere.h" -#include "MantidGeometry/Surfaces/Plane.h" -#include "MantidGeometry/Math/Algebra.h" -#include "MantidGeometry/Surfaces/SurfaceFactory.h" -#include "MantidGeometry/Objects/Track.h" +#include "MantidGeometry/Objects/Object.h" +#include "MantidGeometry/Surfaces/Cylinder.h" +#include "MantidGeometry/Surfaces/Sphere.h" +#include "MantidGeometry/Surfaces/Plane.h" +#include "MantidGeometry/Math/Algebra.h" +#include "MantidGeometry/Surfaces/SurfaceFactory.h" +#include "MantidGeometry/Objects/Track.h" #include "MantidGeometry/Rendering/GluGeometryHandler.h" -#include "MantidGeometry/Objects/BoundingBox.h" #include "MantidGeometry/Objects/ShapeFactory.h" +#include "MantidKernel/Material.h" + #include "MantidTestHelpers/ComponentCreationHelper.h" using namespace Mantid; @@ -34,6 +34,25 @@ class ObjectTest: public CxxTest::TestSuite public: + void testDefaultObjectHasEmptyMaterial() + { + Object obj; + + TSM_ASSERT_DELTA("Expected a zero number density",0.0, obj.material().numberDensity(), 1e-12); + } + + void testObjectSetMaterialReplacesExisting() + { + using Mantid::Kernel::Material; + Object obj; + + TSM_ASSERT_DELTA("Expected a zero number density", 0.0, + obj.material().numberDensity(), 1e-12); + obj.setMaterial(Material("arm", PhysicalConstants::getNeutronAtom(13), 45.0)); + TSM_ASSERT_DELTA("Expected a number density of 45", 45.0, + obj.material().numberDensity(), 1e-12); + } + void testCopyConstructorGivesObjectWithSameAttributes() { Object_sptr original = ComponentCreationHelper::createSphere(1.0, V3D(), "sphere"); @@ -224,7 +243,7 @@ class ObjectTest: public CxxTest::TestSuite void testGetBoundingBoxForSphere() { - Object_sptr geom_obj = createSphere(); + Object_sptr geom_obj = createSphere(); const double tolerance(1e-10); double xmax,ymax,zmax,xmin,ymin,zmin; @@ -279,10 +298,10 @@ class ObjectTest: public CxxTest::TestSuite SphSurMap[41]->setSurface(S41); SphSurMap[41]->setName(41); - // A sphere + // A sphere std::string ObjSphere="-41" ; - Object_sptr geom_obj = Object_sptr(new Object); + Object_sptr geom_obj = Object_sptr(new Object); geom_obj->setObject(41,ObjSphere); geom_obj->populate(SphSurMap); @@ -292,7 +311,7 @@ class ObjectTest: public CxxTest::TestSuite // format = startPoint, endPoint, total distance so far // forward only intercepts means that start point should be track origin expectedResults.push_back(Link(V3D(-1,1.5,1), - V3D(sqrt(16-0.25)+1,1.5,1.0),sqrt(15.75)+2)); + V3D(sqrt(16-0.25)+1,1.5,1.0),sqrt(15.75)+2,*geom_obj)); checkTrackIntercept(geom_obj,track,expectedResults); } @@ -304,7 +323,7 @@ class ObjectTest: public CxxTest::TestSuite Track track(V3D(0,-10,0),V3D(0,1,0)); //format = startPoint, endPoint, total distance so far - expectedResults.push_back(Link(V3D(0,-4.1,0),V3D(0,4.1,0),14.1)); + expectedResults.push_back(Link(V3D(0,-4.1,0),V3D(0,4.1,0),14.1,*geom_obj)); checkTrackIntercept(geom_obj,track,expectedResults); } @@ -316,7 +335,7 @@ class ObjectTest: public CxxTest::TestSuite Track track(V3D(-10,0,0),V3D(1,0,0)); //format = startPoint, endPoint, total distance so far - expectedResults.push_back(Link(V3D(-4.1,0,0),V3D(4.1,0,0),14.1)); + expectedResults.push_back(Link(V3D(-4.1,0,0),V3D(4.1,0,0),14.1,*geom_obj)); checkTrackIntercept(geom_obj,track,expectedResults); } @@ -325,7 +344,7 @@ class ObjectTest: public CxxTest::TestSuite std::vector expectedResults; Object_sptr geom_obj = createCappedCylinder(); //format = startPoint, endPoint, total distance so far - expectedResults.push_back(Link(V3D(0,-3,0),V3D(0,3,0),13)); + expectedResults.push_back(Link(V3D(0,-3,0),V3D(0,3,0),13,*geom_obj)); Track track(V3D(0,-10,0),V3D(0,1,0)); checkTrackIntercept(geom_obj,track,expectedResults); @@ -338,7 +357,7 @@ class ObjectTest: public CxxTest::TestSuite Track track(V3D(-10,0,0),V3D(1,0,0)); //format = startPoint, endPoint, total distance so far - expectedResults.push_back(Link(V3D(-3.2,0,0),V3D(1.2,0,0),11.2)); + expectedResults.push_back(Link(V3D(-3.2,0,0),V3D(1.2,0,0),11.2,*geom_obj)); checkTrackIntercept(geom_obj,track,expectedResults); } @@ -399,8 +418,8 @@ class ObjectTest: public CxxTest::TestSuite TS_ASSERT(object2.interceptSurface(TL)!=0); std::vector expectedResults; - expectedResults.push_back(Link(V3D(-1,0,0),V3D(1,0,0),6)); - expectedResults.push_back(Link(V3D(4.5,0,0),V3D(6.5,0,0),11.5)); + expectedResults.push_back(Link(V3D(-1,0,0),V3D(1,0,0),6,object1)); + expectedResults.push_back(Link(V3D(4.5,0,0),V3D(6.5,0,0),11.5,object2)); checkTrackIntercept(TL,expectedResults); } @@ -430,8 +449,8 @@ class ObjectTest: public CxxTest::TestSuite TS_ASSERT(object2.interceptSurface(TL)!=0); std::vector expectedResults; - expectedResults.push_back(Link(V3D(-1,0,0),V3D(1,0,0),6)); - expectedResults.push_back(Link(V3D(1,0,0),V3D(6.5,0,0),11.5)); + expectedResults.push_back(Link(V3D(-1,0,0),V3D(1,0,0),6, object1)); + expectedResults.push_back(Link(V3D(1,0,0),V3D(6.5,0,0),11.5, object2)); checkTrackIntercept(TL,expectedResults); @@ -463,9 +482,9 @@ class ObjectTest: public CxxTest::TestSuite TS_ASSERT(object2.interceptSurface(TL)!=0); std::vector expectedResults; - expectedResults.push_back(Link(V3D(-1,0,0),V3D(-0.8,0,0),4.2)); - expectedResults.push_back(Link(V3D(-0.8,0,0),V3D(0.8,0,0),5.8)); - expectedResults.push_back(Link(V3D(0.8,0,0),V3D(1,0,0),6)); + expectedResults.push_back(Link(V3D(-1,0,0),V3D(-0.8,0,0),4.2,object1)); + expectedResults.push_back(Link(V3D(-0.8,0,0),V3D(0.8,0,0),5.8,object1)); + expectedResults.push_back(Link(V3D(0.8,0,0),V3D(1,0,0),6,object2)); checkTrackIntercept(TL,expectedResults); } @@ -495,9 +514,9 @@ class ObjectTest: public CxxTest::TestSuite TS_ASSERT(object2.interceptSurface(TL)!=0); std::vector expectedResults; - expectedResults.push_back(Link(V3D(-1,0,0),V3D(-0.4,0,0),4.6)); - expectedResults.push_back(Link(V3D(-0.4,0,0),V3D(0.2,0,0),5.2)); - expectedResults.push_back(Link(V3D(0.2,0,0),V3D(1,0,0),6)); + expectedResults.push_back(Link(V3D(-1,0,0),V3D(-0.4,0,0),4.6,object1)); + expectedResults.push_back(Link(V3D(-0.4,0,0),V3D(0.2,0,0),5.2,object1)); + expectedResults.push_back(Link(V3D(0.2,0,0),V3D(1,0,0),6,object2)); checkTrackIntercept(TL,expectedResults); } @@ -814,7 +833,7 @@ class ObjectTest: public CxxTest::TestSuite private: /// Surface type - typedef std::map STYPE ; + typedef std::map STYPE ; /// set timeTest true to get time comparisons of soild angle methods const static bool timeTest=false; @@ -840,11 +859,11 @@ class ObjectTest: public CxxTest::TestSuite CylSurMap[32]->setName(32); CylSurMap[33]->setName(33); - // Capped cylinder (id 21) + // Capped cylinder (id 21) // using surface ids: 31 (cylinder) 32 (plane (top) ) and 33 (plane (base)) std::string ObjCapCylinder="-31 -32 33"; - Object_sptr retVal = Object_sptr(new Object); + Object_sptr retVal = Object_sptr(new Object); retVal->setObject(21,ObjCapCylinder); retVal->populate(CylSurMap); @@ -874,11 +893,11 @@ class ObjectTest: public CxxTest::TestSuite CylSurMap[32]->setName(32); CylSurMap[33]->setName(33); - // Capped cylinder (id 21) + // Capped cylinder (id 21) // using surface ids: 31 (cylinder) 32 (plane (top) ) and 33 (plane (base)) std::string ObjCapCylinder="-31 -32 33"; - Object_sptr retVal = Object_sptr(new Object); + Object_sptr retVal = Object_sptr(new Object); retVal->setObject(21,ObjCapCylinder); retVal->populate(CylSurMap); @@ -895,10 +914,10 @@ class ObjectTest: public CxxTest::TestSuite SphSurMap[41]->setSurface(S41); SphSurMap[41]->setName(41); - // A sphere + // A sphere std::string ObjSphere="-41" ; - Object_sptr retVal = Object_sptr(new Object); + Object_sptr retVal = Object_sptr(new Object); retVal->setObject(41,ObjSphere); retVal->populate(SphSurMap); @@ -957,7 +976,7 @@ class ObjectTest: public CxxTest::TestSuite // Note that the testObject now manages the "new Plane" Geometry::Surface* A; for(vc=SurfLine.begin();vc!=SurfLine.end();vc++) - { + { A=Geometry::SurfaceFactory::Instance()->processLine(vc->second); if (!A) { @@ -1003,11 +1022,11 @@ class ObjectTest: public CxxTest::TestSuite CubeSurMap[5]->setName(5); CubeSurMap[6]->setName(6); - // Cube (id 68) + // Cube (id 68) // using surface ids: 1-6 std::string ObjCube="1 -2 3 -4 5 -6"; - Object_sptr retVal = Object_sptr(new Object); + Object_sptr retVal = Object_sptr(new Object); retVal->setObject(68,ObjCube); retVal->populate(CubeSurMap); @@ -1046,11 +1065,11 @@ class ObjectTest: public CxxTest::TestSuite CubeSurMap[5]->setName(5); CubeSurMap[6]->setName(6); - // Cube (id 68) + // Cube (id 68) // using surface ids: 1-6 std::string ObjCube="1 -2 3 -4 5 -6"; - Object_sptr retVal = Object_sptr(new Object); + Object_sptr retVal = Object_sptr(new Object); retVal->setObject(68,ObjCube); retVal->populate(CubeSurMap); diff --git a/Code/Mantid/Framework/Geometry/test/PointGroupFactoryTest.h b/Code/Mantid/Framework/Geometry/test/PointGroupFactoryTest.h new file mode 100644 index 000000000000..c4a4fd000735 --- /dev/null +++ b/Code/Mantid/Framework/Geometry/test/PointGroupFactoryTest.h @@ -0,0 +1,158 @@ +#ifndef MANTID_GEOMETRY_POINTGROUPFACTORYTEST_H_ +#define MANTID_GEOMETRY_POINTGROUPFACTORYTEST_H_ + +#include + +#include "MantidGeometry/Crystal/PointGroupFactory.h" +#include "MantidGeometry/Crystal/PointGroup.h" +#include "MantidKernel/Exception.h" + + +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 TestPointGroupCubicA : public PointGroup +{ +public: + TestPointGroupCubicA() : PointGroup("cubicA") + { } + ~TestPointGroupCubicA() { } + + std::string getName() const { return "cubicA (test)"; } + bool isEquivalent(const Mantid::Kernel::V3D &hkl, const Mantid::Kernel::V3D &hkl2) const + { + UNUSED_ARG(hkl); + UNUSED_ARG(hkl2); + + return false; + } + + PointGroup::CrystalSystem crystalSystem() const { return PointGroup::Cubic; } + + void init() { } +}; + +class TestPointGroupCubicB : public PointGroup +{ +public: + TestPointGroupCubicB() : PointGroup("cubicB") + { } + ~TestPointGroupCubicB() { } + + std::string getName() const { return "cubicB (test)"; } + bool isEquivalent(const Mantid::Kernel::V3D &hkl, const Mantid::Kernel::V3D &hkl2) const + { + UNUSED_ARG(hkl); + UNUSED_ARG(hkl2); + + return false; + } + + PointGroup::CrystalSystem crystalSystem() const { return PointGroup::Cubic; } + + void init() { } +}; + +class TestPointGroupTriclinic : public PointGroup +{ +public: + TestPointGroupTriclinic() : PointGroup("triclinic") + { } + ~TestPointGroupTriclinic() { } + + std::string getName() const { return "triclinic (test)"; } + bool isEquivalent(const Mantid::Kernel::V3D &hkl, const Mantid::Kernel::V3D &hkl2) const + { + UNUSED_ARG(hkl); + UNUSED_ARG(hkl2); + + return false; + } + + PointGroup::CrystalSystem crystalSystem() const { return PointGroup::Triclinic; } + + void init() { } +}; + +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(); + PointGroupFactory::Instance().subscribePointGroup(); + PointGroupFactory::Instance().subscribePointGroup(); + } + + ~PointGroupFactoryTest() + { + // Unsubscribing the fake point groups + PointGroupFactory::Instance().unsubscribePointGroup("cubicA"); + PointGroupFactory::Instance().unsubscribePointGroup("cubicB"); + PointGroupFactory::Instance().unsubscribePointGroup("triclinic"); + } + + void testCreatePointGroup() + { + TS_ASSERT_THROWS_NOTHING(PointGroupFactory::Instance().createPointGroup("cubicA")); + TS_ASSERT_THROWS_NOTHING(PointGroupFactory::Instance().createPointGroup("cubicB")); + TS_ASSERT_THROWS_NOTHING(PointGroupFactory::Instance().createPointGroup("triclinic")); + + TS_ASSERT_THROWS(PointGroupFactory::Instance().createPointGroup("cubicC"), Mantid::Kernel::Exception::NotFoundError); + } + + void testGetAllPointGroupSymbols() + { + std::vector symbols = PointGroupFactory::Instance().getAllPointGroupSymbols(); + + TS_ASSERT_DIFFERS(findString(symbols, "cubicA"), symbols.end()); + TS_ASSERT_DIFFERS(findString(symbols, "cubicB"), symbols.end()); + TS_ASSERT_DIFFERS(findString(symbols, "triclinic"), symbols.end()); + } + + void testGetAllPointGroupSymbolsCrystalSystems() + { + std::vector cubic = PointGroupFactory::Instance().getPointGroupSymbols(PointGroup::Cubic); + TS_ASSERT_DIFFERS(findString(cubic, "cubicA"), cubic.end()); + TS_ASSERT_DIFFERS(findString(cubic, "cubicB"), cubic.end()); + + std::vector triclinic = PointGroupFactory::Instance().getPointGroupSymbols(PointGroup::Triclinic); + TS_ASSERT_DIFFERS(findString(triclinic, "triclinic"), triclinic.end()); + } + + void testUnsubscribePointGroup() + { + TS_ASSERT_THROWS_NOTHING(PointGroupFactory::Instance().createPointGroup("cubicA")); + + PointGroupFactory::Instance().unsubscribePointGroup("cubicA"); + + std::vector allSymbols = PointGroupFactory::Instance().getAllPointGroupSymbols(); + TS_ASSERT_EQUALS(findString(allSymbols, "cubicA"), allSymbols.end()); + + TS_ASSERT_THROWS(PointGroupFactory::Instance().create("cubicA"), Mantid::Kernel::Exception::NotFoundError); + + PointGroupFactory::Instance().subscribePointGroup(); + TS_ASSERT_THROWS_NOTHING(PointGroupFactory::Instance().createPointGroup("cubicA")); + } + +private: + std::vector::const_iterator findString(const std::vector &vector, const std::string &searchString) + { + return std::find(vector.begin(), vector.end(), searchString); + } +}; + + +#endif /* MANTID_GEOMETRY_POINTGROUPFACTORYTEST_H_ */ diff --git a/Code/Mantid/Framework/Geometry/test/PointGroupTest.h b/Code/Mantid/Framework/Geometry/test/PointGroupTest.h index 0d8e6caa3e37..b86a23fb4782 100644 --- a/Code/Mantid/Framework/Geometry/test/PointGroupTest.h +++ b/Code/Mantid/Framework/Geometry/test/PointGroupTest.h @@ -9,9 +9,10 @@ #include "MantidKernel/System.h" #include #include +#include "MantidGeometry/Crystal/PointGroupFactory.h" #include "MantidGeometry/Crystal/PointGroup.h" #include - +#include "MantidGeometry/Crystal/SymmetryOperationFactory.h" using namespace Mantid; using namespace Mantid::Kernel; using namespace Mantid::Geometry; @@ -20,48 +21,42 @@ class PointGroupTest : public CxxTest::TestSuite { public: - void check_point_group(std::string name, V3D hkl, size_t numEquiv, V3D * equiv) - { - std::vector pgs = getAllPointGroups(); - for (size_t i=0; igetName().substr(0, name.size()) == name) - { - std::vector equivalents = pgs[i]->getEquivalents(hkl); + PointGroup_sptr testedPointGroup = PointGroupFactory::Instance().createPointGroup(name); + + std::vector equivalents = testedPointGroup->getEquivalents(hkl); // check that the number of equivalent reflections is as expected. TSM_ASSERT_EQUALS(name + ": Expected " + boost::lexical_cast(numEquiv) + " equivalents, got " + boost::lexical_cast(equivalents.size()) + " instead.", equivalents.size(), numEquiv); // get reflection family for this hkl - V3D family = pgs[i]->getReflectionFamily(hkl); + V3D family = testedPointGroup->getReflectionFamily(hkl); for (size_t j=0; jisEquivalent(hkl, equiv[j])) - { - TSM_ASSERT( name + " : " + hkl.toString() + " is not equivalent to " + equiv[j].toString(), false); - } - - // make sure family for equiv[j] is the same as the one for hkl - TS_ASSERT_EQUALS(pgs[i]->getReflectionFamily(equiv[j]), family); - // also make sure that current equivalent is in the collection of equivalents. - TS_ASSERT_DIFFERS(std::find(equivalents.begin(), equivalents.end(), equiv[j]), equivalents.end()); + //std::cout << j << std::endl; + if (!testedPointGroup->isEquivalent(hkl, equiv[j])) + { + TSM_ASSERT( name + " : " + hkl.toString() + " is not equivalent to " + equiv[j].toString(), false); + } + + // make sure family for equiv[j] is the same as the one for hkl + TS_ASSERT_EQUALS(testedPointGroup->getReflectionFamily(equiv[j]), family); + // also make sure that current equivalent is in the collection of equivalents. + TS_ASSERT_DIFFERS(std::find(equivalents.begin(), equivalents.end(), equiv[j]), equivalents.end()); } return; - } } - TSM_ASSERT("Point group not found", false); - } void test_all_point_groups() { { V3D equiv[] = {V3D(1,2,3),V3D(-1,-2,-3)}; check_point_group("-1", V3D(1,2,3), 2, equiv); } { V3D equiv[] = {V3D(1,2,3), V3D(-1,-2,-3), V3D(-1,2,-3), V3D(1,-2,3) }; - check_point_group("1 2/m 1", V3D(1,2,3), 4, equiv); } + check_point_group("2/m", V3D(1,2,3), 4, equiv); } { V3D equiv[] = {V3D(1,2,3), V3D(-1,-2,3), V3D(-1,-2,-3), V3D(1,2,-3) }; - check_point_group("1 1 2/m", V3D(1,2,3), 4, equiv); } + check_point_group("112/m", V3D(1,2,3), 4, equiv); } { V3D equiv[] = {V3D(1,2,3),V3D(-1,-2,3), V3D(-1,2,-3), V3D(1,-2,-3), V3D(-1,-2,-3), V3D(1,2,-3), V3D(1,-2,3), V3D(-1,2,3)}; check_point_group("mmm", V3D(1,2,3), 8, equiv); } { 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)}; @@ -121,7 +116,6 @@ class PointGroupTest : public CxxTest::TestSuite TestablePointGroup defaultPointgroup; TS_ASSERT_EQUALS(defaultPointgroup.m_symmetryOperations.size(), 0); - TS_ASSERT_EQUALS(defaultPointgroup.m_transformationMatrices.size(), 0); } void testAddSymmetryOperation() @@ -130,42 +124,31 @@ class PointGroupTest : public CxxTest::TestSuite TS_ASSERT_EQUALS(pg.getSymmetryOperations().size(), 0); - SymmetryOperation_const_sptr symOp(new SymOpInversion); + SymmetryOperation symOp = SymmetryOperationFactory::Instance().createSymOp("x,y,z"); pg.addSymmetryOperation(symOp); - std::vector ops = pg.getSymmetryOperations(); + std::vector ops = pg.getSymmetryOperations(); TS_ASSERT_EQUALS(ops.size(), 1); TS_ASSERT_EQUALS(ops[0], symOp); } - void testSetTransformationMatrices() - { - TestablePointGroup pg; - - std::vector matrices(1, IntMatrix(3, 3, true)); - pg.setTransformationMatrices(matrices); - - TS_ASSERT_EQUALS(pg.m_transformationMatrices.size(), 1); - TS_ASSERT_EQUALS(pg.m_transformationMatrices[0], IntMatrix(3, 3, true)); - } - void testGenerateTransformationMatrices() { TestablePointGroup pg; - SymmetryOperation_const_sptr identity(new SymOpIdentity); - SymmetryOperation_const_sptr inversion(new SymOpInversion); - SymmetryOperation_const_sptr mirror(new SymOpMirrorPlaneZ); - SymmetryOperation_const_sptr twoFold(new SymOpRotationTwoFoldZ); + SymmetryOperation identity = SymmetryOperationFactory::Instance().createSymOp("x,y,z"); + SymmetryOperation inversion = SymmetryOperationFactory::Instance().createSymOp("x,y,z"); + SymmetryOperation mirror = SymmetryOperationFactory::Instance().createSymOp("x,y,-z"); + SymmetryOperation twoFold = SymmetryOperationFactory::Instance().createSymOp("-x,-y,z"); pg.addSymmetryOperation(mirror); pg.addSymmetryOperation(twoFold); - std::vector ops = pg.getSymmetryOperations(); + std::vector ops = pg.getSymmetryOperations(); TS_ASSERT_EQUALS(ops.size(), 2); - std::vector matrices = pg.generateTransformationMatrices(ops); + std::vector matrices = pg.generateSymmetryOperations(ops); // Mirror and 2-fold axis generate inversion, identity is implicit. TS_ASSERT_EQUALS(matrices.size(), 4); @@ -173,12 +156,12 @@ class PointGroupTest : public CxxTest::TestSuite auto matrixVectorBegin = matrices.begin(); auto matrixVectorEnd = matrices.end(); - IntMatrix identityMatrix(3, 3, true); + SymmetryOperation identityOp = SymmetryOperationFactory::Instance().createSymOp("x,y,z"); - TS_ASSERT_DIFFERS(std::find(matrixVectorBegin, matrixVectorEnd, identity->apply(identityMatrix)), matrixVectorEnd); - TS_ASSERT_DIFFERS(std::find(matrixVectorBegin, matrixVectorEnd, inversion->apply(identityMatrix)), matrixVectorEnd); - TS_ASSERT_DIFFERS(std::find(matrixVectorBegin, matrixVectorEnd, mirror->apply(identityMatrix)), matrixVectorEnd); - TS_ASSERT_DIFFERS(std::find(matrixVectorBegin, matrixVectorEnd, twoFold->apply(identityMatrix)), matrixVectorEnd); + TS_ASSERT_DIFFERS(std::find(matrixVectorBegin, matrixVectorEnd, identity * identityOp), matrixVectorEnd); + TS_ASSERT_DIFFERS(std::find(matrixVectorBegin, matrixVectorEnd, inversion * identityOp), matrixVectorEnd); + TS_ASSERT_DIFFERS(std::find(matrixVectorBegin, matrixVectorEnd, mirror * identityOp), matrixVectorEnd); + TS_ASSERT_DIFFERS(std::find(matrixVectorBegin, matrixVectorEnd, twoFold * identityOp), matrixVectorEnd); TS_ASSERT_DIFFERS(matrices[0], matrices[1]); } @@ -223,19 +206,32 @@ class PointGroupTest : public CxxTest::TestSuite TS_ASSERT_EQUALS(pgMap.count(PointGroup::Cubic), 2); } + void testInit() + { + PointGroupLaue13 pg; + + TS_ASSERT_EQUALS(pg.getEquivalents(V3D(1, 2, 3)).size(), 1); + + pg.init(); + + TS_ASSERT_EQUALS(pg.getEquivalents(V3D(1, 2, 3)).size(), 48); + } + private: class TestablePointGroup : public PointGroup { friend class PointGroupTest; public: - TestablePointGroup() : PointGroup() + TestablePointGroup() : PointGroup("") { } ~TestablePointGroup() {} - MOCK_METHOD0(getName, std::string()); - MOCK_METHOD2(isEquivalent, bool(V3D hkl, V3D hkl2)); + MOCK_CONST_METHOD0(getName, std::string()); + MOCK_CONST_METHOD2(isEquivalent, bool(const V3D &hkl, const V3D &hkl2)); MOCK_CONST_METHOD0(crystalSystem, PointGroup::CrystalSystem()); + + void init() { } }; }; diff --git a/Code/Mantid/Framework/Geometry/test/ProductOfCyclicGroupsTest.h b/Code/Mantid/Framework/Geometry/test/ProductOfCyclicGroupsTest.h new file mode 100644 index 000000000000..a4159c15524b --- /dev/null +++ b/Code/Mantid/Framework/Geometry/test/ProductOfCyclicGroupsTest.h @@ -0,0 +1,89 @@ +#ifndef MANTID_GEOMETRY_PRODUCTGROUPTEST_H_ +#define MANTID_GEOMETRY_PRODUCTGROUPTEST_H_ + +#include + +#include "MantidGeometry/Crystal/ProductOfCyclicGroups.h" +#include "MantidGeometry/Crystal/CyclicGroup.h" +#include "MantidGeometry/Crystal/SymmetryOperationFactory.h" + +using namespace Mantid::Geometry; + +class ProductOfCyclicGroupsTest : 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 ProductOfCyclicGroupsTest *createSuite() { return new ProductOfCyclicGroupsTest(); } + static void destroySuite( ProductOfCyclicGroupsTest *suite ) { delete suite; } + + + void testStringConstructor() + { + TS_ASSERT_THROWS_NOTHING(ProductOfCyclicGroups group("x,y,z")); + + TS_ASSERT_THROWS_ANYTHING(ProductOfCyclicGroups group("x,y,z; doesnt work")); + TS_ASSERT_THROWS_ANYTHING(ProductOfCyclicGroups group("x,y,z| z,x,y")); + } + + void testVectorConstructor() + { + std::vector groups; + groups.push_back(GroupFactory::create("-x,-y,-z")); + groups.push_back(GroupFactory::create("x,-y,z")); + + TS_ASSERT_THROWS_NOTHING(ProductOfCyclicGroups group(groups)); + + Group_const_sptr null; + groups.push_back(null); + + TS_ASSERT_THROWS_ANYTHING(ProductOfCyclicGroups group(groups)); + } + + void testGetGeneratedGroup() + { + TestableProductOfCyclicGroups group; + + Group_const_sptr generatedGroup = group.getGeneratedGroup("-x,-y,-z; x,-y,z"); + + // Inversion generates 1, -1; Mirror 1, m [010] -> results in 1, -1, m [010], 2 [010] + TS_ASSERT_EQUALS(generatedGroup->order(), 4); + } + + void testGetFactorGroups() + { + TestableProductOfCyclicGroups group; + + std::vector symmetryOperations = SymmetryOperationFactory::Instance().createSymOps("-x,-y,-z; x,-y,z"); + std::vector generatedGroup = group.getFactorGroups(symmetryOperations); + // one group for each symmetry operation + TS_ASSERT_EQUALS(generatedGroup.size(), 2); + } + + void testGetProductOfCyclicGroups() + { + TestableProductOfCyclicGroups group; + + std::vector groups; + groups.push_back(GroupFactory::create("-x,-y,-z")); + groups.push_back(GroupFactory::create("x,-y,z")); + + Group_const_sptr productGroup = group.getProductOfCyclicGroups(groups); + + TS_ASSERT_EQUALS(productGroup->order(), 4); + } + +private: + class TestableProductOfCyclicGroups : public ProductOfCyclicGroups + { + friend class ProductOfCyclicGroupsTest; + public: + TestableProductOfCyclicGroups() : + ProductOfCyclicGroups("x,y,z") { } + ~TestableProductOfCyclicGroups() { } + }; + +}; + + +#endif /* MANTID_GEOMETRY_PRODUCTGROUPTEST_H_ */ diff --git a/Code/Mantid/Framework/Geometry/test/SpaceGroupFactoryTest.h b/Code/Mantid/Framework/Geometry/test/SpaceGroupFactoryTest.h new file mode 100644 index 000000000000..5803c6dfd543 --- /dev/null +++ b/Code/Mantid/Framework/Geometry/test/SpaceGroupFactoryTest.h @@ -0,0 +1,181 @@ +#ifndef MANTID_GEOMETRY_SPACEGROUPFACTORYTEST_H_ +#define MANTID_GEOMETRY_SPACEGROUPFACTORYTEST_H_ + +#include + +#include "MantidGeometry/Crystal/SpaceGroupFactory.h" + +using namespace Mantid::Geometry; +using Mantid::Kernel::V3D; + +class SpaceGroupFactoryTest : 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 SpaceGroupFactoryTest *createSuite() { return new SpaceGroupFactoryTest(); } + static void destroySuite( SpaceGroupFactoryTest *suite ) { delete suite; } + + void testInstance() + { + TS_ASSERT_THROWS_NOTHING(SpaceGroupFactory::Instance()); + } + + void testSubscribeGeneratedSpaceGroup() + { + TestableSpaceGroupFactory factory; + + TS_ASSERT(!factory.isSubscribed(2)); + TS_ASSERT(!factory.isSubscribed("P-1")); + + TS_ASSERT_THROWS_NOTHING(factory.subscribeGeneratedSpaceGroup(2, "P-1", "-x,-y,-z")); + + TS_ASSERT(factory.isSubscribed(2)); + TS_ASSERT(factory.isSubscribed("P-1")); + + // subscribing twice does not work + TS_ASSERT_THROWS(factory.subscribeGeneratedSpaceGroup(2, "P-1", "-x,-y,-z"), std::invalid_argument); + + + // but having a different symbol for the same number is ok. + TS_ASSERT_THROWS_NOTHING(factory.subscribeGeneratedSpaceGroup(2, "F-1", "-x,-y,-z")) + + // neither does with a tabulated space group + TS_ASSERT_THROWS(factory.subscribeTabulatedSpaceGroup(2, "P-1", "x,y,z; -x,-y,-z"), std::invalid_argument); + + // Different number with same symbol - does not work + TS_ASSERT_THROWS(factory.subscribeGeneratedSpaceGroup(3, "P-1", "-x,-y,-z"), std::invalid_argument); + + // invalid generators are caught before anything is done + TS_ASSERT_THROWS_ANYTHING(factory.subscribeGeneratedSpaceGroup(4, "Fake", "invalid")); + + TS_ASSERT(!factory.isSubscribed(4)); + TS_ASSERT(!factory.isSubscribed("Fake")); + } + + void testSubscribeTabulatedSpaceGroup() + { + TestableSpaceGroupFactory factory; + + TS_ASSERT(!factory.isSubscribed(2)); + TS_ASSERT(!factory.isSubscribed("P-1")); + + TS_ASSERT_THROWS_NOTHING(factory.subscribeTabulatedSpaceGroup(2, "P-1", "x,y,z; -x,-y,-z")); + + TS_ASSERT(factory.isSubscribed(2)); + TS_ASSERT(factory.isSubscribed("P-1")); + + // subscribing twice does not work + TS_ASSERT_THROWS(factory.subscribeTabulatedSpaceGroup(2, "P-1", "x,y,z; -x,-y,-z"), std::invalid_argument); + + // but having a different symbol for the same number is ok. + TS_ASSERT_THROWS_NOTHING(factory.subscribeTabulatedSpaceGroup(2, "F-1", "x,y,z; -x,-y,-z")) + + // neither does with a generated space group + TS_ASSERT_THROWS(factory.subscribeGeneratedSpaceGroup(2, "P-1", "-x,-y,-z"), std::invalid_argument); + + // Different number with same symbol - does not work + TS_ASSERT_THROWS(factory.subscribeTabulatedSpaceGroup(3, "P-1", "-x,-y,-z"), std::invalid_argument); + + // invalid generators are caught before anything is done + TS_ASSERT_THROWS_ANYTHING(factory.subscribeTabulatedSpaceGroup(4, "Fake", "invalid")); + + TS_ASSERT(!factory.isSubscribed(4)); + TS_ASSERT(!factory.isSubscribed("Fake")); + } + + void testIsSubscribed() + { + TestableSpaceGroupFactory factory; + + TS_ASSERT(!factory.isSubscribed(1)); + + TS_ASSERT(!factory.isSubscribed(2)); + TS_ASSERT(!factory.isSubscribed("P-1")); + + TS_ASSERT_THROWS_NOTHING(factory.subscribeTabulatedSpaceGroup(2, "P-1", "x,y,z; -x,-y,-z")); + + TS_ASSERT(factory.isSubscribed(2)); + TS_ASSERT(factory.isSubscribed("P-1")); + + TS_ASSERT(!factory.isSubscribed(1)); + } + + void testSubscribedSpaceGroupSymbols() + { + TestableSpaceGroupFactory factory; + + TS_ASSERT(factory.subscribedSpaceGroupSymbols().empty()); + + TS_ASSERT_THROWS_NOTHING(factory.subscribeTabulatedSpaceGroup(2, "P-1", "x,y,z; -x,-y,-z")); + + std::vector symbols = factory.subscribedSpaceGroupSymbols(); + TS_ASSERT_EQUALS(symbols.size(), 1); + TS_ASSERT_DIFFERS(std::find(symbols.begin(), symbols.end(), "P-1"), symbols.end()); + + TS_ASSERT_THROWS_NOTHING(factory.subscribeTabulatedSpaceGroup(1, "P1", "x,y,z")); + symbols = factory.subscribedSpaceGroupSymbols(); + TS_ASSERT_EQUALS(symbols.size(), 2); + TS_ASSERT_DIFFERS(std::find(symbols.begin(), symbols.end(), "P1"), symbols.end()); + } + + void testSubscribedSpaceGroupNumbers() + { + TestableSpaceGroupFactory factory; + + TS_ASSERT(factory.subscribedSpaceGroupNumbers().empty()); + + TS_ASSERT_THROWS_NOTHING(factory.subscribeTabulatedSpaceGroup(2, "P-1", "x,y,z; -x,-y,-z")); + + std::vector numbers = factory.subscribedSpaceGroupNumbers(); + TS_ASSERT_EQUALS(numbers.size(), 1); + TS_ASSERT_DIFFERS(std::find(numbers.begin(), numbers.end(), 2), numbers.end()); + + TS_ASSERT_THROWS_NOTHING(factory.subscribeTabulatedSpaceGroup(1, "P1", "x,y,z")); + numbers = factory.subscribedSpaceGroupNumbers(); + TS_ASSERT_EQUALS(numbers.size(), 2); + TS_ASSERT_DIFFERS(std::find(numbers.begin(), numbers.end(), 1), numbers.end()); + + // Subscribing the same number twice should not influence vector size + TS_ASSERT_THROWS_NOTHING(factory.subscribeTabulatedSpaceGroup(1, "F1", "x,y,z")); + numbers = factory.subscribedSpaceGroupNumbers(); + TS_ASSERT_EQUALS(numbers.size(), 2); + } + + void testSubscribedSpaceGroupSymbolsForNumber() + { + TestableSpaceGroupFactory factory; + factory.subscribeTabulatedSpaceGroup(2, "P-1", "x,y,z; -x,-y,-z"); + factory.subscribeTabulatedSpaceGroup(2, "F-1", "x,y,z; -x,-y,-z"); + factory.subscribeTabulatedSpaceGroup(1, "P1", "x,y,z"); + + std::vector symbols = factory.subscribedSpaceGroupSymbols(1); + TS_ASSERT_EQUALS(symbols.size(), 1); + + symbols = factory.subscribedSpaceGroupSymbols(2); + TS_ASSERT_EQUALS(symbols.size(), 2); + } + + void testUnsubscribeSymbol() + { + TestableSpaceGroupFactory factory; + + TS_ASSERT_THROWS(factory.unsubscribeSpaceGroup("P-1"), std::invalid_argument); + + TS_ASSERT_THROWS_NOTHING(factory.subscribeTabulatedSpaceGroup(2, "P-1", "x,y,z; -x,-y,-z")); + TS_ASSERT_THROWS_NOTHING(factory.unsubscribeSpaceGroup("P-1")); + } + +private: + class TestableSpaceGroupFactory : public SpaceGroupFactoryImpl + { + friend class SpaceGroupFactoryTest; + public: + TestableSpaceGroupFactory() : SpaceGroupFactoryImpl() { } + ~TestableSpaceGroupFactory() { } + }; + +}; + + +#endif /* MANTID_GEOMETRY_SPACEGROUPFACTORYTEST_H_ */ diff --git a/Code/Mantid/Framework/Geometry/test/SpaceGroupTest.h b/Code/Mantid/Framework/Geometry/test/SpaceGroupTest.h new file mode 100644 index 000000000000..92aabd1b36c9 --- /dev/null +++ b/Code/Mantid/Framework/Geometry/test/SpaceGroupTest.h @@ -0,0 +1,77 @@ +#ifndef MANTID_GEOMETRY_SPACEGROUPTEST_H_ +#define MANTID_GEOMETRY_SPACEGROUPTEST_H_ + +#include + +#include "MantidGeometry/Crystal/SpaceGroup.h" +#include "MantidGeometry/Crystal/SymmetryOperationFactory.h" +#include "MantidGeometry/Crystal/CyclicGroup.h" +#include "MantidKernel/V3D.h" + +using namespace Mantid::Geometry; +using Mantid::Kernel::V3D; + +class SpaceGroupTest : 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 SpaceGroupTest *createSuite() { return new SpaceGroupTest(); } + static void destroySuite( SpaceGroupTest *suite ) { delete suite; } + + + void testConstruction() + { + Group_const_sptr inversion = GroupFactory::create("-x,-y,-z"); + SpaceGroup p1bar(2, "P-1", *inversion); + + TS_ASSERT_EQUALS(p1bar.number(), 2); + TS_ASSERT_EQUALS(p1bar.hmSymbol(), "P-1"); + TS_ASSERT_EQUALS(p1bar.order(), 2); + TS_ASSERT_EQUALS(p1bar.getSymmetryOperations().size(), 2); + } + + void testNumber() + { + TestableSpaceGroup empty; + TS_ASSERT_EQUALS(empty.number(), 0); + + empty.m_number = 2; + TS_ASSERT_EQUALS(empty.number(), 2); + } + + void testSymbol() + { + TestableSpaceGroup empty; + TS_ASSERT_EQUALS(empty.hmSymbol(), ""); + + empty.m_hmSymbol = "Test"; + TS_ASSERT_EQUALS(empty.hmSymbol(), "Test"); + } + + void testAssignmentOperator() + { + Group_const_sptr inversion = GroupFactory::create("-x,-y,-z"); + SpaceGroup p1bar(2, "P-1", *inversion); + + SpaceGroup other = p1bar; + + TS_ASSERT_EQUALS(other.number(), p1bar.number()); + TS_ASSERT_EQUALS(other.hmSymbol(), p1bar.hmSymbol()); + TS_ASSERT_EQUALS(other.order(), p1bar.order()); + } + +private: + class TestableSpaceGroup : public SpaceGroup { + friend class SpaceGroupTest; + public: + TestableSpaceGroup() : + SpaceGroup(0, "", Group()) + { } + + ~TestableSpaceGroup() { } + }; +}; + + +#endif /* MANTID_GEOMETRY_SPACEGROUPTEST_H_ */ diff --git a/Code/Mantid/Framework/Geometry/test/SymmetryOperationFactoryTest.h b/Code/Mantid/Framework/Geometry/test/SymmetryOperationFactoryTest.h new file mode 100644 index 000000000000..50db96be1f8b --- /dev/null +++ b/Code/Mantid/Framework/Geometry/test/SymmetryOperationFactoryTest.h @@ -0,0 +1,135 @@ +#ifndef MANTID_GEOMETRY_SYMMETRYOPERATIONFACTORYTEST_H_ +#define MANTID_GEOMETRY_SYMMETRYOPERATIONFACTORYTEST_H_ + +#include + +#include "MantidGeometry/Crystal/SymmetryOperationFactory.h" +#include "MantidKernel/Matrix.h" +#include "MantidKernel/Exception.h" + +#include + +using namespace Mantid::Geometry; +using namespace Mantid::Kernel; + + +class SymmetryOperationFactoryTest : 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 SymmetryOperationFactoryTest *createSuite() { return new SymmetryOperationFactoryTest(); } + static void destroySuite( SymmetryOperationFactoryTest *suite ) { delete suite; } + + SymmetryOperationFactoryTest() + { + SymmetryOperationFactory::Instance().subscribeSymOp("x,y,z"); + } + + ~SymmetryOperationFactoryTest() + { + SymmetryOperationFactory::Instance().unsubscribeSymOp("x,y,z"); + } + + + void testCreateSymOp() + { + TS_ASSERT_THROWS_NOTHING(SymmetryOperationFactory::Instance().createSymOp("x,y,z")); + TS_ASSERT_THROWS(SymmetryOperationFactory::Instance().createSymOp("fake2"), Mantid::Kernel::Exception::ParseError); + + // createSymOp also works when an operation is not subscribed + TS_ASSERT_THROWS_NOTHING(SymmetryOperationFactory::Instance().unsubscribeSymOp("x,y,z")); + TS_ASSERT_EQUALS(SymmetryOperationFactory::Instance().isSubscribed("x,y,z"), false); + + TS_ASSERT_THROWS_NOTHING(SymmetryOperationFactory::Instance().createSymOp("x,y,z")); + + // it's automatically registered + TS_ASSERT_EQUALS(SymmetryOperationFactory::Instance().isSubscribed("x,y,z"), true); + } + + void testCreateSymOpsVector() + { + std::vector opStrings; + opStrings.push_back("x,y,z"); + + std::vector symOps = SymmetryOperationFactory::Instance().createSymOps(opStrings); + TS_ASSERT_EQUALS(symOps.size(), 1); + TS_ASSERT_EQUALS(symOps.front().identifier(), "x,y,z"); + + // Add another one + opStrings.push_back("-x,-y,-z"); + + TS_ASSERT_THROWS_NOTHING(symOps = SymmetryOperationFactory::Instance().createSymOps(opStrings)); + TS_ASSERT_EQUALS(symOps.size(), 2); + TS_ASSERT_EQUALS(symOps.front().identifier(), "x,y,z"); + TS_ASSERT_EQUALS(symOps.back().identifier(), "-x,-y,-z"); + + opStrings.push_back("doesNotWork"); + TS_ASSERT_THROWS(symOps = SymmetryOperationFactory::Instance().createSymOps(opStrings), Mantid::Kernel::Exception::ParseError); + } + + void testCreateSymOpsString() + { + std::string validOne("-x,-y,-z"); + std::string validTwo("-x,-y,-z; x+1/2,y+1/2,z+1/2"); + std::string validThree("-x,-y,-z; x+1/2,y+1/2,z+1/2; x,-y,z"); + + TS_ASSERT_THROWS_NOTHING(SymmetryOperationFactory::Instance().createSymOps(validOne)); + TS_ASSERT_THROWS_NOTHING(SymmetryOperationFactory::Instance().createSymOps(validTwo)); + TS_ASSERT_THROWS_NOTHING(SymmetryOperationFactory::Instance().createSymOps(validThree)); + + std::string invalidSep("-x,-y,-z | x+1/2,y+1/2,z+1/2"); + std::string invalidOne("-x,-y,-z; invalid"); + + TS_ASSERT_THROWS(SymmetryOperationFactory::Instance().createSymOps(invalidSep), Mantid::Kernel::Exception::ParseError); + TS_ASSERT_THROWS(SymmetryOperationFactory::Instance().createSymOps(invalidOne), Mantid::Kernel::Exception::ParseError); + } + + void testUnsubscribe() + { + TS_ASSERT_EQUALS(SymmetryOperationFactory::Instance().isSubscribed("x,y,z"), true); + + TS_ASSERT_THROWS_NOTHING(SymmetryOperationFactory::Instance().unsubscribeSymOp("x,y,z")); + TS_ASSERT_EQUALS(SymmetryOperationFactory::Instance().isSubscribed("x,y,z"), false); + + TS_ASSERT_THROWS_NOTHING(SymmetryOperationFactory::Instance().subscribeSymOp("x,y,z")); + } + + void testIsSubscribed() + { + TS_ASSERT_THROWS_NOTHING(SymmetryOperationFactory::Instance().unsubscribeSymOp("x,y,z")); + TS_ASSERT_EQUALS(SymmetryOperationFactory::Instance().isSubscribed("x,y,z"), false); + TS_ASSERT_THROWS_NOTHING(SymmetryOperationFactory::Instance().subscribeSymOp("x,y,z")); + TS_ASSERT_EQUALS(SymmetryOperationFactory::Instance().isSubscribed("x,y,z"), true); + } + + void testSubscribedSymbols() + { + // Clear factory + std::vector allSymbols = SymmetryOperationFactory::Instance().subscribedSymbols(); + for(auto it = allSymbols.begin(); it != allSymbols.end(); ++it) { + SymmetryOperationFactory::Instance().unsubscribeSymOp(*it); + } + + // Subscribe two symmetry operations + SymmetryOperationFactory::Instance().subscribeSymOp("x,y,z"); + SymmetryOperationFactory::Instance().subscribeSymOp("-x,-y,-z"); + + std::vector symbols = SymmetryOperationFactory::Instance().subscribedSymbols(); + + TS_ASSERT_EQUALS(symbols.size(), 2); + TS_ASSERT_DIFFERS(std::find(symbols.begin(), symbols.end(), "x,y,z"), symbols.end()); + TS_ASSERT_DIFFERS(std::find(symbols.begin(), symbols.end(), "-x,-y,-z"), symbols.end()); + + SymmetryOperationFactory::Instance().unsubscribeSymOp("x,y,z"); + SymmetryOperationFactory::Instance().unsubscribeSymOp("-x,-y,-z"); + + // Restore factory + for(auto it = allSymbols.begin(); it != allSymbols.end(); ++it) { + SymmetryOperationFactory::Instance().subscribeSymOp(*it); + } + } +}; + + +#endif /* MANTID_GEOMETRY_SYMMETRYOPERATIONFACTORYTEST_H_ */ diff --git a/Code/Mantid/Framework/Geometry/test/SymmetryOperationSymbolParserTest.h b/Code/Mantid/Framework/Geometry/test/SymmetryOperationSymbolParserTest.h new file mode 100644 index 000000000000..0ffea012f147 --- /dev/null +++ b/Code/Mantid/Framework/Geometry/test/SymmetryOperationSymbolParserTest.h @@ -0,0 +1,252 @@ +#ifndef MANTID_GEOMETRY_SYMMETRYOPERATIONSYMBOLPARSERTEST_H_ +#define MANTID_GEOMETRY_SYMMETRYOPERATIONSYMBOLPARSERTEST_H_ + +#include +#include + +#include "MantidGeometry/Crystal/SymmetryOperationSymbolParser.h" + +using Mantid::Geometry::SymmetryOperationSymbolParser; +using namespace Mantid::Geometry; + +class SymmetryOperationSymbolParserTest : 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 SymmetryOperationSymbolParserTest *createSuite() { return new SymmetryOperationSymbolParserTest(); } + static void destroySuite( SymmetryOperationSymbolParserTest *suite ) { delete suite; } + + void testGetFactorForSign() + { + TS_ASSERT_EQUALS(TestableSymmetryOperationSymbolParser::getFactorForSign('-'), -1); + TS_ASSERT_EQUALS(TestableSymmetryOperationSymbolParser::getFactorForSign('+'), 1); + TS_ASSERT_THROWS(TestableSymmetryOperationSymbolParser::getFactorForSign('f'), std::runtime_error); + TS_ASSERT_THROWS(TestableSymmetryOperationSymbolParser::getFactorForSign('t'), std::runtime_error); + TS_ASSERT_THROWS(TestableSymmetryOperationSymbolParser::getFactorForSign('1'), std::runtime_error); + } + + void testGetVectorForSymbol() + { + std::vector x; + TS_ASSERT_THROWS_NOTHING(x = TestableSymmetryOperationSymbolParser::getVectorForSymbol('x')); + TS_ASSERT_EQUALS(x.size(), 3); + TS_ASSERT_EQUALS(x[0], 1); + TS_ASSERT_EQUALS(x[1], 0); + TS_ASSERT_EQUALS(x[2], 0); + + std::vector y; + TS_ASSERT_THROWS_NOTHING(y = TestableSymmetryOperationSymbolParser::getVectorForSymbol('y')); + TS_ASSERT_EQUALS(y.size(), 3); + TS_ASSERT_EQUALS(y[0], 0); + TS_ASSERT_EQUALS(y[1], 1); + TS_ASSERT_EQUALS(y[2], 0); + + std::vector z; + TS_ASSERT_THROWS_NOTHING(z = TestableSymmetryOperationSymbolParser::getVectorForSymbol('z')); + TS_ASSERT_EQUALS(z.size(), 3); + TS_ASSERT_EQUALS(z[0], 0); + TS_ASSERT_EQUALS(z[1], 0); + TS_ASSERT_EQUALS(z[2], 1); + + std::vector yMinus; + TS_ASSERT_THROWS_NOTHING(yMinus = TestableSymmetryOperationSymbolParser::getVectorForSymbol('y', '-')); + TS_ASSERT_EQUALS(yMinus.size(), 3); + TS_ASSERT_EQUALS(yMinus[0], 0); + TS_ASSERT_EQUALS(yMinus[1], -1); + TS_ASSERT_EQUALS(yMinus[2], 0); + + TS_ASSERT_THROWS(TestableSymmetryOperationSymbolParser::getVectorForSymbol('t'), std::runtime_error); + TS_ASSERT_THROWS(TestableSymmetryOperationSymbolParser::getVectorForSymbol('1'), std::runtime_error); + TS_ASSERT_THROWS(TestableSymmetryOperationSymbolParser::getVectorForSymbol('+'), std::runtime_error); + } + + void testAddToVector() + { + std::vector one(3, 1); + std::vector two(3, 2); + std::vector wrongSize(1, 3); + + TS_ASSERT_THROWS_NOTHING(TestableSymmetryOperationSymbolParser::addToVector(one, two)); + + TS_ASSERT_EQUALS(one[0], 3); + TS_ASSERT_EQUALS(one[1], 3); + TS_ASSERT_EQUALS(one[2], 3); + + TS_ASSERT_THROWS(TestableSymmetryOperationSymbolParser::addToVector(one, wrongSize), std::runtime_error); + } + + void testProcessMatrixRowToken() + { + std::vector matrixRow(3, 0); + TS_ASSERT_THROWS_NOTHING(TestableSymmetryOperationSymbolParser::processMatrixRowToken("+x", matrixRow)); + + TS_ASSERT_EQUALS(matrixRow[0], 1); + TS_ASSERT_EQUALS(matrixRow[1], 0); + TS_ASSERT_EQUALS(matrixRow[2], 0); + + TS_ASSERT_THROWS_NOTHING(TestableSymmetryOperationSymbolParser::processMatrixRowToken("+y", matrixRow)); + + TS_ASSERT_EQUALS(matrixRow[0], 1); + TS_ASSERT_EQUALS(matrixRow[1], 1); + TS_ASSERT_EQUALS(matrixRow[2], 0); + + TS_ASSERT_THROWS_NOTHING(TestableSymmetryOperationSymbolParser::processMatrixRowToken("-y", matrixRow)); + + TS_ASSERT_EQUALS(matrixRow[0], 1); + TS_ASSERT_EQUALS(matrixRow[1], 0); + TS_ASSERT_EQUALS(matrixRow[2], 0); + + TS_ASSERT_THROWS_NOTHING(TestableSymmetryOperationSymbolParser::processMatrixRowToken("-z", matrixRow)); + + TS_ASSERT_EQUALS(matrixRow[0], 1); + TS_ASSERT_EQUALS(matrixRow[1], 0); + TS_ASSERT_EQUALS(matrixRow[2], -1); + + TS_ASSERT_THROWS_NOTHING(TestableSymmetryOperationSymbolParser::processMatrixRowToken("z", matrixRow)); + + TS_ASSERT_EQUALS(matrixRow[0], 1); + TS_ASSERT_EQUALS(matrixRow[1], 0); + TS_ASSERT_EQUALS(matrixRow[2], 0); + + TS_ASSERT_THROWS(TestableSymmetryOperationSymbolParser::processMatrixRowToken("g", matrixRow), std::runtime_error); + TS_ASSERT_THROWS(TestableSymmetryOperationSymbolParser::processMatrixRowToken("", matrixRow), std::runtime_error); + TS_ASSERT_THROWS(TestableSymmetryOperationSymbolParser::processMatrixRowToken("+-g", matrixRow), std::runtime_error); + TS_ASSERT_THROWS(TestableSymmetryOperationSymbolParser::processMatrixRowToken("-+", matrixRow), std::runtime_error); + TS_ASSERT_THROWS(TestableSymmetryOperationSymbolParser::processMatrixRowToken("xx", matrixRow), std::runtime_error); + } + + void testProcessVectorComponentToken() + { + RationalNumber num; + + TS_ASSERT_THROWS_NOTHING(TestableSymmetryOperationSymbolParser::processVectorComponentToken("+1/4", num) ); + TS_ASSERT_EQUALS(num, RationalNumber(1, 4)); + + TS_ASSERT_THROWS_NOTHING(TestableSymmetryOperationSymbolParser::processVectorComponentToken("+1/2", num) ); + TS_ASSERT_EQUALS(num, RationalNumber(3, 4)); + + TS_ASSERT_THROWS_NOTHING(TestableSymmetryOperationSymbolParser::processVectorComponentToken("-10/20", num) ); + TS_ASSERT_EQUALS(num, RationalNumber(1, 4)); + + TS_ASSERT_THROWS_NOTHING(TestableSymmetryOperationSymbolParser::processVectorComponentToken("-1/4", num) ); + TS_ASSERT_EQUALS(num, 0); + + TS_ASSERT_THROWS_NOTHING(TestableSymmetryOperationSymbolParser::processVectorComponentToken("12", num) ); + TS_ASSERT_EQUALS(num, 12); + + TS_ASSERT_THROWS_NOTHING(TestableSymmetryOperationSymbolParser::processVectorComponentToken("-12", num) ); + TS_ASSERT_EQUALS(num, 0); + + TS_ASSERT_THROWS(TestableSymmetryOperationSymbolParser::processVectorComponentToken("1/2/3", num), std::runtime_error); + TS_ASSERT_THROWS(TestableSymmetryOperationSymbolParser::processVectorComponentToken("/2/3", num), std::runtime_error); + TS_ASSERT_THROWS(TestableSymmetryOperationSymbolParser::processVectorComponentToken("-/2/3", num), std::runtime_error); + + TS_ASSERT_THROWS(TestableSymmetryOperationSymbolParser::processVectorComponentToken("", num), boost::bad_lexical_cast); + TS_ASSERT_THROWS(TestableSymmetryOperationSymbolParser::processVectorComponentToken("g/d", num), boost::bad_lexical_cast); + TS_ASSERT_THROWS(TestableSymmetryOperationSymbolParser::processVectorComponentToken("--2", num), boost::bad_lexical_cast); + TS_ASSERT_THROWS(TestableSymmetryOperationSymbolParser::processVectorComponentToken("+3e", num), boost::bad_lexical_cast); + TS_ASSERT_THROWS(TestableSymmetryOperationSymbolParser::processVectorComponentToken("1/f", num), boost::bad_lexical_cast); + } + + void testParseComponent() + { + std::pair, RationalNumber> result; + TS_ASSERT_THROWS_NOTHING(result = TestableSymmetryOperationSymbolParser::parseComponent("x+1/4")); + TS_ASSERT_EQUALS(result.first[0], 1); + TS_ASSERT_EQUALS(result.first[1], 0); + TS_ASSERT_EQUALS(result.first[2], 0); + TS_ASSERT_EQUALS(result.second, RationalNumber(1, 4)); + + TS_ASSERT_THROWS_NOTHING(result = TestableSymmetryOperationSymbolParser::parseComponent("x+y-1/4")); + TS_ASSERT_EQUALS(result.first[0], 1); + TS_ASSERT_EQUALS(result.first[1], 1); + TS_ASSERT_EQUALS(result.first[2], 0); + TS_ASSERT_EQUALS(result.second, RationalNumber(-1, 4)); + + TS_ASSERT_THROWS_NOTHING(result = TestableSymmetryOperationSymbolParser::parseComponent("1/4-x")); + TS_ASSERT_EQUALS(result.first[0], -1); + TS_ASSERT_EQUALS(result.first[1], 0); + TS_ASSERT_EQUALS(result.first[2], 0); + TS_ASSERT_EQUALS(result.second, RationalNumber(1, 4)); + + TS_ASSERT_THROWS_NOTHING(result = TestableSymmetryOperationSymbolParser::parseComponent("-x+z-1/4")); + TS_ASSERT_EQUALS(result.first[0], -1); + TS_ASSERT_EQUALS(result.first[1], 0); + TS_ASSERT_EQUALS(result.first[2], 1); + TS_ASSERT_EQUALS(result.second, RationalNumber(-1, 4)); + + TS_ASSERT_THROWS(result = TestableSymmetryOperationSymbolParser::parseComponent("x+x+1/4"), std::runtime_error); + TS_ASSERT_THROWS(result = TestableSymmetryOperationSymbolParser::parseComponent("--1/4"), std::runtime_error); + TS_ASSERT_THROWS(result = TestableSymmetryOperationSymbolParser::parseComponent("-s/4"), std::runtime_error); + TS_ASSERT_THROWS(result = TestableSymmetryOperationSymbolParser::parseComponent("argwertq"), std::runtime_error); + TS_ASSERT_THROWS(result = TestableSymmetryOperationSymbolParser::parseComponent("x/4+z"), std::runtime_error); + } + + void testGetCleanComponentString() + { + TestableSymmetryOperationSymbolParser symOpParser; + + TS_ASSERT_EQUALS(TestableSymmetryOperationSymbolParser::getCleanComponentString("x + 1/2"), "x+1/2"); + TS_ASSERT_EQUALS(TestableSymmetryOperationSymbolParser::getCleanComponentString(" x + 1/2 "), "x+1/2"); + TS_ASSERT_EQUALS(TestableSymmetryOperationSymbolParser::getCleanComponentString(" x + 1 / 2 "), "x+1/2"); + } + + void testParseComponents() + { + std::vector components; + components.push_back("x+z"); + components.push_back("1/4-x"); + components.push_back("y"); + + std::pair parsed; + TS_ASSERT_THROWS_NOTHING(parsed = TestableSymmetryOperationSymbolParser::parseComponents(components)); + + TS_ASSERT_EQUALS(parsed.first[0][0], 1); + TS_ASSERT_EQUALS(parsed.first[0][1], 0); + TS_ASSERT_EQUALS(parsed.first[0][2], 1); + + TS_ASSERT_EQUALS(parsed.first[1][0], -1); + TS_ASSERT_EQUALS(parsed.first[1][1], 0); + TS_ASSERT_EQUALS(parsed.first[1][2], 0); + + TS_ASSERT_EQUALS(parsed.first[2][0], 0); + TS_ASSERT_EQUALS(parsed.first[2][1], 1); + TS_ASSERT_EQUALS(parsed.first[2][2], 0); + + TS_ASSERT_EQUALS(parsed.second, V3R(0, RationalNumber(1, 4), 0)); + } + + void testParseIdentifier() + { + TS_ASSERT_THROWS_NOTHING(TestableSymmetryOperationSymbolParser::parseIdentifier("x, y, z")); + TS_ASSERT_THROWS_NOTHING(TestableSymmetryOperationSymbolParser::parseIdentifier("x, -y, -z")); + TS_ASSERT_THROWS_NOTHING(TestableSymmetryOperationSymbolParser::parseIdentifier("-x, y, z")); + TS_ASSERT_THROWS_NOTHING(TestableSymmetryOperationSymbolParser::parseIdentifier("1/4 - x, 1/2+y, z-x")); + + TS_ASSERT_THROWS(TestableSymmetryOperationSymbolParser::parseIdentifier("1/4, x, -z-x"), std::runtime_error); + TS_ASSERT_THROWS(TestableSymmetryOperationSymbolParser::parseIdentifier("x, -z-x"), std::runtime_error); + TS_ASSERT_THROWS(TestableSymmetryOperationSymbolParser::parseIdentifier("y, x, -z-x, z"), std::runtime_error); + } + + void testGetNormalizedIdentifier() + { + std::pair param1 = SymmetryOperationSymbolParser::parseIdentifier("x+1/2, y, -z-1/2"); + TS_ASSERT_EQUALS(SymmetryOperationSymbolParser::getNormalizedIdentifier(param1), "x+1/2,y,-z-1/2"); + + std::pair param2 = TestableSymmetryOperationSymbolParser::parseIdentifier("1/2+x, y, -1/2-z"); + TS_ASSERT_EQUALS(SymmetryOperationSymbolParser::getNormalizedIdentifier(param2), "x+1/2,y,-z-1/2"); + } + +private: + class TestableSymmetryOperationSymbolParser : SymmetryOperationSymbolParser + { + friend class SymmetryOperationSymbolParserTest; + public: + TestableSymmetryOperationSymbolParser() : SymmetryOperationSymbolParser() { } + ~TestableSymmetryOperationSymbolParser() { } + }; +}; + + +#endif /* MANTID_GEOMETRY_SYMMETRYOPERATIONSYMBOLPARSERTEST_H_ */ diff --git a/Code/Mantid/Framework/Geometry/test/SymmetryOperationTest.h b/Code/Mantid/Framework/Geometry/test/SymmetryOperationTest.h index 41a9bbe58583..9a8bacfa36ea 100644 --- a/Code/Mantid/Framework/Geometry/test/SymmetryOperationTest.h +++ b/Code/Mantid/Framework/Geometry/test/SymmetryOperationTest.h @@ -4,9 +4,10 @@ #include #include "MantidGeometry/Crystal/SymmetryOperation.h" +#include "MantidGeometry/Crystal/SymmetryOperationSymbolParser.h" + #include "MantidKernel/V3D.h" -#include #include #include @@ -20,7 +21,7 @@ class TestableSymmetryOperation : SymmetryOperation friend class SymmetryOperationTest; public: TestableSymmetryOperation() : - SymmetryOperation(0, IntMatrix(3, 3, false), "0") + SymmetryOperation() { } }; @@ -38,8 +39,7 @@ class SymmetryOperationTest : public CxxTest::TestSuite m_hhl(m_h, m_h, m_l), m_hk0(m_h, m_k, 0.0), m_h00(m_h, 0.0, 0.0), - m_allHkl(), - m_identifierRegex("^-?((1)|((2|3|4|6|m) \\[(-?\\d{1}){3}\\]h?))$") + m_allHkl() { m_allHkl.push_back(m_hkl); m_allHkl.push_back(m_hhl); @@ -47,261 +47,307 @@ class SymmetryOperationTest : public CxxTest::TestSuite m_allHkl.push_back(m_h00); } - void testAssignMatrixFromArray() + void testDefaultConstructor() + { + SymmetryOperation symOp; + TS_ASSERT(symOp.isIdentity()); + TS_ASSERT(!symOp.hasTranslation()) + TS_ASSERT_EQUALS(symOp.order(), 1); + TS_ASSERT_EQUALS(symOp.identifier(), "x,y,z"); + + V3D hkl(1, 1, 1); + TS_ASSERT_EQUALS(symOp * hkl, hkl); + } + + void testStringConstructor() { - TestableSymmetryOperation emptyOp; + SymmetryOperation inversion("-x,-y,-z"); - TS_ASSERT_DIFFERS(emptyOp.m_matrix, IntMatrix(3, 3, true)); + TS_ASSERT(!inversion.isIdentity()); + TS_ASSERT(!inversion.hasTranslation()); + TS_ASSERT_EQUALS(inversion.order(), 2); + TS_ASSERT_EQUALS(inversion.identifier(), "-x,-y,-z"); - int identity[] = {1, 0, 0, - 0, 1, 0, - 0, 0, 1}; + V3D hkl(1, 1, 1); + TS_ASSERT_EQUALS(inversion * hkl, hkl * -1.0); - emptyOp.setMatrixFromArray(identity); + // translational components are wrapped to the unit cell + SymmetryOperation screw21z("-x,-y,z+3/2"); + TS_ASSERT_EQUALS(screw21z.identifier(), "-x,-y,z+1/2"); + } - TS_ASSERT_EQUALS(emptyOp.m_matrix, IntMatrix(3, 3, true)); + void testCopyConstructor() + { + SymmetryOperation inversion("-x,-y,-z"); + SymmetryOperation anotherInversion(inversion); - int someMatrix[] = {1, 2, 3, - 4, 5, 6, - 7, 8, 9}; + TS_ASSERT_EQUALS(inversion, anotherInversion); + TS_ASSERT_EQUALS(inversion.order(), anotherInversion.order()); + TS_ASSERT_EQUALS(inversion.identifier(), anotherInversion.identifier()); + } - emptyOp.setMatrixFromArray(someMatrix); + void testIsIdentity() + { + SymmetryOperation identity; + TS_ASSERT(identity.isIdentity()); - // first row - TS_ASSERT_EQUALS(emptyOp.m_matrix[0][0], 1); - TS_ASSERT_EQUALS(emptyOp.m_matrix[0][1], 2); - TS_ASSERT_EQUALS(emptyOp.m_matrix[0][2], 3); + SymmetryOperation inversion("-x,-y,-z"); + TS_ASSERT(!inversion.isIdentity()); - // second row - TS_ASSERT_EQUALS(emptyOp.m_matrix[1][0], 4); - TS_ASSERT_EQUALS(emptyOp.m_matrix[1][1], 5); - TS_ASSERT_EQUALS(emptyOp.m_matrix[1][2], 6); + SymmetryOperation screw21z("-x,-y,z+1/2"); + TS_ASSERT(!screw21z.isIdentity()); - // third row - TS_ASSERT_EQUALS(emptyOp.m_matrix[2][0], 7); - TS_ASSERT_EQUALS(emptyOp.m_matrix[2][1], 8); - TS_ASSERT_EQUALS(emptyOp.m_matrix[2][2], 9); + SymmetryOperation shift("x+1/2,y+1/2,z+1/2"); + TS_ASSERT(!shift.isIdentity()); } - void testIdentifierRegEx() + void testHasTranslation() { - std::vector goodInput; - goodInput.push_back("1"); - goodInput.push_back("-1"); - goodInput.push_back("2 [100]"); - goodInput.push_back("3 [100]"); - goodInput.push_back("4 [100]"); - goodInput.push_back("6 [100]"); - goodInput.push_back("m [100]"); - goodInput.push_back("2 [100]h"); - goodInput.push_back("m [-100]"); - goodInput.push_back("m [-1-1-1]"); - goodInput.push_back("-3 [100]"); - - for(size_t i = 0; i < goodInput.size(); ++i) { - TSM_ASSERT(goodInput[i] + " did not match regular expression.", boost::regex_match(goodInput[i], m_identifierRegex)); - } + SymmetryOperation identity; + TS_ASSERT(!identity.hasTranslation()); - std::vector badInput; - badInput.push_back("1 [100]"); - badInput.push_back("-1 [100]"); - badInput.push_back("2"); - badInput.push_back("-2"); - badInput.push_back("2 [100"); - badInput.push_back("2 100"); - badInput.push_back("2 [10]"); - badInput.push_back("2 [1002]"); - badInput.push_back("2 [--120]"); - badInput.push_back("2 [120]k"); - - for(size_t i = 0; i < badInput.size(); ++i) { - TSM_ASSERT(badInput[i] + " unexpectedly matched regular expression.", !boost::regex_match(badInput[i], m_identifierRegex)); - } + SymmetryOperation inversion("-x,-y,-z"); + TS_ASSERT(!inversion.hasTranslation()); + + SymmetryOperation screw21z("-x,-y,z+1/2"); + TS_ASSERT(screw21z.hasTranslation()); + + SymmetryOperation shift("x+1/2,y+1/2,z+1/2"); + TS_ASSERT(shift.hasTranslation()); } - void testIdentity() + void testMultiplicationOperator() { - auto identity = boost::make_shared(); + SymmetryOperation inversion("-x,-y,-z"); - checkCorrectOrder(identity, 1); - TS_ASSERT_EQUALS(applyOrderTimes(identity, m_hkl), m_hkl); + V3D hklDouble(1.0, 1.0, 1.0); + V3D hklDoubleReferenceInversion(-1.0, -1.0, -1.0); + TS_ASSERT_EQUALS(inversion * hklDouble, hklDoubleReferenceInversion); - checkCorrectOrderAll(identity); - } + V3R hklRational(1, 1, 1); + V3R hklRationalReferenceInversion(-1, -1, -1); + TS_ASSERT_EQUALS(inversion * hklRational, hklRationalReferenceInversion); - void testInversion() - { - testSymmetryOperation(boost::make_shared(), - 2, m_hkl * -1.0, "-1"); - } + SymmetryOperation screw21z("-x,-y,z+1/2"); - // Rotations - // 2-fold - void testRotationTwoFoldX() - { - testSymmetryOperation(boost::make_shared(), - 2, V3D(m_h, -m_k, -m_l), "2 [100]"); - } + V3D coordinates(0.35, 0.45, 0.75); + V3D coordinatesReference(-0.35, -0.45, 1.25); - void testRotationTwoFoldY() - { - testSymmetryOperation(boost::make_shared(), - 2, V3D(-m_h, m_k, -m_l), "2 [010]"); + TS_ASSERT_EQUALS(screw21z * coordinates, coordinatesReference); } - void testRotationTwoFoldZ() + void testMultiplicationOperatorSymmetryOperation() { - testSymmetryOperation(boost::make_shared(), - 2, V3D(-m_h, -m_k, m_l), "2 [001]"); - } + SymmetryOperation screw21z("-x,-y,z+1/2"); + SymmetryOperation identity; - void testRotationTwoFoldXHexagonal() - { - testSymmetryOperation(boost::make_shared(), - 2, V3D(m_h-m_k, -m_k, -m_l), "2 [100]h"); + // should be identity, since 1/2 + 1/2 = 1 => 0 + TS_ASSERT_EQUALS(screw21z * screw21z, identity); } - void testRotationTwoFold210Hexagonal() + void testInverse() { - testSymmetryOperation(boost::make_shared(), - 2, V3D(m_h, m_h-m_k, -m_l), "2 [210]h"); - } + SymmetryOperation identity("x,y,z"); + SymmetryOperation inversion = identity.inverse(); + TS_ASSERT_EQUALS(inversion.identifier(), "x,y,z"); - // 4-fold - void testRotation4FoldZ() - { - testSymmetryOperation(boost::make_shared(), - 4, V3D(-m_k, m_h, m_l), "4 [001]"); - } + SymmetryOperation fourFoldZPlus("-y,x,z"); + SymmetryOperation fourFoldZMinus = fourFoldZPlus.inverse(); + TS_ASSERT_EQUALS(fourFoldZMinus.identifier(), "y,-x,z"); - // 3-fold - void testRotationThreeFoldZHexagonal() - { - testSymmetryOperation(boost::make_shared(), - 3, V3D(-m_k, m_h-m_k, m_l), "3 [001]h"); + SymmetryOperation fourOneScrewZPlus("-y,x,z+1/4"); + SymmetryOperation fourOneScrewZMinus = fourOneScrewZPlus.inverse(); + TS_ASSERT_EQUALS(fourOneScrewZMinus.identifier(), "y,-x,z+3/4"); + + // (Op^-1)^-1 = Op + TS_ASSERT_EQUALS(fourOneScrewZMinus.inverse(), fourOneScrewZPlus); + + // Op * Op^-1 = Identity + TS_ASSERT_EQUALS(fourOneScrewZPlus * fourOneScrewZMinus, identity); } - void testRotationThreeFold111() + void testGetWrappedVectorV3R() { - testSymmetryOperation(boost::make_shared(), - 3, V3D(m_l, m_h, m_k), "3 [111]"); + V3R one = V3R(1, 1, 1) / 2; + TS_ASSERT_EQUALS(one, getWrappedVector(one)); + + V3R two = one + 1; + TS_ASSERT_EQUALS(one, getWrappedVector(two)); + + V3R three = one - 1; + TS_ASSERT_EQUALS(one, getWrappedVector(three)); + + V3R four = one - 10; + TS_ASSERT_EQUALS(one, getWrappedVector(four)); + + V3R five = one + 10; + TS_ASSERT_EQUALS(one, getWrappedVector(five)); } - // 6-fold - void testRotationSixFoldZHexagonal() + void testGetWrappedVectorV3D() { - testSymmetryOperation(boost::make_shared(), - 6, V3D(m_h-m_k, m_h, m_l), "6 [001]h"); + V3D one = V3D(0.5, 0.5, 0.5); + TS_ASSERT_EQUALS(one, getWrappedVector(one)); + + V3D two = one + V3D(1.0, 1.0, 1.0); + TS_ASSERT_EQUALS(one, getWrappedVector(two)); + + V3D three = one + V3D(1.0, 1.0, 1.0); + TS_ASSERT_EQUALS(one, getWrappedVector(three)); + + V3D four = one + V3D(10.0, 10.0, 10.0); + TS_ASSERT_EQUALS(one, getWrappedVector(four)); + + V3D five = one + V3D(10.0, 10.0, 10.0); + TS_ASSERT_EQUALS(one, getWrappedVector(five)); } - // Mirror planes - void testMirrorPlaneY() + void testGetOrderFromComponents() { - testSymmetryOperation(boost::make_shared(), - 2, V3D(m_h, -m_k, m_l), "m [010]"); + TestableSymmetryOperation symOp; + + // identity - 0 + std::pair param1 = SymmetryOperationSymbolParser::parseIdentifier("x, y, z"); + TS_ASSERT_EQUALS(symOp.getOrderFromMatrix(param1.first), 1); + + // inversion - 1 + std::pair param2 = SymmetryOperationSymbolParser::parseIdentifier("-x, -y, -z"); + TS_ASSERT_EQUALS(symOp.getOrderFromMatrix(param2.first), 2); + + // mirror perpendicular to z + std::pair param3 = SymmetryOperationSymbolParser::parseIdentifier("x, y, -z"); + TS_ASSERT_EQUALS(symOp.getOrderFromMatrix(param3.first), 2); + + // 4_1 screw axis along z + std::pair param4 = SymmetryOperationSymbolParser::parseIdentifier("-y, x, z+1/4"); + TS_ASSERT_EQUALS(symOp.getOrderFromMatrix(param4.first), 4); + + // check that random matrices don't work + Mantid::Kernel::IntMatrix randMatrix(3, 3, false); + + for(int i = 1; i < 10; ++i) { + randMatrix.setRandom(-0, -i, i); + TS_ASSERT_THROWS(symOp.getOrderFromMatrix(randMatrix), std::runtime_error); + } } - void testMirrorPlaneZ() + void testComparisonOperator() { - testSymmetryOperation(boost::make_shared(), - 2, V3D(m_h, m_k, -m_l), "m [001]"); + SymmetryOperation inversion1("-x, -y, -z"); + SymmetryOperation inversion2("-x, -y, -z"); + + + TS_ASSERT(inversion1 == inversion2); } - void testMirrorPlane210Hexagonal() + void testSymmetryOperations() { - testSymmetryOperation(boost::make_shared(), - 2, V3D(-m_h, m_k-m_h, m_l), "m [210]h"); + // Inversion + SymmetryOperation inversionOp("-x, -y, -z"); + testSymmetryOperation(inversionOp, + 2, m_hkl * -1.0, "-x,-y,-z"); + + // 2-fold rotation around x + SymmetryOperation twoFoldXOp("x, -y, -z"); + testSymmetryOperation(twoFoldXOp, + 2, V3D(m_h, -m_k, -m_l), "x,-y,-z"); + + // 2-fold rotation around [210] in hexagonal system + SymmetryOperation twoFold210Op("x, x-y, -z"); + testSymmetryOperation(twoFold210Op, + 2, V3D(m_h, m_h-m_k, -m_l), "x,x-y,-z"); } private: - V3D applyOrderTimes(const SymmetryOperation_const_sptr &symOp, const V3D &vector) + V3D applyOrderTimes(const SymmetryOperation &symOp, const V3D &vector) { - return applyNTimes(symOp, vector, symOp->order()); + return applyNTimes(symOp, vector, symOp.order()); } - V3D applyLessThanOrderTimes(const SymmetryOperation_const_sptr &symOp, const V3D &vector) + V3D applyLessThanOrderTimes(const SymmetryOperation &symOp, const V3D &vector) { - return applyNTimes(symOp, vector, symOp->order() - 1); + return applyNTimes(symOp, vector, symOp.order() - 1); } - V3D applyNTimes(const SymmetryOperation_const_sptr &symOp, const V3D &vector, size_t n) + V3D applyNTimes(const SymmetryOperation &symOp, const V3D &vector, size_t n) { V3D vectorCopy(vector); for(size_t i = 0; i < n; ++i) { - vectorCopy = symOp->apply(vectorCopy); + vectorCopy = symOp * vectorCopy; } return vectorCopy; } - void testSymmetryOperation(const SymmetryOperation_const_sptr &symOp, size_t expectedOrder, const V3D &expectedHKL, const std::string &expectedIdentifier) + void testSymmetryOperation(SymmetryOperation &symOp, size_t expectedOrder, const V3D &expectedHKL, const std::string &expectedIdentifier) { checkCorrectOrder(symOp, expectedOrder); checkCorrectTransformationGeneralHKL(symOp, expectedHKL); checkIdentifierString(symOp, expectedIdentifier); performCommonTests(symOp); + } - void checkCorrectOrder(const SymmetryOperation_const_sptr &symOp, size_t expected) + void checkCorrectOrder(const SymmetryOperation &symOp, size_t expected) { - size_t order = symOp->order(); + size_t order = symOp.order(); - TSM_ASSERT_EQUALS(symOp->identifier() + ": Order is " + boost::lexical_cast(order) + ", expected " + boost::lexical_cast(expected), + TSM_ASSERT_EQUALS(symOp.identifier() + ": Order is " + boost::lexical_cast(order) + ", expected " + boost::lexical_cast(expected), order, expected); } - void checkCorrectTransformationGeneralHKL(const SymmetryOperation_const_sptr &symOp, const V3D &expected) + void checkCorrectTransformationGeneralHKL(const SymmetryOperation &symOp, const V3D &expected) { - V3D transformed = symOp->apply(m_hkl); + V3D transformed = symOp * m_hkl; - TSM_ASSERT_EQUALS(symOp->identifier() + ": Transformed hkl is " + transformed.toString() + ", expected " + expected.toString(), + TSM_ASSERT_EQUALS(symOp.identifier() + ": Transformed hkl is " + transformed.toString() + ", expected " + expected.toString(), transformed, expected); } - void checkIdentifierString(const SymmetryOperation_const_sptr &symOp, const std::string &expected) + void checkIdentifierString(const SymmetryOperation &symOp, const std::string &expected) { - std::string identifier = symOp->identifier(); + std::string identifier = symOp.identifier(); - TSM_ASSERT(identifier + ": Does not match regular expression.", - boost::regex_match(identifier, m_identifierRegex)); TSM_ASSERT_EQUALS(identifier + ": Does not match expected identifier " + expected, identifier, expected); } - void performCommonTests(const SymmetryOperation_const_sptr &symOp) + void performCommonTests(const SymmetryOperation &symOp) { checkGeneralReflection(symOp); checkCorrectOrderAll(symOp); checkDeterminant(symOp); } - void checkGeneralReflection(const SymmetryOperation_const_sptr &symOp) + void checkGeneralReflection(const SymmetryOperation &symOp) { V3D transformedOrderTimes = applyOrderTimes(symOp, m_hkl); - TSM_ASSERT_EQUALS(symOp->identifier() + ": Transforming " + m_hkl.toString() + " $order times lead to unexpected result " + transformedOrderTimes.toString(), + TSM_ASSERT_EQUALS(symOp.identifier() + ": Transforming " + m_hkl.toString() + " $order times lead to unexpected result " + transformedOrderTimes.toString(), transformedOrderTimes, m_hkl); V3D transformedLessThanOrderTimes = applyLessThanOrderTimes(symOp, m_hkl); - TSM_ASSERT_DIFFERS(symOp->identifier() + ": Transforming " + m_hkl.toString() + " less than $order times lead to unexpected result " + transformedLessThanOrderTimes.toString(), + TSM_ASSERT_DIFFERS(symOp.identifier() + ": Transforming " + m_hkl.toString() + " less than $order times lead to unexpected result " + transformedLessThanOrderTimes.toString(), transformedLessThanOrderTimes, m_hkl); } - void checkCorrectOrderAll(const SymmetryOperation_const_sptr &symOp) + void checkCorrectOrderAll(const SymmetryOperation &symOp) { for(size_t i = 0; i < m_allHkl.size(); ++i) { TS_ASSERT_EQUALS(applyOrderTimes(symOp, m_allHkl[i]), m_allHkl[i]); } } - void checkDeterminant(const SymmetryOperation_const_sptr &symOp) + void checkDeterminant(const SymmetryOperation &symOp) { - IntMatrix symOpMatrix = symOp->apply(IntMatrix(3, 3, true)); - int determinant = abs(symOpMatrix.determinant()); + SymmetryOperation identity; - TSM_ASSERT_EQUALS(symOp->identifier() + ": Determinant of symmetry operation matrix is expected to be 1. Actual value: " + boost::lexical_cast(determinant), + SymmetryOperation symOpMatrix = symOp * identity; + int determinant = abs(symOpMatrix.matrix().determinant()); + + TSM_ASSERT_EQUALS(symOp.identifier() + ": Determinant of symmetry operation matrix is expected to be 1. Actual value: " + boost::lexical_cast(determinant), determinant, 1); } @@ -316,9 +362,6 @@ class SymmetryOperationTest : public CxxTest::TestSuite V3D m_h00; std::vector m_allHkl; - - // regex for matching symmetry operation identifiers - boost::regex m_identifierRegex; }; diff --git a/Code/Mantid/Framework/Geometry/test/TrackTest.h b/Code/Mantid/Framework/Geometry/test/TrackTest.h index 0e1ad153792b..b1cfb51fd7f9 100644 --- a/Code/Mantid/Framework/Geometry/test/TrackTest.h +++ b/Code/Mantid/Framework/Geometry/test/TrackTest.h @@ -15,110 +15,115 @@ using Mantid::Kernel::V3D; class TrackTest : public CxxTest::TestSuite { public: - void testConstructor(){ - Track A(V3D(0,0,0),V3D(1.0,0.0,0.0)); - TS_ASSERT_EQUALS(A.startPoint(),V3D(0.0,0.0,0)); - TS_ASSERT_EQUALS(A.direction(),V3D(1.0,0.0,0.0)); - } + void testConstructor(){ + Track A(V3D(0,0,0),V3D(1.0,0.0,0.0)); + TS_ASSERT_EQUALS(A.startPoint(),V3D(0.0,0.0,0)); + TS_ASSERT_EQUALS(A.direction(),V3D(1.0,0.0,0.0)); + } - void testTrackParamConstructor(){ - Track A(V3D(1,1,1),V3D(1.0,0.0,0.0)); - TS_ASSERT_EQUALS(A.startPoint(),V3D(1.0,1.0,1)); - TS_ASSERT_EQUALS(A.direction(),V3D(1.0,0.0,0.0)); - Track B(A); - TS_ASSERT_EQUALS(B.startPoint(),V3D(1.0,1.0,1)); - TS_ASSERT_EQUALS(B.direction(),V3D(1.0,0.0,0.0)); - } + void testTrackParamConstructor(){ + Track A(V3D(1,1,1),V3D(1.0,0.0,0.0)); + TS_ASSERT_EQUALS(A.startPoint(),V3D(1.0,1.0,1)); + TS_ASSERT_EQUALS(A.direction(),V3D(1.0,0.0,0.0)); + Track B(A); + TS_ASSERT_EQUALS(B.startPoint(),V3D(1.0,1.0,1)); + TS_ASSERT_EQUALS(B.direction(),V3D(1.0,0.0,0.0)); + } - void testIterator(){ - Track A(V3D(1,1,1),V3D(1.0,0.0,0.0)); - Track::LType::const_iterator iterBegin=A.begin(); - Track::LType::const_iterator iterEnd=A.end(); - TS_ASSERT_EQUALS(iterBegin,iterEnd); - } + void testIterator(){ + Track A(V3D(1,1,1),V3D(1.0,0.0,0.0)); + Track::LType::const_iterator iterBegin=A.begin(); + Track::LType::const_iterator iterEnd=A.end(); + TS_ASSERT_EQUALS(iterBegin,iterEnd); + } - void testAddLink(){ - Track A(V3D(1,1,1),V3D(1.0,0.0,0.0)); - A.addLink(V3D(2,2,2),V3D(3,3,3),2.0,NULL); - Track::LType::const_iterator iterBegin=A.begin(); - Track::LType::const_iterator iterEnd=A.end(); - iterBegin++; - TS_ASSERT_EQUALS(iterBegin,iterEnd); - } + void testAddLink(){ + Track A(V3D(1,1,1),V3D(1.0,0.0,0.0)); + Object shape; + A.addLink(V3D(2,2,2),V3D(3,3,3),2.0, shape, NULL); + Track::LType::const_iterator iterBegin=A.begin(); + Track::LType::const_iterator iterEnd=A.end(); + iterBegin++; + TS_ASSERT_EQUALS(iterBegin,iterEnd); + } - void testreset(){ - Track A(V3D(1,1,1),V3D(1.0,0.0,0.0)); - TS_ASSERT_EQUALS(A.startPoint(),V3D(1.0,1.0,1)); - TS_ASSERT_EQUALS(A.direction(),V3D(1.0,0.0,0.0)); - A.reset(V3D(2,2,2),V3D(0.0,1.0,0.0)); - TS_ASSERT_EQUALS(A.startPoint(),V3D(2.0,2.0,2)); - TS_ASSERT_EQUALS(A.direction(),V3D(0.0,1.0,0.0)); - } + void testreset(){ + Track A(V3D(1,1,1),V3D(1.0,0.0,0.0)); + TS_ASSERT_EQUALS(A.startPoint(),V3D(1.0,1.0,1)); + TS_ASSERT_EQUALS(A.direction(),V3D(1.0,0.0,0.0)); + A.reset(V3D(2,2,2),V3D(0.0,1.0,0.0)); + TS_ASSERT_EQUALS(A.startPoint(),V3D(2.0,2.0,2)); + TS_ASSERT_EQUALS(A.direction(),V3D(0.0,1.0,0.0)); + } - void testAssignment(){ //Also have to test the Links and Points - Track A(V3D(1,1,1),V3D(1.0,0.0,0.0)); - TS_ASSERT_EQUALS(A.startPoint(),V3D(1.0,1.0,1)); - TS_ASSERT_EQUALS(A.direction(),V3D(1.0,0.0,0.0)); - Track B(V3D(2,2,2),V3D(0.0,1.0,0.0)); - TS_ASSERT_EQUALS(B.startPoint(),V3D(2.0,2.0,2)); - TS_ASSERT_EQUALS(B.direction(),V3D(0.0,1.0,0.0)); - B=A; - TS_ASSERT_EQUALS(B.startPoint(),V3D(1.0,1.0,1)); - TS_ASSERT_EQUALS(B.direction(),V3D(1.0,0.0,0.0)); - } + void testAssignment(){ //Also have to test the Links and Points + Track A(V3D(1,1,1),V3D(1.0,0.0,0.0)); + TS_ASSERT_EQUALS(A.startPoint(),V3D(1.0,1.0,1)); + TS_ASSERT_EQUALS(A.direction(),V3D(1.0,0.0,0.0)); + Track B(V3D(2,2,2),V3D(0.0,1.0,0.0)); + TS_ASSERT_EQUALS(B.startPoint(),V3D(2.0,2.0,2)); + TS_ASSERT_EQUALS(B.direction(),V3D(0.0,1.0,0.0)); + B=A; + TS_ASSERT_EQUALS(B.startPoint(),V3D(1.0,1.0,1)); + TS_ASSERT_EQUALS(B.direction(),V3D(1.0,0.0,0.0)); + } - void testBuildLink(){ - Track A(V3D(-5,-5,0),V3D(1.0,0.0,0.0)); - TS_ASSERT_EQUALS(A.startPoint(),V3D(-5.0,-5.0,0.0)); - TS_ASSERT_EQUALS(A.direction(),V3D(1.0,0.0,0.0)); - A.addPoint(1,V3D(-5.0,-2.0,0.0)); //Entry at -5,-2,0 - A.addPoint(-1,V3D(-5.0,2.0,0.0)); //Exit point at -5,2,0 - A.buildLink(); - //Check track length - int index=0; - for(Track::LType::const_iterator it=A.begin();it!=A.end();++it){ - TS_ASSERT_DELTA(it->distFromStart,7,0.0001); - TS_ASSERT_DELTA(it->distInsideObject,4,0.0001); - TS_ASSERT_EQUALS(it->componentID, (Component *)NULL); - TS_ASSERT_EQUALS(it->entryPoint,V3D(-5.0,-2.0,0.0)); - TS_ASSERT_EQUALS(it->exitPoint,V3D(-5.0,2.0,0.0)); - index++; - } - TS_ASSERT_EQUALS(index,1); - } + void testBuildLink(){ + Track A(V3D(-5,-5,0),V3D(1.0,0.0,0.0)); + Object shape; - void testRemoveCojoins(){ - Track A(V3D(1,1,1),V3D(1.0,0.0,0.0)); - A.addLink(V3D(2,2,2),V3D(3,3,3),2.0); - A.addLink(V3D(2.0001,2.0001,2.0001),V3D(3,3,3),2.001); - //Check track length - int index=0; - for(Track::LType::const_iterator it=A.begin();it!=A.end();++it){ - index++; - } - TS_ASSERT_EQUALS(index,2); - A.removeCojoins(); - index=0; - { - for(Track::LType::const_iterator it=A.begin();it!=A.end();++it){ - index++; - } - } - TS_ASSERT_EQUALS(index,1); - } + TS_ASSERT_EQUALS(A.startPoint(),V3D(-5.0,-5.0,0.0)); + TS_ASSERT_EQUALS(A.direction(),V3D(1.0,0.0,0.0)); + A.addPoint(1,V3D(-5.0,-2.0,0.0), shape); //Entry at -5,-2,0 + A.addPoint(-1,V3D(-5.0,2.0,0.0), shape); //Exit point at -5,2,0 + A.buildLink(); + //Check track length + int index=0; + for(Track::LType::const_iterator it=A.begin();it!=A.end();++it){ + TS_ASSERT_DELTA(it->distFromStart,7,0.0001); + TS_ASSERT_DELTA(it->distInsideObject,4,0.0001); + TS_ASSERT_EQUALS(it->componentID, (Component *)NULL); + TS_ASSERT_EQUALS(it->entryPoint,V3D(-5.0,-2.0,0.0)); + TS_ASSERT_EQUALS(it->exitPoint,V3D(-5.0,2.0,0.0)); + index++; + } + TS_ASSERT_EQUALS(index,1); + } - void testNonComplete(){ - Track A(V3D(1,1,1),V3D(1.0,0.0,0.0)); - A.addLink(V3D(2,2,2),V3D(3,3,3),2.0); - A.addLink(V3D(2.0001,2.0001,2.0001),V3D(3,3,3),2.001); - TS_ASSERT(A.nonComplete()>0); - Track B(V3D(1,1,1),V3D(1.0,0.0,0.0)); - TS_ASSERT_EQUALS(B.startPoint(),V3D(1.0,1.0,1)); - TS_ASSERT_EQUALS(B.direction(),V3D(1.0,0.0,0.0)); - B.addLink(V3D(1,1,1),V3D(1,3,1),0.0); - B.addLink(V3D(1,3,1),V3D(1,5,1),2.0); - TS_ASSERT_EQUALS(B.nonComplete(),0); - } + void testRemoveCojoins(){ + Track A(V3D(1,1,1),V3D(1.0,0.0,0.0)); + Object shape; + A.addLink(V3D(2,2,2),V3D(3,3,3),2.0, shape); + A.addLink(V3D(2.0001,2.0001,2.0001),V3D(3,3,3),2.001, shape); + //Check track length + int index=0; + for(Track::LType::const_iterator it=A.begin();it!=A.end();++it){ + index++; + } + TS_ASSERT_EQUALS(index,2); + A.removeCojoins(); + index=0; + { + for(Track::LType::const_iterator it=A.begin();it!=A.end();++it){ + index++; + } + } + TS_ASSERT_EQUALS(index,1); + } + + void testNonComplete(){ + Track A(V3D(1,1,1),V3D(1.0,0.0,0.0)); + Object shape; + A.addLink(V3D(2,2,2),V3D(3,3,3),2.0, shape); + A.addLink(V3D(2.0001,2.0001,2.0001),V3D(3,3,3),2.001, shape); + TS_ASSERT(A.nonComplete()>0); + Track B(V3D(1,1,1),V3D(1.0,0.0,0.0)); + TS_ASSERT_EQUALS(B.startPoint(),V3D(1.0,1.0,1)); + TS_ASSERT_EQUALS(B.direction(),V3D(1.0,0.0,0.0)); + B.addLink(V3D(1,1,1),V3D(1,3,1),0.0, shape); + B.addLink(V3D(1,3,1),V3D(1,5,1),2.0, shape); + TS_ASSERT_EQUALS(B.nonComplete(),0); + } }; #endif diff --git a/Code/Mantid/Framework/Geometry/test/UnitCellTest.h b/Code/Mantid/Framework/Geometry/test/UnitCellTest.h index 6ca9c3621f2f..4dc36d03ee07 100644 --- a/Code/Mantid/Framework/Geometry/test/UnitCellTest.h +++ b/Code/Mantid/Framework/Geometry/test/UnitCellTest.h @@ -146,6 +146,25 @@ class UnitCellTest : public CxxTest::TestSuite } } + void testStrToUnitCell() + { + UnitCell cell(2.0, 4.0, 5.0, 90.0, 100.0, 102.0); + std::string cellString = unitCellToStr(cell); + UnitCell other = strToUnitCell(cellString); + + TS_ASSERT_EQUALS(cell.getG(), other.getG()); + + UnitCell precisionLimit(2.1234567891, 3.0, 4.1234567891, 90.0, 90.0, 90.0); + std::string precisionLimitString = unitCellToStr(precisionLimit); + UnitCell precisionLimitOther = strToUnitCell(precisionLimitString); + + TS_ASSERT_DIFFERS(precisionLimit.a(), precisionLimitOther.a()); + TS_ASSERT_DELTA(precisionLimit.a(), precisionLimitOther.a(), 1e-9); + + TS_ASSERT_DIFFERS(precisionLimit.c(), precisionLimitOther.c()); + TS_ASSERT_DELTA(precisionLimit.c(), precisionLimitOther.c(), 1e-9); + } + }; diff --git a/Code/Mantid/Framework/Geometry/test/V3RTest.h b/Code/Mantid/Framework/Geometry/test/V3RTest.h new file mode 100644 index 000000000000..87bb11267ce0 --- /dev/null +++ b/Code/Mantid/Framework/Geometry/test/V3RTest.h @@ -0,0 +1,432 @@ +#ifndef MANTID_GEOMETRY_V3RTEST_H_ +#define MANTID_GEOMETRY_V3RTEST_H_ + +#include + +#include "MantidGeometry/Crystal/V3R.h" +#include "MantidKernel/Exception.h" + +using namespace Mantid::Geometry; +using Mantid::Kernel::V3D; +using Mantid::Kernel::IntMatrix; + +class V3RTest : 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 V3RTest *createSuite() { return new V3RTest(); } + static void destroySuite( V3RTest *suite ) { delete suite; } + + + void testConstructors() + { + // default constructor + V3R defConstr; + TS_ASSERT_EQUALS(defConstr.x(), 0); + TS_ASSERT_EQUALS(defConstr.y(), 0); + TS_ASSERT_EQUALS(defConstr.z(), 0); + + // Constructor from rational numbers + V3R rational(RationalNumber(1, 4), RationalNumber(1, 2), RationalNumber(2, 3)); + V3D rationalV3D = rational; + TS_ASSERT_EQUALS(rationalV3D.X(), 0.25); + TS_ASSERT_EQUALS(rationalV3D.Y(), 0.5); + TS_ASSERT_EQUALS(rationalV3D.Z(), 2.0/3.0); + + std::vector good(3, 1); + V3R rationalIntVec(good); + TS_ASSERT_EQUALS(rationalIntVec.x(), 1); + TS_ASSERT_EQUALS(rationalIntVec.y(), 1); + TS_ASSERT_EQUALS(rationalIntVec.z(), 1); + + std::vector bad(4, 1); + TS_ASSERT_THROWS(V3R rationalIntVecBad(bad), Mantid::Kernel::Exception::MisMatch); + + // copy constructor + V3R copied(rational); + TS_ASSERT_EQUALS(copied.x(), rational.x()); + TS_ASSERT_EQUALS(copied.y(), rational.y()); + TS_ASSERT_EQUALS(copied.z(), rational.z()); + } + + void testXGetterSetter() + { + V3R vector; + TS_ASSERT_EQUALS(vector.x(), 0); + + TS_ASSERT_THROWS_NOTHING(vector.setX(RationalNumber(1, 4))); + TS_ASSERT_EQUALS(vector.x(), RationalNumber(1, 4)); + } + + void testYGetterSetter() + { + V3R vector; + TS_ASSERT_EQUALS(vector.y(), 0); + + TS_ASSERT_THROWS_NOTHING(vector.setY(RationalNumber(1, 4))); + TS_ASSERT_EQUALS(vector.y(), RationalNumber(1, 4)); + } + + void testZGetterSetter() + { + V3R vector; + TS_ASSERT_EQUALS(vector.z(), 0); + + TS_ASSERT_THROWS_NOTHING(vector.setZ(RationalNumber(1, 4))); + TS_ASSERT_EQUALS(vector.z(), RationalNumber(1, 4)); + } + + void testArrayAccess() + { + V3R vector(1, 2, 3); + TS_ASSERT_EQUALS(vector[0], 1); + TS_ASSERT_EQUALS(vector[1], 2); + TS_ASSERT_EQUALS(vector[2], 3); + TS_ASSERT_THROWS(vector[3], Mantid::Kernel::Exception::IndexError); + + TS_ASSERT_THROWS_NOTHING(vector[0] = RationalNumber(2, 3)); + TS_ASSERT_THROWS_NOTHING(vector[1] = RationalNumber(2, 3)); + TS_ASSERT_THROWS_NOTHING(vector[2] = RationalNumber(2, 3)); + TS_ASSERT_THROWS(vector[3] = RationalNumber(2, 3), Mantid::Kernel::Exception::IndexError); + } + + void testIntegerAddition() + { + V3R vector(RationalNumber(1, 4), RationalNumber(2, 3), RationalNumber(1, 2)); + V3R originalVector(vector); + + V3R vectorAdd = vector + 1; + TS_ASSERT_EQUALS(vectorAdd.x(), RationalNumber(5, 4)); + TS_ASSERT_EQUALS(vectorAdd.y(), RationalNumber(5, 3)); + TS_ASSERT_EQUALS(vectorAdd.z(), RationalNumber(3, 2)); + + vector += 1; + TS_ASSERT_EQUALS(vector, vectorAdd); + + vector += -1; + TS_ASSERT_EQUALS(vector, originalVector); + } + + void testIntegerSubtraction() + { + V3R vector(RationalNumber(1, 4), RationalNumber(2, 3), RationalNumber(1, 2)); + V3R originalVector(vector); + + V3R vectorAdd = vector - 1; + TS_ASSERT_EQUALS(vectorAdd.x(), RationalNumber(-3, 4)); + TS_ASSERT_EQUALS(vectorAdd.y(), RationalNumber(-1, 3)); + TS_ASSERT_EQUALS(vectorAdd.z(), RationalNumber(-1, 2)); + + vector -= 1; + TS_ASSERT_EQUALS(vector, vectorAdd); + + vector -= -1; + TS_ASSERT_EQUALS(vector, originalVector); + } + + void testIntegerMultiplication() + { + V3R vector(RationalNumber(1, 4), RationalNumber(2, 3), RationalNumber(1, 2)); + V3R originalVector(vector); + + V3R vectorAdd = vector * 2; + TS_ASSERT_EQUALS(vectorAdd.x(), RationalNumber(1, 2)); + TS_ASSERT_EQUALS(vectorAdd.y(), RationalNumber(4, 3)); + TS_ASSERT_EQUALS(vectorAdd.z(), RationalNumber(1, 1)); + + vector *= 2; + TS_ASSERT_EQUALS(vector, vectorAdd); + + vector /= 2; + TS_ASSERT_EQUALS(vector, originalVector); + + V3R nullVector = vector * 0; + TS_ASSERT_EQUALS(nullVector.x(), 0); + TS_ASSERT_EQUALS(nullVector.y(), 0); + TS_ASSERT_EQUALS(nullVector.z(), 0); + } + + void testIntegerDivision() + { + V3R vector(RationalNumber(1, 4), RationalNumber(2, 3), RationalNumber(1, 2)); + V3R originalVector(vector); + + V3R vectorAdd = vector / 2; + TS_ASSERT_EQUALS(vectorAdd.x(), RationalNumber(1, 8)); + TS_ASSERT_EQUALS(vectorAdd.y(), RationalNumber(1, 3)); + TS_ASSERT_EQUALS(vectorAdd.z(), RationalNumber(1, 4)); + + vector /= 2; + TS_ASSERT_EQUALS(vector, vectorAdd); + + vector *= 2; + TS_ASSERT_EQUALS(vector, originalVector); + + TS_ASSERT_THROWS(vector / 0, boost::bad_rational); + } + + void testRationalAddition() + { + V3R vector(RationalNumber(1, 4), RationalNumber(2, 3), RationalNumber(1, 2)); + V3R originalVector(vector); + + V3R vectorAdd = vector + RationalNumber(1, 2); + TS_ASSERT_EQUALS(vectorAdd.x(), RationalNumber(3, 4)); + TS_ASSERT_EQUALS(vectorAdd.y(), RationalNumber(7, 6)); + TS_ASSERT_EQUALS(vectorAdd.z(), RationalNumber(1, 1)); + + vector += RationalNumber(1, 2); + TS_ASSERT_EQUALS(vector, vectorAdd); + + vector += RationalNumber(-1, 2); + TS_ASSERT_EQUALS(vector, originalVector); + } + + void testRationalSubtraction() + { + V3R vector(RationalNumber(1, 4), RationalNumber(2, 3), RationalNumber(1, 2)); + V3R originalVector(vector); + + V3R vectorAdd = vector - RationalNumber(1, 2); + TS_ASSERT_EQUALS(vectorAdd.x(), RationalNumber(-1, 4)); + TS_ASSERT_EQUALS(vectorAdd.y(), RationalNumber(1, 6)); + TS_ASSERT_EQUALS(vectorAdd.z(), RationalNumber(0)); + + vector -= RationalNumber(1, 2); + TS_ASSERT_EQUALS(vector, vectorAdd); + + vector -= RationalNumber(-1, 2); + TS_ASSERT_EQUALS(vector, originalVector); + } + + void testRationalMultiplication() + { + V3R vector(RationalNumber(1, 4), RationalNumber(2, 3), RationalNumber(1, 2)); + V3R originalVector(vector); + + V3R vectorAdd = vector * RationalNumber(1, 2); + TS_ASSERT_EQUALS(vectorAdd.x(), RationalNumber(1, 8)); + TS_ASSERT_EQUALS(vectorAdd.y(), RationalNumber(1, 3)); + TS_ASSERT_EQUALS(vectorAdd.z(), RationalNumber(1, 4)); + + vector *= RationalNumber(1, 2); + TS_ASSERT_EQUALS(vector, vectorAdd); + + vector /= RationalNumber(1, 2); + TS_ASSERT_EQUALS(vector, originalVector); + } + + void testRationalDivision() + { + V3R vector(RationalNumber(1, 4), RationalNumber(2, 3), RationalNumber(1, 2)); + V3R originalVector(vector); + + V3R vectorAdd = vector / RationalNumber(1, 2); + TS_ASSERT_EQUALS(vectorAdd.x(), RationalNumber(1, 2)); + TS_ASSERT_EQUALS(vectorAdd.y(), RationalNumber(4, 3)); + TS_ASSERT_EQUALS(vectorAdd.z(), RationalNumber(1)); + + vector /= RationalNumber(1, 2); + TS_ASSERT_EQUALS(vector, vectorAdd); + + vector *= RationalNumber(1, 2); + TS_ASSERT_EQUALS(vector, originalVector); + } + + void testVectorAddition() + { + V3R vector(RationalNumber(1, 4), RationalNumber(2, 3), RationalNumber(1, 2)); + V3R otherVector(RationalNumber(-3, 7), RationalNumber(1, 3), RationalNumber(7, 9)); + V3R originalVector(vector); + + V3R vectorAdd = vector + otherVector; + TS_ASSERT_EQUALS(vectorAdd.x(), RationalNumber(-5, 28)); + TS_ASSERT_EQUALS(vectorAdd.y(), RationalNumber(1)); + TS_ASSERT_EQUALS(vectorAdd.z(), RationalNumber(23, 18)); + + vector += otherVector; + TS_ASSERT_EQUALS(vector, vectorAdd); + + vector += -otherVector; + TS_ASSERT_EQUALS(vector, originalVector); + + V3R nullVector = vector + (-vector); + TS_ASSERT_EQUALS(nullVector.x(), 0); + TS_ASSERT_EQUALS(nullVector.y(), 0); + TS_ASSERT_EQUALS(nullVector.z(), 0); + } + + void testVectorSubtraction() + { + V3R vector(RationalNumber(1, 4), RationalNumber(2, 3), RationalNumber(1, 2)); + V3R otherVector(RationalNumber(-3, 7), RationalNumber(1, 3), RationalNumber(7, 9)); + V3R originalVector(vector); + + V3R vectorAdd = vector - otherVector; + TS_ASSERT_EQUALS(vectorAdd.x(), RationalNumber(19, 28)); + TS_ASSERT_EQUALS(vectorAdd.y(), RationalNumber(1, 3)); + TS_ASSERT_EQUALS(vectorAdd.z(), RationalNumber(-5, 18)); + + vector -= otherVector; + TS_ASSERT_EQUALS(vector, vectorAdd); + + vector -= -otherVector; + TS_ASSERT_EQUALS(vector, originalVector); + + V3R nullVector = vector - vector; + TS_ASSERT_EQUALS(nullVector.x(), 0); + TS_ASSERT_EQUALS(nullVector.y(), 0); + TS_ASSERT_EQUALS(nullVector.z(), 0); + } + + void testV3DAddition() + { + V3R vector(RationalNumber(1, 4), RationalNumber(2, 3), RationalNumber(1, 2)); + V3D factor(0.5, 0.5, 0.5); + + V3D newVector = factor + vector; + + TS_ASSERT_EQUALS(newVector.X(), 0.75); + + // It's not exactly equal because of floating point precision + TS_ASSERT_DIFFERS(newVector.Y(), 7.0/6.0); + TS_ASSERT_EQUALS(newVector.Y(), 0.5 + 2.0/3.0); + TS_ASSERT_DELTA(newVector.Y(), 7.0/6.0, 1e-15); + + TS_ASSERT_EQUALS(newVector.Z(), 1.0); + + // check operation with different operand ordering + V3D equalVector = vector + factor; + TS_ASSERT_EQUALS(equalVector, newVector); + + } + + void testV3DSubtraction() + { + V3R vector(RationalNumber(1, 4), RationalNumber(2, 3), RationalNumber(1, 2)); + V3D factor(0.5, 0.5, 0.5); + + V3D newVector = factor - vector; + + TS_ASSERT_EQUALS(newVector.X(), 0.25); + + // It's not exactly equal because of floating point precision + TS_ASSERT_DIFFERS(newVector.Y(), -1.0/6.0); + TS_ASSERT_EQUALS(newVector.Y(), 0.5 - 2.0/3.0); + TS_ASSERT_DELTA(newVector.Y(), -1.0/6.0, 1e-16); + + TS_ASSERT_EQUALS(newVector.Z(), 0.0); + } + + void testEqualityOperator() + { + V3R one(RationalNumber(1, 4), RationalNumber(2, 3), RationalNumber(1, 2)); + V3R two(RationalNumber(1, 4), RationalNumber(2, 3), RationalNumber(1, 2)); + TS_ASSERT_EQUALS(one, two); + + V3R three(RationalNumber(2, 8), RationalNumber(6, 9), RationalNumber(14, 28)); + TS_ASSERT_EQUALS(one, three); + + V3R four(RationalNumber(1, 5), RationalNumber(2, 3), RationalNumber(1, 2)); + TS_ASSERT_DIFFERS(one, four); + + V3R five(RationalNumber(1, 4), RationalNumber(2, 4), RationalNumber(1, 2)); + TS_ASSERT_DIFFERS(one, five); + + V3R six(RationalNumber(1, 4), RationalNumber(2, 3), RationalNumber(1, 3)); + TS_ASSERT_DIFFERS(one, six); + } + + void testComparison() + { + V3R one(RationalNumber(1, 4), RationalNumber(2, 3), RationalNumber(1, 2)); + + V3R two(RationalNumber(1, 5), RationalNumber(2, 3), RationalNumber(1, 2)); + TS_ASSERT_LESS_THAN(two, one); + + V3R three(RationalNumber(1, 3), RationalNumber(2, 3), RationalNumber(1, 2)); + TS_ASSERT_LESS_THAN(one, three); + + V3R four(RationalNumber(1, 4), RationalNumber(2, 4), RationalNumber(1, 2)); + TS_ASSERT_LESS_THAN(four, one); + + V3R five(RationalNumber(1, 4), RationalNumber(2, 2), RationalNumber(1, 2)); + TS_ASSERT_LESS_THAN(one, five); + + V3R six(RationalNumber(1, 4), RationalNumber(2, 3), RationalNumber(1, 3)); + TS_ASSERT_LESS_THAN(six, one); + + V3R seven(RationalNumber(1, 4), RationalNumber(2, 3), RationalNumber(2, 2)); + TS_ASSERT_LESS_THAN(one, seven); + } + + void testIntegerComparison() + { + V3R zeros; + TS_ASSERT_EQUALS(zeros, 0); + zeros.setX(RationalNumber(1, 2)); + TS_ASSERT_DIFFERS(zeros, 0); + } + + void testMatrixMultiplication() + { + V3R vector(RationalNumber(1, 4), RationalNumber(2, 3), RationalNumber(1, 2)); + // unit matrix - resulting vector must be equal + IntMatrix unity(3, 3, true); + V3R transformedUnity = unity * vector; + TS_ASSERT_EQUALS(transformedUnity, vector); + + // inversion + IntMatrix inversion = unity * -1; + V3R transformedInversion = inversion * vector; + TS_ASSERT_EQUALS(transformedInversion, -vector); + + // general + IntMatrix operation(3, 3); + operation[0][0] = 0; + operation[0][1] = 1; + operation[0][2] = 1; + + operation[1][0] = 1; + operation[1][1] = -1; + operation[1][2] = 1; + + operation[2][0] = -1; + operation[2][1] = -1; + operation[2][2] = 0; + + V3R transformedGeneral = operation * vector; + TS_ASSERT_EQUALS(transformedGeneral.x(), RationalNumber(7, 6)); // y + z + TS_ASSERT_EQUALS(transformedGeneral.y(), RationalNumber(1, 12)); // x - y + z + TS_ASSERT_EQUALS(transformedGeneral.z(), RationalNumber(-11, 12)); // -x - y + + // wrong sizes + IntMatrix wrongOne(3, 4); + TS_ASSERT_THROWS(wrongOne * vector, Mantid::Kernel::Exception::MisMatch); + + IntMatrix wrongTwo(4, 3); + TS_ASSERT_THROWS(wrongTwo * vector, Mantid::Kernel::Exception::IndexError); + + // Smaller works + IntMatrix wrongThree(2, 3); + wrongThree[0][0] = 1; + wrongThree[0][1] = 0; + wrongThree[0][2] = 0; + + wrongThree[1][0] = 0; + wrongThree[1][1] = 1; + wrongThree[1][2] = 0; + + TS_ASSERT_THROWS_NOTHING(wrongThree * vector); + V3R transformedSmaller = wrongThree * vector; + + TS_ASSERT_EQUALS(transformedSmaller.x(), vector.x()); + TS_ASSERT_EQUALS(transformedSmaller.y(), vector.y()); + TS_ASSERT_EQUALS(transformedSmaller.z(), 0); + } + +}; + + +#endif /* MANTID_GEOMETRY_V3RTEST_H_ */ diff --git a/Code/Mantid/Framework/Geometry/test/XMLlogfileTest.h b/Code/Mantid/Framework/Geometry/test/XMLInstrumentParameterTest.h similarity index 80% rename from Code/Mantid/Framework/Geometry/test/XMLlogfileTest.h rename to Code/Mantid/Framework/Geometry/test/XMLInstrumentParameterTest.h index 0ec6903f7d78..6108848a6085 100644 --- a/Code/Mantid/Framework/Geometry/test/XMLlogfileTest.h +++ b/Code/Mantid/Framework/Geometry/test/XMLInstrumentParameterTest.h @@ -2,7 +2,7 @@ #define MANTID_GEOMETRY_XMLLOGFILETEST_H_ #include "MantidKernel/TimeSeriesProperty.h" -#include "MantidGeometry/Instrument/XMLlogfile.h" +#include "MantidGeometry/Instrument/XMLInstrumentParameter.h" #include "MantidKernel/System.h" #include "MantidKernel/Timer.h" #include @@ -15,16 +15,16 @@ using namespace Mantid; using namespace Mantid::Geometry; using namespace Mantid::Kernel; -class XMLlogfileTest : public CxxTest::TestSuite +class XMLInstrumentParameterTest : public CxxTest::TestSuite { private: - typedef boost::shared_ptr XMLlogfile_sptr; + typedef boost::shared_ptr XMLInstrumentParameter_sptr; /** - Construction logic for the XMLlogfile type isn't great, so this method acts a helper to keep the test methods cleaner. + Construction logic for the XMLInstrumentParameter type isn't great, so this method acts a helper to keep the test methods cleaner. */ - XMLlogfile_sptr make_logfile_object(const std::string& filterBy) + XMLInstrumentParameter_sptr make_logfile_object(const std::string& filterBy) { const std::string logfileID = "1"; const std::string value; @@ -42,7 +42,7 @@ class XMLlogfileTest : public CxxTest::TestSuite const Geometry::IComponent* comp = NULL; double angleConvertConst = 0.0; - return boost::shared_ptr(new XMLlogfile(logfileID, value, interpolation, formula, formulaUnit, resultUnit, paramName, type, tie, constraint, penaltyFactor, fitFunc, filterBy, eq, comp, angleConvertConst)); + return boost::shared_ptr(new XMLInstrumentParameter(logfileID, value, interpolation, formula, formulaUnit, resultUnit, paramName, type, tie, constraint, penaltyFactor, fitFunc, filterBy, eq, comp, angleConvertConst)); } public: @@ -53,7 +53,7 @@ class XMLlogfileTest : public CxxTest::TestSuite series.addValue("2000-11-30T01:01:01", 1); const std::string made_up_flag = "mode"; //We do not support mode statistics filtering. - XMLlogfile_sptr logFile = make_logfile_object(made_up_flag); + XMLInstrumentParameter_sptr logFile = make_logfile_object(made_up_flag); TSM_ASSERT_THROWS("Unknown flag should cause failure", logFile->createParamValue(&series), Kernel::Exception::InstrumentDefinitionError) } @@ -66,7 +66,7 @@ class XMLlogfileTest : public CxxTest::TestSuite series.addValue("2000-11-30T01:01:01", expectedFilteredValue); series.addValue("2000-11-30T01:01:02", 2); - XMLlogfile_sptr logFile = make_logfile_object("first_value"); + XMLInstrumentParameter_sptr logFile = make_logfile_object("first_value"); const double actualFilteredValue = logFile->createParamValue(&series); TSM_ASSERT_EQUALS("Filtering by First Value is not performed correctly", expectedFilteredValue, actualFilteredValue); } @@ -79,7 +79,7 @@ class XMLlogfileTest : public CxxTest::TestSuite series.addValue("2000-11-30T01:01:01", 0); series.addValue("2000-11-30T01:01:02", expectedFilteredValue); - XMLlogfile_sptr logFile = make_logfile_object("last_value"); + XMLInstrumentParameter_sptr logFile = make_logfile_object("last_value"); const double actualFilteredValue = logFile->createParamValue(&series); TSM_ASSERT_EQUALS("Filtering by Last Value is not performed correctly", expectedFilteredValue, actualFilteredValue); } @@ -93,7 +93,7 @@ class XMLlogfileTest : public CxxTest::TestSuite series.addValue("2000-11-30T01:01:02", expectedFilteredValue); // maximum. 1 > 0.9 > 0.1 series.addValue("2000-11-30T01:01:03", 0.9); - XMLlogfile_sptr logFile = make_logfile_object("maximum"); + XMLInstrumentParameter_sptr logFile = make_logfile_object("maximum"); const double actualFilteredValue = logFile->createParamValue(&series); TSM_ASSERT_EQUALS("Filtering by Maximum is not performed correctly", expectedFilteredValue, actualFilteredValue); } @@ -107,7 +107,7 @@ class XMLlogfileTest : public CxxTest::TestSuite series.addValue("2000-11-30T01:01:02", expectedFilteredValue); // minimum. 1 < 3 < 4 series.addValue("2000-11-30T01:01:03", 4); - XMLlogfile_sptr logFile = make_logfile_object("minimum"); + XMLInstrumentParameter_sptr logFile = make_logfile_object("minimum"); const double actualFilteredValue = logFile->createParamValue(&series); TSM_ASSERT_EQUALS("Filtering by Minimum is not performed correctly", expectedFilteredValue, actualFilteredValue); } @@ -122,7 +122,7 @@ class XMLlogfileTest : public CxxTest::TestSuite series.addValue("2000-11-30T01:01:03", 2); - XMLlogfile_sptr logFile = make_logfile_object("mean"); + XMLInstrumentParameter_sptr logFile = make_logfile_object("mean"); const double actualFilteredValue = logFile->createParamValue(&series); TSM_ASSERT_EQUALS("Filtering by Mean is not performed correctly", expectedFilteredValue, actualFilteredValue); } @@ -138,7 +138,7 @@ class XMLlogfileTest : public CxxTest::TestSuite series.addValue("2000-11-30T01:01:04", 4); series.addValue("2000-11-30T01:02:00", 5); - XMLlogfile_sptr logFile = make_logfile_object("median"); + XMLInstrumentParameter_sptr logFile = make_logfile_object("median"); const double actualFilteredValue = logFile->createParamValue(&series); TSM_ASSERT_EQUALS("Filtering by Median is not performed correctly", expectedFilteredValue, actualFilteredValue); } @@ -154,7 +154,7 @@ class XMLlogfileTest : public CxxTest::TestSuite series.addValue("2000-11-30T01:01:03", 2); series.addValue("2000-11-30T01:01:04", 3); - XMLlogfile_sptr logFile = make_logfile_object("position 1"); + XMLInstrumentParameter_sptr logFile = make_logfile_object("position 1"); const double actualFilteredValue = logFile->createParamValue(&series); TSM_ASSERT_EQUALS("Filtering by Nth position is not performed correctly", expectedFilteredValue, actualFilteredValue); } diff --git a/Code/Mantid/Framework/ICat/inc/MantidICat/CatalogPublish.h b/Code/Mantid/Framework/ICat/inc/MantidICat/CatalogPublish.h index dfd73ccdc678..27e0c545019b 100644 --- a/Code/Mantid/Framework/ICat/inc/MantidICat/CatalogPublish.h +++ b/Code/Mantid/Framework/ICat/inc/MantidICat/CatalogPublish.h @@ -1,5 +1,5 @@ #ifndef MANTID_ICAT_CATALOGPUBLISH_H -#define MATIND_ICAT_CATALOGPUBLISH_H +#define MANTID_ICAT_CATALOGPUBLISH_H #include "MantidAPI/Algorithm.h" #include "MantidAPI/ICatalogInfoService.h" diff --git a/Code/Mantid/Framework/ICat/src/GSoap/soapserializersC.cpp b/Code/Mantid/Framework/ICat/src/GSoap/soapserializersC.cpp index c97f31f0740a..dd73832bd9a7 100644 --- a/Code/Mantid/Framework/ICat/src/GSoap/soapserializersC.cpp +++ b/Code/Mantid/Framework/ICat/src/GSoap/soapserializersC.cpp @@ -435,7 +435,7 @@ SOAP_FMAC3 char * SOAP_FMAC4 soap_in_byte(struct soap *soap, const char *tag, ch SOAP_FMAC3 int SOAP_FMAC4 soap_put_byte(struct soap *soap, const char *a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_byte); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_byte); if (soap_out_byte(soap, tag?tag:"byte", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -472,7 +472,7 @@ SOAP_FMAC3 int * SOAP_FMAC4 soap_in_int(struct soap *soap, const char *tag, int SOAP_FMAC3 int SOAP_FMAC4 soap_put_int(struct soap *soap, const int *a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_int); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_int); if (soap_out_int(soap, tag?tag:"int", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -631,7 +631,7 @@ SOAP_FMAC3 struct SOAP_ENV__Fault * SOAP_FMAC4 soap_in_SOAP_ENV__Fault(struct so SOAP_FMAC3 int SOAP_FMAC4 soap_put_SOAP_ENV__Fault(struct soap *soap, const struct SOAP_ENV__Fault *a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_SOAP_ENV__Fault); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_SOAP_ENV__Fault); if (soap_out_SOAP_ENV__Fault(soap, tag?tag:"SOAP-ENV:Fault", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -743,7 +743,7 @@ SOAP_FMAC3 struct SOAP_ENV__Reason * SOAP_FMAC4 soap_in_SOAP_ENV__Reason(struct SOAP_FMAC3 int SOAP_FMAC4 soap_put_SOAP_ENV__Reason(struct soap *soap, const struct SOAP_ENV__Reason *a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_SOAP_ENV__Reason); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_SOAP_ENV__Reason); if (soap_out_SOAP_ENV__Reason(soap, tag?tag:"SOAP-ENV:Reason", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -862,7 +862,7 @@ SOAP_FMAC3 struct SOAP_ENV__Detail * SOAP_FMAC4 soap_in_SOAP_ENV__Detail(struct SOAP_FMAC3 int SOAP_FMAC4 soap_put_SOAP_ENV__Detail(struct soap *soap, const struct SOAP_ENV__Detail *a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_SOAP_ENV__Detail); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_SOAP_ENV__Detail); if (soap_out_SOAP_ENV__Detail(soap, tag?tag:"SOAP-ENV:Detail", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -983,7 +983,7 @@ SOAP_FMAC3 struct SOAP_ENV__Code * SOAP_FMAC4 soap_in_SOAP_ENV__Code(struct soap SOAP_FMAC3 int SOAP_FMAC4 soap_put_SOAP_ENV__Code(struct soap *soap, const struct SOAP_ENV__Code *a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_SOAP_ENV__Code); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_SOAP_ENV__Code); if (soap_out_SOAP_ENV__Code(soap, tag?tag:"SOAP-ENV:Code", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -1083,7 +1083,7 @@ SOAP_FMAC3 struct SOAP_ENV__Header * SOAP_FMAC4 soap_in_SOAP_ENV__Header(struct SOAP_FMAC3 int SOAP_FMAC4 soap_put_SOAP_ENV__Header(struct soap *soap, const struct SOAP_ENV__Header *a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_SOAP_ENV__Header); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_SOAP_ENV__Header); if (soap_out_SOAP_ENV__Header(soap, tag?tag:"SOAP-ENV:Header", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -1170,7 +1170,7 @@ SOAP_FMAC3 struct SOAP_ENV__Reason ** SOAP_FMAC4 soap_in_PointerToSOAP_ENV__Reas SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerToSOAP_ENV__Reason(struct soap *soap, struct SOAP_ENV__Reason *const*a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_PointerToSOAP_ENV__Reason); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_PointerToSOAP_ENV__Reason); if (soap_out_PointerToSOAP_ENV__Reason(soap, tag?tag:"SOAP-ENV:Reason", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -1227,7 +1227,7 @@ SOAP_FMAC3 struct SOAP_ENV__Detail ** SOAP_FMAC4 soap_in_PointerToSOAP_ENV__Deta SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerToSOAP_ENV__Detail(struct soap *soap, struct SOAP_ENV__Detail *const*a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_PointerToSOAP_ENV__Detail); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_PointerToSOAP_ENV__Detail); if (soap_out_PointerToSOAP_ENV__Detail(soap, tag?tag:"SOAP-ENV:Detail", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -1284,7 +1284,7 @@ SOAP_FMAC3 struct SOAP_ENV__Code ** SOAP_FMAC4 soap_in_PointerToSOAP_ENV__Code(s SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerToSOAP_ENV__Code(struct soap *soap, struct SOAP_ENV__Code *const*a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_PointerToSOAP_ENV__Code); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_PointerToSOAP_ENV__Code); if (soap_out_PointerToSOAP_ENV__Code(soap, tag?tag:"SOAP-ENV:Code", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -1320,7 +1320,7 @@ SOAP_FMAC3 char * * SOAP_FMAC4 soap_in__QName(struct soap *soap, const char *tag SOAP_FMAC3 int SOAP_FMAC4 soap_put__QName(struct soap *soap, char *const*a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE__QName); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE__QName); if (soap_out__QName(soap, tag?tag:"byte", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -1364,7 +1364,7 @@ SOAP_FMAC3 char * * SOAP_FMAC4 soap_in_string(struct soap *soap, const char *tag SOAP_FMAC3 int SOAP_FMAC4 soap_put_string(struct soap *soap, char *const*a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_string); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_string); if (soap_out_string(soap, tag?tag:"byte", id, a, type)) return soap->error; return soap_putindependent(soap); diff --git a/Code/Mantid/Framework/ICat/src/GSoap/stdsoap2.cpp b/Code/Mantid/Framework/ICat/src/GSoap/stdsoap2.cpp index 5e82d0ece918..b508411947bb 100644 --- a/Code/Mantid/Framework/ICat/src/GSoap/stdsoap2.cpp +++ b/Code/Mantid/Framework/ICat/src/GSoap/stdsoap2.cpp @@ -536,7 +536,7 @@ extern int h_errno; #ifndef PALM_1 static int fsend(struct soap *soap, const char *s, size_t n) -{ register int nwritten, err; +{ int nwritten, err; SOAP_SOCKET sk; #if defined(__cplusplus) && !defined(WITH_LEAN) && !defined(WITH_COMPAT) if (soap->os) @@ -555,7 +555,7 @@ fsend(struct soap *soap, const char *s, size_t n) { if (soap->send_timeout) { for (;;) - { register int r; + { int r; #ifdef WITH_OPENSSL if (soap->ssl) r = tcp_select(soap, sk, SOAP_TCP_SELECT_ALL, soap->send_timeout); @@ -636,7 +636,7 @@ fsend(struct soap *soap, const char *s, size_t n) #endif if (nwritten <= 0) { - register int r = 0; + int r = 0; err = soap_socket_errno(sk); #ifdef WITH_OPENSSL if (soap->ssl && (r = SSL_get_error(soap->ssl, nwritten)) != SSL_ERROR_NONE && r != SSL_ERROR_WANT_READ && r != SSL_ERROR_WANT_WRITE) @@ -740,7 +740,7 @@ soap_send_raw(struct soap *soap, const char *s, size_t n) if (soap->mode & SOAP_IO_LENGTH) soap->count += n; else if (soap->mode & SOAP_IO) - { register size_t i = SOAP_BUFLEN - soap->bufidx; + { size_t i = SOAP_BUFLEN - soap->bufidx; while (n >= i) { memcpy(soap->buf + soap->bufidx, s, i); soap->bufidx = SOAP_BUFLEN; @@ -765,12 +765,12 @@ SOAP_FMAC1 int SOAP_FMAC2 soap_flush(struct soap *soap) -{ register size_t n = soap->bufidx; +{ size_t n = soap->bufidx; if (n) { #ifndef WITH_LEANER if ((soap->mode & SOAP_IO) == SOAP_IO_STORE) - { register int r; + { int r; if (soap->fpreparesend && (r = soap->fpreparesend(soap, soap->buf, n))) return soap->error = r; } @@ -812,7 +812,7 @@ int SOAP_FMAC2 soap_flush_raw(struct soap *soap, const char *s, size_t n) { if ((soap->mode & SOAP_IO) == SOAP_IO_STORE) - { register char *t; + { char *t; if (!(t = (char*)soap_push_block(soap, NULL, n))) return soap->error = SOAP_EOM; memcpy(t, s, n); @@ -879,8 +879,8 @@ soap_send3(struct soap *soap, const char *s1, const char *s2, const char *s3) #ifndef PALM_1 static size_t frecv(struct soap *soap, char *s, size_t n) -{ register int r; - register int retries = 100; /* max 100 retries with non-blocking sockets */ +{ int r; + int retries = 100; /* max 100 retries with non-blocking sockets */ SOAP_SOCKET sk; soap->errnum = 0; #if defined(__cplusplus) && !defined(WITH_LEAN) && !defined(WITH_COMPAT) @@ -897,7 +897,7 @@ frecv(struct soap *soap, char *s, size_t n) { for (;;) { #ifdef WITH_OPENSSL - register int err = 0; + int err = 0; #endif #ifdef WITH_OPENSSL if (soap->recv_timeout && !soap->ssl) /* SSL: sockets are nonblocking */ @@ -1051,9 +1051,9 @@ SOAP_FMAC1 int SOAP_FMAC2 soap_recv_raw(struct soap *soap) -{ register size_t ret; +{ size_t ret; #if !defined(WITH_LEANER) || defined(WITH_ZLIB) - register int r; + int r; #endif #ifdef WITH_ZLIB if (soap->mode & SOAP_ENC_ZLIB) @@ -1107,7 +1107,7 @@ soap_recv_raw(struct soap *soap) #ifndef WITH_NOHTTP if ((soap->mode & SOAP_IO) == SOAP_IO_CHUNK) /* read HTTP chunked transfer */ { for (;;) - { register soap_wchar c; + { soap_wchar c; char *t, tmp[17]; if (soap->chunksize) { soap->buflen = ret = soap->frecv(soap, soap->buf, soap->chunksize > SOAP_BUFLEN ? SOAP_BUFLEN : soap->chunksize); @@ -1331,7 +1331,7 @@ SOAP_FMAC1 soap_wchar SOAP_FMAC2 soap_getchar(struct soap *soap) -{ register soap_wchar c; +{ soap_wchar c; c = soap->ahead; if (c) { if (c != EOF) @@ -1396,12 +1396,12 @@ SOAP_FMAC1 long SOAP_FMAC2 soap_code_bits(const struct soap_code_map *code_map, const char *str) -{ register long bits = 0; +{ long bits = 0; if (code_map) { while (str && *str) { const struct soap_code_map *p; for (p = code_map; p->string; p++) - { register size_t n = strlen(p->string); + { size_t n = strlen(p->string); if (!strncmp(p->string, str, n) && soap_blank((soap_wchar)str[n])) { bits |= p->code; str += n; @@ -1424,11 +1424,11 @@ SOAP_FMAC1 const char* SOAP_FMAC2 soap_code_list(struct soap *soap, const struct soap_code_map *code_map, long code) -{ register char *t = soap->tmpbuf; +{ char *t = soap->tmpbuf; if (code_map) { while (code_map->string) { if (code_map->code & code) - { register const char *s = code_map->string; + { const char *s = code_map->string; if (t != soap->tmpbuf) *t++ = ' '; while (*s && t < soap->tmpbuf + sizeof(soap->tmpbuf) - 1) @@ -1449,9 +1449,9 @@ soap_code_list(struct soap *soap, const struct soap_code_map *code_map, long cod static soap_wchar soap_char(struct soap *soap) { char tmp[8]; - register int i; - register soap_wchar c; - register char *s = tmp; + int i; + soap_wchar c; + char *s = tmp; for (i = 0; i < 7; i++) { c = soap_get1(soap); if (c == ';' || (int)c == EOF) @@ -1512,7 +1512,7 @@ SOAP_FMAC1 soap_wchar SOAP_FMAC2 soap_get(struct soap *soap) -{ register soap_wchar c; +{ soap_wchar c; c = soap->ahead; if (c) { if ((int)c != EOF) @@ -1549,7 +1549,7 @@ soap_get(struct soap *soap) do c = soap_get1(soap); while (soap_blank(c)); if (c == '!' || c == '?' || c == '%') - { register int k = 1; + { int k = 1; if (c == '!') { c = soap_get1(soap); if (c == '[') @@ -1609,9 +1609,9 @@ soap_get(struct soap *soap) static soap_wchar soap_get_pi(struct soap *soap) { char buf[64]; - register char *s = buf; - register int i = sizeof(buf); - register soap_wchar c = soap_getchar(soap); + char *s = buf; + int i = sizeof(buf); + soap_wchar c = soap_getchar(soap); /* This is a quick way to parse XML PI and we could use a callback instead to * enable applications to intercept processing instructions */ while ((int)c != EOF && c != '?') @@ -1677,7 +1677,7 @@ soap_tell(struct soap *soap) SOAP_FMAC1 int SOAP_FMAC2 -soap_pututf8(struct soap *soap, register unsigned long c) +soap_pututf8(struct soap *soap, unsigned long c) { char tmp[16]; if (c < 0x80 && c > 0) { *tmp = (char)c; @@ -1685,7 +1685,7 @@ soap_pututf8(struct soap *soap, register unsigned long c) } #ifndef WITH_LEAN if (c >= 0x80) - { register char *t = tmp; + { char *t = tmp; if (c < 0x0800) *t++ = (char)(0xC0 | ((c >> 6) & 0x1F)); else @@ -1723,7 +1723,7 @@ SOAP_FMAC1 soap_wchar SOAP_FMAC2 soap_getutf8(struct soap *soap) -{ register soap_wchar c, c1, c2, c3, c4; +{ soap_wchar c, c1, c2, c3, c4; c = soap->ahead; if (c) soap->ahead = 0; @@ -1759,7 +1759,7 @@ int SOAP_FMAC2 soap_puthex(struct soap *soap, const unsigned char *s, int n) { char d[2]; - register int i; + int i; #ifdef WITH_DOM if ((soap->mode & SOAP_XML_DOM) && soap->dom) { if (!(soap->dom->data = soap_s2hex(soap, s, NULL, n))) @@ -1768,7 +1768,7 @@ soap_puthex(struct soap *soap, const unsigned char *s, int n) } #endif for (i = 0; i < n; i++) - { register int m = *s++; + { int m = *s++; d[0] = (char)((m >> 4) + (m > 159 ? '7' : '0')); m &= 0x0F; d[1] = (char)(m + (m > 9 ? '7' : '0')); @@ -1795,16 +1795,16 @@ soap_gethex(struct soap *soap, int *n) #ifdef WITH_FAST soap->labidx = 0; for (;;) - { register char *s; - register size_t i, k; + { char *s; + size_t i, k; if (soap_append_lab(soap, NULL, 0)) return NULL; s = soap->labbuf + soap->labidx; k = soap->lablen - soap->labidx; soap->labidx = soap->lablen; for (i = 0; i < k; i++) - { register char d1, d2; - register soap_wchar c; + { char d1, d2; + soap_wchar c; c = soap_get(soap); if (soap_isxdigit(c)) { d1 = (char)c; @@ -1833,15 +1833,15 @@ soap_gethex(struct soap *soap, int *n) if (soap_new_block(soap) == NULL) return NULL; for (;;) - { register int i; - register char *s = (char*)soap_push_block(soap, NULL, SOAP_BLKLEN); + { int i; + char *s = (char*)soap_push_block(soap, NULL, SOAP_BLKLEN); if (!s) { soap_end_block(soap, NULL); return NULL; } for (i = 0; i < SOAP_BLKLEN; i++) - { register char d1, d2; - register soap_wchar c = soap_get(soap); + { char d1, d2; + soap_wchar c = soap_get(soap); if (soap_isxdigit(c)) { d1 = (char)c; c = soap_get(soap); @@ -1874,8 +1874,8 @@ SOAP_FMAC1 int SOAP_FMAC2 soap_putbase64(struct soap *soap, const unsigned char *s, int n) -{ register int i; - register unsigned long m; +{ int i; + unsigned long m; char d[4]; if (!s) return SOAP_OK; @@ -1928,8 +1928,8 @@ soap_getbase64(struct soap *soap, int *n, int malloc_flag) #ifdef WITH_FAST soap->labidx = 0; for (;;) - { register size_t i, k; - register char *s; + { size_t i, k; + char *s; if (soap_append_lab(soap, NULL, 2)) return NULL; s = soap->labbuf + soap->labidx; @@ -1939,10 +1939,10 @@ soap_getbase64(struct soap *soap, int *n, int malloc_flag) return NULL; if (k > 2) { for (i = 0; i < k - 2; i += 3) - { register unsigned long m = 0; - register int j = 0; + { unsigned long m = 0; + int j = 0; do - { register soap_wchar c = soap_get(soap); + { soap_wchar c = soap_get(soap); if (c < SOAP_AP) c &= 0x7FFFFFFF; if (c == '=' || c < 0) @@ -1971,7 +1971,7 @@ soap_getbase64(struct soap *soap, int *n, int malloc_flag) } c -= '+'; if (c >= 0 && c <= 79) - { register int b = soap_base64i[c]; + { int b = soap_base64i[c]; if (b >= 64) { soap->error = SOAP_TYPE; return NULL; @@ -1994,17 +1994,17 @@ soap_getbase64(struct soap *soap, int *n, int malloc_flag) if (soap_new_block(soap) == NULL) return NULL; for (;;) - { register int i; - register char *s = (char*)soap_push_block(soap, NULL, 3 * SOAP_BLKLEN); /* must be multiple of 3 */ + { int i; + char *s = (char*)soap_push_block(soap, NULL, 3 * SOAP_BLKLEN); /* must be multiple of 3 */ if (!s) { soap_end_block(soap, NULL); return NULL; } for (i = 0; i < SOAP_BLKLEN; i++) - { register unsigned long m = 0; - register int j = 0; + { unsigned long m = 0; + int j = 0; do - { register soap_wchar c = soap_get(soap); + { soap_wchar c = soap_get(soap); if (c == '=' || c < 0) { unsigned char *p; i *= 3; @@ -2207,12 +2207,12 @@ soap_update_pointers(struct soap *soap, char *start, char *end, char *p1, char * { #ifndef WITH_NOIDREF int i; - register struct soap_ilist *ip = NULL; - register struct soap_flist *fp = NULL; + struct soap_ilist *ip = NULL; + struct soap_flist *fp = NULL; #ifndef WITH_LEANER - register struct soap_xlist *xp = NULL; + struct soap_xlist *xp = NULL; #endif - register void *p, **q; + void *p, **q; for (i = 0; i < SOAP_IDHASH; i++) { for (ip = soap->iht[i]; ip; ip = ip->next) { if (ip->ptr && (char*)ip->ptr >= start && (char*)ip->ptr < end) @@ -2262,11 +2262,11 @@ soap_update_pointers(struct soap *soap, char *start, char *end, char *p1, char * #ifndef WITH_NOIDREF #ifndef PALM_1 static int -soap_has_copies(struct soap *soap, register const char *start, register const char *end) -{ register int i; - register struct soap_ilist *ip = NULL; - register struct soap_flist *fp = NULL; - register const char *p; +soap_has_copies(struct soap *soap, const char *start, const char *end) +{ int i; + struct soap_ilist *ip = NULL; + struct soap_flist *fp = NULL; + const char *p; for (i = 0; i < SOAP_IDHASH; i++) { for (ip = soap->iht[i]; ip; ip = ip->next) { for (p = (const char*)ip->copy; p; p = *(const char**)p) @@ -2289,15 +2289,15 @@ SOAP_FMAC1 int SOAP_FMAC2 soap_resolve(struct soap *soap) -{ register int i; - register struct soap_ilist *ip = NULL; - register struct soap_flist *fp = NULL; +{ int i; + struct soap_ilist *ip = NULL; + struct soap_flist *fp = NULL; short flag; DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Resolving forwarded data\n")); for (i = 0; i < SOAP_IDHASH; i++) { for (ip = soap->iht[i]; ip; ip = ip->next) { if (ip->ptr) - { register void *p, **q, *r; + { void *p, **q, *r; q = (void**)ip->link; ip->link = NULL; r = ip->ptr; @@ -2323,7 +2323,7 @@ soap_resolve(struct soap *soap) { for (ip = soap->iht[i]; ip; ip = ip->next) { if (ip->ptr && !soap_has_copies(soap, (const char*)ip->ptr, (const char*)ip->ptr + ip->size)) { if (ip->copy) - { register void *p, **q = (void**)ip->copy; + { void *p, **q = (void**)ip->copy; DBGLOG(TEST, if (q) SOAP_MESSAGE(fdebug, "Traversing copy chain to resolve id='%s'\n", ip->id)); ip->copy = NULL; do @@ -2335,11 +2335,11 @@ soap_resolve(struct soap *soap) flag = 1; } for (fp = ip->flist; fp; fp = ip->flist) - { register unsigned int k = fp->level; - register void *p = ip->ptr; + { unsigned int k = fp->level; + void *p = ip->ptr; DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Resolving forwarded data type=%d location=%p level=%u,%u id='%s'\n", ip->type, p, ip->level, fp->level, ip->id)); while (ip->level < k) - { register void **q = (void**)soap_malloc(soap, sizeof(void*)); + { void **q = (void**)soap_malloc(soap, sizeof(void*)); if (!q) return soap->error; *q = p; @@ -2486,8 +2486,8 @@ SOAP_FMAC1 char* SOAP_FMAC2 soap_save_block(struct soap *soap, struct soap_blist *b, char *p, int flag) -{ register size_t n; - register char *q, *s; +{ size_t n; + char *q, *s; if (!b) b = soap->blist; if (b->size) @@ -2581,7 +2581,7 @@ SOAP_FMAC1 char * SOAP_FMAC2 soap_putoffsets(struct soap *soap, const int *offset, int dim) -{ register int i; +{ int i; sprintf(soap->arrayOffset, "[%d", offset[0]); for (i = 1; i < dim; i++) sprintf(soap->arrayOffset + strlen(soap->arrayOffset), ",%d", offset[i]); @@ -2596,7 +2596,7 @@ SOAP_FMAC1 int SOAP_FMAC2 soap_size(const int *size, int dim) -{ register int i, n = size[0]; +{ int i, n = size[0]; for (i = 1; i < dim; i++) n *= size[i]; return n; @@ -2609,7 +2609,7 @@ SOAP_FMAC1 int SOAP_FMAC2 soap_getoffsets(const char *attr, const int *size, int *offset, int dim) -{ register int i, j = 0; +{ int i, j = 0; if (offset) for (i = 0; i < dim && attr && *attr; i++) { attr++; @@ -2634,7 +2634,7 @@ SOAP_FMAC1 int SOAP_FMAC2 soap_getsize(const char *attr1, const char *attr2, int *j) -{ register int n, k; +{ int n, k; char *s; *j = 0; if (!*attr1) @@ -2673,7 +2673,7 @@ SOAP_FMAC1 int SOAP_FMAC2 soap_getsizes(const char *attr, int *size, int dim) -{ register int i, k, n; +{ int i, k, n; if (!*attr) return -1; i = (int)strlen(attr); @@ -2697,7 +2697,7 @@ SOAP_FMAC1 int SOAP_FMAC2 soap_getposition(const char *attr, int *pos) -{ register int i, n; +{ int i, n; if (!*attr) return -1; n = 0; @@ -2719,10 +2719,10 @@ SOAP_FMAC1 struct soap_nlist * SOAP_FMAC2 soap_push_namespace(struct soap *soap, const char *id, const char *ns) -{ register struct soap_nlist *np; - register struct Namespace *p; - register short i = -1; - register size_t n, k; +{ struct soap_nlist *np; + struct Namespace *p; + short i = -1; + size_t n, k; n = strlen(id); k = strlen(ns) + 1; p = soap->local_namespaces; @@ -2776,7 +2776,7 @@ SOAP_FMAC1 void SOAP_FMAC2 soap_pop_namespace(struct soap *soap) -{ register struct soap_nlist *np, *nq; +{ struct soap_nlist *np, *nq; for (np = soap->nlist; np && np->level >= soap->level; np = nq) { nq = np->next; DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Pop namespace binding (level=%u) '%s'\n", soap->level, np->id)); @@ -2792,7 +2792,7 @@ SOAP_FMAC1 int SOAP_FMAC2 soap_match_namespace(struct soap *soap, const char *id1, const char *id2, size_t n1, size_t n2) -{ register struct soap_nlist *np = soap->nlist; +{ struct soap_nlist *np = soap->nlist; const char *s; while (np && (strncmp(np->id, id1, n1) || np->id[n1])) np = np->next; @@ -2818,8 +2818,8 @@ SOAP_FMAC1 const char* SOAP_FMAC2 soap_current_namespace(struct soap *soap, const char *tag) -{ register struct soap_nlist *np; - register const char *s; +{ struct soap_nlist *np; + const char *s; if (!tag || !strncmp(tag, "xml", 3)) return NULL; np = soap->nlist; @@ -2850,8 +2850,8 @@ int SOAP_FMAC2 soap_tag_cmp(const char *s, const char *t) { for (;;) - { register int c1 = *s; - register int c2 = *t; + { int c1 = *s; + int c2 = *t; if (!c1 || c1 == '"') break; if (c2 != '-') @@ -2897,8 +2897,8 @@ SOAP_FMAC1 int SOAP_FMAC2 soap_match_tag(struct soap *soap, const char *tag1, const char *tag2) -{ register const char *s, *t; - register int err; +{ const char *s, *t; + int err; if (!tag1 || !tag2 || !*tag2) return SOAP_OK; s = strchr(tag1, ':'); @@ -3646,7 +3646,7 @@ tcp_init(struct soap *soap) #ifndef PALM_1 static const char* tcp_error(struct soap *soap) -{ register const char *msg = NULL; +{ const char *msg = NULL; switch (soap->errmode) { case 0: msg = soap_strerror(soap); @@ -4024,7 +4024,7 @@ tcp_connect(struct soap *soap, const char *endpoint, const char *host, int port) { SOAP_SOCKLEN_T k; for (;;) - { register int r; + { int r; r = tcp_select(soap, sk, SOAP_TCP_SELECT_SND, soap->connect_timeout); if (r > 0) break; @@ -4190,7 +4190,7 @@ tcp_connect(struct soap *soap, const char *endpoint, const char *host, int port) { if ((r = SSL_connect(soap->ssl)) <= 0) { int err = SSL_get_error(soap->ssl, r); if (err == SSL_ERROR_WANT_CONNECT || err == SSL_ERROR_WANT_READ || err == SSL_ERROR_WANT_WRITE) - { register int s; + { int s; if (err == SSL_ERROR_WANT_READ) s = tcp_select(soap, sk, SOAP_TCP_SELECT_RCV | SOAP_TCP_SELECT_ERR, -100000); else @@ -4422,7 +4422,7 @@ tcp_connect(struct soap *soap, const char *endpoint, const char *host, int port) #ifndef PALM_1 static int tcp_select(struct soap *soap, SOAP_SOCKET sk, int flags, int timeout) -{ register int r; +{ int r; struct timeval tv; fd_set fd[3], *rfd, *sfd, *efd; soap->errnum = 0; @@ -4835,7 +4835,7 @@ SOAP_FMAC2 soap_poll(struct soap *soap) { #ifndef WITH_LEAN - register int r; + int r; if (soap_valid_socket(soap->socket)) { r = tcp_select(soap, soap->socket, SOAP_TCP_SELECT_ALL, 0); if (r > 0 && (r & SOAP_TCP_SELECT_ERR)) @@ -4887,7 +4887,7 @@ SOAP_SOCKET SOAP_FMAC2 soap_accept(struct soap *soap) { int n = (int)sizeof(soap->peer); - register int err; + int err; #ifndef WITH_LEAN #ifndef WIN32 int len = SOAP_BUFLEN; @@ -4913,7 +4913,7 @@ soap_accept(struct soap *soap) for (;;) { if (soap->accept_timeout || soap->send_timeout || soap->recv_timeout) { for (;;) - { register int r; + { int r; r = tcp_select(soap, soap->master, SOAP_TCP_SELECT_ALL, soap->accept_timeout ? soap->accept_timeout : 60); if (r > 0) break; @@ -5024,7 +5024,7 @@ SOAP_FMAC1 int SOAP_FMAC2 soap_closesock(struct soap *soap) -{ register int status = soap->error; +{ int status = soap->error; #ifndef WITH_LEANER if (status) /* close on error: attachment state is not to be trusted */ { soap->mime.first = NULL; @@ -5115,7 +5115,7 @@ soap_done(struct soap *soap) soap_free_cookies(soap); #endif while (soap->plugins) - { register struct soap_plugin *p = soap->plugins->next; + { struct soap_plugin *p = soap->plugins->next; DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Removing plugin '%s'\n", soap->plugins->id)); if (soap->plugins->fcopy || soap->state == SOAP_INIT) soap->plugins->fdelete(soap, soap->plugins); @@ -5586,10 +5586,10 @@ SOAP_FMAC1 const char* SOAP_FMAC2 soap_get_header_attribute(struct soap *soap, const char *line, const char *key) -{ register const char *s = line; +{ const char *s = line; if (s) { while (*s) - { register short flag; + { short flag; s = soap_decode_key(soap->tmpbuf, sizeof(soap->tmpbuf), s); flag = soap_tag_cmp(soap->tmpbuf, key); s = soap_decode_val(soap->tmpbuf, sizeof(soap->tmpbuf), s); @@ -5669,7 +5669,7 @@ soap_decode(char *buf, size_t len, const char *val, const char *sep) #ifndef PALM_1 static const char* http_error(struct soap *soap, int status) -{ register const char *msg = SOAP_STR_EOS; +{ const char *msg = SOAP_STR_EOS; (void)soap; #ifndef WITH_LEAN msg = soap_code_str(h_http_error_codes, status); @@ -5720,8 +5720,8 @@ http_200(struct soap *soap) #ifndef PALM_1 static int http_post(struct soap *soap, const char *endpoint, const char *host, int port, const char *path, const char *action, size_t count) -{ register const char *s; - register int err; +{ const char *s; + int err; switch (soap->status) { case SOAP_GET: s = "GET"; @@ -5849,7 +5849,7 @@ http_post(struct soap *soap, const char *endpoint, const char *host, int port, c #ifndef PALM_1 static int http_send_header(struct soap *soap, const char *s) -{ register const char *t; +{ const char *t; do { t = strchr(s, '\n'); /* disallow \n in HTTP headers */ if (!t) @@ -5884,7 +5884,7 @@ http_post_header(struct soap *soap, const char *key, const char *val) #ifndef PALM_1 static int http_response(struct soap *soap, int status, size_t count) -{ register int err; +{ int err; #ifdef WMW_RPM_IO if (soap->rpmreqid) httpOutputEnable(soap->rpmreqid); @@ -5965,7 +5965,7 @@ SOAP_FMAC1 int SOAP_FMAC2 soap_response(struct soap *soap, int status) -{ register size_t count; +{ size_t count; if (!(soap->omode & (SOAP_ENC_XML | SOAP_IO_STORE /* this tests for chunking too */)) && (status == SOAP_HTML || status == SOAP_FILE)) soap->omode = (soap->omode & ~SOAP_IO) | SOAP_IO_STORE; @@ -5975,7 +5975,7 @@ soap_response(struct soap *soap, int status) return soap->error; #ifndef WITH_NOHTTP if ((soap->mode & SOAP_IO) != SOAP_IO_STORE && !(soap->mode & SOAP_ENC_XML)) - { register int n = soap->mode; + { int n = soap->mode; soap->mode &= ~(SOAP_IO | SOAP_ENC_ZLIB); if ((n & SOAP_IO) != SOAP_IO_FLUSH) soap->mode |= SOAP_IO_BUFFER; @@ -6014,8 +6014,8 @@ SOAP_FMAC1 size_t SOAP_FMAC2 soap_encode_url(const char *s, char *t, size_t len) -{ register int c; - register size_t n = len; +{ int c; + size_t n = len; while ((c = *s++) && --n > 0) { if (c > ' ' && c < 128 && !strchr("()<>@,;:\\\"/[]?={}#!$&'*+", c)) *t++ = c; @@ -6735,8 +6735,8 @@ soap_free_cookies(struct soap *soap) SOAP_FMAC1 size_t SOAP_FMAC2 -soap_hash(register const char *s) -{ register size_t h = 0; +soap_hash(const char *s) +{ size_t h = 0; while (*s) h = 65599*h + *s++; return h % SOAP_IDHASH; @@ -6749,7 +6749,7 @@ soap_hash(register const char *s) #ifndef PALM_1 static void soap_init_pht(struct soap *soap) -{ register int i; +{ int i; soap->pblk = NULL; soap->pidx = 0; for (i = 0; i < (int)SOAP_PTRHASH; i++) @@ -6797,8 +6797,8 @@ soap_del(struct soap *soap) #ifndef PALM_1 static void soap_free_pht(struct soap *soap) -{ register struct soap_pblk *pb, *next; - register int i; +{ struct soap_pblk *pb, *next; + int i; DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Free pointer hashtable\n")); for (pb = soap->pblk; pb; pb = next) { next = pb->next; @@ -6819,7 +6819,7 @@ SOAP_FMAC1 int SOAP_FMAC2 soap_embed(struct soap *soap, const void *p, const struct soap_array *a, int n, const char *tag, int type) -{ register int i; +{ int i; struct soap_plist *pp; (void)soap; if (soap->version == 2) @@ -6846,7 +6846,7 @@ SOAP_FMAC1 int SOAP_FMAC2 soap_pointer_lookup(struct soap *soap, const void *p, int type, struct soap_plist **ppp) -{ register struct soap_plist *pp; +{ struct soap_plist *pp; *ppp = NULL; if (p) { for (pp = soap->pht[soap_hash_ptr(p)]; pp; pp = pp->next) @@ -6870,11 +6870,11 @@ SOAP_FMAC1 int SOAP_FMAC2 soap_pointer_enter(struct soap *soap, const void *p, const struct soap_array *a, int n, int type, struct soap_plist **ppp) -{ register size_t h; - register struct soap_plist *pp; +{ size_t h; + struct soap_plist *pp; (void)n; if (!soap->pblk || soap->pidx >= SOAP_PTRBLK) - { register struct soap_pblk *pb = (struct soap_pblk*)SOAP_MALLOC(soap, sizeof(struct soap_pblk)); + { struct soap_pblk *pb = (struct soap_pblk*)SOAP_MALLOC(soap, sizeof(struct soap_pblk)); if (!pb) { soap->error = SOAP_EOM; return 0; @@ -6909,13 +6909,13 @@ SOAP_FMAC1 int SOAP_FMAC2 soap_array_pointer_lookup(struct soap *soap, const void *p, const struct soap_array *a, int n, int type, struct soap_plist **ppp) -{ register struct soap_plist *pp; +{ struct soap_plist *pp; *ppp = NULL; if (!p || !a->__ptr) return 0; for (pp = soap->pht[soap_hash_ptr(a->__ptr)]; pp; pp = pp->next) { if (pp->type == type && pp->array && pp->array->__ptr == a->__ptr) - { register int i; + { int i; for (i = 0; i < n; i++) if (((const int*)&pp->array->__size)[i] != ((const int*)&a->__size)[i]) break; @@ -7380,7 +7380,7 @@ soap_attachment(struct soap *soap, const char *tag, int id, const void *p, const #ifndef PALM_1 static void soap_init_iht(struct soap *soap) -{ register int i; +{ int i; for (i = 0; i < SOAP_IDHASH; i++) soap->iht[i] = NULL; } @@ -7392,9 +7392,9 @@ soap_init_iht(struct soap *soap) #ifndef PALM_1 static void soap_free_iht(struct soap *soap) -{ register int i; - register struct soap_ilist *ip = NULL, *p = NULL; - register struct soap_flist *fp = NULL, *fq = NULL; +{ int i; + struct soap_ilist *ip = NULL, *p = NULL; + struct soap_flist *fp = NULL, *fq = NULL; DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Free ID hashtable\n")); for (i = 0; i < SOAP_IDHASH; i++) { for (ip = soap->iht[i]; ip; ip = p) @@ -7418,7 +7418,7 @@ SOAP_FMAC1 struct soap_ilist * SOAP_FMAC2 soap_lookup(struct soap *soap, const char *id) -{ register struct soap_ilist *ip = NULL; +{ struct soap_ilist *ip = NULL; for (ip = soap->iht[soap_hash(id)]; ip; ip = ip->next) if (!strcmp(ip->id, id)) return ip; @@ -7434,8 +7434,8 @@ SOAP_FMAC1 struct soap_ilist * SOAP_FMAC2 soap_enter(struct soap *soap, const char *id) -{ register size_t h; - register struct soap_ilist *ip; +{ size_t h; + struct soap_ilist *ip; ip = (struct soap_ilist*)SOAP_MALLOC(soap, sizeof(struct soap_ilist) + strlen(id)); if (ip) { h = soap_hash(id); @@ -7454,7 +7454,7 @@ SOAP_FMAC1 void* SOAP_FMAC2 soap_malloc(struct soap *soap, size_t n) -{ register char *p; +{ char *p; if (!n) return (void*)SOAP_NON_NULL; if (!soap) @@ -7484,7 +7484,7 @@ soap_malloc(struct soap *soap, size_t n) #ifdef SOAP_MEM_DEBUG static void soap_init_mht(struct soap *soap) -{ register int i; +{ int i; for (i = 0; i < (int)SOAP_PTRHASH; i++) soap->mht[i] = NULL; } @@ -7494,8 +7494,8 @@ soap_init_mht(struct soap *soap) #ifdef SOAP_MEM_DEBUG static void soap_free_mht(struct soap *soap) -{ register int i; - register struct soap_mlist *mp, *mq; +{ int i; + struct soap_mlist *mp, *mq; for (i = 0; i < (int)SOAP_PTRHASH; i++) { for (mp = soap->mht[i]; mp; mp = mq) { mq = mp->next; @@ -7514,10 +7514,10 @@ SOAP_FMAC1 void* SOAP_FMAC2 soap_track_malloc(struct soap *soap, const char *file, int line, size_t size) -{ register void *p = malloc(size); +{ void *p = malloc(size); if (soap) - { register size_t h = soap_hash_ptr(p); - register struct soap_mlist *mp = (struct soap_mlist*)malloc(sizeof(struct soap_mlist)); + { size_t h = soap_hash_ptr(p); + struct soap_mlist *mp = (struct soap_mlist*)malloc(sizeof(struct soap_mlist)); if (soap->fdebug[SOAP_INDEX_TEST]) { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "%s(%d): malloc(%lu) = %p\n", file, line, (unsigned long)size, p)); } @@ -7538,8 +7538,8 @@ SOAP_FMAC1 void SOAP_FMAC2 soap_track_free(struct soap *soap, const char *file, int line, void *p) -{ register size_t h = soap_hash_ptr(p); - register struct soap_mlist *mp; +{ size_t h = soap_hash_ptr(p); + struct soap_mlist *mp; for (mp = soap->mht[h]; mp; mp = mp->next) if (mp->ptr == p) break; @@ -7563,8 +7563,8 @@ soap_track_free(struct soap *soap, const char *file, int line, void *p) #ifdef SOAP_MEM_DEBUG static void soap_track_unlink(struct soap *soap, const void *p) -{ register size_t h = soap_hash_ptr(p); - register struct soap_mlist *mp; +{ size_t h = soap_hash_ptr(p); + struct soap_mlist *mp; for (mp = soap->mht[h]; mp; mp = mp->next) if (mp->ptr == p) break; @@ -7582,7 +7582,7 @@ soap_dealloc(struct soap *soap, void *p) { if (soap_check_state(soap)) return; if (p) - { register char **q; + { char **q; for (q = (char**)&soap->alist; *q; q = *(char***)q) { if (*(unsigned short*)(char*)(*q - sizeof(unsigned short)) != (unsigned short)SOAP_CANARY) @@ -7606,7 +7606,7 @@ soap_dealloc(struct soap *soap, void *p) soap_delete(soap, p); } else - { register char *q; + { char *q; DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Free all soap_malloc() data\n")); while (soap->alist) { q = (char*)soap->alist; @@ -7649,14 +7649,14 @@ SOAP_FMAC1 void SOAP_FMAC2 soap_delete(struct soap *soap, void *p) -{ register struct soap_clist **cp; +{ struct soap_clist **cp; if (soap_check_state(soap)) return; cp = &soap->clist; if (p) { while (*cp) { if (p == (*cp)->ptr) - { register struct soap_clist *q = *cp; + { struct soap_clist *q = *cp; *cp = q->next; if (q->fdelete(q)) { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Could not dealloc data %p: deletion callback failed for object type %d\n", q->ptr, q->type)); @@ -7673,7 +7673,7 @@ soap_delete(struct soap *soap, void *p) } else { while (*cp) - { register struct soap_clist *q = *cp; + { struct soap_clist *q = *cp; *cp = q->next; if (q->fdelete(q)) { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Could not dealloc data %p: deletion callback failed for object type %d\n", q->ptr, q->type)); @@ -7695,11 +7695,11 @@ SOAP_FMAC1 void SOAP_FMAC2 soap_delegate_deletion(struct soap *soap, struct soap *soap_to) -{ register struct soap_clist *cp; - register char **q; +{ struct soap_clist *cp; + char **q; #ifdef SOAP_MEM_DEBUG - register void *p; - register struct soap_mlist **mp, *mq; + void *p; + struct soap_mlist **mp, *mq; size_t h; #endif for (q = (char**)&soap->alist; *q; q = *(char***)q) @@ -7766,7 +7766,7 @@ SOAP_FMAC1 struct soap_clist * SOAP_FMAC2 soap_link(struct soap *soap, void *p, int t, int n, int (*fdelete)(struct soap_clist*)) -{ register struct soap_clist *cp; +{ struct soap_clist *cp; if ((cp = (struct soap_clist*)SOAP_MALLOC(soap, sizeof(struct soap_clist)))) { cp->next = soap->clist; cp->type = t; @@ -7785,8 +7785,8 @@ SOAP_FMAC1 int SOAP_FMAC2 soap_unlink(struct soap *soap, const void *p) -{ register char **q; - register struct soap_clist **cp; +{ char **q; + struct soap_clist **cp; if (soap && p) { for (q = (char**)&soap->alist; *q; q = *(char***)q) { if (p == (void*)(*q - *(size_t*)(*q + sizeof(void*)))) @@ -7819,7 +7819,7 @@ SOAP_FMAC1 int SOAP_FMAC2 soap_lookup_type(struct soap *soap, const char *id) -{ register struct soap_ilist *ip; +{ struct soap_ilist *ip; if (id && *id) { ip = soap_lookup(soap, id); if (ip) @@ -7951,7 +7951,7 @@ soap_id_forward(struct soap *soap, const char *href, void *p, size_t len, int st return NULL; } if (fcopy || n < sizeof(void*) || *href != '#') - { register struct soap_flist *fp = (struct soap_flist*)SOAP_MALLOC(soap, sizeof(struct soap_flist)); + { struct soap_flist *fp = (struct soap_flist*)SOAP_MALLOC(soap, sizeof(struct soap_flist)); if (!fp) { soap->error = SOAP_EOM; return NULL; @@ -8307,8 +8307,8 @@ SOAP_FMAC1 void SOAP_FMAC2 soap_free_temp(struct soap *soap) -{ register struct soap_attribute *tp, *tq; - register struct Namespace *ns; +{ struct soap_attribute *tp, *tq; + struct Namespace *ns; soap_free_ns(soap); DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Free any remaining temp blocks\n")); while (soap->blist) @@ -8361,7 +8361,7 @@ soap_free_temp(struct soap *soap) #ifndef PALM_1 static void soap_free_ns(struct soap *soap) -{ register struct soap_nlist *np, *nq; +{ struct soap_nlist *np, *nq; DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Free namespace stack\n")); for (np = soap->nlist; np; np = nq) { nq = np->next; @@ -8488,7 +8488,7 @@ soap_copy_context(struct soap *copy, const struct soap *soap) if (soap_check_state(soap)) return NULL; if (copy) - { register struct soap_plugin *p = NULL; + { struct soap_plugin *p = NULL; DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Copying context\n")); #ifdef __cplusplus *copy = *soap; @@ -8565,7 +8565,7 @@ soap_copy_context(struct soap *copy, const struct soap *soap) #endif copy->plugins = NULL; for (p = soap->plugins; p; p = p->next) - { register struct soap_plugin *q = (struct soap_plugin*)SOAP_MALLOC(copy, sizeof(struct soap_plugin)); + { struct soap_plugin *q = (struct soap_plugin*)SOAP_MALLOC(copy, sizeof(struct soap_plugin)); if (!q) return NULL; DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Copying plugin '%s'\n", p->id)); @@ -8663,10 +8663,10 @@ soap_copy_stream(struct soap *copy, struct soap *soap) soap_set_local_namespaces(copy); copy->version = soap->version; if (soap->nlist && soap->local_namespaces) - { register struct soap_nlist *np = NULL, *nq; + { struct soap_nlist *np = NULL, *nq; /* copy reversed nlist */ for (nq = soap->nlist; nq; nq = nq->next) - { register struct soap_nlist *nr = np; + { struct soap_nlist *nr = np; size_t n = sizeof(struct soap_nlist) + strlen(nq->id); np = (struct soap_nlist*)SOAP_MALLOC(copy, n); if (!np) @@ -8675,7 +8675,7 @@ soap_copy_stream(struct soap *copy, struct soap *soap) np->next = nr; } while (np) - { register const char *s = np->ns; + { const char *s = np->ns; copy->level = np->level; /* preserve element nesting level */ if (!s && np->index >= 0) { s = soap->local_namespaces[np->index].out; @@ -9085,7 +9085,7 @@ soap_end(struct soap *soap) soap_free_temp(soap); soap_dealloc(soap, NULL); while (soap->clist) - { register struct soap_clist *cp = soap->clist->next; + { struct soap_clist *cp = soap->clist->next; SOAP_FREE(soap, soap->clist); soap->clist = cp; } @@ -9126,9 +9126,9 @@ SOAP_FMAC1 int SOAP_FMAC2 soap_set_namespaces(struct soap *soap, const struct Namespace *p) -{ register struct Namespace *ns = soap->local_namespaces; - register struct soap_nlist *np, *nq, *nr; - register unsigned int level = soap->level; +{ struct Namespace *ns = soap->local_namespaces; + struct soap_nlist *np, *nq, *nr; + unsigned int level = soap->level; soap->namespaces = p; soap->local_namespaces = NULL; soap_set_local_namespaces(soap); @@ -9147,7 +9147,7 @@ soap_set_namespaces(struct soap *soap, const struct Namespace *p) } /* then push on new stack */ while (np) - { register const char *s; + { const char *s; soap->level = np->level; /* preserve element nesting level */ s = np->ns; if (!s && np->index >= 0 && ns) @@ -9162,7 +9162,7 @@ soap_set_namespaces(struct soap *soap, const struct Namespace *p) SOAP_FREE(soap, nq); } if (ns) - { register int i; + { int i; for (i = 0; ns[i].id; i++) { if (ns[i].out) { SOAP_FREE(soap, ns[i].out); @@ -9183,9 +9183,9 @@ void SOAP_FMAC2 soap_set_local_namespaces(struct soap *soap) { if (soap->namespaces && !soap->local_namespaces) - { register const struct Namespace *ns1; - register struct Namespace *ns2; - register size_t n = 1; + { const struct Namespace *ns1; + struct Namespace *ns2; + size_t n = 1; for (ns1 = soap->namespaces; ns1->id; ns1++) n++; n *= sizeof(struct Namespace); @@ -9214,11 +9214,11 @@ const char * SOAP_FMAC2 soap_tagsearch(const char *big, const char *little) { if (little) - { register size_t n = strlen(little); - register const char *s = big; + { size_t n = strlen(little); + const char *s = big; while (s) - { register const char *t = s; - register size_t i; + { const char *t = s; + size_t i; for (i = 0; i < n; i++, t++) { if (*t != little[i]) break; @@ -9244,7 +9244,7 @@ SOAP_FMAC1 struct soap_nlist * SOAP_FMAC2 soap_lookup_ns(struct soap *soap, const char *tag, size_t n) -{ register struct soap_nlist *np; +{ struct soap_nlist *np; for (np = soap->nlist; np; np = np->next) { if (!strncmp(np->id, tag, n) && !np->id[n]) return np; @@ -9258,7 +9258,7 @@ soap_lookup_ns(struct soap *soap, const char *tag, size_t n) #ifndef WITH_LEAN static struct soap_nlist * soap_push_ns(struct soap *soap, const char *id, const char *ns, short utilized) -{ register struct soap_nlist *np; +{ struct soap_nlist *np; size_t n, k; if (soap_tagsearch(soap->c14nexclude, id)) return NULL; @@ -9302,7 +9302,7 @@ soap_push_ns(struct soap *soap, const char *id, const char *ns, short utilized) #ifndef WITH_LEAN static void soap_utilize_ns(struct soap *soap, const char *tag) -{ register struct soap_nlist *np; +{ struct soap_nlist *np; size_t n = 0; const char *t = strchr(tag, ':'); if (t) @@ -9329,7 +9329,7 @@ SOAP_FMAC2 soap_element(struct soap *soap, const char *tag, int id, const char *type) { #ifndef WITH_LEAN - register const char *s; + const char *s; #endif DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Element begin tag='%s' level='%u' id='%d' type='%s'\n", tag, soap->level, id, type ? type : SOAP_STR_EOS)); soap->level++; @@ -9347,7 +9347,7 @@ soap_element(struct soap *soap, const char *tag, int id, const char *type) { if (soap->evlev >= soap->level) soap->evlev = 0; if (soap->event == SOAP_SEC_BEGIN && !soap->evlev) - { register struct soap_nlist *np; + { struct soap_nlist *np; /* non-nested wsu:Id found: clear xmlns, re-emit them for exc-c14n */ for (np = soap->nlist; np; np = np->next) { if (np->index == 2) @@ -9361,7 +9361,7 @@ soap_element(struct soap *soap, const char *tag, int id, const char *type) } #endif if (soap->mode & SOAP_XML_DOM) - { register struct soap_dom_element *elt = (struct soap_dom_element*)soap_malloc(soap, sizeof(struct soap_dom_element)); + { struct soap_dom_element *elt = (struct soap_dom_element*)soap_malloc(soap, sizeof(struct soap_dom_element)); if (!elt) return soap->error; elt->soap = soap; @@ -9488,7 +9488,7 @@ soap_element(struct soap *soap, const char *tag, int id, const char *type) #endif } if (soap->null && soap->position > 0) - { register int i; + { int i; sprintf(soap->tmpbuf, "[%d", soap->positions[0]); for (i = 1; i < soap->position; i++) sprintf(soap->tmpbuf + strlen(soap->tmpbuf), ",%d", soap->positions[i]); @@ -9557,7 +9557,7 @@ SOAP_FMAC1 char* SOAP_FMAC2 soap_strrchr(const char *s, int t) -{ register char *r = NULL; +{ char *r = NULL; while (*s) if (*s++ == t) r = (char*)s - 1; @@ -9573,8 +9573,8 @@ SOAP_FMAC1 long SOAP_FMAC2 soap_strtol(const char *s, char **t, int b) -{ register long n = 0; - register int c; +{ long n = 0; + int c; while (*s > 0 && *s <= 32) s++; if (b == 10) @@ -9625,7 +9625,7 @@ unsigned long SOAP_FMAC2 soap_strtoul(const char *s, char **t, int b) { unsigned long n = 0; - register int c; + int c; while (*s > 0 && *s <= 32) s++; if (b == 10) @@ -9703,7 +9703,7 @@ SOAP_FMAC1 int SOAP_FMAC2 soap_element_start_end_out(struct soap *soap, const char *tag) -{ register struct soap_attribute *tp; +{ struct soap_attribute *tp; #ifndef WITH_LEAN if (soap->mode & SOAP_XML_CANONICAL) { struct soap_nlist *np; @@ -9726,7 +9726,7 @@ soap_element_start_end_out(struct soap *soap, const char *tag) #endif #ifdef WITH_DOM if ((soap->mode & SOAP_XML_DOM) && soap->dom) - { register struct soap_dom_attribute **att; + { struct soap_dom_attribute **att; att = &soap->dom->atts; for (tp = soap->attributes; tp; tp = tp->next) { if (tp->visible) @@ -9840,8 +9840,8 @@ SOAP_FMAC1 int SOAP_FMAC2 soap_element_ref(struct soap *soap, const char *tag, int id, int href) -{ register const char *s = "ref"; - register int n = 1; +{ const char *s = "ref"; + int n = 1; if (soap->version == 1) { s = "href"; n = 0; @@ -9982,7 +9982,7 @@ soap_attribute(struct soap *soap, const char *name, const char *value) DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Attribute '%s'='%s'\n", name, value)); #ifdef WITH_DOM if ((soap->mode & SOAP_XML_DOM) && !(soap->mode & SOAP_XML_CANONICAL) && soap->dom) - { register struct soap_dom_attribute *a = (struct soap_dom_attribute*)soap_malloc(soap, sizeof(struct soap_dom_attribute)); + { struct soap_dom_attribute *a = (struct soap_dom_attribute*)soap_malloc(soap, sizeof(struct soap_dom_attribute)); if (!a) return soap->error; a->next = soap->dom->atts; @@ -10052,9 +10052,9 @@ SOAP_FMAC1 int SOAP_FMAC2 soap_element_end_in(struct soap *soap, const char *tag) -{ register soap_wchar c; - register char *s; - register int n = 0; +{ soap_wchar c; + char *s; + int n = 0; if (tag && *tag == '-') return SOAP_OK; if (soap->error == SOAP_NO_TAG) @@ -10128,7 +10128,7 @@ SOAP_FMAC1 const char * SOAP_FMAC2 soap_attr_value(struct soap *soap, const char *name, int flag) -{ register struct soap_attribute *tp; +{ struct soap_attribute *tp; if (*name == '-') return SOAP_STR_EOS; for (tp = soap->attributes; tp; tp = tp->next) @@ -10155,7 +10155,7 @@ SOAP_FMAC1 int SOAP_FMAC2 soap_set_attr(struct soap *soap, const char *name, const char *value, int flag) -{ register struct soap_attribute *tp; +{ struct soap_attribute *tp; if (*name == '-') return SOAP_OK; DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Set attribute %s='%s'\n", name, value ? value : SOAP_STR_EOS)); @@ -10254,7 +10254,7 @@ SOAP_FMAC1 void SOAP_FMAC2 soap_clr_attr(struct soap *soap) -{ register struct soap_attribute *tp; +{ struct soap_attribute *tp; #ifndef WITH_LEAN if ((soap->mode & SOAP_XML_CANONICAL)) { while (soap->attributes) @@ -10277,9 +10277,9 @@ soap_clr_attr(struct soap *soap) #ifndef PALM_2 static int soap_getattrval(struct soap *soap, char *s, size_t n, soap_wchar d) -{ register size_t i; +{ size_t i; for (i = 0; i < n; i++) - { register soap_wchar c = soap_get(soap); + { soap_wchar c = soap_get(soap); switch (c) { case SOAP_TT: @@ -10352,7 +10352,7 @@ int SOAP_FMAC2 soap_append_lab(struct soap *soap, const char *s, size_t n) { if (soap->labidx + n >= soap->lablen) - { register char *t = soap->labbuf; + { char *t = soap->labbuf; DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Enlarging look-aside buffer to append data, old size=%lu", (unsigned long)soap->lablen)); if (soap->lablen == 0) soap->lablen = SOAP_LABLEN; @@ -10387,14 +10387,14 @@ SOAP_FMAC2 soap_peek_element(struct soap *soap) { #ifdef WITH_DOM - register struct soap_dom_attribute **att = NULL; - register char *lead = NULL; -#endif - register struct soap_attribute *tp, *tq = NULL; - register const char *t; - register char *s; - register soap_wchar c; - register int i; + struct soap_dom_attribute **att = NULL; + char *lead = NULL; +#endif + struct soap_attribute *tp, *tq = NULL; + const char *t; + char *s; + soap_wchar c; + int i; if (soap->peeked) { if (!*soap->tag) return soap->error = SOAP_NO_TAG; @@ -10481,7 +10481,7 @@ soap_peek_element(struct soap *soap) *s = '\0'; #ifdef WITH_DOM if (soap->mode & SOAP_XML_DOM) - { register struct soap_dom_element *elt; + { struct soap_dom_element *elt; elt = (struct soap_dom_element*)soap_malloc(soap, sizeof(struct soap_dom_element)); if (!elt) return soap->error; @@ -10825,9 +10825,9 @@ SOAP_FMAC1 int SOAP_FMAC2 soap_string_out(struct soap *soap, const char *s, int flag) -{ register const char *t; - register soap_wchar c; - register soap_wchar mask = (soap_wchar)0xFFFFFF80UL; +{ const char *t; + soap_wchar c; + soap_wchar mask = (soap_wchar)0xFFFFFF80UL; #ifdef WITH_DOM if ((soap->mode & SOAP_XML_DOM) && soap->dom) { soap->dom->data = soap_strdup(soap, s); @@ -10888,7 +10888,7 @@ soap_string_out(struct soap *soap, const char *s, int flag) #ifdef HAVE_MBTOWC if (soap->mode & SOAP_C_MBSTRING) { wchar_t wc; - register int m = mbtowc(&wc, t - 1, MB_CUR_MAX); + int m = mbtowc(&wc, t - 1, MB_CUR_MAX); if (m > 0 && !((soap_wchar)wc == c && m == 1 && c < 0x80)) { if (soap_send_raw(soap, s, t - s - 1) || soap_pututf8(soap, (unsigned long)wc)) return soap->error; @@ -10917,12 +10917,12 @@ SOAP_FMAC1 char * SOAP_FMAC2 soap_string_in(struct soap *soap, int flag, long minlen, long maxlen) -{ register char *s; +{ char *s; char *t = NULL; - register size_t i; - register long l = 0; - register int n = 0, f = 0, m = 0; - register soap_wchar c; + size_t i; + long l = 0; + int n = 0, f = 0, m = 0; + soap_wchar c; #if !defined(WITH_LEANER) && defined(HAVE_WCTOMB) char buf[MB_LEN_MAX > 8 ? MB_LEN_MAX : 8]; #else @@ -10971,7 +10971,7 @@ soap_string_in(struct soap *soap, int flag, long minlen, long maxlen) } #ifdef WITH_CDATA if (!flag) - { register int state = 0; + { int state = 0; #ifdef WITH_FAST soap->labidx = 0; /* use look-aside buffer */ #else @@ -10981,14 +10981,14 @@ soap_string_in(struct soap *soap, int flag, long minlen, long maxlen) for (;;) { #ifdef WITH_FAST - register size_t k; + size_t k; if (soap_append_lab(soap, NULL, 0)) /* allocate more space in look-aside buffer if necessary */ return NULL; s = soap->labbuf + soap->labidx; /* space to populate */ k = soap->lablen - soap->labidx; /* number of bytes available */ soap->labidx = soap->lablen; /* claim this space */ #else - register size_t k = SOAP_BLKLEN; + size_t k = SOAP_BLKLEN; if (!(s = (char*)soap_push_block(soap, NULL, k))) return NULL; #endif @@ -11218,14 +11218,14 @@ soap_string_in(struct soap *soap, int flag, long minlen, long maxlen) for (;;) { #ifdef WITH_FAST - register size_t k; + size_t k; if (soap_append_lab(soap, NULL, 0)) /* allocate more space in look-aside buffer if necessary */ return NULL; s = soap->labbuf + soap->labidx; /* space to populate */ k = soap->lablen - soap->labidx; /* number of bytes available */ soap->labidx = soap->lablen; /* claim this space */ #else - register size_t k = SOAP_BLKLEN; + size_t k = SOAP_BLKLEN; if (!(s = (char*)soap_push_block(soap, NULL, k))) return NULL; #endif @@ -11418,7 +11418,7 @@ SOAP_FMAC2 soap_wstring_out(struct soap *soap, const wchar_t *s, int flag) { const char *t; char tmp; - register soap_wchar c; + soap_wchar c; #ifdef WITH_DOM if ((soap->mode & SOAP_XML_DOM) && soap->dom) { wchar_t *r = (wchar_t*)s; @@ -11476,7 +11476,7 @@ soap_wstring_out(struct soap *soap, const wchar_t *s, int flag) else { /* check for UTF16 encoding when wchar_t is too small to hold UCS */ if (sizeof(wchar_t) < 4 && (c & 0xFC00) == 0xD800) - { register soap_wchar d = *s++; + { soap_wchar d = *s++; if ((d & 0xFC00) == 0xDC00) c = ((c - 0xD800) << 10) + (d - 0xDC00) + 0x10000; else @@ -11503,9 +11503,9 @@ wchar_t * SOAP_FMAC2 soap_wstring_in(struct soap *soap, int flag, long minlen, long maxlen) { wchar_t *s; - register int i, n = 0, f = 0; - register long l = 0; - register soap_wchar c; + int i, n = 0, f = 0; + long l = 0; + soap_wchar c; char *t = NULL; DBGLOG(TEST,SOAP_MESSAGE(fdebug, "Reading wide string content\n")); if (soap->peeked) @@ -11623,7 +11623,7 @@ soap_wstring_in(struct soap *soap, int flag, long minlen, long maxlen) goto end; /* use UTF16 encoding when wchar_t is too small to hold UCS */ if (sizeof(wchar_t) < 4 && c > 0xFFFF) - { register soap_wchar c1, c2; + { soap_wchar c1, c2; c1 = 0xD800 - (0x10000 >> 10) + (c >> 10); c2 = 0xDC00 + (c & 0x3FF); c = c1; @@ -12778,7 +12778,7 @@ soap_s2QName(struct soap *soap, const char *s, char **t, long minlen, long maxle for (;;) { size_t n; struct soap_nlist *np; - register const char *p; + const char *p; /* skip blanks */ while (*s && soap_blank((soap_wchar)*s)) s++; @@ -12956,7 +12956,7 @@ soap_s2wchar(struct soap *soap, const char *s, wchar_t **t, long minlen, long ma else { /* Convert UTF8 to wchar */ while (*s) - { register soap_wchar c, c1, c2, c3, c4; + { soap_wchar c, c1, c2, c3, c4; c = (unsigned char)*s++; if (c < 0x80) *r++ = (wchar_t)c; @@ -12999,8 +12999,8 @@ SOAP_FMAC1 const char* SOAP_FMAC2 soap_wchar2s(struct soap *soap, const wchar_t *s) -{ register soap_wchar c; - register char *r, *t; +{ soap_wchar c; + char *r, *t; const wchar_t *q = s; size_t n = 0; while ((c = *q++)) @@ -13554,9 +13554,9 @@ SOAP_FMAC1 const char * SOAP_FMAC2 soap_value(struct soap *soap) -{ register size_t i; - register soap_wchar c = 0; - register char *s = soap->tmpbuf; +{ size_t i; + soap_wchar c = 0; + char *s = soap->tmpbuf; if (!soap->body) return SOAP_STR_EOS; do c = soap_get(soap); @@ -13631,8 +13631,8 @@ static size_t soap_count_attachments(struct soap *soap) { #ifndef WITH_LEANER - register struct soap_multipart *content; - register size_t count = soap->count; + struct soap_multipart *content; + size_t count = soap->count; DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Calculating the message size with attachments, current count=%lu\n", (unsigned long)count)); if ((soap->mode & SOAP_ENC_DIME) && !(soap->mode & SOAP_ENC_MTOM)) { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Calculating the size of DIME attachments\n")); @@ -13648,10 +13648,10 @@ soap_count_attachments(struct soap *soap) } } if ((soap->mode & SOAP_ENC_MIME) && soap->mime.boundary) - { register size_t n = strlen(soap->mime.boundary); + { size_t n = strlen(soap->mime.boundary); DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Calculating the size of MIME attachments\n")); for (content = soap->mime.first; content; content = content->next) - { register const char *s; + { const char *s; /* count \r\n--boundary\r\n */ count += 6 + n; /* count Content-Type: ...\r\n */ @@ -13859,10 +13859,10 @@ soap_putdime(struct soap *soap) #ifndef PALM_1 static char * soap_getdimefield(struct soap *soap, size_t n) -{ register soap_wchar c; - register size_t i; - register char *s; - register char *p = NULL; +{ soap_wchar c; + size_t i; + char *s; + char *p = NULL; if (n) { p = (char*)soap_malloc(soap, n + 1); if (p) @@ -13893,9 +13893,9 @@ SOAP_FMAC1 int SOAP_FMAC2 soap_getdimehdr(struct soap *soap) -{ register soap_wchar c; - register char *s; - register int i; +{ soap_wchar c; + char *s; + int i; unsigned char tmp[12]; size_t optlen, idlen, typelen; if (!(soap->mode & SOAP_ENC_DIME)) @@ -13952,7 +13952,7 @@ soap_getdime(struct soap *soap) if (soap_move(soap, (long)(((soap->dime.size+3)&(~3))-soap_tell(soap)))) return soap->error = SOAP_EOF; for (;;) - { register struct soap_multipart *content; + { struct soap_multipart *content; if (soap_getdimehdr(soap)) break; if (soap->fdimewriteopen && ((soap->dime.ptr = (char*)soap->fdimewriteopen(soap, soap->dime.id, soap->dime.type, soap->dime.options)) || soap->error)) @@ -14006,9 +14006,9 @@ soap_getdime(struct soap *soap) if (soap_new_block(soap) == NULL) return SOAP_EOM; for (;;) - { register soap_wchar c; - register size_t i; - register char *s; + { soap_wchar c; + size_t i; + char *s; s = (char*)soap_push_block(soap, NULL, soap->dime.size); if (!s) return soap->error = SOAP_EOM; @@ -14083,8 +14083,8 @@ soap_getmimehdr(struct soap *soap) return soap->error = SOAP_EOM; content = soap->mime.last; for (;;) - { register char *key = soap->msgbuf; - register char *val; + { char *key = soap->msgbuf; + char *val; if (!*key) break; DBGLOG(TEST,SOAP_MESSAGE(fdebug, "MIME header: %s\n", key)); @@ -14161,11 +14161,11 @@ SOAP_FMAC1 struct soap_multipart * SOAP_FMAC2 soap_get_mime_attachment(struct soap *soap, void *handle) -{ register soap_wchar c = 0; - register size_t i, m = 0; - register char *s, *t = NULL; - register struct soap_multipart *content; - register short flag = 0; +{ soap_wchar c = 0; + size_t i, m = 0; + char *s, *t = NULL; + struct soap_multipart *content; + short flag = 0; if (!(soap->mode & SOAP_ENC_MIME)) return NULL; content = soap->mime.last; @@ -14283,7 +14283,7 @@ SOAP_FMAC1 int SOAP_FMAC2 soap_match_cid(struct soap *soap, const char *s, const char *t) -{ register size_t n; +{ size_t n; if (!s) return 1; if (!strcmp(s, t)) @@ -14311,10 +14311,10 @@ soap_match_cid(struct soap *soap, const char *s, const char *t) static void soap_resolve_attachment(struct soap *soap, struct soap_multipart *content) { if (content->id) - { register struct soap_xlist **xp = &soap->xlist; + { struct soap_xlist **xp = &soap->xlist; DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Resolving attachment data for id=%s\n", content->id)); while (*xp) - { register struct soap_xlist *xq = *xp; + { struct soap_xlist *xq = *xp; if (!soap_match_cid(soap, xq->id, content->id)) { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Found matching attachment %s for content id=%s\n", xq->id, content->id)); *xp = xq->next; @@ -14574,8 +14574,8 @@ soap_next_multipart(struct soap_multipart *content) static void soap_select_mime_boundary(struct soap *soap) { while (!soap->mime.boundary || soap_valid_mime_boundary(soap)) - { register char *s = soap->mime.boundary; - register size_t n = 0; + { char *s = soap->mime.boundary; + size_t n = 0; if (s) n = strlen(s); if (n < 16) @@ -14604,15 +14604,15 @@ soap_select_mime_boundary(struct soap *soap) #ifndef PALM_1 static int soap_valid_mime_boundary(struct soap *soap) -{ register struct soap_multipart *content; - register size_t k; +{ struct soap_multipart *content; + size_t k; if (soap->fmimeread) return SOAP_OK; k = strlen(soap->mime.boundary); for (content = soap->mime.first; content; content = content->next) { if (content->ptr && content->size >= k) - { register const char *p = (const char*)content->ptr; - register size_t i; + { const char *p = (const char*)content->ptr; + size_t i; for (i = 0; i < content->size - k; i++, p++) { if (!strncmp(p, soap->mime.boundary, k)) return SOAP_ERR; @@ -14705,7 +14705,7 @@ SOAP_FMAC1 int SOAP_FMAC2 soap_begin_recv(struct soap *soap) -{ register soap_wchar c; +{ soap_wchar c; DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Initializing for input\n")); soap->error = SOAP_OK; soap->filterstop = SOAP_OK; @@ -15069,8 +15069,8 @@ SOAP_FMAC2 soap_get_http_body(struct soap *soap) { #ifndef WITH_LEAN - register size_t l = 0, n = 0; - register char *s; + size_t l = 0, n = 0; + char *s; /* get HTML body of HTTP error content */ if (!(soap->mode & SOAP_ENC_ZLIB) && (soap->mode & SOAP_IO) != SOAP_IO_CHUNK) { n = soap->length; @@ -15087,19 +15087,19 @@ soap_get_http_body(struct soap *soap) for (;;) { #ifdef WITH_FAST - register size_t i, k; + size_t i, k; if (soap_append_lab(soap, NULL, 0)) /* allocate more space in look-aside buffer if necessary */ return NULL; s = soap->labbuf + soap->labidx; /* space to populate */ k = soap->lablen - soap->labidx; /* number of bytes available */ soap->labidx = soap->lablen; /* claim this space */ #else - register size_t i, k = SOAP_BLKLEN; + size_t i, k = SOAP_BLKLEN; if (!(s = (char*)soap_push_block(soap, NULL, k))) return NULL; #endif for (i = 0; i < k; i++) - { register soap_wchar c; + { soap_wchar c; l++; if (n > 0 && l > n) goto end; @@ -15131,7 +15131,7 @@ SOAP_FMAC1 int SOAP_FMAC2 soap_envelope_begin_in(struct soap *soap) -{ register struct Namespace *p; +{ struct Namespace *p; soap->part = SOAP_IN_ENVELOPE; if (soap_element_begin_in(soap, "SOAP-ENV:Envelope", 0, NULL)) { if (soap->error == SOAP_TAG_MISMATCH) @@ -15268,8 +15268,8 @@ SOAP_FMAC1 void SOAP_FMAC2 soap_set_endpoint(struct soap *soap, const char *endpoint) -{ register const char *s; - register size_t i, n; +{ const char *s; + size_t i, n; soap->endpoint[0] = '\0'; soap->host[0] = '\0'; soap->path[0] = '/'; @@ -15537,9 +15537,9 @@ SOAP_FMAC1 char* SOAP_FMAC2 soap_s2base64(struct soap *soap, const unsigned char *s, char *t, int n) -{ register int i; - register unsigned long m; - register char *p; +{ int i; + unsigned long m; + char *p; if (!t) t = (char*)soap_malloc(soap, (n + 2) / 3 * 4 + 1); if (!t) @@ -15579,10 +15579,10 @@ SOAP_FMAC1 const char* SOAP_FMAC2 soap_base642s(struct soap *soap, const char *s, char *t, size_t l, int *n) -{ register size_t i, j; - register soap_wchar c; - register unsigned long m; - register const char *p; +{ size_t i, j; + soap_wchar c; + unsigned long m; + const char *p; if (!s || !*s) { if (n) *n = 0; @@ -15661,7 +15661,7 @@ SOAP_FMAC1 char* SOAP_FMAC2 soap_s2hex(struct soap *soap, const unsigned char *s, char *t, int n) -{ register char *p; +{ char *p; if (!t) t = (char*)soap_malloc(soap, 2 * n + 1); if (!t) @@ -15670,7 +15670,7 @@ soap_s2hex(struct soap *soap, const unsigned char *s, char *t, int n) t[0] = '\0'; if (s) { for (; n > 0; n--) - { register int m = *s++; + { int m = *s++; *t++ = (char)((m >> 4) + (m > 159 ? 'a' - 10 : '0')); m &= 0x0F; *t++ = (char)(m + (m > 9 ? 'a' - 10 : '0')); @@ -15687,7 +15687,7 @@ SOAP_FMAC1 const char* SOAP_FMAC2 soap_hex2s(struct soap *soap, const char *s, char *t, size_t l, int *n) -{ register const char *p; +{ const char *p; if (!s || !*s) { if (n) *n = 0; @@ -15703,7 +15703,7 @@ soap_hex2s(struct soap *soap, const char *s, char *t, size_t l, int *n) return NULL; p = t; while (l) - { register int d1, d2; + { int d1, d2; d1 = *s++; if (!d1) break; @@ -15729,10 +15729,10 @@ int SOAP_FMAC2 soap_puthttphdr(struct soap *soap, int status, size_t count) { if (soap->status != SOAP_GET && soap->status != SOAP_DEL && soap->status != SOAP_CONNECT) - { register const char *s = "text/xml; charset=utf-8"; - register int err = SOAP_OK; + { const char *s = "text/xml; charset=utf-8"; + int err = SOAP_OK; #ifndef WITH_LEANER - register const char *r = NULL; + const char *r = NULL; #endif if ((status == SOAP_FILE || soap->status == SOAP_PUT || soap->status == SOAP_POST_FILE) && soap->http_content) s = soap->http_content; @@ -15755,7 +15755,7 @@ soap_puthttphdr(struct soap *soap, int status, size_t count) s = "application/dime"; } if ((soap->mode & SOAP_ENC_MIME) && soap->mime.boundary && strlen(soap->mime.boundary) + strlen(soap->mime.start ? soap->mime.start : SOAP_STR_EOS) < sizeof(soap->tmpbuf) - 80) - { register const char *t = strchr(s, ';'); + { const char *t = strchr(s, ';'); sprintf(soap->tmpbuf, "multipart/related; charset=utf-8; boundary=\"%s\"; type=\"", soap->mime.boundary); if (t) { strncat(soap->tmpbuf, s, t - s); @@ -16067,7 +16067,7 @@ SOAP_FMAC1 int SOAP_FMAC2 soap_send_fault(struct soap *soap) -{ register int status = soap->error; +{ int status = soap->error; if (status == SOAP_STOP) return soap_closesock(soap); DBGLOG(TEST,SOAP_MESSAGE(fdebug, "Sending back fault struct for error code %d\n", soap->error)); @@ -16128,7 +16128,7 @@ SOAP_FMAC1 int SOAP_FMAC2 soap_recv_fault(struct soap *soap, int check) -{ register int status = soap->error; +{ int status = soap->error; DBGLOG(TEST,SOAP_MESSAGE(fdebug, "Check if receiving SOAP Fault\n")); if (!check) { /* try getfault when no tag or tag mismatched at level 2, otherwise ret */ @@ -16149,7 +16149,7 @@ soap_recv_fault(struct soap *soap, int check) soap_set_fault(soap); } else - { register const char *s = *soap_faultcode(soap); + { const char *s = *soap_faultcode(soap); if (!soap_match_tag(soap, s, "SOAP-ENV:Server") || !soap_match_tag(soap, s, "SOAP-ENV:Receiver")) status = SOAP_SVR_FAULT; else if (!soap_match_tag(soap, s, "SOAP-ENV:Client") || !soap_match_tag(soap, s, "SOAP-ENV:Sender")) @@ -16178,7 +16178,7 @@ SOAP_FMAC1 int SOAP_FMAC2 soap_send_empty_response(struct soap *soap, int httpstatuscode) -{ register soap_mode m = soap->omode; +{ soap_mode m = soap->omode; if (!(m & SOAP_IO_UDP)) { soap->count = 0; if ((m & SOAP_IO) == SOAP_IO_CHUNK) @@ -16215,7 +16215,7 @@ soap_recv_empty_response(struct soap *soap) #ifndef PALM_1 static const char* soap_strerror(struct soap *soap) -{ register int err = soap->errnum; +{ int err = soap->errnum; *soap->msgbuf = '\0'; if (err) { @@ -16279,7 +16279,7 @@ soap_set_error(struct soap *soap, const char *faultcode, const char *faultsubcod *soap_faultsubcode(soap) = faultsubcodeQName; *soap_faultstring(soap) = faultstring; if (faultdetailXML && *faultdetailXML) - { register const char **s = soap_faultdetail(soap); + { const char **s = soap_faultdetail(soap); if (s) *s = faultdetailXML; } @@ -16495,8 +16495,8 @@ SOAP_FMAC1 int SOAP_FMAC2 soap_register_plugin_arg(struct soap *soap, int (*fcreate)(struct soap*, struct soap_plugin*, void*), void *arg) -{ register struct soap_plugin *p; - register int r; +{ struct soap_plugin *p; + int r; if (!(p = (struct soap_plugin*)SOAP_MALLOC(soap, sizeof(struct soap_plugin)))) return soap->error = SOAP_EOM; p->id = NULL; @@ -16520,7 +16520,7 @@ soap_register_plugin_arg(struct soap *soap, int (*fcreate)(struct soap*, struct #ifndef PALM_1 static void * fplugin(struct soap *soap, const char *id) -{ register struct soap_plugin *p; +{ struct soap_plugin *p; for (p = soap->plugins; p; p = p->next) if (p->id == id || !strcmp(p->id, id)) return p->data; diff --git a/Code/Mantid/Framework/ICat/src/ICat3/GSoapGenerated/ICat3C.cpp b/Code/Mantid/Framework/ICat/src/ICat3/GSoapGenerated/ICat3C.cpp index 67f0137d70c6..22939e9c8492 100644 --- a/Code/Mantid/Framework/ICat/src/ICat3/GSoapGenerated/ICat3C.cpp +++ b/Code/Mantid/Framework/ICat/src/ICat3/GSoapGenerated/ICat3C.cpp @@ -11795,7 +11795,7 @@ SOAP_FMAC3 char * SOAP_FMAC4 soap_in_byte(struct soap *soap, const char *tag, ch SOAP_FMAC3 int SOAP_FMAC4 soap_put_byte(struct soap *soap, const char *a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_byte); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_byte); if (soap_out_byte(soap, tag?tag:"byte", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -11832,7 +11832,7 @@ SOAP_FMAC3 int * SOAP_FMAC4 soap_in_int(struct soap *soap, const char *tag, int SOAP_FMAC3 int SOAP_FMAC4 soap_put_int(struct soap *soap, const int *a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_int); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_int); if (soap_out_int(soap, tag?tag:"int", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -11869,7 +11869,7 @@ SOAP_FMAC3 LONG64 * SOAP_FMAC4 soap_in_LONG64(struct soap *soap, const char *tag SOAP_FMAC3 int SOAP_FMAC4 soap_put_LONG64(struct soap *soap, const LONG64 *a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_LONG64); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_LONG64); if (soap_out_LONG64(soap, tag?tag:"long", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -11906,7 +11906,7 @@ SOAP_FMAC3 float * SOAP_FMAC4 soap_in_float(struct soap *soap, const char *tag, SOAP_FMAC3 int SOAP_FMAC4 soap_put_float(struct soap *soap, const float *a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_float); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_float); if (soap_out_float(soap, tag?tag:"float", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -11943,7 +11943,7 @@ SOAP_FMAC3 double * SOAP_FMAC4 soap_in_double(struct soap *soap, const char *tag SOAP_FMAC3 int SOAP_FMAC4 soap_put_double(struct soap *soap, const double *a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_double); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_double); if (soap_out_double(soap, tag?tag:"double", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -11980,7 +11980,7 @@ SOAP_FMAC3 time_t * SOAP_FMAC4 soap_in_time(struct soap *soap, const char *tag, SOAP_FMAC3 int SOAP_FMAC4 soap_put_time(struct soap *soap, const time_t *a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_time); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_time); if (soap_out_time(soap, tag?tag:"dateTime", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -12070,7 +12070,7 @@ SOAP_FMAC3 enum ns1__elementType * SOAP_FMAC4 soap_in_ns1__elementType(struct so SOAP_FMAC3 int SOAP_FMAC4 soap_put_ns1__elementType(struct soap *soap, const enum ns1__elementType *a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__elementType); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__elementType); if (soap_out_ns1__elementType(soap, tag?tag:"ns1:elementType", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -12152,7 +12152,7 @@ SOAP_FMAC3 enum ns1__parameterType * SOAP_FMAC4 soap_in_ns1__parameterType(struc SOAP_FMAC3 int SOAP_FMAC4 soap_put_ns1__parameterType(struct soap *soap, const enum ns1__parameterType *a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__parameterType); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__parameterType); if (soap_out_ns1__parameterType(soap, tag?tag:"ns1:parameterType", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -12234,7 +12234,7 @@ SOAP_FMAC3 enum ns1__keywordType * SOAP_FMAC4 soap_in_ns1__keywordType(struct so SOAP_FMAC3 int SOAP_FMAC4 soap_put_ns1__keywordType(struct soap *soap, const enum ns1__keywordType *a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__keywordType); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__keywordType); if (soap_out_ns1__keywordType(soap, tag?tag:"ns1:keywordType", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -12323,7 +12323,7 @@ SOAP_FMAC3 enum ns1__comparisonOperator * SOAP_FMAC4 soap_in_ns1__comparisonOper SOAP_FMAC3 int SOAP_FMAC4 soap_put_ns1__comparisonOperator(struct soap *soap, const enum ns1__comparisonOperator *a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__comparisonOperator); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__comparisonOperator); if (soap_out_ns1__comparisonOperator(soap, tag?tag:"ns1:comparisonOperator", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -12405,7 +12405,7 @@ SOAP_FMAC3 enum ns1__parameterValueType * SOAP_FMAC4 soap_in_ns1__parameterValue SOAP_FMAC3 int SOAP_FMAC4 soap_put_ns1__parameterValueType(struct soap *soap, const enum ns1__parameterValueType *a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__parameterValueType); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__parameterValueType); if (soap_out_ns1__parameterValueType(soap, tag?tag:"ns1:parameterValueType", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -12485,7 +12485,7 @@ SOAP_FMAC3 enum ns1__sampleInclude * SOAP_FMAC4 soap_in_ns1__sampleInclude(struc SOAP_FMAC3 int SOAP_FMAC4 soap_put_ns1__sampleInclude(struct soap *soap, const enum ns1__sampleInclude *a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__sampleInclude); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__sampleInclude); if (soap_out_ns1__sampleInclude(soap, tag?tag:"ns1:sampleInclude", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -12627,7 +12627,7 @@ SOAP_FMAC3 enum ns1__restrictionAttributes * SOAP_FMAC4 soap_in_ns1__restriction SOAP_FMAC3 int SOAP_FMAC4 soap_put_ns1__restrictionAttributes(struct soap *soap, const enum ns1__restrictionAttributes *a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__restrictionAttributes); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__restrictionAttributes); if (soap_out_ns1__restrictionAttributes(soap, tag?tag:"ns1:restrictionAttributes", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -12724,7 +12724,7 @@ SOAP_FMAC3 enum ns1__investigationInclude * SOAP_FMAC4 soap_in_ns1__investigatio SOAP_FMAC3 int SOAP_FMAC4 soap_put_ns1__investigationInclude(struct soap *soap, const enum ns1__investigationInclude *a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__investigationInclude); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__investigationInclude); if (soap_out_ns1__investigationInclude(soap, tag?tag:"ns1:investigationInclude", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -12807,7 +12807,7 @@ SOAP_FMAC3 enum ns1__datasetInclude * SOAP_FMAC4 soap_in_ns1__datasetInclude(str SOAP_FMAC3 int SOAP_FMAC4 soap_put_ns1__datasetInclude(struct soap *soap, const enum ns1__datasetInclude *a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__datasetInclude); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__datasetInclude); if (soap_out_ns1__datasetInclude(soap, tag?tag:"ns1:datasetInclude", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -12890,7 +12890,7 @@ SOAP_FMAC3 enum ns1__datafileInclude * SOAP_FMAC4 soap_in_ns1__datafileInclude(s SOAP_FMAC3 int SOAP_FMAC4 soap_put_ns1__datafileInclude(struct soap *soap, const enum ns1__datafileInclude *a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__datafileInclude); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__datafileInclude); if (soap_out_ns1__datafileInclude(soap, tag?tag:"ns1:datafileInclude", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -12971,7 +12971,7 @@ SOAP_FMAC3 enum ns1__logicalOperator * SOAP_FMAC4 soap_in_ns1__logicalOperator(s SOAP_FMAC3 int SOAP_FMAC4 soap_put_ns1__logicalOperator(struct soap *soap, const enum ns1__logicalOperator *a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__logicalOperator); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__logicalOperator); if (soap_out_ns1__logicalOperator(soap, tag?tag:"ns1:logicalOperator", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -13055,7 +13055,7 @@ SOAP_FMAC3 bool * SOAP_FMAC4 soap_in_bool(struct soap *soap, const char *tag, bo SOAP_FMAC3 int SOAP_FMAC4 soap_put_bool(struct soap *soap, const bool *a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_bool); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_bool); if (soap_out_bool(soap, tag?tag:"boolean", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -13122,7 +13122,7 @@ SOAP_FMAC3 ns1__elementType_ * SOAP_FMAC4 soap_in_ns1__elementType_(struct soap int ns1__elementType_::soap_put(struct soap *soap, const char *tag, const char *type) const { - register int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__elementType_); + int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__elementType_); if (this->soap_out(soap, tag?tag:"ns1:elementType", id, type)) return soap->error; return soap_putindependent(soap); @@ -13228,7 +13228,7 @@ SOAP_FMAC3 ns1__parameterType_ * SOAP_FMAC4 soap_in_ns1__parameterType_(struct s int ns1__parameterType_::soap_put(struct soap *soap, const char *tag, const char *type) const { - register int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__parameterType_); + int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__parameterType_); if (this->soap_out(soap, tag?tag:"ns1:parameterType", id, type)) return soap->error; return soap_putindependent(soap); @@ -13334,7 +13334,7 @@ SOAP_FMAC3 ns1__keywordType_ * SOAP_FMAC4 soap_in_ns1__keywordType_(struct soap int ns1__keywordType_::soap_put(struct soap *soap, const char *tag, const char *type) const { - register int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__keywordType_); + int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__keywordType_); if (this->soap_out(soap, tag?tag:"ns1:keywordType", id, type)) return soap->error; return soap_putindependent(soap); @@ -13440,7 +13440,7 @@ SOAP_FMAC3 ns1__comparisonOperator_ * SOAP_FMAC4 soap_in_ns1__comparisonOperator int ns1__comparisonOperator_::soap_put(struct soap *soap, const char *tag, const char *type) const { - register int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__comparisonOperator_); + int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__comparisonOperator_); if (this->soap_out(soap, tag?tag:"ns1:comparisonOperator", id, type)) return soap->error; return soap_putindependent(soap); @@ -13546,7 +13546,7 @@ SOAP_FMAC3 ns1__parameterValueType_ * SOAP_FMAC4 soap_in_ns1__parameterValueType int ns1__parameterValueType_::soap_put(struct soap *soap, const char *tag, const char *type) const { - register int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__parameterValueType_); + int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__parameterValueType_); if (this->soap_out(soap, tag?tag:"ns1:parameterValueType", id, type)) return soap->error; return soap_putindependent(soap); @@ -13652,7 +13652,7 @@ SOAP_FMAC3 ns1__sampleInclude_ * SOAP_FMAC4 soap_in_ns1__sampleInclude_(struct s int ns1__sampleInclude_::soap_put(struct soap *soap, const char *tag, const char *type) const { - register int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__sampleInclude_); + int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__sampleInclude_); if (this->soap_out(soap, tag?tag:"ns1:sampleInclude", id, type)) return soap->error; return soap_putindependent(soap); @@ -13758,7 +13758,7 @@ SOAP_FMAC3 ns1__restrictionAttributes_ * SOAP_FMAC4 soap_in_ns1__restrictionAttr int ns1__restrictionAttributes_::soap_put(struct soap *soap, const char *tag, const char *type) const { - register int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__restrictionAttributes_); + int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__restrictionAttributes_); if (this->soap_out(soap, tag?tag:"ns1:restrictionAttributes", id, type)) return soap->error; return soap_putindependent(soap); @@ -13864,7 +13864,7 @@ SOAP_FMAC3 ns1__investigationInclude_ * SOAP_FMAC4 soap_in_ns1__investigationInc int ns1__investigationInclude_::soap_put(struct soap *soap, const char *tag, const char *type) const { - register int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__investigationInclude_); + int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__investigationInclude_); if (this->soap_out(soap, tag?tag:"ns1:investigationInclude", id, type)) return soap->error; return soap_putindependent(soap); @@ -13970,7 +13970,7 @@ SOAP_FMAC3 ns1__datasetInclude_ * SOAP_FMAC4 soap_in_ns1__datasetInclude_(struct int ns1__datasetInclude_::soap_put(struct soap *soap, const char *tag, const char *type) const { - register int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__datasetInclude_); + int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__datasetInclude_); if (this->soap_out(soap, tag?tag:"ns1:datasetInclude", id, type)) return soap->error; return soap_putindependent(soap); @@ -14076,7 +14076,7 @@ SOAP_FMAC3 ns1__datafileInclude_ * SOAP_FMAC4 soap_in_ns1__datafileInclude_(stru int ns1__datafileInclude_::soap_put(struct soap *soap, const char *tag, const char *type) const { - register int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__datafileInclude_); + int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__datafileInclude_); if (this->soap_out(soap, tag?tag:"ns1:datafileInclude", id, type)) return soap->error; return soap_putindependent(soap); @@ -14182,7 +14182,7 @@ SOAP_FMAC3 ns1__logicalOperator_ * SOAP_FMAC4 soap_in_ns1__logicalOperator_(stru int ns1__logicalOperator_::soap_put(struct soap *soap, const char *tag, const char *type) const { - register int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__logicalOperator_); + int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__logicalOperator_); if (this->soap_out(soap, tag?tag:"ns1:logicalOperator", id, type)) return soap->error; return soap_putindependent(soap); @@ -14343,7 +14343,7 @@ SOAP_FMAC3 ns3__NoSuchUserException * SOAP_FMAC4 soap_in_ns3__NoSuchUserExceptio int ns3__NoSuchUserException::soap_put(struct soap *soap, const char *tag, const char *type) const { - register int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns3__NoSuchUserException); + int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns3__NoSuchUserException); if (this->soap_out(soap, tag?tag:"ns3:NoSuchUserException", id, type)) return soap->error; return soap_putindependent(soap); @@ -14484,7 +14484,7 @@ SOAP_FMAC3 ns3__getUserDetailsResponse * SOAP_FMAC4 soap_in_ns3__getUserDetailsR int ns3__getUserDetailsResponse::soap_put(struct soap *soap, const char *tag, const char *type) const { - register int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns3__getUserDetailsResponse); + int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns3__getUserDetailsResponse); if (this->soap_out(soap, tag?tag:"ns3:getUserDetailsResponse", id, type)) return soap->error; return soap_putindependent(soap); @@ -14635,7 +14635,7 @@ SOAP_FMAC3 ns3__getUserDetails * SOAP_FMAC4 soap_in_ns3__getUserDetails(struct s int ns3__getUserDetails::soap_put(struct soap *soap, const char *tag, const char *type) const { - register int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns3__getUserDetails); + int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns3__getUserDetails); if (this->soap_out(soap, tag?tag:"ns3:getUserDetails", id, type)) return soap->error; return soap_putindependent(soap); @@ -14796,7 +14796,7 @@ SOAP_FMAC3 ns3__ValidationException * SOAP_FMAC4 soap_in_ns3__ValidationExceptio int ns3__ValidationException::soap_put(struct soap *soap, const char *tag, const char *type) const { - register int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns3__ValidationException); + int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns3__ValidationException); if (this->soap_out(soap, tag?tag:"ns3:ValidationException", id, type)) return soap->error; return soap_putindependent(soap); @@ -14957,7 +14957,7 @@ SOAP_FMAC3 ns3__NoSuchObjectFoundException * SOAP_FMAC4 soap_in_ns3__NoSuchObjec int ns3__NoSuchObjectFoundException::soap_put(struct soap *soap, const char *tag, const char *type) const { - register int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns3__NoSuchObjectFoundException); + int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns3__NoSuchObjectFoundException); if (this->soap_out(soap, tag?tag:"ns3:NoSuchObjectFoundException", id, type)) return soap->error; return soap_putindependent(soap); @@ -15118,7 +15118,7 @@ SOAP_FMAC3 ns3__SessionException * SOAP_FMAC4 soap_in_ns3__SessionException(stru int ns3__SessionException::soap_put(struct soap *soap, const char *tag, const char *type) const { - register int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns3__SessionException); + int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns3__SessionException); if (this->soap_out(soap, tag?tag:"ns3:SessionException", id, type)) return soap->error; return soap_putindependent(soap); @@ -15256,7 +15256,7 @@ SOAP_FMAC3 ns1__searchInvestigationByRestrictionComparasionResponse * SOAP_FMAC4 int ns1__searchInvestigationByRestrictionComparasionResponse::soap_put(struct soap *soap, const char *tag, const char *type) const { - register int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__searchInvestigationByRestrictionComparasionResponse); + int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__searchInvestigationByRestrictionComparasionResponse); if (this->soap_out(soap, tag?tag:"ns1:searchInvestigationByRestrictionComparasionResponse", id, type)) return soap->error; return soap_putindependent(soap); @@ -15404,7 +15404,7 @@ SOAP_FMAC3 ns1__searchInvestigationByRestrictionComparasion * SOAP_FMAC4 soap_in int ns1__searchInvestigationByRestrictionComparasion::soap_put(struct soap *soap, const char *tag, const char *type) const { - register int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__searchInvestigationByRestrictionComparasion); + int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__searchInvestigationByRestrictionComparasion); if (this->soap_out(soap, tag?tag:"ns1:searchInvestigationByRestrictionComparasion", id, type)) return soap->error; return soap_putindependent(soap); @@ -15542,7 +15542,7 @@ SOAP_FMAC3 ns1__getDatasetsResponse * SOAP_FMAC4 soap_in_ns1__getDatasetsRespons int ns1__getDatasetsResponse::soap_put(struct soap *soap, const char *tag, const char *type) const { - register int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__getDatasetsResponse); + int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__getDatasetsResponse); if (this->soap_out(soap, tag?tag:"ns1:getDatasetsResponse", id, type)) return soap->error; return soap_putindependent(soap); @@ -15690,7 +15690,7 @@ SOAP_FMAC3 ns1__getDatasets * SOAP_FMAC4 soap_in_ns1__getDatasets(struct soap *s int ns1__getDatasets::soap_put(struct soap *soap, const char *tag, const char *type) const { - register int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__getDatasets); + int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__getDatasets); if (this->soap_out(soap, tag?tag:"ns1:getDatasets", id, type)) return soap->error; return soap_putindependent(soap); @@ -15794,7 +15794,7 @@ SOAP_FMAC3 ns1__modifyDataFileParameterResponse * SOAP_FMAC4 soap_in_ns1__modify int ns1__modifyDataFileParameterResponse::soap_put(struct soap *soap, const char *tag, const char *type) const { - register int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__modifyDataFileParameterResponse); + int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__modifyDataFileParameterResponse); if (this->soap_out(soap, tag?tag:"ns1:modifyDataFileParameterResponse", id, type)) return soap->error; return soap_putindependent(soap); @@ -15945,7 +15945,7 @@ SOAP_FMAC3 ns1__modifyDataFileParameter * SOAP_FMAC4 soap_in_ns1__modifyDataFile int ns1__modifyDataFileParameter::soap_put(struct soap *soap, const char *tag, const char *type) const { - register int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__modifyDataFileParameter); + int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__modifyDataFileParameter); if (this->soap_out(soap, tag?tag:"ns1:modifyDataFileParameter", id, type)) return soap->error; return soap_putindependent(soap); @@ -16083,7 +16083,7 @@ SOAP_FMAC3 ns1__listParametersResponse * SOAP_FMAC4 soap_in_ns1__listParametersR int ns1__listParametersResponse::soap_put(struct soap *soap, const char *tag, const char *type) const { - register int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__listParametersResponse); + int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__listParametersResponse); if (this->soap_out(soap, tag?tag:"ns1:listParametersResponse", id, type)) return soap->error; return soap_putindependent(soap); @@ -16224,7 +16224,7 @@ SOAP_FMAC3 ns1__listParameters * SOAP_FMAC4 soap_in_ns1__listParameters(struct s int ns1__listParameters::soap_put(struct soap *soap, const char *tag, const char *type) const { - register int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__listParameters); + int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__listParameters); if (this->soap_out(soap, tag?tag:"ns1:listParameters", id, type)) return soap->error; return soap_putindependent(soap); @@ -16362,7 +16362,7 @@ SOAP_FMAC3 ns1__searchSampleByParameterComparisonResponse * SOAP_FMAC4 soap_in_n int ns1__searchSampleByParameterComparisonResponse::soap_put(struct soap *soap, const char *tag, const char *type) const { - register int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__searchSampleByParameterComparisonResponse); + int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__searchSampleByParameterComparisonResponse); if (this->soap_out(soap, tag?tag:"ns1:searchSampleByParameterComparisonResponse", id, type)) return soap->error; return soap_putindependent(soap); @@ -16510,7 +16510,7 @@ SOAP_FMAC3 ns1__searchSampleByParameterComparison * SOAP_FMAC4 soap_in_ns1__sear int ns1__searchSampleByParameterComparison::soap_put(struct soap *soap, const char *tag, const char *type) const { - register int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__searchSampleByParameterComparison); + int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__searchSampleByParameterComparison); if (this->soap_out(soap, tag?tag:"ns1:searchSampleByParameterComparison", id, type)) return soap->error; return soap_putindependent(soap); @@ -16614,7 +16614,7 @@ SOAP_FMAC3 ns1__deleteSampleParameterResponse * SOAP_FMAC4 soap_in_ns1__deleteSa int ns1__deleteSampleParameterResponse::soap_put(struct soap *soap, const char *tag, const char *type) const { - register int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__deleteSampleParameterResponse); + int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__deleteSampleParameterResponse); if (this->soap_out(soap, tag?tag:"ns1:deleteSampleParameterResponse", id, type)) return soap->error; return soap_putindependent(soap); @@ -16765,7 +16765,7 @@ SOAP_FMAC3 ns1__deleteSampleParameter * SOAP_FMAC4 soap_in_ns1__deleteSamplePara int ns1__deleteSampleParameter::soap_put(struct soap *soap, const char *tag, const char *type) const { - register int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__deleteSampleParameter); + int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__deleteSampleParameter); if (this->soap_out(soap, tag?tag:"ns1:deleteSampleParameter", id, type)) return soap->error; return soap_putindependent(soap); @@ -16903,7 +16903,7 @@ SOAP_FMAC3 ns1__searchSampleByRestrictionLogicalResponse * SOAP_FMAC4 soap_in_ns int ns1__searchSampleByRestrictionLogicalResponse::soap_put(struct soap *soap, const char *tag, const char *type) const { - register int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__searchSampleByRestrictionLogicalResponse); + int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__searchSampleByRestrictionLogicalResponse); if (this->soap_out(soap, tag?tag:"ns1:searchSampleByRestrictionLogicalResponse", id, type)) return soap->error; return soap_putindependent(soap); @@ -17054,7 +17054,7 @@ SOAP_FMAC3 ns1__searchSampleByRestrictionLogical * SOAP_FMAC4 soap_in_ns1__searc int ns1__searchSampleByRestrictionLogical::soap_put(struct soap *soap, const char *tag, const char *type) const { - register int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__searchSampleByRestrictionLogical); + int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__searchSampleByRestrictionLogical); if (this->soap_out(soap, tag?tag:"ns1:searchSampleByRestrictionLogical", id, type)) return soap->error; return soap_putindependent(soap); @@ -17195,7 +17195,7 @@ SOAP_FMAC3 ns1__addDataFileParameterResponse * SOAP_FMAC4 soap_in_ns1__addDataFi int ns1__addDataFileParameterResponse::soap_put(struct soap *soap, const char *tag, const char *type) const { - register int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__addDataFileParameterResponse); + int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__addDataFileParameterResponse); if (this->soap_out(soap, tag?tag:"ns1:addDataFileParameterResponse", id, type)) return soap->error; return soap_putindependent(soap); @@ -17356,7 +17356,7 @@ SOAP_FMAC3 ns1__addDataFileParameter * SOAP_FMAC4 soap_in_ns1__addDataFileParame int ns1__addDataFileParameter::soap_put(struct soap *soap, const char *tag, const char *type) const { - register int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__addDataFileParameter); + int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__addDataFileParameter); if (this->soap_out(soap, tag?tag:"ns1:addDataFileParameter", id, type)) return soap->error; return soap_putindependent(soap); @@ -17494,7 +17494,7 @@ SOAP_FMAC3 ns1__searchDatasetsBySampleResponse * SOAP_FMAC4 soap_in_ns1__searchD int ns1__searchDatasetsBySampleResponse::soap_put(struct soap *soap, const char *tag, const char *type) const { - register int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__searchDatasetsBySampleResponse); + int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__searchDatasetsBySampleResponse); if (this->soap_out(soap, tag?tag:"ns1:searchDatasetsBySampleResponse", id, type)) return soap->error; return soap_putindependent(soap); @@ -17645,7 +17645,7 @@ SOAP_FMAC3 ns1__searchDatasetsBySample * SOAP_FMAC4 soap_in_ns1__searchDatasetsB int ns1__searchDatasetsBySample::soap_put(struct soap *soap, const char *tag, const char *type) const { - register int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__searchDatasetsBySample); + int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__searchDatasetsBySample); if (this->soap_out(soap, tag?tag:"ns1:searchDatasetsBySample", id, type)) return soap->error; return soap_putindependent(soap); @@ -17786,7 +17786,7 @@ SOAP_FMAC3 ns1__createInvestigationResponse * SOAP_FMAC4 soap_in_ns1__createInve int ns1__createInvestigationResponse::soap_put(struct soap *soap, const char *tag, const char *type) const { - register int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__createInvestigationResponse); + int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__createInvestigationResponse); if (this->soap_out(soap, tag?tag:"ns1:createInvestigationResponse", id, type)) return soap->error; return soap_putindependent(soap); @@ -17937,7 +17937,7 @@ SOAP_FMAC3 ns1__createInvestigation * SOAP_FMAC4 soap_in_ns1__createInvestigatio int ns1__createInvestigation::soap_put(struct soap *soap, const char *tag, const char *type) const { - register int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__createInvestigation); + int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__createInvestigation); if (this->soap_out(soap, tag?tag:"ns1:createInvestigation", id, type)) return soap->error; return soap_putindependent(soap); @@ -18078,7 +18078,7 @@ SOAP_FMAC3 ns1__addPublicationResponse * SOAP_FMAC4 soap_in_ns1__addPublicationR int ns1__addPublicationResponse::soap_put(struct soap *soap, const char *tag, const char *type) const { - register int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__addPublicationResponse); + int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__addPublicationResponse); if (this->soap_out(soap, tag?tag:"ns1:addPublicationResponse", id, type)) return soap->error; return soap_putindependent(soap); @@ -18239,7 +18239,7 @@ SOAP_FMAC3 ns1__addPublication * SOAP_FMAC4 soap_in_ns1__addPublication(struct s int ns1__addPublication::soap_put(struct soap *soap, const char *tag, const char *type) const { - register int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__addPublication); + int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__addPublication); if (this->soap_out(soap, tag?tag:"ns1:addPublication", id, type)) return soap->error; return soap_putindependent(soap); @@ -18343,7 +18343,7 @@ SOAP_FMAC3 ns1__deleteDataFileParameterResponse * SOAP_FMAC4 soap_in_ns1__delete int ns1__deleteDataFileParameterResponse::soap_put(struct soap *soap, const char *tag, const char *type) const { - register int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__deleteDataFileParameterResponse); + int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__deleteDataFileParameterResponse); if (this->soap_out(soap, tag?tag:"ns1:deleteDataFileParameterResponse", id, type)) return soap->error; return soap_putindependent(soap); @@ -18494,7 +18494,7 @@ SOAP_FMAC3 ns1__deleteDataFileParameter * SOAP_FMAC4 soap_in_ns1__deleteDataFile int ns1__deleteDataFileParameter::soap_put(struct soap *soap, const char *tag, const char *type) const { - register int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__deleteDataFileParameter); + int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__deleteDataFileParameter); if (this->soap_out(soap, tag?tag:"ns1:deleteDataFileParameter", id, type)) return soap->error; return soap_putindependent(soap); @@ -18635,7 +18635,7 @@ SOAP_FMAC3 ns1__getInvestigationResponse * SOAP_FMAC4 soap_in_ns1__getInvestigat int ns1__getInvestigationResponse::soap_put(struct soap *soap, const char *tag, const char *type) const { - register int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__getInvestigationResponse); + int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__getInvestigationResponse); if (this->soap_out(soap, tag?tag:"ns1:getInvestigationResponse", id, type)) return soap->error; return soap_putindependent(soap); @@ -18786,7 +18786,7 @@ SOAP_FMAC3 ns1__getInvestigation * SOAP_FMAC4 soap_in_ns1__getInvestigation(stru int ns1__getInvestigation::soap_put(struct soap *soap, const char *tag, const char *type) const { - register int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__getInvestigation); + int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__getInvestigation); if (this->soap_out(soap, tag?tag:"ns1:getInvestigation", id, type)) return soap->error; return soap_putindependent(soap); @@ -18927,7 +18927,7 @@ SOAP_FMAC3 ns1__getInvestigationIncludesResponse * SOAP_FMAC4 soap_in_ns1__getIn int ns1__getInvestigationIncludesResponse::soap_put(struct soap *soap, const char *tag, const char *type) const { - register int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__getInvestigationIncludesResponse); + int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__getInvestigationIncludesResponse); if (this->soap_out(soap, tag?tag:"ns1:getInvestigationIncludesResponse", id, type)) return soap->error; return soap_putindependent(soap); @@ -19088,7 +19088,7 @@ SOAP_FMAC3 ns1__getInvestigationIncludes * SOAP_FMAC4 soap_in_ns1__getInvestigat int ns1__getInvestigationIncludes::soap_put(struct soap *soap, const char *tag, const char *type) const { - register int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__getInvestigationIncludes); + int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__getInvestigationIncludes); if (this->soap_out(soap, tag?tag:"ns1:getInvestigationIncludes", id, type)) return soap->error; return soap_putindependent(soap); @@ -19192,7 +19192,7 @@ SOAP_FMAC3 ns1__modifyDataFileResponse * SOAP_FMAC4 soap_in_ns1__modifyDataFileR int ns1__modifyDataFileResponse::soap_put(struct soap *soap, const char *tag, const char *type) const { - register int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__modifyDataFileResponse); + int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__modifyDataFileResponse); if (this->soap_out(soap, tag?tag:"ns1:modifyDataFileResponse", id, type)) return soap->error; return soap_putindependent(soap); @@ -19343,7 +19343,7 @@ SOAP_FMAC3 ns1__modifyDataFile * SOAP_FMAC4 soap_in_ns1__modifyDataFile(struct s int ns1__modifyDataFile::soap_put(struct soap *soap, const char *tag, const char *type) const { - register int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__modifyDataFile); + int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__modifyDataFile); if (this->soap_out(soap, tag?tag:"ns1:modifyDataFile", id, type)) return soap->error; return soap_putindependent(soap); @@ -19484,7 +19484,7 @@ SOAP_FMAC3 ns1__getDatafileResponse * SOAP_FMAC4 soap_in_ns1__getDatafileRespons int ns1__getDatafileResponse::soap_put(struct soap *soap, const char *tag, const char *type) const { - register int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__getDatafileResponse); + int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__getDatafileResponse); if (this->soap_out(soap, tag?tag:"ns1:getDatafileResponse", id, type)) return soap->error; return soap_putindependent(soap); @@ -19635,7 +19635,7 @@ SOAP_FMAC3 ns1__getDatafile * SOAP_FMAC4 soap_in_ns1__getDatafile(struct soap *s int ns1__getDatafile::soap_put(struct soap *soap, const char *tag, const char *type) const { - register int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__getDatafile); + int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__getDatafile); if (this->soap_out(soap, tag?tag:"ns1:getDatafile", id, type)) return soap->error; return soap_putindependent(soap); @@ -19796,7 +19796,7 @@ SOAP_FMAC3 ns1__ICATAPIException * SOAP_FMAC4 soap_in_ns1__ICATAPIException(stru int ns1__ICATAPIException::soap_put(struct soap *soap, const char *tag, const char *type) const { - register int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__ICATAPIException); + int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__ICATAPIException); if (this->soap_out(soap, tag?tag:"ns1:ICATAPIException", id, type)) return soap->error; return soap_putindependent(soap); @@ -19934,7 +19934,7 @@ SOAP_FMAC3 ns1__ingestMetadataResponse * SOAP_FMAC4 soap_in_ns1__ingestMetadataR int ns1__ingestMetadataResponse::soap_put(struct soap *soap, const char *tag, const char *type) const { - register int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__ingestMetadataResponse); + int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__ingestMetadataResponse); if (this->soap_out(soap, tag?tag:"ns1:ingestMetadataResponse", id, type)) return soap->error; return soap_putindependent(soap); @@ -20085,7 +20085,7 @@ SOAP_FMAC3 ns1__ingestMetadata * SOAP_FMAC4 soap_in_ns1__ingestMetadata(struct s int ns1__ingestMetadata::soap_put(struct soap *soap, const char *tag, const char *type) const { - register int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__ingestMetadata); + int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__ingestMetadata); if (this->soap_out(soap, tag?tag:"ns1:ingestMetadata", id, type)) return soap->error; return soap_putindependent(soap); @@ -20223,7 +20223,7 @@ SOAP_FMAC3 ns1__searchDatasetByRestrictionResponse * SOAP_FMAC4 soap_in_ns1__sea int ns1__searchDatasetByRestrictionResponse::soap_put(struct soap *soap, const char *tag, const char *type) const { - register int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__searchDatasetByRestrictionResponse); + int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__searchDatasetByRestrictionResponse); if (this->soap_out(soap, tag?tag:"ns1:searchDatasetByRestrictionResponse", id, type)) return soap->error; return soap_putindependent(soap); @@ -20374,7 +20374,7 @@ SOAP_FMAC3 ns1__searchDatasetByRestriction * SOAP_FMAC4 soap_in_ns1__searchDatas int ns1__searchDatasetByRestriction::soap_put(struct soap *soap, const char *tag, const char *type) const { - register int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__searchDatasetByRestriction); + int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__searchDatasetByRestriction); if (this->soap_out(soap, tag?tag:"ns1:searchDatasetByRestriction", id, type)) return soap->error; return soap_putindependent(soap); @@ -20512,7 +20512,7 @@ SOAP_FMAC3 ns1__listRolesResponse * SOAP_FMAC4 soap_in_ns1__listRolesResponse(st int ns1__listRolesResponse::soap_put(struct soap *soap, const char *tag, const char *type) const { - register int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__listRolesResponse); + int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__listRolesResponse); if (this->soap_out(soap, tag?tag:"ns1:listRolesResponse", id, type)) return soap->error; return soap_putindependent(soap); @@ -20653,7 +20653,7 @@ SOAP_FMAC3 ns1__listRoles * SOAP_FMAC4 soap_in_ns1__listRoles(struct soap *soap, int ns1__listRoles::soap_put(struct soap *soap, const char *tag, const char *type) const { - register int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__listRoles); + int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__listRoles); if (this->soap_out(soap, tag?tag:"ns1:listRoles", id, type)) return soap->error; return soap_putindependent(soap); @@ -20757,7 +20757,7 @@ SOAP_FMAC3 ns1__updateAuthorisationResponse * SOAP_FMAC4 soap_in_ns1__updateAuth int ns1__updateAuthorisationResponse::soap_put(struct soap *soap, const char *tag, const char *type) const { - register int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__updateAuthorisationResponse); + int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__updateAuthorisationResponse); if (this->soap_out(soap, tag?tag:"ns1:updateAuthorisationResponse", id, type)) return soap->error; return soap_putindependent(soap); @@ -20918,7 +20918,7 @@ SOAP_FMAC3 ns1__updateAuthorisation * SOAP_FMAC4 soap_in_ns1__updateAuthorisatio int ns1__updateAuthorisation::soap_put(struct soap *soap, const char *tag, const char *type) const { - register int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__updateAuthorisation); + int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__updateAuthorisation); if (this->soap_out(soap, tag?tag:"ns1:updateAuthorisation", id, type)) return soap->error; return soap_putindependent(soap); @@ -21059,7 +21059,7 @@ SOAP_FMAC3 ns1__getDatasetIncludesResponse * SOAP_FMAC4 soap_in_ns1__getDatasetI int ns1__getDatasetIncludesResponse::soap_put(struct soap *soap, const char *tag, const char *type) const { - register int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__getDatasetIncludesResponse); + int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__getDatasetIncludesResponse); if (this->soap_out(soap, tag?tag:"ns1:getDatasetIncludesResponse", id, type)) return soap->error; return soap_putindependent(soap); @@ -21220,7 +21220,7 @@ SOAP_FMAC3 ns1__getDatasetIncludes * SOAP_FMAC4 soap_in_ns1__getDatasetIncludes( int ns1__getDatasetIncludes::soap_put(struct soap *soap, const char *tag, const char *type) const { - register int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__getDatasetIncludes); + int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__getDatasetIncludes); if (this->soap_out(soap, tag?tag:"ns1:getDatasetIncludes", id, type)) return soap->error; return soap_putindependent(soap); @@ -21361,7 +21361,7 @@ SOAP_FMAC3 ns1__getDatasetResponse * SOAP_FMAC4 soap_in_ns1__getDatasetResponse( int ns1__getDatasetResponse::soap_put(struct soap *soap, const char *tag, const char *type) const { - register int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__getDatasetResponse); + int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__getDatasetResponse); if (this->soap_out(soap, tag?tag:"ns1:getDatasetResponse", id, type)) return soap->error; return soap_putindependent(soap); @@ -21512,7 +21512,7 @@ SOAP_FMAC3 ns1__getDataset * SOAP_FMAC4 soap_in_ns1__getDataset(struct soap *soa int ns1__getDataset::soap_put(struct soap *soap, const char *tag, const char *type) const { - register int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__getDataset); + int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__getDataset); if (this->soap_out(soap, tag?tag:"ns1:getDataset", id, type)) return soap->error; return soap_putindependent(soap); @@ -21616,7 +21616,7 @@ SOAP_FMAC3 ns1__deleteAuthorisationResponse * SOAP_FMAC4 soap_in_ns1__deleteAuth int ns1__deleteAuthorisationResponse::soap_put(struct soap *soap, const char *tag, const char *type) const { - register int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__deleteAuthorisationResponse); + int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__deleteAuthorisationResponse); if (this->soap_out(soap, tag?tag:"ns1:deleteAuthorisationResponse", id, type)) return soap->error; return soap_putindependent(soap); @@ -21767,7 +21767,7 @@ SOAP_FMAC3 ns1__deleteAuthorisation * SOAP_FMAC4 soap_in_ns1__deleteAuthorisatio int ns1__deleteAuthorisation::soap_put(struct soap *soap, const char *tag, const char *type) const { - register int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__deleteAuthorisation); + int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__deleteAuthorisation); if (this->soap_out(soap, tag?tag:"ns1:deleteAuthorisation", id, type)) return soap->error; return soap_putindependent(soap); @@ -21871,7 +21871,7 @@ SOAP_FMAC3 ns1__deletePublicationResponse * SOAP_FMAC4 soap_in_ns1__deletePublic int ns1__deletePublicationResponse::soap_put(struct soap *soap, const char *tag, const char *type) const { - register int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__deletePublicationResponse); + int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__deletePublicationResponse); if (this->soap_out(soap, tag?tag:"ns1:deletePublicationResponse", id, type)) return soap->error; return soap_putindependent(soap); @@ -22022,7 +22022,7 @@ SOAP_FMAC3 ns1__deletePublication * SOAP_FMAC4 soap_in_ns1__deletePublication(st int ns1__deletePublication::soap_put(struct soap *soap, const char *tag, const char *type) const { - register int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__deletePublication); + int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__deletePublication); if (this->soap_out(soap, tag?tag:"ns1:deletePublication", id, type)) return soap->error; return soap_putindependent(soap); @@ -22163,7 +22163,7 @@ SOAP_FMAC3 ns1__loginResponse * SOAP_FMAC4 soap_in_ns1__loginResponse(struct soa int ns1__loginResponse::soap_put(struct soap *soap, const char *tag, const char *type) const { - register int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__loginResponse); + int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__loginResponse); if (this->soap_out(soap, tag?tag:"ns1:loginResponse", id, type)) return soap->error; return soap_putindependent(soap); @@ -22314,7 +22314,7 @@ SOAP_FMAC3 ns1__login * SOAP_FMAC4 soap_in_ns1__login(struct soap *soap, const c int ns1__login::soap_put(struct soap *soap, const char *tag, const char *type) const { - register int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__login); + int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__login); if (this->soap_out(soap, tag?tag:"ns1:login", id, type)) return soap->error; return soap_putindependent(soap); @@ -22455,7 +22455,7 @@ SOAP_FMAC3 ns1__loginLifetimeResponse * SOAP_FMAC4 soap_in_ns1__loginLifetimeRes int ns1__loginLifetimeResponse::soap_put(struct soap *soap, const char *tag, const char *type) const { - register int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__loginLifetimeResponse); + int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__loginLifetimeResponse); if (this->soap_out(soap, tag?tag:"ns1:loginLifetimeResponse", id, type)) return soap->error; return soap_putindependent(soap); @@ -22620,7 +22620,7 @@ SOAP_FMAC3 ns1__loginLifetime * SOAP_FMAC4 soap_in_ns1__loginLifetime(struct soa int ns1__loginLifetime::soap_put(struct soap *soap, const char *tag, const char *type) const { - register int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__loginLifetime); + int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__loginLifetime); if (this->soap_out(soap, tag?tag:"ns1:loginLifetime", id, type)) return soap->error; return soap_putindependent(soap); @@ -22758,7 +22758,7 @@ SOAP_FMAC3 ns1__getParameterByUnitsResponse * SOAP_FMAC4 soap_in_ns1__getParamet int ns1__getParameterByUnitsResponse::soap_put(struct soap *soap, const char *tag, const char *type) const { - register int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__getParameterByUnitsResponse); + int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__getParameterByUnitsResponse); if (this->soap_out(soap, tag?tag:"ns1:getParameterByUnitsResponse", id, type)) return soap->error; return soap_putindependent(soap); @@ -22909,7 +22909,7 @@ SOAP_FMAC3 ns1__getParameterByUnits * SOAP_FMAC4 soap_in_ns1__getParameterByUnit int ns1__getParameterByUnits::soap_put(struct soap *soap, const char *tag, const char *type) const { - register int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__getParameterByUnits); + int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__getParameterByUnits); if (this->soap_out(soap, tag?tag:"ns1:getParameterByUnits", id, type)) return soap->error; return soap_putindependent(soap); @@ -23050,7 +23050,7 @@ SOAP_FMAC3 ns1__addSampleResponse * SOAP_FMAC4 soap_in_ns1__addSampleResponse(st int ns1__addSampleResponse::soap_put(struct soap *soap, const char *tag, const char *type) const { - register int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__addSampleResponse); + int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__addSampleResponse); if (this->soap_out(soap, tag?tag:"ns1:addSampleResponse", id, type)) return soap->error; return soap_putindependent(soap); @@ -23211,7 +23211,7 @@ SOAP_FMAC3 ns1__addSample * SOAP_FMAC4 soap_in_ns1__addSample(struct soap *soap, int ns1__addSample::soap_put(struct soap *soap, const char *tag, const char *type) const { - register int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__addSample); + int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__addSample); if (this->soap_out(soap, tag?tag:"ns1:addSample", id, type)) return soap->error; return soap_putindependent(soap); @@ -23352,7 +23352,7 @@ SOAP_FMAC3 ns1__addAuthorisationResponse * SOAP_FMAC4 soap_in_ns1__addAuthorisat int ns1__addAuthorisationResponse::soap_put(struct soap *soap, const char *tag, const char *type) const { - register int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__addAuthorisationResponse); + int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__addAuthorisationResponse); if (this->soap_out(soap, tag?tag:"ns1:addAuthorisationResponse", id, type)) return soap->error; return soap_putindependent(soap); @@ -23533,7 +23533,7 @@ SOAP_FMAC3 ns1__addAuthorisation * SOAP_FMAC4 soap_in_ns1__addAuthorisation(stru int ns1__addAuthorisation::soap_put(struct soap *soap, const char *tag, const char *type) const { - register int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__addAuthorisation); + int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__addAuthorisation); if (this->soap_out(soap, tag?tag:"ns1:addAuthorisation", id, type)) return soap->error; return soap_putindependent(soap); @@ -23671,7 +23671,7 @@ SOAP_FMAC3 ns1__createDataFilesResponse * SOAP_FMAC4 soap_in_ns1__createDataFile int ns1__createDataFilesResponse::soap_put(struct soap *soap, const char *tag, const char *type) const { - register int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__createDataFilesResponse); + int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__createDataFilesResponse); if (this->soap_out(soap, tag?tag:"ns1:createDataFilesResponse", id, type)) return soap->error; return soap_putindependent(soap); @@ -23829,7 +23829,7 @@ SOAP_FMAC3 ns1__createDataFiles * SOAP_FMAC4 soap_in_ns1__createDataFiles(struct int ns1__createDataFiles::soap_put(struct soap *soap, const char *tag, const char *type) const { - register int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__createDataFiles); + int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__createDataFiles); if (this->soap_out(soap, tag?tag:"ns1:createDataFiles", id, type)) return soap->error; return soap_putindependent(soap); @@ -23970,7 +23970,7 @@ SOAP_FMAC3 ns1__addDataSetParameterResponse * SOAP_FMAC4 soap_in_ns1__addDataSet int ns1__addDataSetParameterResponse::soap_put(struct soap *soap, const char *tag, const char *type) const { - register int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__addDataSetParameterResponse); + int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__addDataSetParameterResponse); if (this->soap_out(soap, tag?tag:"ns1:addDataSetParameterResponse", id, type)) return soap->error; return soap_putindependent(soap); @@ -24131,7 +24131,7 @@ SOAP_FMAC3 ns1__addDataSetParameter * SOAP_FMAC4 soap_in_ns1__addDataSetParamete int ns1__addDataSetParameter::soap_put(struct soap *soap, const char *tag, const char *type) const { - register int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__addDataSetParameter); + int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__addDataSetParameter); if (this->soap_out(soap, tag?tag:"ns1:addDataSetParameter", id, type)) return soap->error; return soap_putindependent(soap); @@ -24235,7 +24235,7 @@ SOAP_FMAC3 ns1__modifyInvestigatorResponse * SOAP_FMAC4 soap_in_ns1__modifyInves int ns1__modifyInvestigatorResponse::soap_put(struct soap *soap, const char *tag, const char *type) const { - register int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__modifyInvestigatorResponse); + int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__modifyInvestigatorResponse); if (this->soap_out(soap, tag?tag:"ns1:modifyInvestigatorResponse", id, type)) return soap->error; return soap_putindependent(soap); @@ -24386,7 +24386,7 @@ SOAP_FMAC3 ns1__modifyInvestigator * SOAP_FMAC4 soap_in_ns1__modifyInvestigator( int ns1__modifyInvestigator::soap_put(struct soap *soap, const char *tag, const char *type) const { - register int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__modifyInvestigator); + int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__modifyInvestigator); if (this->soap_out(soap, tag?tag:"ns1:modifyInvestigator", id, type)) return soap->error; return soap_putindependent(soap); @@ -24490,7 +24490,7 @@ SOAP_FMAC3 ns1__modifySampleParameterResponse * SOAP_FMAC4 soap_in_ns1__modifySa int ns1__modifySampleParameterResponse::soap_put(struct soap *soap, const char *tag, const char *type) const { - register int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__modifySampleParameterResponse); + int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__modifySampleParameterResponse); if (this->soap_out(soap, tag?tag:"ns1:modifySampleParameterResponse", id, type)) return soap->error; return soap_putindependent(soap); @@ -24641,7 +24641,7 @@ SOAP_FMAC3 ns1__modifySampleParameter * SOAP_FMAC4 soap_in_ns1__modifySamplePara int ns1__modifySampleParameter::soap_put(struct soap *soap, const char *tag, const char *type) const { - register int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__modifySampleParameter); + int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__modifySampleParameter); if (this->soap_out(soap, tag?tag:"ns1:modifySampleParameter", id, type)) return soap->error; return soap_putindependent(soap); @@ -24779,7 +24779,7 @@ SOAP_FMAC3 ns1__listDatafileFormatsResponse * SOAP_FMAC4 soap_in_ns1__listDatafi int ns1__listDatafileFormatsResponse::soap_put(struct soap *soap, const char *tag, const char *type) const { - register int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__listDatafileFormatsResponse); + int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__listDatafileFormatsResponse); if (this->soap_out(soap, tag?tag:"ns1:listDatafileFormatsResponse", id, type)) return soap->error; return soap_putindependent(soap); @@ -24920,7 +24920,7 @@ SOAP_FMAC3 ns1__listDatafileFormats * SOAP_FMAC4 soap_in_ns1__listDatafileFormat int ns1__listDatafileFormats::soap_put(struct soap *soap, const char *tag, const char *type) const { - register int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__listDatafileFormats); + int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__listDatafileFormats); if (this->soap_out(soap, tag?tag:"ns1:listDatafileFormats", id, type)) return soap->error; return soap_putindependent(soap); @@ -25058,7 +25058,7 @@ SOAP_FMAC3 ns1__searchInvestigationByParameterResponse * SOAP_FMAC4 soap_in_ns1_ int ns1__searchInvestigationByParameterResponse::soap_put(struct soap *soap, const char *tag, const char *type) const { - register int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__searchInvestigationByParameterResponse); + int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__searchInvestigationByParameterResponse); if (this->soap_out(soap, tag?tag:"ns1:searchInvestigationByParameterResponse", id, type)) return soap->error; return soap_putindependent(soap); @@ -25206,7 +25206,7 @@ SOAP_FMAC3 ns1__searchInvestigationByParameter * SOAP_FMAC4 soap_in_ns1__searchI int ns1__searchInvestigationByParameter::soap_put(struct soap *soap, const char *tag, const char *type) const { - register int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__searchInvestigationByParameter); + int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__searchInvestigationByParameter); if (this->soap_out(soap, tag?tag:"ns1:searchInvestigationByParameter", id, type)) return soap->error; return soap_putindependent(soap); @@ -25344,7 +25344,7 @@ SOAP_FMAC3 ns1__searchByAdvancedResponse * SOAP_FMAC4 soap_in_ns1__searchByAdvan int ns1__searchByAdvancedResponse::soap_put(struct soap *soap, const char *tag, const char *type) const { - register int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__searchByAdvancedResponse); + int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__searchByAdvancedResponse); if (this->soap_out(soap, tag?tag:"ns1:searchByAdvancedResponse", id, type)) return soap->error; return soap_putindependent(soap); @@ -25495,7 +25495,7 @@ SOAP_FMAC3 ns1__searchByAdvanced * SOAP_FMAC4 soap_in_ns1__searchByAdvanced(stru int ns1__searchByAdvanced::soap_put(struct soap *soap, const char *tag, const char *type) const { - register int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__searchByAdvanced); + int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__searchByAdvanced); if (this->soap_out(soap, tag?tag:"ns1:searchByAdvanced", id, type)) return soap->error; return soap_putindependent(soap); @@ -25633,7 +25633,7 @@ SOAP_FMAC3 ns1__searchByAdvancedPaginationResponse * SOAP_FMAC4 soap_in_ns1__sea int ns1__searchByAdvancedPaginationResponse::soap_put(struct soap *soap, const char *tag, const char *type) const { - register int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__searchByAdvancedPaginationResponse); + int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__searchByAdvancedPaginationResponse); if (this->soap_out(soap, tag?tag:"ns1:searchByAdvancedPaginationResponse", id, type)) return soap->error; return soap_putindependent(soap); @@ -25938,7 +25938,7 @@ SOAP_FMAC3 ns1__advancedSearchDetails * SOAP_FMAC4 soap_in_ns1__advancedSearchDe int ns1__advancedSearchDetails::soap_put(struct soap *soap, const char *tag, const char *type) const { - register int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__advancedSearchDetails); + int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__advancedSearchDetails); if (this->soap_out(soap, tag?tag:"ns1:advancedSearchDetails", id, type)) return soap->error; return soap_putindependent(soap); @@ -26113,7 +26113,7 @@ SOAP_FMAC3 ns1__searchByAdvancedPagination * SOAP_FMAC4 soap_in_ns1__searchByAdv int ns1__searchByAdvancedPagination::soap_put(struct soap *soap, const char *tag, const char *type) const { - register int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__searchByAdvancedPagination); + int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__searchByAdvancedPagination); if (this->soap_out(soap, tag?tag:"ns1:searchByAdvancedPagination", id, type)) return soap->error; return soap_putindependent(soap); @@ -26251,7 +26251,7 @@ SOAP_FMAC3 ns1__searchDatafileByParameterComparisonResponse * SOAP_FMAC4 soap_in int ns1__searchDatafileByParameterComparisonResponse::soap_put(struct soap *soap, const char *tag, const char *type) const { - register int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__searchDatafileByParameterComparisonResponse); + int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__searchDatafileByParameterComparisonResponse); if (this->soap_out(soap, tag?tag:"ns1:searchDatafileByParameterComparisonResponse", id, type)) return soap->error; return soap_putindependent(soap); @@ -26399,7 +26399,7 @@ SOAP_FMAC3 ns1__searchDatafileByParameterComparison * SOAP_FMAC4 soap_in_ns1__se int ns1__searchDatafileByParameterComparison::soap_put(struct soap *soap, const char *tag, const char *type) const { - register int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__searchDatafileByParameterComparison); + int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__searchDatafileByParameterComparison); if (this->soap_out(soap, tag?tag:"ns1:searchDatafileByParameterComparison", id, type)) return soap->error; return soap_putindependent(soap); @@ -26537,7 +26537,7 @@ SOAP_FMAC3 ns1__searchByRunNumberResponse * SOAP_FMAC4 soap_in_ns1__searchByRunN int ns1__searchByRunNumberResponse::soap_put(struct soap *soap, const char *tag, const char *type) const { - register int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__searchByRunNumberResponse); + int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__searchByRunNumberResponse); if (this->soap_out(soap, tag?tag:"ns1:searchByRunNumberResponse", id, type)) return soap->error; return soap_putindependent(soap); @@ -26707,7 +26707,7 @@ SOAP_FMAC3 ns1__searchByRunNumber * SOAP_FMAC4 soap_in_ns1__searchByRunNumber(st int ns1__searchByRunNumber::soap_put(struct soap *soap, const char *tag, const char *type) const { - register int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__searchByRunNumber); + int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__searchByRunNumber); if (this->soap_out(soap, tag?tag:"ns1:searchByRunNumber", id, type)) return soap->error; return soap_putindependent(soap); @@ -26845,7 +26845,7 @@ SOAP_FMAC3 ns1__searchByRunNumberPaginationResponse * SOAP_FMAC4 soap_in_ns1__se int ns1__searchByRunNumberPaginationResponse::soap_put(struct soap *soap, const char *tag, const char *type) const { - register int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__searchByRunNumberPaginationResponse); + int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__searchByRunNumberPaginationResponse); if (this->soap_out(soap, tag?tag:"ns1:searchByRunNumberPaginationResponse", id, type)) return soap->error; return soap_putindependent(soap); @@ -27035,7 +27035,7 @@ SOAP_FMAC3 ns1__searchByRunNumberPagination * SOAP_FMAC4 soap_in_ns1__searchByRu int ns1__searchByRunNumberPagination::soap_put(struct soap *soap, const char *tag, const char *type) const { - register int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__searchByRunNumberPagination); + int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__searchByRunNumberPagination); if (this->soap_out(soap, tag?tag:"ns1:searchByRunNumberPagination", id, type)) return soap->error; return soap_putindependent(soap); @@ -27173,7 +27173,7 @@ SOAP_FMAC3 ns1__addDataSetParametersResponse * SOAP_FMAC4 soap_in_ns1__addDataSe int ns1__addDataSetParametersResponse::soap_put(struct soap *soap, const char *tag, const char *type) const { - register int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__addDataSetParametersResponse); + int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__addDataSetParametersResponse); if (this->soap_out(soap, tag?tag:"ns1:addDataSetParametersResponse", id, type)) return soap->error; return soap_putindependent(soap); @@ -27331,7 +27331,7 @@ SOAP_FMAC3 ns1__addDataSetParameters * SOAP_FMAC4 soap_in_ns1__addDataSetParamet int ns1__addDataSetParameters::soap_put(struct soap *soap, const char *tag, const char *type) const { - register int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__addDataSetParameters); + int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__addDataSetParameters); if (this->soap_out(soap, tag?tag:"ns1:addDataSetParameters", id, type)) return soap->error; return soap_putindependent(soap); @@ -27435,7 +27435,7 @@ SOAP_FMAC3 ns1__deleteKeywordResponse * SOAP_FMAC4 soap_in_ns1__deleteKeywordRes int ns1__deleteKeywordResponse::soap_put(struct soap *soap, const char *tag, const char *type) const { - register int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__deleteKeywordResponse); + int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__deleteKeywordResponse); if (this->soap_out(soap, tag?tag:"ns1:deleteKeywordResponse", id, type)) return soap->error; return soap_putindependent(soap); @@ -27586,7 +27586,7 @@ SOAP_FMAC3 ns1__deleteKeyword * SOAP_FMAC4 soap_in_ns1__deleteKeyword(struct soa int ns1__deleteKeyword::soap_put(struct soap *soap, const char *tag, const char *type) const { - register int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__deleteKeyword); + int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__deleteKeyword); if (this->soap_out(soap, tag?tag:"ns1:deleteKeyword", id, type)) return soap->error; return soap_putindependent(soap); @@ -27724,7 +27724,7 @@ SOAP_FMAC3 ns1__searchDatasetByParameterResponse * SOAP_FMAC4 soap_in_ns1__searc int ns1__searchDatasetByParameterResponse::soap_put(struct soap *soap, const char *tag, const char *type) const { - register int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__searchDatasetByParameterResponse); + int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__searchDatasetByParameterResponse); if (this->soap_out(soap, tag?tag:"ns1:searchDatasetByParameterResponse", id, type)) return soap->error; return soap_putindependent(soap); @@ -27872,7 +27872,7 @@ SOAP_FMAC3 ns1__searchDatasetByParameter * SOAP_FMAC4 soap_in_ns1__searchDataset int ns1__searchDatasetByParameter::soap_put(struct soap *soap, const char *tag, const char *type) const { - register int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__searchDatasetByParameter); + int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__searchDatasetByParameter); if (this->soap_out(soap, tag?tag:"ns1:searchDatasetByParameter", id, type)) return soap->error; return soap_putindependent(soap); @@ -27976,7 +27976,7 @@ SOAP_FMAC3 ns1__deleteSampleResponse * SOAP_FMAC4 soap_in_ns1__deleteSampleRespo int ns1__deleteSampleResponse::soap_put(struct soap *soap, const char *tag, const char *type) const { - register int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__deleteSampleResponse); + int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__deleteSampleResponse); if (this->soap_out(soap, tag?tag:"ns1:deleteSampleResponse", id, type)) return soap->error; return soap_putindependent(soap); @@ -28127,7 +28127,7 @@ SOAP_FMAC3 ns1__deleteSample * SOAP_FMAC4 soap_in_ns1__deleteSample(struct soap int ns1__deleteSample::soap_put(struct soap *soap, const char *tag, const char *type) const { - register int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__deleteSample); + int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__deleteSample); if (this->soap_out(soap, tag?tag:"ns1:deleteSample", id, type)) return soap->error; return soap_putindependent(soap); @@ -28265,7 +28265,7 @@ SOAP_FMAC3 ns1__listDatasetStatusResponse * SOAP_FMAC4 soap_in_ns1__listDatasetS int ns1__listDatasetStatusResponse::soap_put(struct soap *soap, const char *tag, const char *type) const { - register int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__listDatasetStatusResponse); + int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__listDatasetStatusResponse); if (this->soap_out(soap, tag?tag:"ns1:listDatasetStatusResponse", id, type)) return soap->error; return soap_putindependent(soap); @@ -28406,7 +28406,7 @@ SOAP_FMAC3 ns1__listDatasetStatus * SOAP_FMAC4 soap_in_ns1__listDatasetStatus(st int ns1__listDatasetStatus::soap_put(struct soap *soap, const char *tag, const char *type) const { - register int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__listDatasetStatus); + int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__listDatasetStatus); if (this->soap_out(soap, tag?tag:"ns1:listDatasetStatus", id, type)) return soap->error; return soap_putindependent(soap); @@ -28510,7 +28510,7 @@ SOAP_FMAC3 ns1__modifyInvestigationResponse * SOAP_FMAC4 soap_in_ns1__modifyInve int ns1__modifyInvestigationResponse::soap_put(struct soap *soap, const char *tag, const char *type) const { - register int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__modifyInvestigationResponse); + int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__modifyInvestigationResponse); if (this->soap_out(soap, tag?tag:"ns1:modifyInvestigationResponse", id, type)) return soap->error; return soap_putindependent(soap); @@ -28661,7 +28661,7 @@ SOAP_FMAC3 ns1__modifyInvestigation * SOAP_FMAC4 soap_in_ns1__modifyInvestigatio int ns1__modifyInvestigation::soap_put(struct soap *soap, const char *tag, const char *type) const { - register int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__modifyInvestigation); + int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__modifyInvestigation); if (this->soap_out(soap, tag?tag:"ns1:modifyInvestigation", id, type)) return soap->error; return soap_putindependent(soap); @@ -28890,7 +28890,7 @@ SOAP_FMAC3 ns1__icatAuthorisation * SOAP_FMAC4 soap_in_ns1__icatAuthorisation(st int ns1__icatAuthorisation::soap_put(struct soap *soap, const char *tag, const char *type) const { - register int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__icatAuthorisation); + int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__icatAuthorisation); if (this->soap_out(soap, tag?tag:"ns1:icatAuthorisation", id, type)) return soap->error; return soap_putindependent(soap); @@ -29028,7 +29028,7 @@ SOAP_FMAC3 ns1__getAuthorisationsResponse * SOAP_FMAC4 soap_in_ns1__getAuthorisa int ns1__getAuthorisationsResponse::soap_put(struct soap *soap, const char *tag, const char *type) const { - register int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__getAuthorisationsResponse); + int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__getAuthorisationsResponse); if (this->soap_out(soap, tag?tag:"ns1:getAuthorisationsResponse", id, type)) return soap->error; return soap_putindependent(soap); @@ -29189,7 +29189,7 @@ SOAP_FMAC3 ns1__getAuthorisations * SOAP_FMAC4 soap_in_ns1__getAuthorisations(st int ns1__getAuthorisations::soap_put(struct soap *soap, const char *tag, const char *type) const { - register int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__getAuthorisations); + int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__getAuthorisations); if (this->soap_out(soap, tag?tag:"ns1:getAuthorisations", id, type)) return soap->error; return soap_putindependent(soap); @@ -29330,7 +29330,7 @@ SOAP_FMAC3 ns1__addKeywordResponse * SOAP_FMAC4 soap_in_ns1__addKeywordResponse( int ns1__addKeywordResponse::soap_put(struct soap *soap, const char *tag, const char *type) const { - register int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__addKeywordResponse); + int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__addKeywordResponse); if (this->soap_out(soap, tag?tag:"ns1:addKeywordResponse", id, type)) return soap->error; return soap_putindependent(soap); @@ -29491,7 +29491,7 @@ SOAP_FMAC3 ns1__addKeyword * SOAP_FMAC4 soap_in_ns1__addKeyword(struct soap *soa int ns1__addKeyword::soap_put(struct soap *soap, const char *tag, const char *type) const { - register int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__addKeyword); + int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__addKeyword); if (this->soap_out(soap, tag?tag:"ns1:addKeyword", id, type)) return soap->error; return soap_putindependent(soap); @@ -29629,7 +29629,7 @@ SOAP_FMAC3 ns1__searchDatasetByRestrictionComparisonResponse * SOAP_FMAC4 soap_i int ns1__searchDatasetByRestrictionComparisonResponse::soap_put(struct soap *soap, const char *tag, const char *type) const { - register int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__searchDatasetByRestrictionComparisonResponse); + int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__searchDatasetByRestrictionComparisonResponse); if (this->soap_out(soap, tag?tag:"ns1:searchDatasetByRestrictionComparisonResponse", id, type)) return soap->error; return soap_putindependent(soap); @@ -29777,7 +29777,7 @@ SOAP_FMAC3 ns1__searchDatasetByRestrictionComparison * SOAP_FMAC4 soap_in_ns1__s int ns1__searchDatasetByRestrictionComparison::soap_put(struct soap *soap, const char *tag, const char *type) const { - register int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__searchDatasetByRestrictionComparison); + int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__searchDatasetByRestrictionComparison); if (this->soap_out(soap, tag?tag:"ns1:searchDatasetByRestrictionComparison", id, type)) return soap->error; return soap_putindependent(soap); @@ -29915,7 +29915,7 @@ SOAP_FMAC3 ns1__searchSampleByParameterLogicalResponse * SOAP_FMAC4 soap_in_ns1_ int ns1__searchSampleByParameterLogicalResponse::soap_put(struct soap *soap, const char *tag, const char *type) const { - register int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__searchSampleByParameterLogicalResponse); + int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__searchSampleByParameterLogicalResponse); if (this->soap_out(soap, tag?tag:"ns1:searchSampleByParameterLogicalResponse", id, type)) return soap->error; return soap_putindependent(soap); @@ -30066,7 +30066,7 @@ SOAP_FMAC3 ns1__searchSampleByParameterLogical * SOAP_FMAC4 soap_in_ns1__searchS int ns1__searchSampleByParameterLogical::soap_put(struct soap *soap, const char *tag, const char *type) const { - register int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__searchSampleByParameterLogical); + int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__searchSampleByParameterLogical); if (this->soap_out(soap, tag?tag:"ns1:searchSampleByParameterLogical", id, type)) return soap->error; return soap_putindependent(soap); @@ -30170,7 +30170,7 @@ SOAP_FMAC3 ns1__removeDataSetResponse * SOAP_FMAC4 soap_in_ns1__removeDataSetRes int ns1__removeDataSetResponse::soap_put(struct soap *soap, const char *tag, const char *type) const { - register int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__removeDataSetResponse); + int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__removeDataSetResponse); if (this->soap_out(soap, tag?tag:"ns1:removeDataSetResponse", id, type)) return soap->error; return soap_putindependent(soap); @@ -30321,7 +30321,7 @@ SOAP_FMAC3 ns1__removeDataSet * SOAP_FMAC4 soap_in_ns1__removeDataSet(struct soa int ns1__removeDataSet::soap_put(struct soap *soap, const char *tag, const char *type) const { - register int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__removeDataSet); + int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__removeDataSet); if (this->soap_out(soap, tag?tag:"ns1:removeDataSet", id, type)) return soap->error; return soap_putindependent(soap); @@ -30425,7 +30425,7 @@ SOAP_FMAC3 ns1__modifyDataSetParameterResponse * SOAP_FMAC4 soap_in_ns1__modifyD int ns1__modifyDataSetParameterResponse::soap_put(struct soap *soap, const char *tag, const char *type) const { - register int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__modifyDataSetParameterResponse); + int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__modifyDataSetParameterResponse); if (this->soap_out(soap, tag?tag:"ns1:modifyDataSetParameterResponse", id, type)) return soap->error; return soap_putindependent(soap); @@ -30576,7 +30576,7 @@ SOAP_FMAC3 ns1__modifyDataSetParameter * SOAP_FMAC4 soap_in_ns1__modifyDataSetPa int ns1__modifyDataSetParameter::soap_put(struct soap *soap, const char *tag, const char *type) const { - register int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__modifyDataSetParameter); + int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__modifyDataSetParameter); if (this->soap_out(soap, tag?tag:"ns1:modifyDataSetParameter", id, type)) return soap->error; return soap_putindependent(soap); @@ -30714,7 +30714,7 @@ SOAP_FMAC3 ns1__listInvestigationTypesResponse * SOAP_FMAC4 soap_in_ns1__listInv int ns1__listInvestigationTypesResponse::soap_put(struct soap *soap, const char *tag, const char *type) const { - register int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__listInvestigationTypesResponse); + int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__listInvestigationTypesResponse); if (this->soap_out(soap, tag?tag:"ns1:listInvestigationTypesResponse", id, type)) return soap->error; return soap_putindependent(soap); @@ -30855,7 +30855,7 @@ SOAP_FMAC3 ns1__listInvestigationTypes * SOAP_FMAC4 soap_in_ns1__listInvestigati int ns1__listInvestigationTypes::soap_put(struct soap *soap, const char *tag, const char *type) const { - register int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__listInvestigationTypes); + int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__listInvestigationTypes); if (this->soap_out(soap, tag?tag:"ns1:listInvestigationTypes", id, type)) return soap->error; return soap_putindependent(soap); @@ -30993,7 +30993,7 @@ SOAP_FMAC3 ns1__getKeywordsForUserResponse * SOAP_FMAC4 soap_in_ns1__getKeywords int ns1__getKeywordsForUserResponse::soap_put(struct soap *soap, const char *tag, const char *type) const { - register int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__getKeywordsForUserResponse); + int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__getKeywordsForUserResponse); if (this->soap_out(soap, tag?tag:"ns1:getKeywordsForUserResponse", id, type)) return soap->error; return soap_putindependent(soap); @@ -31134,7 +31134,7 @@ SOAP_FMAC3 ns1__getKeywordsForUser * SOAP_FMAC4 soap_in_ns1__getKeywordsForUser( int ns1__getKeywordsForUser::soap_put(struct soap *soap, const char *tag, const char *type) const { - register int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__getKeywordsForUser); + int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__getKeywordsForUser); if (this->soap_out(soap, tag?tag:"ns1:getKeywordsForUser", id, type)) return soap->error; return soap_putindependent(soap); @@ -31272,7 +31272,7 @@ SOAP_FMAC3 ns1__getKeywordsForUserStartWithMaxResponse * SOAP_FMAC4 soap_in_ns1_ int ns1__getKeywordsForUserStartWithMaxResponse::soap_put(struct soap *soap, const char *tag, const char *type) const { - register int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__getKeywordsForUserStartWithMaxResponse); + int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__getKeywordsForUserStartWithMaxResponse); if (this->soap_out(soap, tag?tag:"ns1:getKeywordsForUserStartWithMaxResponse", id, type)) return soap->error; return soap_putindependent(soap); @@ -31437,7 +31437,7 @@ SOAP_FMAC3 ns1__getKeywordsForUserStartWithMax * SOAP_FMAC4 soap_in_ns1__getKeyw int ns1__getKeywordsForUserStartWithMax::soap_put(struct soap *soap, const char *tag, const char *type) const { - register int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__getKeywordsForUserStartWithMax); + int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__getKeywordsForUserStartWithMax); if (this->soap_out(soap, tag?tag:"ns1:getKeywordsForUserStartWithMax", id, type)) return soap->error; return soap_putindependent(soap); @@ -31575,7 +31575,7 @@ SOAP_FMAC3 ns1__getKeywordsForUserMaxResponse * SOAP_FMAC4 soap_in_ns1__getKeywo int ns1__getKeywordsForUserMaxResponse::soap_put(struct soap *soap, const char *tag, const char *type) const { - register int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__getKeywordsForUserMaxResponse); + int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__getKeywordsForUserMaxResponse); if (this->soap_out(soap, tag?tag:"ns1:getKeywordsForUserMaxResponse", id, type)) return soap->error; return soap_putindependent(soap); @@ -31730,7 +31730,7 @@ SOAP_FMAC3 ns1__getKeywordsForUserMax * SOAP_FMAC4 soap_in_ns1__getKeywordsForUs int ns1__getKeywordsForUserMax::soap_put(struct soap *soap, const char *tag, const char *type) const { - register int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__getKeywordsForUserMax); + int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__getKeywordsForUserMax); if (this->soap_out(soap, tag?tag:"ns1:getKeywordsForUserMax", id, type)) return soap->error; return soap_putindependent(soap); @@ -31868,7 +31868,7 @@ SOAP_FMAC3 ns1__getKeywordsForUserTypeResponse * SOAP_FMAC4 soap_in_ns1__getKeyw int ns1__getKeywordsForUserTypeResponse::soap_put(struct soap *soap, const char *tag, const char *type) const { - register int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__getKeywordsForUserTypeResponse); + int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__getKeywordsForUserTypeResponse); if (this->soap_out(soap, tag?tag:"ns1:getKeywordsForUserTypeResponse", id, type)) return soap->error; return soap_putindependent(soap); @@ -32019,7 +32019,7 @@ SOAP_FMAC3 ns1__getKeywordsForUserType * SOAP_FMAC4 soap_in_ns1__getKeywordsForU int ns1__getKeywordsForUserType::soap_put(struct soap *soap, const char *tag, const char *type) const { - register int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__getKeywordsForUserType); + int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__getKeywordsForUserType); if (this->soap_out(soap, tag?tag:"ns1:getKeywordsForUserType", id, type)) return soap->error; return soap_putindependent(soap); @@ -32157,7 +32157,7 @@ SOAP_FMAC3 ns1__getParameterByNameResponse * SOAP_FMAC4 soap_in_ns1__getParamete int ns1__getParameterByNameResponse::soap_put(struct soap *soap, const char *tag, const char *type) const { - register int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__getParameterByNameResponse); + int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__getParameterByNameResponse); if (this->soap_out(soap, tag?tag:"ns1:getParameterByNameResponse", id, type)) return soap->error; return soap_putindependent(soap); @@ -32308,7 +32308,7 @@ SOAP_FMAC3 ns1__getParameterByName * SOAP_FMAC4 soap_in_ns1__getParameterByName( int ns1__getParameterByName::soap_put(struct soap *soap, const char *tag, const char *type) const { - register int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__getParameterByName); + int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__getParameterByName); if (this->soap_out(soap, tag?tag:"ns1:getParameterByName", id, type)) return soap->error; return soap_putindependent(soap); @@ -32449,7 +32449,7 @@ SOAP_FMAC3 ns1__downloadDatafileResponse * SOAP_FMAC4 soap_in_ns1__downloadDataf int ns1__downloadDatafileResponse::soap_put(struct soap *soap, const char *tag, const char *type) const { - register int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__downloadDatafileResponse); + int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__downloadDatafileResponse); if (this->soap_out(soap, tag?tag:"ns1:downloadDatafileResponse", id, type)) return soap->error; return soap_putindependent(soap); @@ -32600,7 +32600,7 @@ SOAP_FMAC3 ns1__downloadDatafile * SOAP_FMAC4 soap_in_ns1__downloadDatafile(stru int ns1__downloadDatafile::soap_put(struct soap *soap, const char *tag, const char *type) const { - register int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__downloadDatafile); + int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__downloadDatafile); if (this->soap_out(soap, tag?tag:"ns1:downloadDatafile", id, type)) return soap->error; return soap_putindependent(soap); @@ -32704,7 +32704,7 @@ SOAP_FMAC3 ns1__setDataSetSampleResponse * SOAP_FMAC4 soap_in_ns1__setDataSetSam int ns1__setDataSetSampleResponse::soap_put(struct soap *soap, const char *tag, const char *type) const { - register int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__setDataSetSampleResponse); + int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__setDataSetSampleResponse); if (this->soap_out(soap, tag?tag:"ns1:setDataSetSampleResponse", id, type)) return soap->error; return soap_putindependent(soap); @@ -32865,7 +32865,7 @@ SOAP_FMAC3 ns1__setDataSetSample * SOAP_FMAC4 soap_in_ns1__setDataSetSample(stru int ns1__setDataSetSample::soap_put(struct soap *soap, const char *tag, const char *type) const { - register int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__setDataSetSample); + int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__setDataSetSample); if (this->soap_out(soap, tag?tag:"ns1:setDataSetSample", id, type)) return soap->error; return soap_putindependent(soap); @@ -32969,7 +32969,7 @@ SOAP_FMAC3 ns1__deleteDataSetParameterResponse * SOAP_FMAC4 soap_in_ns1__deleteD int ns1__deleteDataSetParameterResponse::soap_put(struct soap *soap, const char *tag, const char *type) const { - register int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__deleteDataSetParameterResponse); + int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__deleteDataSetParameterResponse); if (this->soap_out(soap, tag?tag:"ns1:deleteDataSetParameterResponse", id, type)) return soap->error; return soap_putindependent(soap); @@ -33120,7 +33120,7 @@ SOAP_FMAC3 ns1__deleteDataSetParameter * SOAP_FMAC4 soap_in_ns1__deleteDataSetPa int ns1__deleteDataSetParameter::soap_put(struct soap *soap, const char *tag, const char *type) const { - register int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__deleteDataSetParameter); + int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__deleteDataSetParameter); if (this->soap_out(soap, tag?tag:"ns1:deleteDataSetParameter", id, type)) return soap->error; return soap_putindependent(soap); @@ -33224,7 +33224,7 @@ SOAP_FMAC3 ns1__removeSampleParameterResponse * SOAP_FMAC4 soap_in_ns1__removeSa int ns1__removeSampleParameterResponse::soap_put(struct soap *soap, const char *tag, const char *type) const { - register int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__removeSampleParameterResponse); + int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__removeSampleParameterResponse); if (this->soap_out(soap, tag?tag:"ns1:removeSampleParameterResponse", id, type)) return soap->error; return soap_putindependent(soap); @@ -33375,7 +33375,7 @@ SOAP_FMAC3 ns1__removeSampleParameter * SOAP_FMAC4 soap_in_ns1__removeSamplePara int ns1__removeSampleParameter::soap_put(struct soap *soap, const char *tag, const char *type) const { - register int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__removeSampleParameter); + int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__removeSampleParameter); if (this->soap_out(soap, tag?tag:"ns1:removeSampleParameter", id, type)) return soap->error; return soap_putindependent(soap); @@ -33513,7 +33513,7 @@ SOAP_FMAC3 ns1__searchInvestigationByRestrictionLogicalResponse * SOAP_FMAC4 soa int ns1__searchInvestigationByRestrictionLogicalResponse::soap_put(struct soap *soap, const char *tag, const char *type) const { - register int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__searchInvestigationByRestrictionLogicalResponse); + int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__searchInvestigationByRestrictionLogicalResponse); if (this->soap_out(soap, tag?tag:"ns1:searchInvestigationByRestrictionLogicalResponse", id, type)) return soap->error; return soap_putindependent(soap); @@ -33664,7 +33664,7 @@ SOAP_FMAC3 ns1__searchInvestigationByRestrictionLogical * SOAP_FMAC4 soap_in_ns1 int ns1__searchInvestigationByRestrictionLogical::soap_put(struct soap *soap, const char *tag, const char *type) const { - register int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__searchInvestigationByRestrictionLogical); + int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__searchInvestigationByRestrictionLogical); if (this->soap_out(soap, tag?tag:"ns1:searchInvestigationByRestrictionLogical", id, type)) return soap->error; return soap_putindependent(soap); @@ -33802,7 +33802,7 @@ SOAP_FMAC3 ns1__searchDatafileByParameterRestrictionResponse * SOAP_FMAC4 soap_i int ns1__searchDatafileByParameterRestrictionResponse::soap_put(struct soap *soap, const char *tag, const char *type) const { - register int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__searchDatafileByParameterRestrictionResponse); + int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__searchDatafileByParameterRestrictionResponse); if (this->soap_out(soap, tag?tag:"ns1:searchDatafileByParameterRestrictionResponse", id, type)) return soap->error; return soap_putindependent(soap); @@ -33963,7 +33963,7 @@ SOAP_FMAC3 ns1__searchDatafileByParameterRestriction * SOAP_FMAC4 soap_in_ns1__s int ns1__searchDatafileByParameterRestriction::soap_put(struct soap *soap, const char *tag, const char *type) const { - register int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__searchDatafileByParameterRestriction); + int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__searchDatafileByParameterRestriction); if (this->soap_out(soap, tag?tag:"ns1:searchDatafileByParameterRestriction", id, type)) return soap->error; return soap_putindependent(soap); @@ -34104,7 +34104,7 @@ SOAP_FMAC3 ns1__createDataSetResponse * SOAP_FMAC4 soap_in_ns1__createDataSetRes int ns1__createDataSetResponse::soap_put(struct soap *soap, const char *tag, const char *type) const { - register int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__createDataSetResponse); + int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__createDataSetResponse); if (this->soap_out(soap, tag?tag:"ns1:createDataSetResponse", id, type)) return soap->error; return soap_putindependent(soap); @@ -34265,7 +34265,7 @@ SOAP_FMAC3 ns1__createDataSet * SOAP_FMAC4 soap_in_ns1__createDataSet(struct soa int ns1__createDataSet::soap_put(struct soap *soap, const char *tag, const char *type) const { - register int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__createDataSet); + int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__createDataSet); if (this->soap_out(soap, tag?tag:"ns1:createDataSet", id, type)) return soap->error; return soap_putindependent(soap); @@ -34403,7 +34403,7 @@ SOAP_FMAC3 ns1__searchDatafileByParameterLogicalResponse * SOAP_FMAC4 soap_in_ns int ns1__searchDatafileByParameterLogicalResponse::soap_put(struct soap *soap, const char *tag, const char *type) const { - register int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__searchDatafileByParameterLogicalResponse); + int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__searchDatafileByParameterLogicalResponse); if (this->soap_out(soap, tag?tag:"ns1:searchDatafileByParameterLogicalResponse", id, type)) return soap->error; return soap_putindependent(soap); @@ -34554,7 +34554,7 @@ SOAP_FMAC3 ns1__searchDatafileByParameterLogical * SOAP_FMAC4 soap_in_ns1__searc int ns1__searchDatafileByParameterLogical::soap_put(struct soap *soap, const char *tag, const char *type) const { - register int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__searchDatafileByParameterLogical); + int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__searchDatafileByParameterLogical); if (this->soap_out(soap, tag?tag:"ns1:searchDatafileByParameterLogical", id, type)) return soap->error; return soap_putindependent(soap); @@ -34695,7 +34695,7 @@ SOAP_FMAC3 ns1__addInvestigatorResponse * SOAP_FMAC4 soap_in_ns1__addInvestigato int ns1__addInvestigatorResponse::soap_put(struct soap *soap, const char *tag, const char *type) const { - register int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__addInvestigatorResponse); + int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__addInvestigatorResponse); if (this->soap_out(soap, tag?tag:"ns1:addInvestigatorResponse", id, type)) return soap->error; return soap_putindependent(soap); @@ -34856,7 +34856,7 @@ SOAP_FMAC3 ns1__addInvestigator * SOAP_FMAC4 soap_in_ns1__addInvestigator(struct int ns1__addInvestigator::soap_put(struct soap *soap, const char *tag, const char *type) const { - register int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__addInvestigator); + int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__addInvestigator); if (this->soap_out(soap, tag?tag:"ns1:addInvestigator", id, type)) return soap->error; return soap_putindependent(soap); @@ -34960,7 +34960,7 @@ SOAP_FMAC3 ns1__deleteInvestigatorResponse * SOAP_FMAC4 soap_in_ns1__deleteInves int ns1__deleteInvestigatorResponse::soap_put(struct soap *soap, const char *tag, const char *type) const { - register int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__deleteInvestigatorResponse); + int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__deleteInvestigatorResponse); if (this->soap_out(soap, tag?tag:"ns1:deleteInvestigatorResponse", id, type)) return soap->error; return soap_putindependent(soap); @@ -35111,7 +35111,7 @@ SOAP_FMAC3 ns1__deleteInvestigator * SOAP_FMAC4 soap_in_ns1__deleteInvestigator( int ns1__deleteInvestigator::soap_put(struct soap *soap, const char *tag, const char *type) const { - register int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__deleteInvestigator); + int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__deleteInvestigator); if (this->soap_out(soap, tag?tag:"ns1:deleteInvestigator", id, type)) return soap->error; return soap_putindependent(soap); @@ -35249,7 +35249,7 @@ SOAP_FMAC3 ns1__searchInvestigationByRestrictionResponse * SOAP_FMAC4 soap_in_ns int ns1__searchInvestigationByRestrictionResponse::soap_put(struct soap *soap, const char *tag, const char *type) const { - register int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__searchInvestigationByRestrictionResponse); + int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__searchInvestigationByRestrictionResponse); if (this->soap_out(soap, tag?tag:"ns1:searchInvestigationByRestrictionResponse", id, type)) return soap->error; return soap_putindependent(soap); @@ -35400,7 +35400,7 @@ SOAP_FMAC3 ns1__searchInvestigationByRestriction * SOAP_FMAC4 soap_in_ns1__searc int ns1__searchInvestigationByRestriction::soap_put(struct soap *soap, const char *tag, const char *type) const { - register int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__searchInvestigationByRestriction); + int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__searchInvestigationByRestriction); if (this->soap_out(soap, tag?tag:"ns1:searchInvestigationByRestriction", id, type)) return soap->error; return soap_putindependent(soap); @@ -35541,7 +35541,7 @@ SOAP_FMAC3 ns1__getICATAPIVersionResponse * SOAP_FMAC4 soap_in_ns1__getICATAPIVe int ns1__getICATAPIVersionResponse::soap_put(struct soap *soap, const char *tag, const char *type) const { - register int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__getICATAPIVersionResponse); + int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__getICATAPIVersionResponse); if (this->soap_out(soap, tag?tag:"ns1:getICATAPIVersionResponse", id, type)) return soap->error; return soap_putindependent(soap); @@ -35682,7 +35682,7 @@ SOAP_FMAC3 ns1__getICATAPIVersion * SOAP_FMAC4 soap_in_ns1__getICATAPIVersion(st int ns1__getICATAPIVersion::soap_put(struct soap *soap, const char *tag, const char *type) const { - register int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__getICATAPIVersion); + int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__getICATAPIVersion); if (this->soap_out(soap, tag?tag:"ns1:getICATAPIVersion", id, type)) return soap->error; return soap_putindependent(soap); @@ -35820,7 +35820,7 @@ SOAP_FMAC3 ns1__getDatafilesResponse * SOAP_FMAC4 soap_in_ns1__getDatafilesRespo int ns1__getDatafilesResponse::soap_put(struct soap *soap, const char *tag, const char *type) const { - register int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__getDatafilesResponse); + int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__getDatafilesResponse); if (this->soap_out(soap, tag?tag:"ns1:getDatafilesResponse", id, type)) return soap->error; return soap_putindependent(soap); @@ -35968,7 +35968,7 @@ SOAP_FMAC3 ns1__getDatafiles * SOAP_FMAC4 soap_in_ns1__getDatafiles(struct soap int ns1__getDatafiles::soap_put(struct soap *soap, const char *tag, const char *type) const { - register int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__getDatafiles); + int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__getDatafiles); if (this->soap_out(soap, tag?tag:"ns1:getDatafiles", id, type)) return soap->error; return soap_putindependent(soap); @@ -36112,7 +36112,7 @@ SOAP_FMAC3 ns1__isSessionValidResponse * SOAP_FMAC4 soap_in_ns1__isSessionValidR int ns1__isSessionValidResponse::soap_put(struct soap *soap, const char *tag, const char *type) const { - register int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__isSessionValidResponse); + int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__isSessionValidResponse); if (this->soap_out(soap, tag?tag:"ns1:isSessionValidResponse", id, type)) return soap->error; return soap_putindependent(soap); @@ -36253,7 +36253,7 @@ SOAP_FMAC3 ns1__isSessionValid * SOAP_FMAC4 soap_in_ns1__isSessionValid(struct s int ns1__isSessionValid::soap_put(struct soap *soap, const char *tag, const char *type) const { - register int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__isSessionValid); + int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__isSessionValid); if (this->soap_out(soap, tag?tag:"ns1:isSessionValid", id, type)) return soap->error; return soap_putindependent(soap); @@ -36391,7 +36391,7 @@ SOAP_FMAC3 ns1__searchInvestigationByParameterComparisonResponse * SOAP_FMAC4 so int ns1__searchInvestigationByParameterComparisonResponse::soap_put(struct soap *soap, const char *tag, const char *type) const { - register int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__searchInvestigationByParameterComparisonResponse); + int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__searchInvestigationByParameterComparisonResponse); if (this->soap_out(soap, tag?tag:"ns1:searchInvestigationByParameterComparisonResponse", id, type)) return soap->error; return soap_putindependent(soap); @@ -36539,7 +36539,7 @@ SOAP_FMAC3 ns1__searchInvestigationByParameterComparison * SOAP_FMAC4 soap_in_ns int ns1__searchInvestigationByParameterComparison::soap_put(struct soap *soap, const char *tag, const char *type) const { - register int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__searchInvestigationByParameterComparison); + int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__searchInvestigationByParameterComparison); if (this->soap_out(soap, tag?tag:"ns1:searchInvestigationByParameterComparison", id, type)) return soap->error; return soap_putindependent(soap); @@ -36643,7 +36643,7 @@ SOAP_FMAC3 ns1__deleteDataSetResponse * SOAP_FMAC4 soap_in_ns1__deleteDataSetRes int ns1__deleteDataSetResponse::soap_put(struct soap *soap, const char *tag, const char *type) const { - register int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__deleteDataSetResponse); + int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__deleteDataSetResponse); if (this->soap_out(soap, tag?tag:"ns1:deleteDataSetResponse", id, type)) return soap->error; return soap_putindependent(soap); @@ -36794,7 +36794,7 @@ SOAP_FMAC3 ns1__deleteDataSet * SOAP_FMAC4 soap_in_ns1__deleteDataSet(struct soa int ns1__deleteDataSet::soap_put(struct soap *soap, const char *tag, const char *type) const { - register int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__deleteDataSet); + int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__deleteDataSet); if (this->soap_out(soap, tag?tag:"ns1:deleteDataSet", id, type)) return soap->error; return soap_putindependent(soap); @@ -36932,7 +36932,7 @@ SOAP_FMAC3 ns1__getInvestigationsResponse * SOAP_FMAC4 soap_in_ns1__getInvestiga int ns1__getInvestigationsResponse::soap_put(struct soap *soap, const char *tag, const char *type) const { - register int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__getInvestigationsResponse); + int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__getInvestigationsResponse); if (this->soap_out(soap, tag?tag:"ns1:getInvestigationsResponse", id, type)) return soap->error; return soap_putindependent(soap); @@ -37080,7 +37080,7 @@ SOAP_FMAC3 ns1__getInvestigations * SOAP_FMAC4 soap_in_ns1__getInvestigations(st int ns1__getInvestigations::soap_put(struct soap *soap, const char *tag, const char *type) const { - register int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__getInvestigations); + int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__getInvestigations); if (this->soap_out(soap, tag?tag:"ns1:getInvestigations", id, type)) return soap->error; return soap_putindependent(soap); @@ -37218,7 +37218,7 @@ SOAP_FMAC3 ns1__getInvestigationsIncludesResponse * SOAP_FMAC4 soap_in_ns1__getI int ns1__getInvestigationsIncludesResponse::soap_put(struct soap *soap, const char *tag, const char *type) const { - register int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__getInvestigationsIncludesResponse); + int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__getInvestigationsIncludesResponse); if (this->soap_out(soap, tag?tag:"ns1:getInvestigationsIncludesResponse", id, type)) return soap->error; return soap_putindependent(soap); @@ -37376,7 +37376,7 @@ SOAP_FMAC3 ns1__getInvestigationsIncludes * SOAP_FMAC4 soap_in_ns1__getInvestiga int ns1__getInvestigationsIncludes::soap_put(struct soap *soap, const char *tag, const char *type) const { - register int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__getInvestigationsIncludes); + int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__getInvestigationsIncludes); if (this->soap_out(soap, tag?tag:"ns1:getInvestigationsIncludes", id, type)) return soap->error; return soap_putindependent(soap); @@ -37514,7 +37514,7 @@ SOAP_FMAC3 ns1__searchSampleByParameterResponse * SOAP_FMAC4 soap_in_ns1__search int ns1__searchSampleByParameterResponse::soap_put(struct soap *soap, const char *tag, const char *type) const { - register int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__searchSampleByParameterResponse); + int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__searchSampleByParameterResponse); if (this->soap_out(soap, tag?tag:"ns1:searchSampleByParameterResponse", id, type)) return soap->error; return soap_putindependent(soap); @@ -37662,7 +37662,7 @@ SOAP_FMAC3 ns1__searchSampleByParameter * SOAP_FMAC4 soap_in_ns1__searchSampleBy int ns1__searchSampleByParameter::soap_put(struct soap *soap, const char *tag, const char *type) const { - register int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__searchSampleByParameter); + int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__searchSampleByParameter); if (this->soap_out(soap, tag?tag:"ns1:searchSampleByParameter", id, type)) return soap->error; return soap_putindependent(soap); @@ -37800,7 +37800,7 @@ SOAP_FMAC3 ns1__searchDatasetByParameterConditionResponse * SOAP_FMAC4 soap_in_n int ns1__searchDatasetByParameterConditionResponse::soap_put(struct soap *soap, const char *tag, const char *type) const { - register int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__searchDatasetByParameterConditionResponse); + int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__searchDatasetByParameterConditionResponse); if (this->soap_out(soap, tag?tag:"ns1:searchDatasetByParameterConditionResponse", id, type)) return soap->error; return soap_putindependent(soap); @@ -37951,7 +37951,7 @@ SOAP_FMAC3 ns1__searchDatasetByParameterCondition * SOAP_FMAC4 soap_in_ns1__sear int ns1__searchDatasetByParameterCondition::soap_put(struct soap *soap, const char *tag, const char *type) const { - register int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__searchDatasetByParameterCondition); + int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__searchDatasetByParameterCondition); if (this->soap_out(soap, tag?tag:"ns1:searchDatasetByParameterCondition", id, type)) return soap->error; return soap_putindependent(soap); @@ -38055,7 +38055,7 @@ SOAP_FMAC3 ns1__removeDataFileParameterResponse * SOAP_FMAC4 soap_in_ns1__remove int ns1__removeDataFileParameterResponse::soap_put(struct soap *soap, const char *tag, const char *type) const { - register int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__removeDataFileParameterResponse); + int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__removeDataFileParameterResponse); if (this->soap_out(soap, tag?tag:"ns1:removeDataFileParameterResponse", id, type)) return soap->error; return soap_putindependent(soap); @@ -38206,7 +38206,7 @@ SOAP_FMAC3 ns1__removeDataFileParameter * SOAP_FMAC4 soap_in_ns1__removeDataFile int ns1__removeDataFileParameter::soap_put(struct soap *soap, const char *tag, const char *type) const { - register int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__removeDataFileParameter); + int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__removeDataFileParameter); if (this->soap_out(soap, tag?tag:"ns1:removeDataFileParameter", id, type)) return soap->error; return soap_putindependent(soap); @@ -38344,7 +38344,7 @@ SOAP_FMAC3 ns1__searchDatasetByParameterLogicalResponse * SOAP_FMAC4 soap_in_ns1 int ns1__searchDatasetByParameterLogicalResponse::soap_put(struct soap *soap, const char *tag, const char *type) const { - register int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__searchDatasetByParameterLogicalResponse); + int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__searchDatasetByParameterLogicalResponse); if (this->soap_out(soap, tag?tag:"ns1:searchDatasetByParameterLogicalResponse", id, type)) return soap->error; return soap_putindependent(soap); @@ -38495,7 +38495,7 @@ SOAP_FMAC3 ns1__searchDatasetByParameterLogical * SOAP_FMAC4 soap_in_ns1__search int ns1__searchDatasetByParameterLogical::soap_put(struct soap *soap, const char *tag, const char *type) const { - register int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__searchDatasetByParameterLogical); + int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__searchDatasetByParameterLogical); if (this->soap_out(soap, tag?tag:"ns1:searchDatasetByParameterLogical", id, type)) return soap->error; return soap_putindependent(soap); @@ -38633,7 +38633,7 @@ SOAP_FMAC3 ns1__searchByUserIDPaginationResponse * SOAP_FMAC4 soap_in_ns1__searc int ns1__searchByUserIDPaginationResponse::soap_put(struct soap *soap, const char *tag, const char *type) const { - register int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__searchByUserIDPaginationResponse); + int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__searchByUserIDPaginationResponse); if (this->soap_out(soap, tag?tag:"ns1:searchByUserIDPaginationResponse", id, type)) return soap->error; return soap_putindependent(soap); @@ -38808,7 +38808,7 @@ SOAP_FMAC3 ns1__searchByUserIDPagination * SOAP_FMAC4 soap_in_ns1__searchByUserI int ns1__searchByUserIDPagination::soap_put(struct soap *soap, const char *tag, const char *type) const { - register int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__searchByUserIDPagination); + int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__searchByUserIDPagination); if (this->soap_out(soap, tag?tag:"ns1:searchByUserIDPagination", id, type)) return soap->error; return soap_putindependent(soap); @@ -38946,7 +38946,7 @@ SOAP_FMAC3 ns1__searchByUserIDResponse * SOAP_FMAC4 soap_in_ns1__searchByUserIDR int ns1__searchByUserIDResponse::soap_put(struct soap *soap, const char *tag, const char *type) const { - register int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__searchByUserIDResponse); + int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__searchByUserIDResponse); if (this->soap_out(soap, tag?tag:"ns1:searchByUserIDResponse", id, type)) return soap->error; return soap_putindependent(soap); @@ -39097,7 +39097,7 @@ SOAP_FMAC3 ns1__searchByUserID * SOAP_FMAC4 soap_in_ns1__searchByUserID(struct s int ns1__searchByUserID::soap_put(struct soap *soap, const char *tag, const char *type) const { - register int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__searchByUserID); + int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__searchByUserID); if (this->soap_out(soap, tag?tag:"ns1:searchByUserID", id, type)) return soap->error; return soap_putindependent(soap); @@ -39201,7 +39201,7 @@ SOAP_FMAC3 ns1__modifyPublicationResponse * SOAP_FMAC4 soap_in_ns1__modifyPublic int ns1__modifyPublicationResponse::soap_put(struct soap *soap, const char *tag, const char *type) const { - register int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__modifyPublicationResponse); + int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__modifyPublicationResponse); if (this->soap_out(soap, tag?tag:"ns1:modifyPublicationResponse", id, type)) return soap->error; return soap_putindependent(soap); @@ -39352,7 +39352,7 @@ SOAP_FMAC3 ns1__modifyPublication * SOAP_FMAC4 soap_in_ns1__modifyPublication(st int ns1__modifyPublication::soap_put(struct soap *soap, const char *tag, const char *type) const { - register int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__modifyPublication); + int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__modifyPublication); if (this->soap_out(soap, tag?tag:"ns1:modifyPublication", id, type)) return soap->error; return soap_putindependent(soap); @@ -39490,7 +39490,7 @@ SOAP_FMAC3 ns1__searchInvestigationByParameterRestrictionResponse * SOAP_FMAC4 s int ns1__searchInvestigationByParameterRestrictionResponse::soap_put(struct soap *soap, const char *tag, const char *type) const { - register int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__searchInvestigationByParameterRestrictionResponse); + int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__searchInvestigationByParameterRestrictionResponse); if (this->soap_out(soap, tag?tag:"ns1:searchInvestigationByParameterRestrictionResponse", id, type)) return soap->error; return soap_putindependent(soap); @@ -39651,7 +39651,7 @@ SOAP_FMAC3 ns1__searchInvestigationByParameterRestriction * SOAP_FMAC4 soap_in_n int ns1__searchInvestigationByParameterRestriction::soap_put(struct soap *soap, const char *tag, const char *type) const { - register int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__searchInvestigationByParameterRestriction); + int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__searchInvestigationByParameterRestriction); if (this->soap_out(soap, tag?tag:"ns1:searchInvestigationByParameterRestriction", id, type)) return soap->error; return soap_putindependent(soap); @@ -39789,7 +39789,7 @@ SOAP_FMAC3 ns1__searchSampleByParameterConditionResponse * SOAP_FMAC4 soap_in_ns int ns1__searchSampleByParameterConditionResponse::soap_put(struct soap *soap, const char *tag, const char *type) const { - register int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__searchSampleByParameterConditionResponse); + int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__searchSampleByParameterConditionResponse); if (this->soap_out(soap, tag?tag:"ns1:searchSampleByParameterConditionResponse", id, type)) return soap->error; return soap_putindependent(soap); @@ -39940,7 +39940,7 @@ SOAP_FMAC3 ns1__searchSampleByParameterCondition * SOAP_FMAC4 soap_in_ns1__searc int ns1__searchSampleByParameterCondition::soap_put(struct soap *soap, const char *tag, const char *type) const { - register int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__searchSampleByParameterCondition); + int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__searchSampleByParameterCondition); if (this->soap_out(soap, tag?tag:"ns1:searchSampleByParameterCondition", id, type)) return soap->error; return soap_putindependent(soap); @@ -40044,7 +40044,7 @@ SOAP_FMAC3 ns1__removeDataSetParameterResponse * SOAP_FMAC4 soap_in_ns1__removeD int ns1__removeDataSetParameterResponse::soap_put(struct soap *soap, const char *tag, const char *type) const { - register int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__removeDataSetParameterResponse); + int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__removeDataSetParameterResponse); if (this->soap_out(soap, tag?tag:"ns1:removeDataSetParameterResponse", id, type)) return soap->error; return soap_putindependent(soap); @@ -40195,7 +40195,7 @@ SOAP_FMAC3 ns1__removeDataSetParameter * SOAP_FMAC4 soap_in_ns1__removeDataSetPa int ns1__removeDataSetParameter::soap_put(struct soap *soap, const char *tag, const char *type) const { - register int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__removeDataSetParameter); + int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__removeDataSetParameter); if (this->soap_out(soap, tag?tag:"ns1:removeDataSetParameter", id, type)) return soap->error; return soap_putindependent(soap); @@ -40333,7 +40333,7 @@ SOAP_FMAC3 ns1__searchSampleByParameterRestrictionResponse * SOAP_FMAC4 soap_in_ int ns1__searchSampleByParameterRestrictionResponse::soap_put(struct soap *soap, const char *tag, const char *type) const { - register int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__searchSampleByParameterRestrictionResponse); + int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__searchSampleByParameterRestrictionResponse); if (this->soap_out(soap, tag?tag:"ns1:searchSampleByParameterRestrictionResponse", id, type)) return soap->error; return soap_putindependent(soap); @@ -40494,7 +40494,7 @@ SOAP_FMAC3 ns1__searchSampleByParameterRestriction * SOAP_FMAC4 soap_in_ns1__sea int ns1__searchSampleByParameterRestriction::soap_put(struct soap *soap, const char *tag, const char *type) const { - register int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__searchSampleByParameterRestriction); + int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__searchSampleByParameterRestriction); if (this->soap_out(soap, tag?tag:"ns1:searchSampleByParameterRestriction", id, type)) return soap->error; return soap_putindependent(soap); @@ -40632,7 +40632,7 @@ SOAP_FMAC3 ns1__getMyInvestigationsIncludesPaginationResponse * SOAP_FMAC4 soap_ int ns1__getMyInvestigationsIncludesPaginationResponse::soap_put(struct soap *soap, const char *tag, const char *type) const { - register int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__getMyInvestigationsIncludesPaginationResponse); + int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__getMyInvestigationsIncludesPaginationResponse); if (this->soap_out(soap, tag?tag:"ns1:getMyInvestigationsIncludesPaginationResponse", id, type)) return soap->error; return soap_putindependent(soap); @@ -40807,7 +40807,7 @@ SOAP_FMAC3 ns1__getMyInvestigationsIncludesPagination * SOAP_FMAC4 soap_in_ns1__ int ns1__getMyInvestigationsIncludesPagination::soap_put(struct soap *soap, const char *tag, const char *type) const { - register int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__getMyInvestigationsIncludesPagination); + int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__getMyInvestigationsIncludesPagination); if (this->soap_out(soap, tag?tag:"ns1:getMyInvestigationsIncludesPagination", id, type)) return soap->error; return soap_putindependent(soap); @@ -40945,7 +40945,7 @@ SOAP_FMAC3 ns1__getMyInvestigationsIncludesResponse * SOAP_FMAC4 soap_in_ns1__ge int ns1__getMyInvestigationsIncludesResponse::soap_put(struct soap *soap, const char *tag, const char *type) const { - register int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__getMyInvestigationsIncludesResponse); + int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__getMyInvestigationsIncludesResponse); if (this->soap_out(soap, tag?tag:"ns1:getMyInvestigationsIncludesResponse", id, type)) return soap->error; return soap_putindependent(soap); @@ -41096,7 +41096,7 @@ SOAP_FMAC3 ns1__getMyInvestigationsIncludes * SOAP_FMAC4 soap_in_ns1__getMyInves int ns1__getMyInvestigationsIncludes::soap_put(struct soap *soap, const char *tag, const char *type) const { - register int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__getMyInvestigationsIncludes); + int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__getMyInvestigationsIncludes); if (this->soap_out(soap, tag?tag:"ns1:getMyInvestigationsIncludes", id, type)) return soap->error; return soap_putindependent(soap); @@ -41234,7 +41234,7 @@ SOAP_FMAC3 ns1__getMyInvestigationsResponse * SOAP_FMAC4 soap_in_ns1__getMyInves int ns1__getMyInvestigationsResponse::soap_put(struct soap *soap, const char *tag, const char *type) const { - register int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__getMyInvestigationsResponse); + int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__getMyInvestigationsResponse); if (this->soap_out(soap, tag?tag:"ns1:getMyInvestigationsResponse", id, type)) return soap->error; return soap_putindependent(soap); @@ -41375,7 +41375,7 @@ SOAP_FMAC3 ns1__getMyInvestigations * SOAP_FMAC4 soap_in_ns1__getMyInvestigation int ns1__getMyInvestigations::soap_put(struct soap *soap, const char *tag, const char *type) const { - register int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__getMyInvestigations); + int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__getMyInvestigations); if (this->soap_out(soap, tag?tag:"ns1:getMyInvestigations", id, type)) return soap->error; return soap_putindependent(soap); @@ -41513,7 +41513,7 @@ SOAP_FMAC3 ns1__searchDatafileByRestrictionLogicalResponse * SOAP_FMAC4 soap_in_ int ns1__searchDatafileByRestrictionLogicalResponse::soap_put(struct soap *soap, const char *tag, const char *type) const { - register int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__searchDatafileByRestrictionLogicalResponse); + int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__searchDatafileByRestrictionLogicalResponse); if (this->soap_out(soap, tag?tag:"ns1:searchDatafileByRestrictionLogicalResponse", id, type)) return soap->error; return soap_putindependent(soap); @@ -41664,7 +41664,7 @@ SOAP_FMAC3 ns1__searchDatafileByRestrictionLogical * SOAP_FMAC4 soap_in_ns1__sea int ns1__searchDatafileByRestrictionLogical::soap_put(struct soap *soap, const char *tag, const char *type) const { - register int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__searchDatafileByRestrictionLogical); + int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__searchDatafileByRestrictionLogical); if (this->soap_out(soap, tag?tag:"ns1:searchDatafileByRestrictionLogical", id, type)) return soap->error; return soap_putindependent(soap); @@ -41802,7 +41802,7 @@ SOAP_FMAC3 ns1__getAllInstrumentsResponse * SOAP_FMAC4 soap_in_ns1__getAllInstru int ns1__getAllInstrumentsResponse::soap_put(struct soap *soap, const char *tag, const char *type) const { - register int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__getAllInstrumentsResponse); + int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__getAllInstrumentsResponse); if (this->soap_out(soap, tag?tag:"ns1:getAllInstrumentsResponse", id, type)) return soap->error; return soap_putindependent(soap); @@ -41943,7 +41943,7 @@ SOAP_FMAC3 ns1__getAllInstruments * SOAP_FMAC4 soap_in_ns1__getAllInstruments(st int ns1__getAllInstruments::soap_put(struct soap *soap, const char *tag, const char *type) const { - register int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__getAllInstruments); + int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__getAllInstruments); if (this->soap_out(soap, tag?tag:"ns1:getAllInstruments", id, type)) return soap->error; return soap_putindependent(soap); @@ -42081,7 +42081,7 @@ SOAP_FMAC3 ns1__searchByKeywordsAllResponse * SOAP_FMAC4 soap_in_ns1__searchByKe int ns1__searchByKeywordsAllResponse::soap_put(struct soap *soap, const char *tag, const char *type) const { - register int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__searchByKeywordsAllResponse); + int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__searchByKeywordsAllResponse); if (this->soap_out(soap, tag?tag:"ns1:searchByKeywordsAllResponse", id, type)) return soap->error; return soap_putindependent(soap); @@ -42242,7 +42242,7 @@ SOAP_FMAC3 ns1__keywordDetails * SOAP_FMAC4 soap_in_ns1__keywordDetails(struct s int ns1__keywordDetails::soap_put(struct soap *soap, const char *tag, const char *type) const { - register int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__keywordDetails); + int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__keywordDetails); if (this->soap_out(soap, tag?tag:"ns1:keywordDetails", id, type)) return soap->error; return soap_putindependent(soap); @@ -42417,7 +42417,7 @@ SOAP_FMAC3 ns1__searchByKeywordsAll * SOAP_FMAC4 soap_in_ns1__searchByKeywordsAl int ns1__searchByKeywordsAll::soap_put(struct soap *soap, const char *tag, const char *type) const { - register int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__searchByKeywordsAll); + int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__searchByKeywordsAll); if (this->soap_out(soap, tag?tag:"ns1:searchByKeywordsAll", id, type)) return soap->error; return soap_putindependent(soap); @@ -42555,7 +42555,7 @@ SOAP_FMAC3 ns1__searchByKeywordsResponse * SOAP_FMAC4 soap_in_ns1__searchByKeywo int ns1__searchByKeywordsResponse::soap_put(struct soap *soap, const char *tag, const char *type) const { - register int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__searchByKeywordsResponse); + int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__searchByKeywordsResponse); if (this->soap_out(soap, tag?tag:"ns1:searchByKeywordsResponse", id, type)) return soap->error; return soap_putindependent(soap); @@ -42703,7 +42703,7 @@ SOAP_FMAC3 ns1__searchByKeywords * SOAP_FMAC4 soap_in_ns1__searchByKeywords(stru int ns1__searchByKeywords::soap_put(struct soap *soap, const char *tag, const char *type) const { - register int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__searchByKeywords); + int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__searchByKeywords); if (this->soap_out(soap, tag?tag:"ns1:searchByKeywords", id, type)) return soap->error; return soap_putindependent(soap); @@ -42844,7 +42844,7 @@ SOAP_FMAC3 ns1__checkDatasetDownloadAccessResponse * SOAP_FMAC4 soap_in_ns1__che int ns1__checkDatasetDownloadAccessResponse::soap_put(struct soap *soap, const char *tag, const char *type) const { - register int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__checkDatasetDownloadAccessResponse); + int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__checkDatasetDownloadAccessResponse); if (this->soap_out(soap, tag?tag:"ns1:checkDatasetDownloadAccessResponse", id, type)) return soap->error; return soap_putindependent(soap); @@ -42995,7 +42995,7 @@ SOAP_FMAC3 ns1__checkDatasetDownloadAccess * SOAP_FMAC4 soap_in_ns1__checkDatase int ns1__checkDatasetDownloadAccess::soap_put(struct soap *soap, const char *tag, const char *type) const { - register int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__checkDatasetDownloadAccess); + int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__checkDatasetDownloadAccess); if (this->soap_out(soap, tag?tag:"ns1:checkDatasetDownloadAccess", id, type)) return soap->error; return soap_putindependent(soap); @@ -43133,7 +43133,7 @@ SOAP_FMAC3 ns1__searchDatafileByParameterConditionResponse * SOAP_FMAC4 soap_in_ int ns1__searchDatafileByParameterConditionResponse::soap_put(struct soap *soap, const char *tag, const char *type) const { - register int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__searchDatafileByParameterConditionResponse); + int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__searchDatafileByParameterConditionResponse); if (this->soap_out(soap, tag?tag:"ns1:searchDatafileByParameterConditionResponse", id, type)) return soap->error; return soap_putindependent(soap); @@ -43284,7 +43284,7 @@ SOAP_FMAC3 ns1__searchDatafileByParameterCondition * SOAP_FMAC4 soap_in_ns1__sea int ns1__searchDatafileByParameterCondition::soap_put(struct soap *soap, const char *tag, const char *type) const { - register int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__searchDatafileByParameterCondition); + int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__searchDatafileByParameterCondition); if (this->soap_out(soap, tag?tag:"ns1:searchDatafileByParameterCondition", id, type)) return soap->error; return soap_putindependent(soap); @@ -43422,7 +43422,7 @@ SOAP_FMAC3 ns1__searchByUserSurnamePaginationResponse * SOAP_FMAC4 soap_in_ns1__ int ns1__searchByUserSurnamePaginationResponse::soap_put(struct soap *soap, const char *tag, const char *type) const { - register int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__searchByUserSurnamePaginationResponse); + int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__searchByUserSurnamePaginationResponse); if (this->soap_out(soap, tag?tag:"ns1:searchByUserSurnamePaginationResponse", id, type)) return soap->error; return soap_putindependent(soap); @@ -43597,7 +43597,7 @@ SOAP_FMAC3 ns1__searchByUserSurnamePagination * SOAP_FMAC4 soap_in_ns1__searchBy int ns1__searchByUserSurnamePagination::soap_put(struct soap *soap, const char *tag, const char *type) const { - register int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__searchByUserSurnamePagination); + int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__searchByUserSurnamePagination); if (this->soap_out(soap, tag?tag:"ns1:searchByUserSurnamePagination", id, type)) return soap->error; return soap_putindependent(soap); @@ -43760,7 +43760,7 @@ SOAP_FMAC3 ns1__shiftPK * SOAP_FMAC4 soap_in_ns1__shiftPK(struct soap *soap, con int ns1__shiftPK::soap_put(struct soap *soap, const char *tag, const char *type) const { - register int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__shiftPK); + int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__shiftPK); if (this->soap_out(soap, tag?tag:"ns1:shiftPK", id, type)) return soap->error; return soap_putindependent(soap); @@ -43949,7 +43949,7 @@ SOAP_FMAC3 ns1__shift * SOAP_FMAC4 soap_in_ns1__shift(struct soap *soap, const c int ns1__shift::soap_put(struct soap *soap, const char *tag, const char *type) const { - register int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__shift); + int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__shift); if (this->soap_out(soap, tag?tag:"ns1:shift", id, type)) return soap->error; return soap_putindependent(soap); @@ -44168,7 +44168,7 @@ SOAP_FMAC3 ns1__publication * SOAP_FMAC4 soap_in_ns1__publication(struct soap *s int ns1__publication::soap_put(struct soap *soap, const char *tag, const char *type) const { - register int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__publication); + int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__publication); if (this->soap_out(soap, tag?tag:"ns1:publication", id, type)) return soap->error; return soap_putindependent(soap); @@ -44347,7 +44347,7 @@ SOAP_FMAC3 ns1__keyword * SOAP_FMAC4 soap_in_ns1__keyword(struct soap *soap, con int ns1__keyword::soap_put(struct soap *soap, const char *tag, const char *type) const { - register int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__keyword); + int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__keyword); if (this->soap_out(soap, tag?tag:"ns1:keyword", id, type)) return soap->error; return soap_putindependent(soap); @@ -44546,7 +44546,7 @@ SOAP_FMAC3 ns1__investigator * SOAP_FMAC4 soap_in_ns1__investigator(struct soap int ns1__investigator::soap_put(struct soap *soap, const char *tag, const char *type) const { - register int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__investigator); + int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__investigator); if (this->soap_out(soap, tag?tag:"ns1:investigator", id, type)) return soap->error; return soap_putindependent(soap); @@ -44927,7 +44927,7 @@ SOAP_FMAC3 ns1__investigation * SOAP_FMAC4 soap_in_ns1__investigation(struct soa int ns1__investigation::soap_put(struct soap *soap, const char *tag, const char *type) const { - register int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__investigation); + int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__investigation); if (this->soap_out(soap, tag?tag:"ns1:investigation", id, type)) return soap->error; return soap_putindependent(soap); @@ -45065,7 +45065,7 @@ SOAP_FMAC3 ns1__searchByUserSurnameResponse * SOAP_FMAC4 soap_in_ns1__searchByUs int ns1__searchByUserSurnameResponse::soap_put(struct soap *soap, const char *tag, const char *type) const { - register int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__searchByUserSurnameResponse); + int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__searchByUserSurnameResponse); if (this->soap_out(soap, tag?tag:"ns1:searchByUserSurnameResponse", id, type)) return soap->error; return soap_putindependent(soap); @@ -45216,7 +45216,7 @@ SOAP_FMAC3 ns1__searchByUserSurname * SOAP_FMAC4 soap_in_ns1__searchByUserSurnam int ns1__searchByUserSurname::soap_put(struct soap *soap, const char *tag, const char *type) const { - register int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__searchByUserSurname); + int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__searchByUserSurname); if (this->soap_out(soap, tag?tag:"ns1:searchByUserSurname", id, type)) return soap->error; return soap_putindependent(soap); @@ -45320,7 +45320,7 @@ SOAP_FMAC3 ns1__deleteDataFileResponse * SOAP_FMAC4 soap_in_ns1__deleteDataFileR int ns1__deleteDataFileResponse::soap_put(struct soap *soap, const char *tag, const char *type) const { - register int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__deleteDataFileResponse); + int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__deleteDataFileResponse); if (this->soap_out(soap, tag?tag:"ns1:deleteDataFileResponse", id, type)) return soap->error; return soap_putindependent(soap); @@ -45471,7 +45471,7 @@ SOAP_FMAC3 ns1__deleteDataFile * SOAP_FMAC4 soap_in_ns1__deleteDataFile(struct s int ns1__deleteDataFile::soap_put(struct soap *soap, const char *tag, const char *type) const { - register int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__deleteDataFile); + int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__deleteDataFile); if (this->soap_out(soap, tag?tag:"ns1:deleteDataFile", id, type)) return soap->error; return soap_putindependent(soap); @@ -45636,7 +45636,7 @@ SOAP_FMAC3 ns1__downloadInfo * SOAP_FMAC4 soap_in_ns1__downloadInfo(struct soap int ns1__downloadInfo::soap_put(struct soap *soap, const char *tag, const char *type) const { - register int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__downloadInfo); + int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__downloadInfo); if (this->soap_out(soap, tag?tag:"ns1:downloadInfo", id, type)) return soap->error; return soap_putindependent(soap); @@ -45777,7 +45777,7 @@ SOAP_FMAC3 ns1__checkDatafileDownloadAccessResponse * SOAP_FMAC4 soap_in_ns1__ch int ns1__checkDatafileDownloadAccessResponse::soap_put(struct soap *soap, const char *tag, const char *type) const { - register int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__checkDatafileDownloadAccessResponse); + int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__checkDatafileDownloadAccessResponse); if (this->soap_out(soap, tag?tag:"ns1:checkDatafileDownloadAccessResponse", id, type)) return soap->error; return soap_putindependent(soap); @@ -45925,7 +45925,7 @@ SOAP_FMAC3 ns1__checkDatafileDownloadAccess * SOAP_FMAC4 soap_in_ns1__checkDataf int ns1__checkDatafileDownloadAccess::soap_put(struct soap *soap, const char *tag, const char *type) const { - register int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__checkDatafileDownloadAccess); + int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__checkDatafileDownloadAccess); if (this->soap_out(soap, tag?tag:"ns1:checkDatafileDownloadAccess", id, type)) return soap->error; return soap_putindependent(soap); @@ -46066,7 +46066,7 @@ SOAP_FMAC3 ns1__getFacilityUserByFacilityUserIdResponse * SOAP_FMAC4 soap_in_ns1 int ns1__getFacilityUserByFacilityUserIdResponse::soap_put(struct soap *soap, const char *tag, const char *type) const { - register int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__getFacilityUserByFacilityUserIdResponse); + int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__getFacilityUserByFacilityUserIdResponse); if (this->soap_out(soap, tag?tag:"ns1:getFacilityUserByFacilityUserIdResponse", id, type)) return soap->error; return soap_putindependent(soap); @@ -46217,7 +46217,7 @@ SOAP_FMAC3 ns1__getFacilityUserByFacilityUserId * SOAP_FMAC4 soap_in_ns1__getFac int ns1__getFacilityUserByFacilityUserId::soap_put(struct soap *soap, const char *tag, const char *type) const { - register int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__getFacilityUserByFacilityUserId); + int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__getFacilityUserByFacilityUserId); if (this->soap_out(soap, tag?tag:"ns1:getFacilityUserByFacilityUserId", id, type)) return soap->error; return soap_putindependent(soap); @@ -46355,7 +46355,7 @@ SOAP_FMAC3 ns1__getFacilityCyclesWithDataForInstrumentResponse * SOAP_FMAC4 soap int ns1__getFacilityCyclesWithDataForInstrumentResponse::soap_put(struct soap *soap, const char *tag, const char *type) const { - register int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__getFacilityCyclesWithDataForInstrumentResponse); + int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__getFacilityCyclesWithDataForInstrumentResponse); if (this->soap_out(soap, tag?tag:"ns1:getFacilityCyclesWithDataForInstrumentResponse", id, type)) return soap->error; return soap_putindependent(soap); @@ -46506,7 +46506,7 @@ SOAP_FMAC3 ns1__getFacilityCyclesWithDataForInstrument * SOAP_FMAC4 soap_in_ns1_ int ns1__getFacilityCyclesWithDataForInstrument::soap_put(struct soap *soap, const char *tag, const char *type) const { - register int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__getFacilityCyclesWithDataForInstrument); + int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__getFacilityCyclesWithDataForInstrument); if (this->soap_out(soap, tag?tag:"ns1:getFacilityCyclesWithDataForInstrument", id, type)) return soap->error; return soap_putindependent(soap); @@ -46647,7 +46647,7 @@ SOAP_FMAC3 ns1__addSampleParameterResponse * SOAP_FMAC4 soap_in_ns1__addSamplePa int ns1__addSampleParameterResponse::soap_put(struct soap *soap, const char *tag, const char *type) const { - register int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__addSampleParameterResponse); + int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__addSampleParameterResponse); if (this->soap_out(soap, tag?tag:"ns1:addSampleParameterResponse", id, type)) return soap->error; return soap_putindependent(soap); @@ -46808,7 +46808,7 @@ SOAP_FMAC3 ns1__addSampleParameter * SOAP_FMAC4 soap_in_ns1__addSampleParameter( int ns1__addSampleParameter::soap_put(struct soap *soap, const char *tag, const char *type) const { - register int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__addSampleParameter); + int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__addSampleParameter); if (this->soap_out(soap, tag?tag:"ns1:addSampleParameter", id, type)) return soap->error; return soap_putindependent(soap); @@ -46912,7 +46912,7 @@ SOAP_FMAC3 ns1__modifyDataSetResponse * SOAP_FMAC4 soap_in_ns1__modifyDataSetRes int ns1__modifyDataSetResponse::soap_put(struct soap *soap, const char *tag, const char *type) const { - register int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__modifyDataSetResponse); + int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__modifyDataSetResponse); if (this->soap_out(soap, tag?tag:"ns1:modifyDataSetResponse", id, type)) return soap->error; return soap_putindependent(soap); @@ -47063,7 +47063,7 @@ SOAP_FMAC3 ns1__modifyDataSet * SOAP_FMAC4 soap_in_ns1__modifyDataSet(struct soa int ns1__modifyDataSet::soap_put(struct soap *soap, const char *tag, const char *type) const { - register int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__modifyDataSet); + int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__modifyDataSet); if (this->soap_out(soap, tag?tag:"ns1:modifyDataSet", id, type)) return soap->error; return soap_putindependent(soap); @@ -47201,7 +47201,7 @@ SOAP_FMAC3 ns1__searchDatasetByParameterComparisonResponse * SOAP_FMAC4 soap_in_ int ns1__searchDatasetByParameterComparisonResponse::soap_put(struct soap *soap, const char *tag, const char *type) const { - register int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__searchDatasetByParameterComparisonResponse); + int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__searchDatasetByParameterComparisonResponse); if (this->soap_out(soap, tag?tag:"ns1:searchDatasetByParameterComparisonResponse", id, type)) return soap->error; return soap_putindependent(soap); @@ -47396,7 +47396,7 @@ SOAP_FMAC3 ns1__parameterComparisonCondition * SOAP_FMAC4 soap_in_ns1__parameter int ns1__parameterComparisonCondition::soap_put(struct soap *soap, const char *tag, const char *type) const { - register int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__parameterComparisonCondition); + int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__parameterComparisonCondition); if (this->soap_out(soap, tag?tag:"ns1:parameterComparisonCondition", id, type)) return soap->error; return soap_putindependent(soap); @@ -47544,7 +47544,7 @@ SOAP_FMAC3 ns1__searchDatasetByParameterComparison * SOAP_FMAC4 soap_in_ns1__sea int ns1__searchDatasetByParameterComparison::soap_put(struct soap *soap, const char *tag, const char *type) const { - register int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__searchDatasetByParameterComparison); + int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__searchDatasetByParameterComparison); if (this->soap_out(soap, tag?tag:"ns1:searchDatasetByParameterComparison", id, type)) return soap->error; return soap_putindependent(soap); @@ -47682,7 +47682,7 @@ SOAP_FMAC3 ns1__searchSampleByRestrictionResponse * SOAP_FMAC4 soap_in_ns1__sear int ns1__searchSampleByRestrictionResponse::soap_put(struct soap *soap, const char *tag, const char *type) const { - register int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__searchSampleByRestrictionResponse); + int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__searchSampleByRestrictionResponse); if (this->soap_out(soap, tag?tag:"ns1:searchSampleByRestrictionResponse", id, type)) return soap->error; return soap_putindependent(soap); @@ -47833,7 +47833,7 @@ SOAP_FMAC3 ns1__searchSampleByRestriction * SOAP_FMAC4 soap_in_ns1__searchSample int ns1__searchSampleByRestriction::soap_put(struct soap *soap, const char *tag, const char *type) const { - register int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__searchSampleByRestriction); + int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__searchSampleByRestriction); if (this->soap_out(soap, tag?tag:"ns1:searchSampleByRestriction", id, type)) return soap->error; return soap_putindependent(soap); @@ -47974,7 +47974,7 @@ SOAP_FMAC3 ns1__downloadDatafilesResponse * SOAP_FMAC4 soap_in_ns1__downloadData int ns1__downloadDatafilesResponse::soap_put(struct soap *soap, const char *tag, const char *type) const { - register int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__downloadDatafilesResponse); + int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__downloadDatafilesResponse); if (this->soap_out(soap, tag?tag:"ns1:downloadDatafilesResponse", id, type)) return soap->error; return soap_putindependent(soap); @@ -48122,7 +48122,7 @@ SOAP_FMAC3 ns1__downloadDatafiles * SOAP_FMAC4 soap_in_ns1__downloadDatafiles(st int ns1__downloadDatafiles::soap_put(struct soap *soap, const char *tag, const char *type) const { - register int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__downloadDatafiles); + int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__downloadDatafiles); if (this->soap_out(soap, tag?tag:"ns1:downloadDatafiles", id, type)) return soap->error; return soap_putindependent(soap); @@ -48260,7 +48260,7 @@ SOAP_FMAC3 ns1__searchInvestigationByParameterConditionResponse * SOAP_FMAC4 soa int ns1__searchInvestigationByParameterConditionResponse::soap_put(struct soap *soap, const char *tag, const char *type) const { - register int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__searchInvestigationByParameterConditionResponse); + int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__searchInvestigationByParameterConditionResponse); if (this->soap_out(soap, tag?tag:"ns1:searchInvestigationByParameterConditionResponse", id, type)) return soap->error; return soap_putindependent(soap); @@ -48411,7 +48411,7 @@ SOAP_FMAC3 ns1__searchInvestigationByParameterCondition * SOAP_FMAC4 soap_in_ns1 int ns1__searchInvestigationByParameterCondition::soap_put(struct soap *soap, const char *tag, const char *type) const { - register int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__searchInvestigationByParameterCondition); + int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__searchInvestigationByParameterCondition); if (this->soap_out(soap, tag?tag:"ns1:searchInvestigationByParameterCondition", id, type)) return soap->error; return soap_putindependent(soap); @@ -48549,7 +48549,7 @@ SOAP_FMAC3 ns1__searchDatafileByParameterResponse * SOAP_FMAC4 soap_in_ns1__sear int ns1__searchDatafileByParameterResponse::soap_put(struct soap *soap, const char *tag, const char *type) const { - register int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__searchDatafileByParameterResponse); + int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__searchDatafileByParameterResponse); if (this->soap_out(soap, tag?tag:"ns1:searchDatafileByParameterResponse", id, type)) return soap->error; return soap_putindependent(soap); @@ -48724,7 +48724,7 @@ SOAP_FMAC3 ns1__parameterSearch * SOAP_FMAC4 soap_in_ns1__parameterSearch(struct int ns1__parameterSearch::soap_put(struct soap *soap, const char *tag, const char *type) const { - register int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__parameterSearch); + int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__parameterSearch); if (this->soap_out(soap, tag?tag:"ns1:parameterSearch", id, type)) return soap->error; return soap_putindependent(soap); @@ -48872,7 +48872,7 @@ SOAP_FMAC3 ns1__searchDatafileByParameter * SOAP_FMAC4 soap_in_ns1__searchDatafi int ns1__searchDatafileByParameter::soap_put(struct soap *soap, const char *tag, const char *type) const { - register int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__searchDatafileByParameter); + int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__searchDatafileByParameter); if (this->soap_out(soap, tag?tag:"ns1:searchDatafileByParameter", id, type)) return soap->error; return soap_putindependent(soap); @@ -49093,7 +49093,7 @@ SOAP_FMAC3 ns1__userDetails * SOAP_FMAC4 soap_in_ns1__userDetails(struct soap *s int ns1__userDetails::soap_put(struct soap *soap, const char *tag, const char *type) const { - register int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__userDetails); + int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__userDetails); if (this->soap_out(soap, tag?tag:"ns1:userDetails", id, type)) return soap->error; return soap_putindependent(soap); @@ -49231,7 +49231,7 @@ SOAP_FMAC3 ns1__searchDatafileByRestrictionComparisonResponse * SOAP_FMAC4 soap_ int ns1__searchDatafileByRestrictionComparisonResponse::soap_put(struct soap *soap, const char *tag, const char *type) const { - register int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__searchDatafileByRestrictionComparisonResponse); + int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__searchDatafileByRestrictionComparisonResponse); if (this->soap_out(soap, tag?tag:"ns1:searchDatafileByRestrictionComparisonResponse", id, type)) return soap->error; return soap_putindependent(soap); @@ -49379,7 +49379,7 @@ SOAP_FMAC3 ns1__searchDatafileByRestrictionComparison * SOAP_FMAC4 soap_in_ns1__ int ns1__searchDatafileByRestrictionComparison::soap_put(struct soap *soap, const char *tag, const char *type) const { - register int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__searchDatafileByRestrictionComparison); + int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__searchDatafileByRestrictionComparison); if (this->soap_out(soap, tag?tag:"ns1:searchDatafileByRestrictionComparison", id, type)) return soap->error; return soap_putindependent(soap); @@ -49517,7 +49517,7 @@ SOAP_FMAC3 ns1__getAllKeywordsResponse * SOAP_FMAC4 soap_in_ns1__getAllKeywordsR int ns1__getAllKeywordsResponse::soap_put(struct soap *soap, const char *tag, const char *type) const { - register int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__getAllKeywordsResponse); + int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__getAllKeywordsResponse); if (this->soap_out(soap, tag?tag:"ns1:getAllKeywordsResponse", id, type)) return soap->error; return soap_putindependent(soap); @@ -49668,7 +49668,7 @@ SOAP_FMAC3 ns1__getAllKeywords * SOAP_FMAC4 soap_in_ns1__getAllKeywords(struct s int ns1__getAllKeywords::soap_put(struct soap *soap, const char *tag, const char *type) const { - register int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__getAllKeywords); + int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__getAllKeywords); if (this->soap_out(soap, tag?tag:"ns1:getAllKeywords", id, type)) return soap->error; return soap_putindependent(soap); @@ -49772,7 +49772,7 @@ SOAP_FMAC3 ns1__removePublicationResponse * SOAP_FMAC4 soap_in_ns1__removePublic int ns1__removePublicationResponse::soap_put(struct soap *soap, const char *tag, const char *type) const { - register int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__removePublicationResponse); + int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__removePublicationResponse); if (this->soap_out(soap, tag?tag:"ns1:removePublicationResponse", id, type)) return soap->error; return soap_putindependent(soap); @@ -49923,7 +49923,7 @@ SOAP_FMAC3 ns1__removePublication * SOAP_FMAC4 soap_in_ns1__removePublication(st int ns1__removePublication::soap_put(struct soap *soap, const char *tag, const char *type) const { - register int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__removePublication); + int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__removePublication); if (this->soap_out(soap, tag?tag:"ns1:removePublication", id, type)) return soap->error; return soap_putindependent(soap); @@ -50061,7 +50061,7 @@ SOAP_FMAC3 ns1__createDataSetsResponse * SOAP_FMAC4 soap_in_ns1__createDataSetsR int ns1__createDataSetsResponse::soap_put(struct soap *soap, const char *tag, const char *type) const { - register int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__createDataSetsResponse); + int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__createDataSetsResponse); if (this->soap_out(soap, tag?tag:"ns1:createDataSetsResponse", id, type)) return soap->error; return soap_putindependent(soap); @@ -50224,7 +50224,7 @@ SOAP_FMAC3 ns1__datasetParameterPK * SOAP_FMAC4 soap_in_ns1__datasetParameterPK( int ns1__datasetParameterPK::soap_put(struct soap *soap, const char *tag, const char *type) const { - register int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__datasetParameterPK); + int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__datasetParameterPK); if (this->soap_out(soap, tag?tag:"ns1:datasetParameterPK", id, type)) return soap->error; return soap_putindependent(soap); @@ -50493,7 +50493,7 @@ SOAP_FMAC3 ns1__datasetParameter * SOAP_FMAC4 soap_in_ns1__datasetParameter(stru int ns1__datasetParameter::soap_put(struct soap *soap, const char *tag, const char *type) const { - register int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__datasetParameter); + int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__datasetParameter); if (this->soap_out(soap, tag?tag:"ns1:datasetParameter", id, type)) return soap->error; return soap_putindependent(soap); @@ -50756,7 +50756,7 @@ SOAP_FMAC3 ns1__dataset * SOAP_FMAC4 soap_in_ns1__dataset(struct soap *soap, con int ns1__dataset::soap_put(struct soap *soap, const char *tag, const char *type) const { - register int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__dataset); + int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__dataset); if (this->soap_out(soap, tag?tag:"ns1:dataset", id, type)) return soap->error; return soap_putindependent(soap); @@ -50914,7 +50914,7 @@ SOAP_FMAC3 ns1__createDataSets * SOAP_FMAC4 soap_in_ns1__createDataSets(struct s int ns1__createDataSets::soap_put(struct soap *soap, const char *tag, const char *type) const { - register int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__createDataSets); + int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__createDataSets); if (this->soap_out(soap, tag?tag:"ns1:createDataSets", id, type)) return soap->error; return soap_putindependent(soap); @@ -51018,7 +51018,7 @@ SOAP_FMAC3 ns1__deleteInvestigationResponse * SOAP_FMAC4 soap_in_ns1__deleteInve int ns1__deleteInvestigationResponse::soap_put(struct soap *soap, const char *tag, const char *type) const { - register int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__deleteInvestigationResponse); + int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__deleteInvestigationResponse); if (this->soap_out(soap, tag?tag:"ns1:deleteInvestigationResponse", id, type)) return soap->error; return soap_putindependent(soap); @@ -51169,7 +51169,7 @@ SOAP_FMAC3 ns1__deleteInvestigation * SOAP_FMAC4 soap_in_ns1__deleteInvestigatio int ns1__deleteInvestigation::soap_put(struct soap *soap, const char *tag, const char *type) const { - register int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__deleteInvestigation); + int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__deleteInvestigation); if (this->soap_out(soap, tag?tag:"ns1:deleteInvestigation", id, type)) return soap->error; return soap_putindependent(soap); @@ -51273,7 +51273,7 @@ SOAP_FMAC3 ns1__removeKeywordResponse * SOAP_FMAC4 soap_in_ns1__removeKeywordRes int ns1__removeKeywordResponse::soap_put(struct soap *soap, const char *tag, const char *type) const { - register int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__removeKeywordResponse); + int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__removeKeywordResponse); if (this->soap_out(soap, tag?tag:"ns1:removeKeywordResponse", id, type)) return soap->error; return soap_putindependent(soap); @@ -51426,7 +51426,7 @@ SOAP_FMAC3 ns1__keywordPK * SOAP_FMAC4 soap_in_ns1__keywordPK(struct soap *soap, int ns1__keywordPK::soap_put(struct soap *soap, const char *tag, const char *type) const { - register int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__keywordPK); + int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__keywordPK); if (this->soap_out(soap, tag?tag:"ns1:keywordPK", id, type)) return soap->error; return soap_putindependent(soap); @@ -51577,7 +51577,7 @@ SOAP_FMAC3 ns1__removeKeyword * SOAP_FMAC4 soap_in_ns1__removeKeyword(struct soa int ns1__removeKeyword::soap_put(struct soap *soap, const char *tag, const char *type) const { - register int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__removeKeyword); + int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__removeKeyword); if (this->soap_out(soap, tag?tag:"ns1:removeKeyword", id, type)) return soap->error; return soap_putindependent(soap); @@ -51715,7 +51715,7 @@ SOAP_FMAC3 ns1__getParameterByRestrictionResponse * SOAP_FMAC4 soap_in_ns1__getP int ns1__getParameterByRestrictionResponse::soap_put(struct soap *soap, const char *tag, const char *type) const { - register int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__getParameterByRestrictionResponse); + int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__getParameterByRestrictionResponse); if (this->soap_out(soap, tag?tag:"ns1:getParameterByRestrictionResponse", id, type)) return soap->error; return soap_putindependent(soap); @@ -51866,7 +51866,7 @@ SOAP_FMAC3 ns1__getParameterByRestriction * SOAP_FMAC4 soap_in_ns1__getParameter int ns1__getParameterByRestriction::soap_put(struct soap *soap, const char *tag, const char *type) const { - register int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__getParameterByRestriction); + int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__getParameterByRestriction); if (this->soap_out(soap, tag?tag:"ns1:getParameterByRestriction", id, type)) return soap->error; return soap_putindependent(soap); @@ -51970,7 +51970,7 @@ SOAP_FMAC3 ns1__removeInvestigatorResponse * SOAP_FMAC4 soap_in_ns1__removeInves int ns1__removeInvestigatorResponse::soap_put(struct soap *soap, const char *tag, const char *type) const { - register int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__removeInvestigatorResponse); + int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__removeInvestigatorResponse); if (this->soap_out(soap, tag?tag:"ns1:removeInvestigatorResponse", id, type)) return soap->error; return soap_putindependent(soap); @@ -52123,7 +52123,7 @@ SOAP_FMAC3 ns1__investigatorPK * SOAP_FMAC4 soap_in_ns1__investigatorPK(struct s int ns1__investigatorPK::soap_put(struct soap *soap, const char *tag, const char *type) const { - register int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__investigatorPK); + int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__investigatorPK); if (this->soap_out(soap, tag?tag:"ns1:investigatorPK", id, type)) return soap->error; return soap_putindependent(soap); @@ -52274,7 +52274,7 @@ SOAP_FMAC3 ns1__removeInvestigator * SOAP_FMAC4 soap_in_ns1__removeInvestigator( int ns1__removeInvestigator::soap_put(struct soap *soap, const char *tag, const char *type) const { - register int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__removeInvestigator); + int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__removeInvestigator); if (this->soap_out(soap, tag?tag:"ns1:removeInvestigator", id, type)) return soap->error; return soap_putindependent(soap); @@ -52378,7 +52378,7 @@ SOAP_FMAC3 ns1__removeInvestigationResponse * SOAP_FMAC4 soap_in_ns1__removeInve int ns1__removeInvestigationResponse::soap_put(struct soap *soap, const char *tag, const char *type) const { - register int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__removeInvestigationResponse); + int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__removeInvestigationResponse); if (this->soap_out(soap, tag?tag:"ns1:removeInvestigationResponse", id, type)) return soap->error; return soap_putindependent(soap); @@ -52529,7 +52529,7 @@ SOAP_FMAC3 ns1__removeInvestigation * SOAP_FMAC4 soap_in_ns1__removeInvestigatio int ns1__removeInvestigation::soap_put(struct soap *soap, const char *tag, const char *type) const { - register int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__removeInvestigation); + int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__removeInvestigation); if (this->soap_out(soap, tag?tag:"ns1:removeInvestigation", id, type)) return soap->error; return soap_putindependent(soap); @@ -52670,7 +52670,7 @@ SOAP_FMAC3 ns1__getFacilityUserByFederalIdResponse * SOAP_FMAC4 soap_in_ns1__get int ns1__getFacilityUserByFederalIdResponse::soap_put(struct soap *soap, const char *tag, const char *type) const { - register int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__getFacilityUserByFederalIdResponse); + int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__getFacilityUserByFederalIdResponse); if (this->soap_out(soap, tag?tag:"ns1:getFacilityUserByFederalIdResponse", id, type)) return soap->error; return soap_putindependent(soap); @@ -52821,7 +52821,7 @@ SOAP_FMAC3 ns1__getFacilityUserByFederalId * SOAP_FMAC4 soap_in_ns1__getFacility int ns1__getFacilityUserByFederalId::soap_put(struct soap *soap, const char *tag, const char *type) const { - register int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__getFacilityUserByFederalId); + int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__getFacilityUserByFederalId); if (this->soap_out(soap, tag?tag:"ns1:getFacilityUserByFederalId", id, type)) return soap->error; return soap_putindependent(soap); @@ -52962,7 +52962,7 @@ SOAP_FMAC3 ns1__downloadDatasetResponse * SOAP_FMAC4 soap_in_ns1__downloadDatase int ns1__downloadDatasetResponse::soap_put(struct soap *soap, const char *tag, const char *type) const { - register int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__downloadDatasetResponse); + int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__downloadDatasetResponse); if (this->soap_out(soap, tag?tag:"ns1:downloadDatasetResponse", id, type)) return soap->error; return soap_putindependent(soap); @@ -53113,7 +53113,7 @@ SOAP_FMAC3 ns1__downloadDataset * SOAP_FMAC4 soap_in_ns1__downloadDataset(struct int ns1__downloadDataset::soap_put(struct soap *soap, const char *tag, const char *type) const { - register int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__downloadDataset); + int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__downloadDataset); if (this->soap_out(soap, tag?tag:"ns1:downloadDataset", id, type)) return soap->error; return soap_putindependent(soap); @@ -53322,7 +53322,7 @@ SOAP_FMAC3 ns1__instrument * SOAP_FMAC4 soap_in_ns1__instrument(struct soap *soa int ns1__instrument::soap_put(struct soap *soap, const char *tag, const char *type) const { - register int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__instrument); + int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__instrument); if (this->soap_out(soap, tag?tag:"ns1:instrument", id, type)) return soap->error; return soap_putindependent(soap); @@ -53460,7 +53460,7 @@ SOAP_FMAC3 ns1__getInstrumentsWithDataResponse * SOAP_FMAC4 soap_in_ns1__getInst int ns1__getInstrumentsWithDataResponse::soap_put(struct soap *soap, const char *tag, const char *type) const { - register int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__getInstrumentsWithDataResponse); + int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__getInstrumentsWithDataResponse); if (this->soap_out(soap, tag?tag:"ns1:getInstrumentsWithDataResponse", id, type)) return soap->error; return soap_putindependent(soap); @@ -53601,7 +53601,7 @@ SOAP_FMAC3 ns1__getInstrumentsWithData * SOAP_FMAC4 soap_in_ns1__getInstrumentsW int ns1__getInstrumentsWithData::soap_put(struct soap *soap, const char *tag, const char *type) const { - register int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__getInstrumentsWithData); + int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__getInstrumentsWithData); if (this->soap_out(soap, tag?tag:"ns1:getInstrumentsWithData", id, type)) return soap->error; return soap_putindependent(soap); @@ -53745,7 +53745,7 @@ SOAP_FMAC3 ns1__logoutResponse * SOAP_FMAC4 soap_in_ns1__logoutResponse(struct s int ns1__logoutResponse::soap_put(struct soap *soap, const char *tag, const char *type) const { - register int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__logoutResponse); + int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__logoutResponse); if (this->soap_out(soap, tag?tag:"ns1:logoutResponse", id, type)) return soap->error; return soap_putindependent(soap); @@ -53886,7 +53886,7 @@ SOAP_FMAC3 ns1__logout * SOAP_FMAC4 soap_in_ns1__logout(struct soap *soap, const int ns1__logout::soap_put(struct soap *soap, const char *tag, const char *type) const { - register int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__logout); + int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__logout); if (this->soap_out(soap, tag?tag:"ns1:logout", id, type)) return soap->error; return soap_putindependent(soap); @@ -54024,7 +54024,7 @@ SOAP_FMAC3 ns1__addDataFileParametersResponse * SOAP_FMAC4 soap_in_ns1__addDataF int ns1__addDataFileParametersResponse::soap_put(struct soap *soap, const char *tag, const char *type) const { - register int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__addDataFileParametersResponse); + int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__addDataFileParametersResponse); if (this->soap_out(soap, tag?tag:"ns1:addDataFileParametersResponse", id, type)) return soap->error; return soap_putindependent(soap); @@ -54182,7 +54182,7 @@ SOAP_FMAC3 ns1__addDataFileParameters * SOAP_FMAC4 soap_in_ns1__addDataFileParam int ns1__addDataFileParameters::soap_put(struct soap *soap, const char *tag, const char *type) const { - register int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__addDataFileParameters); + int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__addDataFileParameters); if (this->soap_out(soap, tag?tag:"ns1:addDataFileParameters", id, type)) return soap->error; return soap_putindependent(soap); @@ -54391,7 +54391,7 @@ SOAP_FMAC3 ns1__facilityCycle * SOAP_FMAC4 soap_in_ns1__facilityCycle(struct soa int ns1__facilityCycle::soap_put(struct soap *soap, const char *tag, const char *type) const { - register int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__facilityCycle); + int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__facilityCycle); if (this->soap_out(soap, tag?tag:"ns1:facilityCycle", id, type)) return soap->error; return soap_putindependent(soap); @@ -54529,7 +54529,7 @@ SOAP_FMAC3 ns1__listFacilityCyclesResponse * SOAP_FMAC4 soap_in_ns1__listFacilit int ns1__listFacilityCyclesResponse::soap_put(struct soap *soap, const char *tag, const char *type) const { - register int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__listFacilityCyclesResponse); + int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__listFacilityCyclesResponse); if (this->soap_out(soap, tag?tag:"ns1:listFacilityCyclesResponse", id, type)) return soap->error; return soap_putindependent(soap); @@ -54670,7 +54670,7 @@ SOAP_FMAC3 ns1__listFacilityCycles * SOAP_FMAC4 soap_in_ns1__listFacilityCycles( int ns1__listFacilityCycles::soap_put(struct soap *soap, const char *tag, const char *type) const { - register int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__listFacilityCycles); + int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__listFacilityCycles); if (this->soap_out(soap, tag?tag:"ns1:listFacilityCycles", id, type)) return soap->error; return soap_putindependent(soap); @@ -54774,7 +54774,7 @@ SOAP_FMAC3 ns1__removeAuthorisationResponse * SOAP_FMAC4 soap_in_ns1__removeAuth int ns1__removeAuthorisationResponse::soap_put(struct soap *soap, const char *tag, const char *type) const { - register int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__removeAuthorisationResponse); + int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__removeAuthorisationResponse); if (this->soap_out(soap, tag?tag:"ns1:removeAuthorisationResponse", id, type)) return soap->error; return soap_putindependent(soap); @@ -54925,7 +54925,7 @@ SOAP_FMAC3 ns1__removeAuthorisation * SOAP_FMAC4 soap_in_ns1__removeAuthorisatio int ns1__removeAuthorisation::soap_put(struct soap *soap, const char *tag, const char *type) const { - register int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__removeAuthorisation); + int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__removeAuthorisation); if (this->soap_out(soap, tag?tag:"ns1:removeAuthorisation", id, type)) return soap->error; return soap_putindependent(soap); @@ -55029,7 +55029,7 @@ SOAP_FMAC3 ns1__removeDataFileResponse * SOAP_FMAC4 soap_in_ns1__removeDataFileR int ns1__removeDataFileResponse::soap_put(struct soap *soap, const char *tag, const char *type) const { - register int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__removeDataFileResponse); + int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__removeDataFileResponse); if (this->soap_out(soap, tag?tag:"ns1:removeDataFileResponse", id, type)) return soap->error; return soap_putindependent(soap); @@ -55180,7 +55180,7 @@ SOAP_FMAC3 ns1__removeDataFile * SOAP_FMAC4 soap_in_ns1__removeDataFile(struct s int ns1__removeDataFile::soap_put(struct soap *soap, const char *tag, const char *type) const { - register int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__removeDataFile); + int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__removeDataFile); if (this->soap_out(soap, tag?tag:"ns1:removeDataFile", id, type)) return soap->error; return soap_putindependent(soap); @@ -55333,7 +55333,7 @@ SOAP_FMAC3 ns1__parameterPK * SOAP_FMAC4 soap_in_ns1__parameterPK(struct soap *s int ns1__parameterPK::soap_put(struct soap *soap, const char *tag, const char *type) const { - register int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__parameterPK); + int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__parameterPK); if (this->soap_out(soap, tag?tag:"ns1:parameterPK", id, type)) return soap->error; return soap_putindependent(soap); @@ -55598,7 +55598,7 @@ SOAP_FMAC3 ns1__parameter * SOAP_FMAC4 soap_in_ns1__parameter(struct soap *soap, int ns1__parameter::soap_put(struct soap *soap, const char *tag, const char *type) const { - register int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__parameter); + int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__parameter); if (this->soap_out(soap, tag?tag:"ns1:parameter", id, type)) return soap->error; return soap_putindependent(soap); @@ -55736,7 +55736,7 @@ SOAP_FMAC3 ns1__getParameterByNameUnitsResponse * SOAP_FMAC4 soap_in_ns1__getPar int ns1__getParameterByNameUnitsResponse::soap_put(struct soap *soap, const char *tag, const char *type) const { - register int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__getParameterByNameUnitsResponse); + int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__getParameterByNameUnitsResponse); if (this->soap_out(soap, tag?tag:"ns1:getParameterByNameUnitsResponse", id, type)) return soap->error; return soap_putindependent(soap); @@ -55897,7 +55897,7 @@ SOAP_FMAC3 ns1__getParameterByNameUnits * SOAP_FMAC4 soap_in_ns1__getParameterBy int ns1__getParameterByNameUnits::soap_put(struct soap *soap, const char *tag, const char *type) const { - register int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__getParameterByNameUnits); + int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__getParameterByNameUnits); if (this->soap_out(soap, tag?tag:"ns1:getParameterByNameUnits", id, type)) return soap->error; return soap_putindependent(soap); @@ -56035,7 +56035,7 @@ SOAP_FMAC3 ns1__searchInvestigationByParameterLogicalResponse * SOAP_FMAC4 soap_ int ns1__searchInvestigationByParameterLogicalResponse::soap_put(struct soap *soap, const char *tag, const char *type) const { - register int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__searchInvestigationByParameterLogicalResponse); + int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__searchInvestigationByParameterLogicalResponse); if (this->soap_out(soap, tag?tag:"ns1:searchInvestigationByParameterLogicalResponse", id, type)) return soap->error; return soap_putindependent(soap); @@ -56207,7 +56207,7 @@ SOAP_FMAC3 ns1__parameterLogicalCondition * SOAP_FMAC4 soap_in_ns1__parameterLog int ns1__parameterLogicalCondition::soap_put(struct soap *soap, const char *tag, const char *type) const { - register int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__parameterLogicalCondition); + int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__parameterLogicalCondition); if (this->soap_out(soap, tag?tag:"ns1:parameterLogicalCondition", id, type)) return soap->error; return soap_putindependent(soap); @@ -56358,7 +56358,7 @@ SOAP_FMAC3 ns1__searchInvestigationByParameterLogical * SOAP_FMAC4 soap_in_ns1__ int ns1__searchInvestigationByParameterLogical::soap_put(struct soap *soap, const char *tag, const char *type) const { - register int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__searchInvestigationByParameterLogical); + int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__searchInvestigationByParameterLogical); if (this->soap_out(soap, tag?tag:"ns1:searchInvestigationByParameterLogical", id, type)) return soap->error; return soap_putindependent(soap); @@ -56462,7 +56462,7 @@ SOAP_FMAC3 ns1__modifySampleResponse * SOAP_FMAC4 soap_in_ns1__modifySampleRespo int ns1__modifySampleResponse::soap_put(struct soap *soap, const char *tag, const char *type) const { - register int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__modifySampleResponse); + int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__modifySampleResponse); if (this->soap_out(soap, tag?tag:"ns1:modifySampleResponse", id, type)) return soap->error; return soap_putindependent(soap); @@ -56613,7 +56613,7 @@ SOAP_FMAC3 ns1__modifySample * SOAP_FMAC4 soap_in_ns1__modifySample(struct soap int ns1__modifySample::soap_put(struct soap *soap, const char *tag, const char *type) const { - register int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__modifySample); + int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__modifySample); if (this->soap_out(soap, tag?tag:"ns1:modifySample", id, type)) return soap->error; return soap_putindependent(soap); @@ -56754,7 +56754,7 @@ SOAP_FMAC3 ns1__createDataFileResponse * SOAP_FMAC4 soap_in_ns1__createDataFileR int ns1__createDataFileResponse::soap_put(struct soap *soap, const char *tag, const char *type) const { - register int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__createDataFileResponse); + int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__createDataFileResponse); if (this->soap_out(soap, tag?tag:"ns1:createDataFileResponse", id, type)) return soap->error; return soap_putindependent(soap); @@ -56907,7 +56907,7 @@ SOAP_FMAC3 ns1__relatedDatafilesPK * SOAP_FMAC4 soap_in_ns1__relatedDatafilesPK( int ns1__relatedDatafilesPK::soap_put(struct soap *soap, const char *tag, const char *type) const { - register int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__relatedDatafilesPK); + int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__relatedDatafilesPK); if (this->soap_out(soap, tag?tag:"ns1:relatedDatafilesPK", id, type)) return soap->error; return soap_putindependent(soap); @@ -57096,7 +57096,7 @@ SOAP_FMAC3 ns1__relatedDatafiles * SOAP_FMAC4 soap_in_ns1__relatedDatafiles(stru int ns1__relatedDatafiles::soap_put(struct soap *soap, const char *tag, const char *type) const { - register int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__relatedDatafiles); + int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__relatedDatafiles); if (this->soap_out(soap, tag?tag:"ns1:relatedDatafiles", id, type)) return soap->error; return soap_putindependent(soap); @@ -57259,7 +57259,7 @@ SOAP_FMAC3 ns1__datafileParameterPK * SOAP_FMAC4 soap_in_ns1__datafileParameterP int ns1__datafileParameterPK::soap_put(struct soap *soap, const char *tag, const char *type) const { - register int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__datafileParameterPK); + int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__datafileParameterPK); if (this->soap_out(soap, tag?tag:"ns1:datafileParameterPK", id, type)) return soap->error; return soap_putindependent(soap); @@ -57518,7 +57518,7 @@ SOAP_FMAC3 ns1__datafileParameter * SOAP_FMAC4 soap_in_ns1__datafileParameter(st int ns1__datafileParameter::soap_put(struct soap *soap, const char *tag, const char *type) const { - register int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__datafileParameter); + int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__datafileParameter); if (this->soap_out(soap, tag?tag:"ns1:datafileParameter", id, type)) return soap->error; return soap_putindependent(soap); @@ -57671,7 +57671,7 @@ SOAP_FMAC3 ns1__datafileFormatPK * SOAP_FMAC4 soap_in_ns1__datafileFormatPK(stru int ns1__datafileFormatPK::soap_put(struct soap *soap, const char *tag, const char *type) const { - register int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__datafileFormatPK); + int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__datafileFormatPK); if (this->soap_out(soap, tag?tag:"ns1:datafileFormatPK", id, type)) return soap->error; return soap_putindependent(soap); @@ -57870,7 +57870,7 @@ SOAP_FMAC3 ns1__datafileFormat * SOAP_FMAC4 soap_in_ns1__datafileFormat(struct s int ns1__datafileFormat::soap_put(struct soap *soap, const char *tag, const char *type) const { - register int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__datafileFormat); + int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__datafileFormat); if (this->soap_out(soap, tag?tag:"ns1:datafileFormat", id, type)) return soap->error; return soap_putindependent(soap); @@ -58210,7 +58210,7 @@ SOAP_FMAC3 ns1__datafile * SOAP_FMAC4 soap_in_ns1__datafile(struct soap *soap, c int ns1__datafile::soap_put(struct soap *soap, const char *tag, const char *type) const { - register int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__datafile); + int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__datafile); if (this->soap_out(soap, tag?tag:"ns1:datafile", id, type)) return soap->error; return soap_putindependent(soap); @@ -58371,7 +58371,7 @@ SOAP_FMAC3 ns1__createDataFile * SOAP_FMAC4 soap_in_ns1__createDataFile(struct s int ns1__createDataFile::soap_put(struct soap *soap, const char *tag, const char *type) const { - register int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__createDataFile); + int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__createDataFile); if (this->soap_out(soap, tag?tag:"ns1:createDataFile", id, type)) return soap->error; return soap_putindependent(soap); @@ -58532,7 +58532,7 @@ SOAP_FMAC3 ns1__InsufficientPrivilegesException * SOAP_FMAC4 soap_in_ns1__Insuff int ns1__InsufficientPrivilegesException::soap_put(struct soap *soap, const char *tag, const char *type) const { - register int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__InsufficientPrivilegesException); + int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__InsufficientPrivilegesException); if (this->soap_out(soap, tag?tag:"ns1:InsufficientPrivilegesException", id, type)) return soap->error; return soap_putindependent(soap); @@ -58636,7 +58636,7 @@ SOAP_FMAC3 ns1__removeSampleResponse * SOAP_FMAC4 soap_in_ns1__removeSampleRespo int ns1__removeSampleResponse::soap_put(struct soap *soap, const char *tag, const char *type) const { - register int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__removeSampleResponse); + int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__removeSampleResponse); if (this->soap_out(soap, tag?tag:"ns1:removeSampleResponse", id, type)) return soap->error; return soap_putindependent(soap); @@ -58787,7 +58787,7 @@ SOAP_FMAC3 ns1__removeSample * SOAP_FMAC4 soap_in_ns1__removeSample(struct soap int ns1__removeSample::soap_put(struct soap *soap, const char *tag, const char *type) const { - register int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__removeSample); + int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__removeSample); if (this->soap_out(soap, tag?tag:"ns1:removeSample", id, type)) return soap->error; return soap_putindependent(soap); @@ -58925,7 +58925,7 @@ SOAP_FMAC3 ns1__listInstrumentsResponse * SOAP_FMAC4 soap_in_ns1__listInstrument int ns1__listInstrumentsResponse::soap_put(struct soap *soap, const char *tag, const char *type) const { - register int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__listInstrumentsResponse); + int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__listInstrumentsResponse); if (this->soap_out(soap, tag?tag:"ns1:listInstrumentsResponse", id, type)) return soap->error; return soap_putindependent(soap); @@ -59066,7 +59066,7 @@ SOAP_FMAC3 ns1__listInstruments * SOAP_FMAC4 soap_in_ns1__listInstruments(struct int ns1__listInstruments::soap_put(struct soap *soap, const char *tag, const char *type) const { - register int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__listInstruments); + int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__listInstruments); if (this->soap_out(soap, tag?tag:"ns1:listInstruments", id, type)) return soap->error; return soap_putindependent(soap); @@ -59204,7 +59204,7 @@ SOAP_FMAC3 ns1__searchDatafileByRestrictionResponse * SOAP_FMAC4 soap_in_ns1__se int ns1__searchDatafileByRestrictionResponse::soap_put(struct soap *soap, const char *tag, const char *type) const { - register int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__searchDatafileByRestrictionResponse); + int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__searchDatafileByRestrictionResponse); if (this->soap_out(soap, tag?tag:"ns1:searchDatafileByRestrictionResponse", id, type)) return soap->error; return soap_putindependent(soap); @@ -59355,7 +59355,7 @@ SOAP_FMAC3 ns1__searchDatafileByRestriction * SOAP_FMAC4 soap_in_ns1__searchData int ns1__searchDatafileByRestriction::soap_put(struct soap *soap, const char *tag, const char *type) const { - register int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__searchDatafileByRestriction); + int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__searchDatafileByRestriction); if (this->soap_out(soap, tag?tag:"ns1:searchDatafileByRestriction", id, type)) return soap->error; return soap_putindependent(soap); @@ -59493,7 +59493,7 @@ SOAP_FMAC3 ns1__searchSampleByRestrictionComparisonResponse * SOAP_FMAC4 soap_in int ns1__searchSampleByRestrictionComparisonResponse::soap_put(struct soap *soap, const char *tag, const char *type) const { - register int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__searchSampleByRestrictionComparisonResponse); + int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__searchSampleByRestrictionComparisonResponse); if (this->soap_out(soap, tag?tag:"ns1:searchSampleByRestrictionComparisonResponse", id, type)) return soap->error; return soap_putindependent(soap); @@ -59760,7 +59760,7 @@ SOAP_FMAC3 ns1__restrictionComparisonCondition * SOAP_FMAC4 soap_in_ns1__restric int ns1__restrictionComparisonCondition::soap_put(struct soap *soap, const char *tag, const char *type) const { - register int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__restrictionComparisonCondition); + int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__restrictionComparisonCondition); if (this->soap_out(soap, tag?tag:"ns1:restrictionComparisonCondition", id, type)) return soap->error; return soap_putindependent(soap); @@ -59908,7 +59908,7 @@ SOAP_FMAC3 ns1__searchSampleByRestrictionComparison * SOAP_FMAC4 soap_in_ns1__se int ns1__searchSampleByRestrictionComparison::soap_put(struct soap *soap, const char *tag, const char *type) const { - register int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__searchSampleByRestrictionComparison); + int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__searchSampleByRestrictionComparison); if (this->soap_out(soap, tag?tag:"ns1:searchSampleByRestrictionComparison", id, type)) return soap->error; return soap_putindependent(soap); @@ -60012,7 +60012,7 @@ SOAP_FMAC3 ns1__entityPrimaryKeyBaseBean * SOAP_FMAC4 soap_in_ns1__entityPrimary int ns1__entityPrimaryKeyBaseBean::soap_put(struct soap *soap, const char *tag, const char *type) const { - register int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__entityPrimaryKeyBaseBean); + int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__entityPrimaryKeyBaseBean); if (this->soap_out(soap, tag?tag:"ns1:entityPrimaryKeyBaseBean", id, type)) return soap->error; return soap_putindependent(soap); @@ -60364,7 +60364,7 @@ SOAP_FMAC3 ns1__sampleParameterPK * SOAP_FMAC4 soap_in_ns1__sampleParameterPK(st int ns1__sampleParameterPK::soap_put(struct soap *soap, const char *tag, const char *type) const { - register int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__sampleParameterPK); + int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__sampleParameterPK); if (this->soap_out(soap, tag?tag:"ns1:sampleParameterPK", id, type)) return soap->error; return soap_putindependent(soap); @@ -60623,7 +60623,7 @@ SOAP_FMAC3 ns1__sampleParameter * SOAP_FMAC4 soap_in_ns1__sampleParameter(struct int ns1__sampleParameter::soap_put(struct soap *soap, const char *tag, const char *type) const { - register int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__sampleParameter); + int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__sampleParameter); if (this->soap_out(soap, tag?tag:"ns1:sampleParameter", id, type)) return soap->error; return soap_putindependent(soap); @@ -60859,7 +60859,7 @@ SOAP_FMAC3 ns1__sample * SOAP_FMAC4 soap_in_ns1__sample(struct soap *soap, const int ns1__sample::soap_put(struct soap *soap, const char *tag, const char *type) const { - register int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__sample); + int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__sample); if (this->soap_out(soap, tag?tag:"ns1:sample", id, type)) return soap->error; return soap_putindependent(soap); @@ -60997,7 +60997,7 @@ SOAP_FMAC3 ns1__searchSamplesBySampleNameResponse * SOAP_FMAC4 soap_in_ns1__sear int ns1__searchSamplesBySampleNameResponse::soap_put(struct soap *soap, const char *tag, const char *type) const { - register int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__searchSamplesBySampleNameResponse); + int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__searchSamplesBySampleNameResponse); if (this->soap_out(soap, tag?tag:"ns1:searchSamplesBySampleNameResponse", id, type)) return soap->error; return soap_putindependent(soap); @@ -61148,7 +61148,7 @@ SOAP_FMAC3 ns1__searchSamplesBySampleName * SOAP_FMAC4 soap_in_ns1__searchSample int ns1__searchSamplesBySampleName::soap_put(struct soap *soap, const char *tag, const char *type) const { - register int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__searchSamplesBySampleName); + int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__searchSamplesBySampleName); if (this->soap_out(soap, tag?tag:"ns1:searchSamplesBySampleName", id, type)) return soap->error; return soap_putindependent(soap); @@ -61417,7 +61417,7 @@ SOAP_FMAC3 ns1__icatRole * SOAP_FMAC4 soap_in_ns1__icatRole(struct soap *soap, c int ns1__icatRole::soap_put(struct soap *soap, const char *tag, const char *type) const { - register int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__icatRole); + int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__icatRole); if (this->soap_out(soap, tag?tag:"ns1:icatRole", id, type)) return soap->error; return soap_putindependent(soap); @@ -61590,7 +61590,7 @@ SOAP_FMAC3 ns1__entityBaseBean * SOAP_FMAC4 soap_in_ns1__entityBaseBean(struct s int ns1__entityBaseBean::soap_put(struct soap *soap, const char *tag, const char *type) const { - register int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__entityBaseBean); + int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__entityBaseBean); if (this->soap_out(soap, tag?tag:"ns1:entityBaseBean", id, type)) return soap->error; return soap_putindependent(soap); @@ -62228,7 +62228,7 @@ SOAP_FMAC3 ns1__facilityUser * SOAP_FMAC4 soap_in_ns1__facilityUser(struct soap int ns1__facilityUser::soap_put(struct soap *soap, const char *tag, const char *type) const { - register int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__facilityUser); + int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__facilityUser); if (this->soap_out(soap, tag?tag:"ns1:facilityUser", id, type)) return soap->error; return soap_putindependent(soap); @@ -62366,7 +62366,7 @@ SOAP_FMAC3 ns1__searchFacilityUserByRestrictionResponse * SOAP_FMAC4 soap_in_ns1 int ns1__searchFacilityUserByRestrictionResponse::soap_put(struct soap *soap, const char *tag, const char *type) const { - register int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__searchFacilityUserByRestrictionResponse); + int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__searchFacilityUserByRestrictionResponse); if (this->soap_out(soap, tag?tag:"ns1:searchFacilityUserByRestrictionResponse", id, type)) return soap->error; return soap_putindependent(soap); @@ -62517,7 +62517,7 @@ SOAP_FMAC3 ns1__searchFacilityUserByRestriction * SOAP_FMAC4 soap_in_ns1__search int ns1__searchFacilityUserByRestriction::soap_put(struct soap *soap, const char *tag, const char *type) const { - register int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__searchFacilityUserByRestriction); + int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__searchFacilityUserByRestriction); if (this->soap_out(soap, tag?tag:"ns1:searchFacilityUserByRestriction", id, type)) return soap->error; return soap_putindependent(soap); @@ -62655,7 +62655,7 @@ SOAP_FMAC3 ns1__listDatasetTypesResponse * SOAP_FMAC4 soap_in_ns1__listDatasetTy int ns1__listDatasetTypesResponse::soap_put(struct soap *soap, const char *tag, const char *type) const { - register int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__listDatasetTypesResponse); + int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__listDatasetTypesResponse); if (this->soap_out(soap, tag?tag:"ns1:listDatasetTypesResponse", id, type)) return soap->error; return soap_putindependent(soap); @@ -62796,7 +62796,7 @@ SOAP_FMAC3 ns1__listDatasetTypes * SOAP_FMAC4 soap_in_ns1__listDatasetTypes(stru int ns1__listDatasetTypes::soap_put(struct soap *soap, const char *tag, const char *type) const { - register int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__listDatasetTypes); + int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__listDatasetTypes); if (this->soap_out(soap, tag?tag:"ns1:listDatasetTypes", id, type)) return soap->error; return soap_putindependent(soap); @@ -62934,7 +62934,7 @@ SOAP_FMAC3 ns1__searchDatasetByParameterRestrictionResponse * SOAP_FMAC4 soap_in int ns1__searchDatasetByParameterRestrictionResponse::soap_put(struct soap *soap, const char *tag, const char *type) const { - register int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__searchDatasetByParameterRestrictionResponse); + int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__searchDatasetByParameterRestrictionResponse); if (this->soap_out(soap, tag?tag:"ns1:searchDatasetByParameterRestrictionResponse", id, type)) return soap->error; return soap_putindependent(soap); @@ -63087,7 +63087,7 @@ SOAP_FMAC3 ns1__parameterCondition * SOAP_FMAC4 soap_in_ns1__parameterCondition( int ns1__parameterCondition::soap_put(struct soap *soap, const char *tag, const char *type) const { - register int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__parameterCondition); + int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__parameterCondition); if (this->soap_out(soap, tag?tag:"ns1:parameterCondition", id, type)) return soap->error; return soap_putindependent(soap); @@ -63311,7 +63311,7 @@ SOAP_FMAC3 ns1__searchDatasetByParameterRestriction * SOAP_FMAC4 soap_in_ns1__se int ns1__searchDatasetByParameterRestriction::soap_put(struct soap *soap, const char *tag, const char *type) const { - register int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__searchDatasetByParameterRestriction); + int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__searchDatasetByParameterRestriction); if (this->soap_out(soap, tag?tag:"ns1:searchDatasetByParameterRestriction", id, type)) return soap->error; return soap_putindependent(soap); @@ -63449,7 +63449,7 @@ SOAP_FMAC3 ns1__searchDatasetByRestrictionLogicalResponse * SOAP_FMAC4 soap_in_n int ns1__searchDatasetByRestrictionLogicalResponse::soap_put(struct soap *soap, const char *tag, const char *type) const { - register int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__searchDatasetByRestrictionLogicalResponse); + int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__searchDatasetByRestrictionLogicalResponse); if (this->soap_out(soap, tag?tag:"ns1:searchDatasetByRestrictionLogicalResponse", id, type)) return soap->error; return soap_putindependent(soap); @@ -63602,7 +63602,7 @@ SOAP_FMAC3 ns1__condition * SOAP_FMAC4 soap_in_ns1__condition(struct soap *soap, int ns1__condition::soap_put(struct soap *soap, const char *tag, const char *type) const { - register int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__condition); + int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__condition); if (this->soap_out(soap, tag?tag:"ns1:condition", id, type)) return soap->error; return soap_putindependent(soap); @@ -63990,7 +63990,7 @@ SOAP_FMAC3 ns1__restrictionCondition * SOAP_FMAC4 soap_in_ns1__restrictionCondit int ns1__restrictionCondition::soap_put(struct soap *soap, const char *tag, const char *type) const { - register int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__restrictionCondition); + int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__restrictionCondition); if (this->soap_out(soap, tag?tag:"ns1:restrictionCondition", id, type)) return soap->error; return soap_putindependent(soap); @@ -64276,7 +64276,7 @@ SOAP_FMAC3 ns1__restrictionLogicalCondition * SOAP_FMAC4 soap_in_ns1__restrictio int ns1__restrictionLogicalCondition::soap_put(struct soap *soap, const char *tag, const char *type) const { - register int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__restrictionLogicalCondition); + int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__restrictionLogicalCondition); if (this->soap_out(soap, tag?tag:"ns1:restrictionLogicalCondition", id, type)) return soap->error; return soap_putindependent(soap); @@ -64427,7 +64427,7 @@ SOAP_FMAC3 ns1__searchDatasetByRestrictionLogical * SOAP_FMAC4 soap_in_ns1__sear int ns1__searchDatasetByRestrictionLogical::soap_put(struct soap *soap, const char *tag, const char *type) const { - register int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__searchDatasetByRestrictionLogical); + int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_ns1__searchDatasetByRestrictionLogical); if (this->soap_out(soap, tag?tag:"ns1:searchDatasetByRestrictionLogical", id, type)) return soap->error; return soap_putindependent(soap); @@ -64526,7 +64526,7 @@ SOAP_FMAC3 std::string * SOAP_FMAC4 soap_in_std__string(struct soap *soap, const SOAP_FMAC3 int SOAP_FMAC4 soap_put_std__string(struct soap *soap, const std::string *a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_std__string); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_std__string); if (soap_out_std__string(soap, tag?tag:"string", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -64624,7 +64624,7 @@ SOAP_FMAC3 xsd__string * SOAP_FMAC4 soap_in_xsd__string(struct soap *soap, const int xsd__string::soap_put(struct soap *soap, const char *tag, const char *type) const { - register int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_xsd__string); + int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_xsd__string); if (this->soap_out(soap, tag?tag:"xsd:string", id, type)) return soap->error; return soap_putindependent(soap); @@ -64730,7 +64730,7 @@ SOAP_FMAC3 xsd__long * SOAP_FMAC4 soap_in_xsd__long(struct soap *soap, const cha int xsd__long::soap_put(struct soap *soap, const char *tag, const char *type) const { - register int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_xsd__long); + int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_xsd__long); if (this->soap_out(soap, tag?tag:"xsd:long", id, type)) return soap->error; return soap_putindependent(soap); @@ -64836,7 +64836,7 @@ SOAP_FMAC3 xsd__int * SOAP_FMAC4 soap_in_xsd__int(struct soap *soap, const char int xsd__int::soap_put(struct soap *soap, const char *tag, const char *type) const { - register int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_xsd__int); + int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_xsd__int); if (this->soap_out(soap, tag?tag:"xsd:int", id, type)) return soap->error; return soap_putindependent(soap); @@ -64941,7 +64941,7 @@ SOAP_FMAC3 xsd__float * SOAP_FMAC4 soap_in_xsd__float(struct soap *soap, const c int xsd__float::soap_put(struct soap *soap, const char *tag, const char *type) const { - register int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_xsd__float); + int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_xsd__float); if (this->soap_out(soap, tag?tag:"xsd:float", id, type)) return soap->error; return soap_putindependent(soap); @@ -65047,7 +65047,7 @@ SOAP_FMAC3 xsd__double * SOAP_FMAC4 soap_in_xsd__double(struct soap *soap, const int xsd__double::soap_put(struct soap *soap, const char *tag, const char *type) const { - register int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_xsd__double); + int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_xsd__double); if (this->soap_out(soap, tag?tag:"xsd:double", id, type)) return soap->error; return soap_putindependent(soap); @@ -65153,7 +65153,7 @@ SOAP_FMAC3 xsd__dateTime * SOAP_FMAC4 soap_in_xsd__dateTime(struct soap *soap, c int xsd__dateTime::soap_put(struct soap *soap, const char *tag, const char *type) const { - register int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_xsd__dateTime); + int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_xsd__dateTime); if (this->soap_out(soap, tag?tag:"xsd:dateTime", id, type)) return soap->error; return soap_putindependent(soap); @@ -65258,7 +65258,7 @@ SOAP_FMAC3 xsd__boolean * SOAP_FMAC4 soap_in_xsd__boolean(struct soap *soap, con int xsd__boolean::soap_put(struct soap *soap, const char *tag, const char *type) const { - register int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_xsd__boolean); + int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_xsd__boolean); if (this->soap_out(soap, tag?tag:"xsd:boolean", id, type)) return soap->error; return soap_putindependent(soap); @@ -65363,7 +65363,7 @@ SOAP_FMAC3 xsd__anyType * SOAP_FMAC4 soap_in_xsd__anyType(struct soap *soap, con int xsd__anyType::soap_put(struct soap *soap, const char *tag, const char *type) const { - register int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_xsd__anyType); + int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat3_xsd__anyType); if (this->soap_out(soap, tag?tag:"xsd:anyType", id, type)) return soap->error; return soap_putindependent(soap); @@ -72827,7 +72827,7 @@ SOAP_FMAC3 struct SOAP_ENV__Fault * SOAP_FMAC4 soap_in_SOAP_ENV__Fault(struct so SOAP_FMAC3 int SOAP_FMAC4 soap_put_SOAP_ENV__Fault(struct soap *soap, const struct SOAP_ENV__Fault *a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_SOAP_ENV__Fault); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_SOAP_ENV__Fault); if (soap_out_SOAP_ENV__Fault(soap, tag?tag:"SOAP-ENV:Fault", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -72939,7 +72939,7 @@ SOAP_FMAC3 struct SOAP_ENV__Reason * SOAP_FMAC4 soap_in_SOAP_ENV__Reason(struct SOAP_FMAC3 int SOAP_FMAC4 soap_put_SOAP_ENV__Reason(struct soap *soap, const struct SOAP_ENV__Reason *a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_SOAP_ENV__Reason); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_SOAP_ENV__Reason); if (soap_out_SOAP_ENV__Reason(soap, tag?tag:"SOAP-ENV:Reason", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -73060,7 +73060,7 @@ SOAP_FMAC3 struct SOAP_ENV__Code * SOAP_FMAC4 soap_in_SOAP_ENV__Code(struct soap SOAP_FMAC3 int SOAP_FMAC4 soap_put_SOAP_ENV__Code(struct soap *soap, const struct SOAP_ENV__Code *a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_SOAP_ENV__Code); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_SOAP_ENV__Code); if (soap_out_SOAP_ENV__Code(soap, tag?tag:"SOAP-ENV:Code", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -73160,7 +73160,7 @@ SOAP_FMAC3 struct SOAP_ENV__Header * SOAP_FMAC4 soap_in_SOAP_ENV__Header(struct SOAP_FMAC3 int SOAP_FMAC4 soap_put_SOAP_ENV__Header(struct soap *soap, const struct SOAP_ENV__Header *a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_SOAP_ENV__Header); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_SOAP_ENV__Header); if (soap_out_SOAP_ENV__Header(soap, tag?tag:"SOAP-ENV:Header", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -73258,7 +73258,7 @@ SOAP_FMAC3 struct __ns1__searchFacilityUserByRestriction * SOAP_FMAC4 soap_in___ SOAP_FMAC3 int SOAP_FMAC4 soap_put___ns1__searchFacilityUserByRestriction(struct soap *soap, const struct __ns1__searchFacilityUserByRestriction *a, const char *tag, const char *type) { - register int id = 0; + int id = 0; if (soap_out___ns1__searchFacilityUserByRestriction(soap, tag?tag:"-ns1:searchFacilityUserByRestriction", id, a, type)) return soap->error; return SOAP_OK; @@ -73354,7 +73354,7 @@ SOAP_FMAC3 struct __ns1__searchSampleByParameterLogical * SOAP_FMAC4 soap_in___n SOAP_FMAC3 int SOAP_FMAC4 soap_put___ns1__searchSampleByParameterLogical(struct soap *soap, const struct __ns1__searchSampleByParameterLogical *a, const char *tag, const char *type) { - register int id = 0; + int id = 0; if (soap_out___ns1__searchSampleByParameterLogical(soap, tag?tag:"-ns1:searchSampleByParameterLogical", id, a, type)) return soap->error; return SOAP_OK; @@ -73450,7 +73450,7 @@ SOAP_FMAC3 struct __ns1__searchDatasetByParameterLogical * SOAP_FMAC4 soap_in___ SOAP_FMAC3 int SOAP_FMAC4 soap_put___ns1__searchDatasetByParameterLogical(struct soap *soap, const struct __ns1__searchDatasetByParameterLogical *a, const char *tag, const char *type) { - register int id = 0; + int id = 0; if (soap_out___ns1__searchDatasetByParameterLogical(soap, tag?tag:"-ns1:searchDatasetByParameterLogical", id, a, type)) return soap->error; return SOAP_OK; @@ -73546,7 +73546,7 @@ SOAP_FMAC3 struct __ns1__searchDatafileByParameterLogical * SOAP_FMAC4 soap_in__ SOAP_FMAC3 int SOAP_FMAC4 soap_put___ns1__searchDatafileByParameterLogical(struct soap *soap, const struct __ns1__searchDatafileByParameterLogical *a, const char *tag, const char *type) { - register int id = 0; + int id = 0; if (soap_out___ns1__searchDatafileByParameterLogical(soap, tag?tag:"-ns1:searchDatafileByParameterLogical", id, a, type)) return soap->error; return SOAP_OK; @@ -73642,7 +73642,7 @@ SOAP_FMAC3 struct __ns1__searchInvestigationByParameterLogical * SOAP_FMAC4 soap SOAP_FMAC3 int SOAP_FMAC4 soap_put___ns1__searchInvestigationByParameterLogical(struct soap *soap, const struct __ns1__searchInvestigationByParameterLogical *a, const char *tag, const char *type) { - register int id = 0; + int id = 0; if (soap_out___ns1__searchInvestigationByParameterLogical(soap, tag?tag:"-ns1:searchInvestigationByParameterLogical", id, a, type)) return soap->error; return SOAP_OK; @@ -73738,7 +73738,7 @@ SOAP_FMAC3 struct __ns1__searchDatafileByRestrictionLogical * SOAP_FMAC4 soap_in SOAP_FMAC3 int SOAP_FMAC4 soap_put___ns1__searchDatafileByRestrictionLogical(struct soap *soap, const struct __ns1__searchDatafileByRestrictionLogical *a, const char *tag, const char *type) { - register int id = 0; + int id = 0; if (soap_out___ns1__searchDatafileByRestrictionLogical(soap, tag?tag:"-ns1:searchDatafileByRestrictionLogical", id, a, type)) return soap->error; return SOAP_OK; @@ -73834,7 +73834,7 @@ SOAP_FMAC3 struct __ns1__searchInvestigationByRestrictionLogical * SOAP_FMAC4 so SOAP_FMAC3 int SOAP_FMAC4 soap_put___ns1__searchInvestigationByRestrictionLogical(struct soap *soap, const struct __ns1__searchInvestigationByRestrictionLogical *a, const char *tag, const char *type) { - register int id = 0; + int id = 0; if (soap_out___ns1__searchInvestigationByRestrictionLogical(soap, tag?tag:"-ns1:searchInvestigationByRestrictionLogical", id, a, type)) return soap->error; return SOAP_OK; @@ -73930,7 +73930,7 @@ SOAP_FMAC3 struct __ns1__searchDatasetByRestrictionLogical * SOAP_FMAC4 soap_in_ SOAP_FMAC3 int SOAP_FMAC4 soap_put___ns1__searchDatasetByRestrictionLogical(struct soap *soap, const struct __ns1__searchDatasetByRestrictionLogical *a, const char *tag, const char *type) { - register int id = 0; + int id = 0; if (soap_out___ns1__searchDatasetByRestrictionLogical(soap, tag?tag:"-ns1:searchDatasetByRestrictionLogical", id, a, type)) return soap->error; return SOAP_OK; @@ -74026,7 +74026,7 @@ SOAP_FMAC3 struct __ns1__searchSampleByRestrictionLogical * SOAP_FMAC4 soap_in__ SOAP_FMAC3 int SOAP_FMAC4 soap_put___ns1__searchSampleByRestrictionLogical(struct soap *soap, const struct __ns1__searchSampleByRestrictionLogical *a, const char *tag, const char *type) { - register int id = 0; + int id = 0; if (soap_out___ns1__searchSampleByRestrictionLogical(soap, tag?tag:"-ns1:searchSampleByRestrictionLogical", id, a, type)) return soap->error; return SOAP_OK; @@ -74122,7 +74122,7 @@ SOAP_FMAC3 struct __ns1__searchSampleByRestrictionComparison * SOAP_FMAC4 soap_i SOAP_FMAC3 int SOAP_FMAC4 soap_put___ns1__searchSampleByRestrictionComparison(struct soap *soap, const struct __ns1__searchSampleByRestrictionComparison *a, const char *tag, const char *type) { - register int id = 0; + int id = 0; if (soap_out___ns1__searchSampleByRestrictionComparison(soap, tag?tag:"-ns1:searchSampleByRestrictionComparison", id, a, type)) return soap->error; return SOAP_OK; @@ -74218,7 +74218,7 @@ SOAP_FMAC3 struct __ns1__searchDatafileByRestrictionComparison * SOAP_FMAC4 soap SOAP_FMAC3 int SOAP_FMAC4 soap_put___ns1__searchDatafileByRestrictionComparison(struct soap *soap, const struct __ns1__searchDatafileByRestrictionComparison *a, const char *tag, const char *type) { - register int id = 0; + int id = 0; if (soap_out___ns1__searchDatafileByRestrictionComparison(soap, tag?tag:"-ns1:searchDatafileByRestrictionComparison", id, a, type)) return soap->error; return SOAP_OK; @@ -74314,7 +74314,7 @@ SOAP_FMAC3 struct __ns1__searchDatasetByRestrictionComparison * SOAP_FMAC4 soap_ SOAP_FMAC3 int SOAP_FMAC4 soap_put___ns1__searchDatasetByRestrictionComparison(struct soap *soap, const struct __ns1__searchDatasetByRestrictionComparison *a, const char *tag, const char *type) { - register int id = 0; + int id = 0; if (soap_out___ns1__searchDatasetByRestrictionComparison(soap, tag?tag:"-ns1:searchDatasetByRestrictionComparison", id, a, type)) return soap->error; return SOAP_OK; @@ -74410,7 +74410,7 @@ SOAP_FMAC3 struct __ns1__searchInvestigationByRestrictionComparasion * SOAP_FMAC SOAP_FMAC3 int SOAP_FMAC4 soap_put___ns1__searchInvestigationByRestrictionComparasion(struct soap *soap, const struct __ns1__searchInvestigationByRestrictionComparasion *a, const char *tag, const char *type) { - register int id = 0; + int id = 0; if (soap_out___ns1__searchInvestigationByRestrictionComparasion(soap, tag?tag:"-ns1:searchInvestigationByRestrictionComparasion", id, a, type)) return soap->error; return SOAP_OK; @@ -74506,7 +74506,7 @@ SOAP_FMAC3 struct __ns1__searchSampleByRestriction * SOAP_FMAC4 soap_in___ns1__s SOAP_FMAC3 int SOAP_FMAC4 soap_put___ns1__searchSampleByRestriction(struct soap *soap, const struct __ns1__searchSampleByRestriction *a, const char *tag, const char *type) { - register int id = 0; + int id = 0; if (soap_out___ns1__searchSampleByRestriction(soap, tag?tag:"-ns1:searchSampleByRestriction", id, a, type)) return soap->error; return SOAP_OK; @@ -74602,7 +74602,7 @@ SOAP_FMAC3 struct __ns1__searchDatafileByRestriction * SOAP_FMAC4 soap_in___ns1_ SOAP_FMAC3 int SOAP_FMAC4 soap_put___ns1__searchDatafileByRestriction(struct soap *soap, const struct __ns1__searchDatafileByRestriction *a, const char *tag, const char *type) { - register int id = 0; + int id = 0; if (soap_out___ns1__searchDatafileByRestriction(soap, tag?tag:"-ns1:searchDatafileByRestriction", id, a, type)) return soap->error; return SOAP_OK; @@ -74698,7 +74698,7 @@ SOAP_FMAC3 struct __ns1__searchDatasetByRestriction * SOAP_FMAC4 soap_in___ns1__ SOAP_FMAC3 int SOAP_FMAC4 soap_put___ns1__searchDatasetByRestriction(struct soap *soap, const struct __ns1__searchDatasetByRestriction *a, const char *tag, const char *type) { - register int id = 0; + int id = 0; if (soap_out___ns1__searchDatasetByRestriction(soap, tag?tag:"-ns1:searchDatasetByRestriction", id, a, type)) return soap->error; return SOAP_OK; @@ -74794,7 +74794,7 @@ SOAP_FMAC3 struct __ns1__searchInvestigationByRestriction * SOAP_FMAC4 soap_in__ SOAP_FMAC3 int SOAP_FMAC4 soap_put___ns1__searchInvestigationByRestriction(struct soap *soap, const struct __ns1__searchInvestigationByRestriction *a, const char *tag, const char *type) { - register int id = 0; + int id = 0; if (soap_out___ns1__searchInvestigationByRestriction(soap, tag?tag:"-ns1:searchInvestigationByRestriction", id, a, type)) return soap->error; return SOAP_OK; @@ -74890,7 +74890,7 @@ SOAP_FMAC3 struct __ns1__searchInvestigationByParameterRestriction * SOAP_FMAC4 SOAP_FMAC3 int SOAP_FMAC4 soap_put___ns1__searchInvestigationByParameterRestriction(struct soap *soap, const struct __ns1__searchInvestigationByParameterRestriction *a, const char *tag, const char *type) { - register int id = 0; + int id = 0; if (soap_out___ns1__searchInvestigationByParameterRestriction(soap, tag?tag:"-ns1:searchInvestigationByParameterRestriction", id, a, type)) return soap->error; return SOAP_OK; @@ -74986,7 +74986,7 @@ SOAP_FMAC3 struct __ns1__searchDatafileByParameterRestriction * SOAP_FMAC4 soap_ SOAP_FMAC3 int SOAP_FMAC4 soap_put___ns1__searchDatafileByParameterRestriction(struct soap *soap, const struct __ns1__searchDatafileByParameterRestriction *a, const char *tag, const char *type) { - register int id = 0; + int id = 0; if (soap_out___ns1__searchDatafileByParameterRestriction(soap, tag?tag:"-ns1:searchDatafileByParameterRestriction", id, a, type)) return soap->error; return SOAP_OK; @@ -75082,7 +75082,7 @@ SOAP_FMAC3 struct __ns1__searchSampleByParameterRestriction * SOAP_FMAC4 soap_in SOAP_FMAC3 int SOAP_FMAC4 soap_put___ns1__searchSampleByParameterRestriction(struct soap *soap, const struct __ns1__searchSampleByParameterRestriction *a, const char *tag, const char *type) { - register int id = 0; + int id = 0; if (soap_out___ns1__searchSampleByParameterRestriction(soap, tag?tag:"-ns1:searchSampleByParameterRestriction", id, a, type)) return soap->error; return SOAP_OK; @@ -75178,7 +75178,7 @@ SOAP_FMAC3 struct __ns1__searchDatasetByParameterRestriction * SOAP_FMAC4 soap_i SOAP_FMAC3 int SOAP_FMAC4 soap_put___ns1__searchDatasetByParameterRestriction(struct soap *soap, const struct __ns1__searchDatasetByParameterRestriction *a, const char *tag, const char *type) { - register int id = 0; + int id = 0; if (soap_out___ns1__searchDatasetByParameterRestriction(soap, tag?tag:"-ns1:searchDatasetByParameterRestriction", id, a, type)) return soap->error; return SOAP_OK; @@ -75274,7 +75274,7 @@ SOAP_FMAC3 struct __ns1__getParameterByUnits * SOAP_FMAC4 soap_in___ns1__getPara SOAP_FMAC3 int SOAP_FMAC4 soap_put___ns1__getParameterByUnits(struct soap *soap, const struct __ns1__getParameterByUnits *a, const char *tag, const char *type) { - register int id = 0; + int id = 0; if (soap_out___ns1__getParameterByUnits(soap, tag?tag:"-ns1:getParameterByUnits", id, a, type)) return soap->error; return SOAP_OK; @@ -75370,7 +75370,7 @@ SOAP_FMAC3 struct __ns1__getParameterByRestriction * SOAP_FMAC4 soap_in___ns1__g SOAP_FMAC3 int SOAP_FMAC4 soap_put___ns1__getParameterByRestriction(struct soap *soap, const struct __ns1__getParameterByRestriction *a, const char *tag, const char *type) { - register int id = 0; + int id = 0; if (soap_out___ns1__getParameterByRestriction(soap, tag?tag:"-ns1:getParameterByRestriction", id, a, type)) return soap->error; return SOAP_OK; @@ -75466,7 +75466,7 @@ SOAP_FMAC3 struct __ns1__getParameterByName * SOAP_FMAC4 soap_in___ns1__getParam SOAP_FMAC3 int SOAP_FMAC4 soap_put___ns1__getParameterByName(struct soap *soap, const struct __ns1__getParameterByName *a, const char *tag, const char *type) { - register int id = 0; + int id = 0; if (soap_out___ns1__getParameterByName(soap, tag?tag:"-ns1:getParameterByName", id, a, type)) return soap->error; return SOAP_OK; @@ -75562,7 +75562,7 @@ SOAP_FMAC3 struct __ns1__getParameterByNameUnits * SOAP_FMAC4 soap_in___ns1__get SOAP_FMAC3 int SOAP_FMAC4 soap_put___ns1__getParameterByNameUnits(struct soap *soap, const struct __ns1__getParameterByNameUnits *a, const char *tag, const char *type) { - register int id = 0; + int id = 0; if (soap_out___ns1__getParameterByNameUnits(soap, tag?tag:"-ns1:getParameterByNameUnits", id, a, type)) return soap->error; return SOAP_OK; @@ -75658,7 +75658,7 @@ SOAP_FMAC3 struct __ns1__searchSampleByParameter * SOAP_FMAC4 soap_in___ns1__sea SOAP_FMAC3 int SOAP_FMAC4 soap_put___ns1__searchSampleByParameter(struct soap *soap, const struct __ns1__searchSampleByParameter *a, const char *tag, const char *type) { - register int id = 0; + int id = 0; if (soap_out___ns1__searchSampleByParameter(soap, tag?tag:"-ns1:searchSampleByParameter", id, a, type)) return soap->error; return SOAP_OK; @@ -75754,7 +75754,7 @@ SOAP_FMAC3 struct __ns1__searchDatasetByParameter * SOAP_FMAC4 soap_in___ns1__se SOAP_FMAC3 int SOAP_FMAC4 soap_put___ns1__searchDatasetByParameter(struct soap *soap, const struct __ns1__searchDatasetByParameter *a, const char *tag, const char *type) { - register int id = 0; + int id = 0; if (soap_out___ns1__searchDatasetByParameter(soap, tag?tag:"-ns1:searchDatasetByParameter", id, a, type)) return soap->error; return SOAP_OK; @@ -75850,7 +75850,7 @@ SOAP_FMAC3 struct __ns1__searchDatafileByParameter * SOAP_FMAC4 soap_in___ns1__s SOAP_FMAC3 int SOAP_FMAC4 soap_put___ns1__searchDatafileByParameter(struct soap *soap, const struct __ns1__searchDatafileByParameter *a, const char *tag, const char *type) { - register int id = 0; + int id = 0; if (soap_out___ns1__searchDatafileByParameter(soap, tag?tag:"-ns1:searchDatafileByParameter", id, a, type)) return soap->error; return SOAP_OK; @@ -75946,7 +75946,7 @@ SOAP_FMAC3 struct __ns1__searchInvestigationByParameter * SOAP_FMAC4 soap_in___n SOAP_FMAC3 int SOAP_FMAC4 soap_put___ns1__searchInvestigationByParameter(struct soap *soap, const struct __ns1__searchInvestigationByParameter *a, const char *tag, const char *type) { - register int id = 0; + int id = 0; if (soap_out___ns1__searchInvestigationByParameter(soap, tag?tag:"-ns1:searchInvestigationByParameter", id, a, type)) return soap->error; return SOAP_OK; @@ -76042,7 +76042,7 @@ SOAP_FMAC3 struct __ns1__searchSampleByParameterComparison * SOAP_FMAC4 soap_in_ SOAP_FMAC3 int SOAP_FMAC4 soap_put___ns1__searchSampleByParameterComparison(struct soap *soap, const struct __ns1__searchSampleByParameterComparison *a, const char *tag, const char *type) { - register int id = 0; + int id = 0; if (soap_out___ns1__searchSampleByParameterComparison(soap, tag?tag:"-ns1:searchSampleByParameterComparison", id, a, type)) return soap->error; return SOAP_OK; @@ -76138,7 +76138,7 @@ SOAP_FMAC3 struct __ns1__searchDatasetByParameterComparison * SOAP_FMAC4 soap_in SOAP_FMAC3 int SOAP_FMAC4 soap_put___ns1__searchDatasetByParameterComparison(struct soap *soap, const struct __ns1__searchDatasetByParameterComparison *a, const char *tag, const char *type) { - register int id = 0; + int id = 0; if (soap_out___ns1__searchDatasetByParameterComparison(soap, tag?tag:"-ns1:searchDatasetByParameterComparison", id, a, type)) return soap->error; return SOAP_OK; @@ -76234,7 +76234,7 @@ SOAP_FMAC3 struct __ns1__searchDatafileByParameterComparison * SOAP_FMAC4 soap_i SOAP_FMAC3 int SOAP_FMAC4 soap_put___ns1__searchDatafileByParameterComparison(struct soap *soap, const struct __ns1__searchDatafileByParameterComparison *a, const char *tag, const char *type) { - register int id = 0; + int id = 0; if (soap_out___ns1__searchDatafileByParameterComparison(soap, tag?tag:"-ns1:searchDatafileByParameterComparison", id, a, type)) return soap->error; return SOAP_OK; @@ -76330,7 +76330,7 @@ SOAP_FMAC3 struct __ns1__searchInvestigationByParameterComparison * SOAP_FMAC4 s SOAP_FMAC3 int SOAP_FMAC4 soap_put___ns1__searchInvestigationByParameterComparison(struct soap *soap, const struct __ns1__searchInvestigationByParameterComparison *a, const char *tag, const char *type) { - register int id = 0; + int id = 0; if (soap_out___ns1__searchInvestigationByParameterComparison(soap, tag?tag:"-ns1:searchInvestigationByParameterComparison", id, a, type)) return soap->error; return SOAP_OK; @@ -76426,7 +76426,7 @@ SOAP_FMAC3 struct __ns1__searchSampleByParameterCondition * SOAP_FMAC4 soap_in__ SOAP_FMAC3 int SOAP_FMAC4 soap_put___ns1__searchSampleByParameterCondition(struct soap *soap, const struct __ns1__searchSampleByParameterCondition *a, const char *tag, const char *type) { - register int id = 0; + int id = 0; if (soap_out___ns1__searchSampleByParameterCondition(soap, tag?tag:"-ns1:searchSampleByParameterCondition", id, a, type)) return soap->error; return SOAP_OK; @@ -76522,7 +76522,7 @@ SOAP_FMAC3 struct __ns1__searchDatasetByParameterCondition * SOAP_FMAC4 soap_in_ SOAP_FMAC3 int SOAP_FMAC4 soap_put___ns1__searchDatasetByParameterCondition(struct soap *soap, const struct __ns1__searchDatasetByParameterCondition *a, const char *tag, const char *type) { - register int id = 0; + int id = 0; if (soap_out___ns1__searchDatasetByParameterCondition(soap, tag?tag:"-ns1:searchDatasetByParameterCondition", id, a, type)) return soap->error; return SOAP_OK; @@ -76618,7 +76618,7 @@ SOAP_FMAC3 struct __ns1__searchDatafileByParameterCondition * SOAP_FMAC4 soap_in SOAP_FMAC3 int SOAP_FMAC4 soap_put___ns1__searchDatafileByParameterCondition(struct soap *soap, const struct __ns1__searchDatafileByParameterCondition *a, const char *tag, const char *type) { - register int id = 0; + int id = 0; if (soap_out___ns1__searchDatafileByParameterCondition(soap, tag?tag:"-ns1:searchDatafileByParameterCondition", id, a, type)) return soap->error; return SOAP_OK; @@ -76714,7 +76714,7 @@ SOAP_FMAC3 struct __ns1__searchInvestigationByParameterCondition * SOAP_FMAC4 so SOAP_FMAC3 int SOAP_FMAC4 soap_put___ns1__searchInvestigationByParameterCondition(struct soap *soap, const struct __ns1__searchInvestigationByParameterCondition *a, const char *tag, const char *type) { - register int id = 0; + int id = 0; if (soap_out___ns1__searchInvestigationByParameterCondition(soap, tag?tag:"-ns1:searchInvestigationByParameterCondition", id, a, type)) return soap->error; return SOAP_OK; @@ -76810,7 +76810,7 @@ SOAP_FMAC3 struct __ns1__getFacilityUserByFederalId * SOAP_FMAC4 soap_in___ns1__ SOAP_FMAC3 int SOAP_FMAC4 soap_put___ns1__getFacilityUserByFederalId(struct soap *soap, const struct __ns1__getFacilityUserByFederalId *a, const char *tag, const char *type) { - register int id = 0; + int id = 0; if (soap_out___ns1__getFacilityUserByFederalId(soap, tag?tag:"-ns1:getFacilityUserByFederalId", id, a, type)) return soap->error; return SOAP_OK; @@ -76906,7 +76906,7 @@ SOAP_FMAC3 struct __ns1__getFacilityUserByFacilityUserId * SOAP_FMAC4 soap_in___ SOAP_FMAC3 int SOAP_FMAC4 soap_put___ns1__getFacilityUserByFacilityUserId(struct soap *soap, const struct __ns1__getFacilityUserByFacilityUserId *a, const char *tag, const char *type) { - register int id = 0; + int id = 0; if (soap_out___ns1__getFacilityUserByFacilityUserId(soap, tag?tag:"-ns1:getFacilityUserByFacilityUserId", id, a, type)) return soap->error; return SOAP_OK; @@ -77002,7 +77002,7 @@ SOAP_FMAC3 struct __ns1__getICATAPIVersion * SOAP_FMAC4 soap_in___ns1__getICATAP SOAP_FMAC3 int SOAP_FMAC4 soap_put___ns1__getICATAPIVersion(struct soap *soap, const struct __ns1__getICATAPIVersion *a, const char *tag, const char *type) { - register int id = 0; + int id = 0; if (soap_out___ns1__getICATAPIVersion(soap, tag?tag:"-ns1:getICATAPIVersion", id, a, type)) return soap->error; return SOAP_OK; @@ -77098,7 +77098,7 @@ SOAP_FMAC3 struct __ns1__checkDatasetDownloadAccess * SOAP_FMAC4 soap_in___ns1__ SOAP_FMAC3 int SOAP_FMAC4 soap_put___ns1__checkDatasetDownloadAccess(struct soap *soap, const struct __ns1__checkDatasetDownloadAccess *a, const char *tag, const char *type) { - register int id = 0; + int id = 0; if (soap_out___ns1__checkDatasetDownloadAccess(soap, tag?tag:"-ns1:checkDatasetDownloadAccess", id, a, type)) return soap->error; return SOAP_OK; @@ -77194,7 +77194,7 @@ SOAP_FMAC3 struct __ns1__checkDatafileDownloadAccess * SOAP_FMAC4 soap_in___ns1_ SOAP_FMAC3 int SOAP_FMAC4 soap_put___ns1__checkDatafileDownloadAccess(struct soap *soap, const struct __ns1__checkDatafileDownloadAccess *a, const char *tag, const char *type) { - register int id = 0; + int id = 0; if (soap_out___ns1__checkDatafileDownloadAccess(soap, tag?tag:"-ns1:checkDatafileDownloadAccess", id, a, type)) return soap->error; return SOAP_OK; @@ -77290,7 +77290,7 @@ SOAP_FMAC3 struct __ns1__downloadDatafiles * SOAP_FMAC4 soap_in___ns1__downloadD SOAP_FMAC3 int SOAP_FMAC4 soap_put___ns1__downloadDatafiles(struct soap *soap, const struct __ns1__downloadDatafiles *a, const char *tag, const char *type) { - register int id = 0; + int id = 0; if (soap_out___ns1__downloadDatafiles(soap, tag?tag:"-ns1:downloadDatafiles", id, a, type)) return soap->error; return SOAP_OK; @@ -77386,7 +77386,7 @@ SOAP_FMAC3 struct __ns1__downloadDataset * SOAP_FMAC4 soap_in___ns1__downloadDat SOAP_FMAC3 int SOAP_FMAC4 soap_put___ns1__downloadDataset(struct soap *soap, const struct __ns1__downloadDataset *a, const char *tag, const char *type) { - register int id = 0; + int id = 0; if (soap_out___ns1__downloadDataset(soap, tag?tag:"-ns1:downloadDataset", id, a, type)) return soap->error; return SOAP_OK; @@ -77482,7 +77482,7 @@ SOAP_FMAC3 struct __ns1__downloadDatafile * SOAP_FMAC4 soap_in___ns1__downloadDa SOAP_FMAC3 int SOAP_FMAC4 soap_put___ns1__downloadDatafile(struct soap *soap, const struct __ns1__downloadDatafile *a, const char *tag, const char *type) { - register int id = 0; + int id = 0; if (soap_out___ns1__downloadDatafile(soap, tag?tag:"-ns1:downloadDatafile", id, a, type)) return soap->error; return SOAP_OK; @@ -77578,7 +77578,7 @@ SOAP_FMAC3 struct __ns1__ingestMetadata * SOAP_FMAC4 soap_in___ns1__ingestMetada SOAP_FMAC3 int SOAP_FMAC4 soap_put___ns1__ingestMetadata(struct soap *soap, const struct __ns1__ingestMetadata *a, const char *tag, const char *type) { - register int id = 0; + int id = 0; if (soap_out___ns1__ingestMetadata(soap, tag?tag:"-ns1:ingestMetadata", id, a, type)) return soap->error; return SOAP_OK; @@ -77674,7 +77674,7 @@ SOAP_FMAC3 struct __ns1__updateAuthorisation * SOAP_FMAC4 soap_in___ns1__updateA SOAP_FMAC3 int SOAP_FMAC4 soap_put___ns1__updateAuthorisation(struct soap *soap, const struct __ns1__updateAuthorisation *a, const char *tag, const char *type) { - register int id = 0; + int id = 0; if (soap_out___ns1__updateAuthorisation(soap, tag?tag:"-ns1:updateAuthorisation", id, a, type)) return soap->error; return SOAP_OK; @@ -77773,7 +77773,7 @@ SOAP_FMAC3 struct __ns1__updateAuthorisationResponse * SOAP_FMAC4 soap_in___ns1_ SOAP_FMAC3 int SOAP_FMAC4 soap_put___ns1__updateAuthorisationResponse(struct soap *soap, const struct __ns1__updateAuthorisationResponse *a, const char *tag, const char *type) { - register int id = 0; + int id = 0; if (soap_out___ns1__updateAuthorisationResponse(soap, tag?tag:"-ns1:updateAuthorisationResponse", id, a, type)) return soap->error; return SOAP_OK; @@ -77869,7 +77869,7 @@ SOAP_FMAC3 struct __ns1__removeAuthorisation * SOAP_FMAC4 soap_in___ns1__removeA SOAP_FMAC3 int SOAP_FMAC4 soap_put___ns1__removeAuthorisation(struct soap *soap, const struct __ns1__removeAuthorisation *a, const char *tag, const char *type) { - register int id = 0; + int id = 0; if (soap_out___ns1__removeAuthorisation(soap, tag?tag:"-ns1:removeAuthorisation", id, a, type)) return soap->error; return SOAP_OK; @@ -77968,7 +77968,7 @@ SOAP_FMAC3 struct __ns1__removeAuthorisationResponse * SOAP_FMAC4 soap_in___ns1_ SOAP_FMAC3 int SOAP_FMAC4 soap_put___ns1__removeAuthorisationResponse(struct soap *soap, const struct __ns1__removeAuthorisationResponse *a, const char *tag, const char *type) { - register int id = 0; + int id = 0; if (soap_out___ns1__removeAuthorisationResponse(soap, tag?tag:"-ns1:removeAuthorisationResponse", id, a, type)) return soap->error; return SOAP_OK; @@ -78064,7 +78064,7 @@ SOAP_FMAC3 struct __ns1__deleteAuthorisation * SOAP_FMAC4 soap_in___ns1__deleteA SOAP_FMAC3 int SOAP_FMAC4 soap_put___ns1__deleteAuthorisation(struct soap *soap, const struct __ns1__deleteAuthorisation *a, const char *tag, const char *type) { - register int id = 0; + int id = 0; if (soap_out___ns1__deleteAuthorisation(soap, tag?tag:"-ns1:deleteAuthorisation", id, a, type)) return soap->error; return SOAP_OK; @@ -78163,7 +78163,7 @@ SOAP_FMAC3 struct __ns1__deleteAuthorisationResponse * SOAP_FMAC4 soap_in___ns1_ SOAP_FMAC3 int SOAP_FMAC4 soap_put___ns1__deleteAuthorisationResponse(struct soap *soap, const struct __ns1__deleteAuthorisationResponse *a, const char *tag, const char *type) { - register int id = 0; + int id = 0; if (soap_out___ns1__deleteAuthorisationResponse(soap, tag?tag:"-ns1:deleteAuthorisationResponse", id, a, type)) return soap->error; return SOAP_OK; @@ -78259,7 +78259,7 @@ SOAP_FMAC3 struct __ns1__addAuthorisation * SOAP_FMAC4 soap_in___ns1__addAuthori SOAP_FMAC3 int SOAP_FMAC4 soap_put___ns1__addAuthorisation(struct soap *soap, const struct __ns1__addAuthorisation *a, const char *tag, const char *type) { - register int id = 0; + int id = 0; if (soap_out___ns1__addAuthorisation(soap, tag?tag:"-ns1:addAuthorisation", id, a, type)) return soap->error; return SOAP_OK; @@ -78355,7 +78355,7 @@ SOAP_FMAC3 struct __ns1__getAuthorisations * SOAP_FMAC4 soap_in___ns1__getAuthor SOAP_FMAC3 int SOAP_FMAC4 soap_put___ns1__getAuthorisations(struct soap *soap, const struct __ns1__getAuthorisations *a, const char *tag, const char *type) { - register int id = 0; + int id = 0; if (soap_out___ns1__getAuthorisations(soap, tag?tag:"-ns1:getAuthorisations", id, a, type)) return soap->error; return SOAP_OK; @@ -78451,7 +78451,7 @@ SOAP_FMAC3 struct __ns1__removeDataFileParameter * SOAP_FMAC4 soap_in___ns1__rem SOAP_FMAC3 int SOAP_FMAC4 soap_put___ns1__removeDataFileParameter(struct soap *soap, const struct __ns1__removeDataFileParameter *a, const char *tag, const char *type) { - register int id = 0; + int id = 0; if (soap_out___ns1__removeDataFileParameter(soap, tag?tag:"-ns1:removeDataFileParameter", id, a, type)) return soap->error; return SOAP_OK; @@ -78550,7 +78550,7 @@ SOAP_FMAC3 struct __ns1__removeDataFileParameterResponse * SOAP_FMAC4 soap_in___ SOAP_FMAC3 int SOAP_FMAC4 soap_put___ns1__removeDataFileParameterResponse(struct soap *soap, const struct __ns1__removeDataFileParameterResponse *a, const char *tag, const char *type) { - register int id = 0; + int id = 0; if (soap_out___ns1__removeDataFileParameterResponse(soap, tag?tag:"-ns1:removeDataFileParameterResponse", id, a, type)) return soap->error; return SOAP_OK; @@ -78646,7 +78646,7 @@ SOAP_FMAC3 struct __ns1__removeDataFile * SOAP_FMAC4 soap_in___ns1__removeDataFi SOAP_FMAC3 int SOAP_FMAC4 soap_put___ns1__removeDataFile(struct soap *soap, const struct __ns1__removeDataFile *a, const char *tag, const char *type) { - register int id = 0; + int id = 0; if (soap_out___ns1__removeDataFile(soap, tag?tag:"-ns1:removeDataFile", id, a, type)) return soap->error; return SOAP_OK; @@ -78745,7 +78745,7 @@ SOAP_FMAC3 struct __ns1__removeDataFileResponse * SOAP_FMAC4 soap_in___ns1__remo SOAP_FMAC3 int SOAP_FMAC4 soap_put___ns1__removeDataFileResponse(struct soap *soap, const struct __ns1__removeDataFileResponse *a, const char *tag, const char *type) { - register int id = 0; + int id = 0; if (soap_out___ns1__removeDataFileResponse(soap, tag?tag:"-ns1:removeDataFileResponse", id, a, type)) return soap->error; return SOAP_OK; @@ -78841,7 +78841,7 @@ SOAP_FMAC3 struct __ns1__deleteDataFileParameter * SOAP_FMAC4 soap_in___ns1__del SOAP_FMAC3 int SOAP_FMAC4 soap_put___ns1__deleteDataFileParameter(struct soap *soap, const struct __ns1__deleteDataFileParameter *a, const char *tag, const char *type) { - register int id = 0; + int id = 0; if (soap_out___ns1__deleteDataFileParameter(soap, tag?tag:"-ns1:deleteDataFileParameter", id, a, type)) return soap->error; return SOAP_OK; @@ -78940,7 +78940,7 @@ SOAP_FMAC3 struct __ns1__deleteDataFileParameterResponse * SOAP_FMAC4 soap_in___ SOAP_FMAC3 int SOAP_FMAC4 soap_put___ns1__deleteDataFileParameterResponse(struct soap *soap, const struct __ns1__deleteDataFileParameterResponse *a, const char *tag, const char *type) { - register int id = 0; + int id = 0; if (soap_out___ns1__deleteDataFileParameterResponse(soap, tag?tag:"-ns1:deleteDataFileParameterResponse", id, a, type)) return soap->error; return SOAP_OK; @@ -79036,7 +79036,7 @@ SOAP_FMAC3 struct __ns1__modifyDataFileParameter * SOAP_FMAC4 soap_in___ns1__mod SOAP_FMAC3 int SOAP_FMAC4 soap_put___ns1__modifyDataFileParameter(struct soap *soap, const struct __ns1__modifyDataFileParameter *a, const char *tag, const char *type) { - register int id = 0; + int id = 0; if (soap_out___ns1__modifyDataFileParameter(soap, tag?tag:"-ns1:modifyDataFileParameter", id, a, type)) return soap->error; return SOAP_OK; @@ -79135,7 +79135,7 @@ SOAP_FMAC3 struct __ns1__modifyDataFileParameterResponse * SOAP_FMAC4 soap_in___ SOAP_FMAC3 int SOAP_FMAC4 soap_put___ns1__modifyDataFileParameterResponse(struct soap *soap, const struct __ns1__modifyDataFileParameterResponse *a, const char *tag, const char *type) { - register int id = 0; + int id = 0; if (soap_out___ns1__modifyDataFileParameterResponse(soap, tag?tag:"-ns1:modifyDataFileParameterResponse", id, a, type)) return soap->error; return SOAP_OK; @@ -79231,7 +79231,7 @@ SOAP_FMAC3 struct __ns1__addDataFileParameters * SOAP_FMAC4 soap_in___ns1__addDa SOAP_FMAC3 int SOAP_FMAC4 soap_put___ns1__addDataFileParameters(struct soap *soap, const struct __ns1__addDataFileParameters *a, const char *tag, const char *type) { - register int id = 0; + int id = 0; if (soap_out___ns1__addDataFileParameters(soap, tag?tag:"-ns1:addDataFileParameters", id, a, type)) return soap->error; return SOAP_OK; @@ -79327,7 +79327,7 @@ SOAP_FMAC3 struct __ns1__addDataFileParameter * SOAP_FMAC4 soap_in___ns1__addDat SOAP_FMAC3 int SOAP_FMAC4 soap_put___ns1__addDataFileParameter(struct soap *soap, const struct __ns1__addDataFileParameter *a, const char *tag, const char *type) { - register int id = 0; + int id = 0; if (soap_out___ns1__addDataFileParameter(soap, tag?tag:"-ns1:addDataFileParameter", id, a, type)) return soap->error; return SOAP_OK; @@ -79423,7 +79423,7 @@ SOAP_FMAC3 struct __ns1__modifyDataFile * SOAP_FMAC4 soap_in___ns1__modifyDataFi SOAP_FMAC3 int SOAP_FMAC4 soap_put___ns1__modifyDataFile(struct soap *soap, const struct __ns1__modifyDataFile *a, const char *tag, const char *type) { - register int id = 0; + int id = 0; if (soap_out___ns1__modifyDataFile(soap, tag?tag:"-ns1:modifyDataFile", id, a, type)) return soap->error; return SOAP_OK; @@ -79522,7 +79522,7 @@ SOAP_FMAC3 struct __ns1__modifyDataFileResponse * SOAP_FMAC4 soap_in___ns1__modi SOAP_FMAC3 int SOAP_FMAC4 soap_put___ns1__modifyDataFileResponse(struct soap *soap, const struct __ns1__modifyDataFileResponse *a, const char *tag, const char *type) { - register int id = 0; + int id = 0; if (soap_out___ns1__modifyDataFileResponse(soap, tag?tag:"-ns1:modifyDataFileResponse", id, a, type)) return soap->error; return SOAP_OK; @@ -79618,7 +79618,7 @@ SOAP_FMAC3 struct __ns1__deleteDataFile * SOAP_FMAC4 soap_in___ns1__deleteDataFi SOAP_FMAC3 int SOAP_FMAC4 soap_put___ns1__deleteDataFile(struct soap *soap, const struct __ns1__deleteDataFile *a, const char *tag, const char *type) { - register int id = 0; + int id = 0; if (soap_out___ns1__deleteDataFile(soap, tag?tag:"-ns1:deleteDataFile", id, a, type)) return soap->error; return SOAP_OK; @@ -79717,7 +79717,7 @@ SOAP_FMAC3 struct __ns1__deleteDataFileResponse * SOAP_FMAC4 soap_in___ns1__dele SOAP_FMAC3 int SOAP_FMAC4 soap_put___ns1__deleteDataFileResponse(struct soap *soap, const struct __ns1__deleteDataFileResponse *a, const char *tag, const char *type) { - register int id = 0; + int id = 0; if (soap_out___ns1__deleteDataFileResponse(soap, tag?tag:"-ns1:deleteDataFileResponse", id, a, type)) return soap->error; return SOAP_OK; @@ -79813,7 +79813,7 @@ SOAP_FMAC3 struct __ns1__createDataFiles * SOAP_FMAC4 soap_in___ns1__createDataF SOAP_FMAC3 int SOAP_FMAC4 soap_put___ns1__createDataFiles(struct soap *soap, const struct __ns1__createDataFiles *a, const char *tag, const char *type) { - register int id = 0; + int id = 0; if (soap_out___ns1__createDataFiles(soap, tag?tag:"-ns1:createDataFiles", id, a, type)) return soap->error; return SOAP_OK; @@ -79909,7 +79909,7 @@ SOAP_FMAC3 struct __ns1__createDataFile * SOAP_FMAC4 soap_in___ns1__createDataFi SOAP_FMAC3 int SOAP_FMAC4 soap_put___ns1__createDataFile(struct soap *soap, const struct __ns1__createDataFile *a, const char *tag, const char *type) { - register int id = 0; + int id = 0; if (soap_out___ns1__createDataFile(soap, tag?tag:"-ns1:createDataFile", id, a, type)) return soap->error; return SOAP_OK; @@ -80005,7 +80005,7 @@ SOAP_FMAC3 struct __ns1__getDatafiles * SOAP_FMAC4 soap_in___ns1__getDatafiles(s SOAP_FMAC3 int SOAP_FMAC4 soap_put___ns1__getDatafiles(struct soap *soap, const struct __ns1__getDatafiles *a, const char *tag, const char *type) { - register int id = 0; + int id = 0; if (soap_out___ns1__getDatafiles(soap, tag?tag:"-ns1:getDatafiles", id, a, type)) return soap->error; return SOAP_OK; @@ -80101,7 +80101,7 @@ SOAP_FMAC3 struct __ns1__getDatafile * SOAP_FMAC4 soap_in___ns1__getDatafile(str SOAP_FMAC3 int SOAP_FMAC4 soap_put___ns1__getDatafile(struct soap *soap, const struct __ns1__getDatafile *a, const char *tag, const char *type) { - register int id = 0; + int id = 0; if (soap_out___ns1__getDatafile(soap, tag?tag:"-ns1:getDatafile", id, a, type)) return soap->error; return SOAP_OK; @@ -80197,7 +80197,7 @@ SOAP_FMAC3 struct __ns1__removeDataSetParameter * SOAP_FMAC4 soap_in___ns1__remo SOAP_FMAC3 int SOAP_FMAC4 soap_put___ns1__removeDataSetParameter(struct soap *soap, const struct __ns1__removeDataSetParameter *a, const char *tag, const char *type) { - register int id = 0; + int id = 0; if (soap_out___ns1__removeDataSetParameter(soap, tag?tag:"-ns1:removeDataSetParameter", id, a, type)) return soap->error; return SOAP_OK; @@ -80296,7 +80296,7 @@ SOAP_FMAC3 struct __ns1__removeDataSetParameterResponse * SOAP_FMAC4 soap_in___n SOAP_FMAC3 int SOAP_FMAC4 soap_put___ns1__removeDataSetParameterResponse(struct soap *soap, const struct __ns1__removeDataSetParameterResponse *a, const char *tag, const char *type) { - register int id = 0; + int id = 0; if (soap_out___ns1__removeDataSetParameterResponse(soap, tag?tag:"-ns1:removeDataSetParameterResponse", id, a, type)) return soap->error; return SOAP_OK; @@ -80392,7 +80392,7 @@ SOAP_FMAC3 struct __ns1__removeDataSet * SOAP_FMAC4 soap_in___ns1__removeDataSet SOAP_FMAC3 int SOAP_FMAC4 soap_put___ns1__removeDataSet(struct soap *soap, const struct __ns1__removeDataSet *a, const char *tag, const char *type) { - register int id = 0; + int id = 0; if (soap_out___ns1__removeDataSet(soap, tag?tag:"-ns1:removeDataSet", id, a, type)) return soap->error; return SOAP_OK; @@ -80491,7 +80491,7 @@ SOAP_FMAC3 struct __ns1__removeDataSetResponse * SOAP_FMAC4 soap_in___ns1__remov SOAP_FMAC3 int SOAP_FMAC4 soap_put___ns1__removeDataSetResponse(struct soap *soap, const struct __ns1__removeDataSetResponse *a, const char *tag, const char *type) { - register int id = 0; + int id = 0; if (soap_out___ns1__removeDataSetResponse(soap, tag?tag:"-ns1:removeDataSetResponse", id, a, type)) return soap->error; return SOAP_OK; @@ -80587,7 +80587,7 @@ SOAP_FMAC3 struct __ns1__addDataSetParameters * SOAP_FMAC4 soap_in___ns1__addDat SOAP_FMAC3 int SOAP_FMAC4 soap_put___ns1__addDataSetParameters(struct soap *soap, const struct __ns1__addDataSetParameters *a, const char *tag, const char *type) { - register int id = 0; + int id = 0; if (soap_out___ns1__addDataSetParameters(soap, tag?tag:"-ns1:addDataSetParameters", id, a, type)) return soap->error; return SOAP_OK; @@ -80683,7 +80683,7 @@ SOAP_FMAC3 struct __ns1__addDataSetParameter * SOAP_FMAC4 soap_in___ns1__addData SOAP_FMAC3 int SOAP_FMAC4 soap_put___ns1__addDataSetParameter(struct soap *soap, const struct __ns1__addDataSetParameter *a, const char *tag, const char *type) { - register int id = 0; + int id = 0; if (soap_out___ns1__addDataSetParameter(soap, tag?tag:"-ns1:addDataSetParameter", id, a, type)) return soap->error; return SOAP_OK; @@ -80779,7 +80779,7 @@ SOAP_FMAC3 struct __ns1__setDataSetSample * SOAP_FMAC4 soap_in___ns1__setDataSet SOAP_FMAC3 int SOAP_FMAC4 soap_put___ns1__setDataSetSample(struct soap *soap, const struct __ns1__setDataSetSample *a, const char *tag, const char *type) { - register int id = 0; + int id = 0; if (soap_out___ns1__setDataSetSample(soap, tag?tag:"-ns1:setDataSetSample", id, a, type)) return soap->error; return SOAP_OK; @@ -80878,7 +80878,7 @@ SOAP_FMAC3 struct __ns1__setDataSetSampleResponse * SOAP_FMAC4 soap_in___ns1__se SOAP_FMAC3 int SOAP_FMAC4 soap_put___ns1__setDataSetSampleResponse(struct soap *soap, const struct __ns1__setDataSetSampleResponse *a, const char *tag, const char *type) { - register int id = 0; + int id = 0; if (soap_out___ns1__setDataSetSampleResponse(soap, tag?tag:"-ns1:setDataSetSampleResponse", id, a, type)) return soap->error; return SOAP_OK; @@ -80974,7 +80974,7 @@ SOAP_FMAC3 struct __ns1__modifyDataSetParameter * SOAP_FMAC4 soap_in___ns1__modi SOAP_FMAC3 int SOAP_FMAC4 soap_put___ns1__modifyDataSetParameter(struct soap *soap, const struct __ns1__modifyDataSetParameter *a, const char *tag, const char *type) { - register int id = 0; + int id = 0; if (soap_out___ns1__modifyDataSetParameter(soap, tag?tag:"-ns1:modifyDataSetParameter", id, a, type)) return soap->error; return SOAP_OK; @@ -81073,7 +81073,7 @@ SOAP_FMAC3 struct __ns1__modifyDataSetParameterResponse * SOAP_FMAC4 soap_in___n SOAP_FMAC3 int SOAP_FMAC4 soap_put___ns1__modifyDataSetParameterResponse(struct soap *soap, const struct __ns1__modifyDataSetParameterResponse *a, const char *tag, const char *type) { - register int id = 0; + int id = 0; if (soap_out___ns1__modifyDataSetParameterResponse(soap, tag?tag:"-ns1:modifyDataSetParameterResponse", id, a, type)) return soap->error; return SOAP_OK; @@ -81169,7 +81169,7 @@ SOAP_FMAC3 struct __ns1__modifyDataSet * SOAP_FMAC4 soap_in___ns1__modifyDataSet SOAP_FMAC3 int SOAP_FMAC4 soap_put___ns1__modifyDataSet(struct soap *soap, const struct __ns1__modifyDataSet *a, const char *tag, const char *type) { - register int id = 0; + int id = 0; if (soap_out___ns1__modifyDataSet(soap, tag?tag:"-ns1:modifyDataSet", id, a, type)) return soap->error; return SOAP_OK; @@ -81268,7 +81268,7 @@ SOAP_FMAC3 struct __ns1__modifyDataSetResponse * SOAP_FMAC4 soap_in___ns1__modif SOAP_FMAC3 int SOAP_FMAC4 soap_put___ns1__modifyDataSetResponse(struct soap *soap, const struct __ns1__modifyDataSetResponse *a, const char *tag, const char *type) { - register int id = 0; + int id = 0; if (soap_out___ns1__modifyDataSetResponse(soap, tag?tag:"-ns1:modifyDataSetResponse", id, a, type)) return soap->error; return SOAP_OK; @@ -81364,7 +81364,7 @@ SOAP_FMAC3 struct __ns1__deleteDataSetParameter * SOAP_FMAC4 soap_in___ns1__dele SOAP_FMAC3 int SOAP_FMAC4 soap_put___ns1__deleteDataSetParameter(struct soap *soap, const struct __ns1__deleteDataSetParameter *a, const char *tag, const char *type) { - register int id = 0; + int id = 0; if (soap_out___ns1__deleteDataSetParameter(soap, tag?tag:"-ns1:deleteDataSetParameter", id, a, type)) return soap->error; return SOAP_OK; @@ -81463,7 +81463,7 @@ SOAP_FMAC3 struct __ns1__deleteDataSetParameterResponse * SOAP_FMAC4 soap_in___n SOAP_FMAC3 int SOAP_FMAC4 soap_put___ns1__deleteDataSetParameterResponse(struct soap *soap, const struct __ns1__deleteDataSetParameterResponse *a, const char *tag, const char *type) { - register int id = 0; + int id = 0; if (soap_out___ns1__deleteDataSetParameterResponse(soap, tag?tag:"-ns1:deleteDataSetParameterResponse", id, a, type)) return soap->error; return SOAP_OK; @@ -81559,7 +81559,7 @@ SOAP_FMAC3 struct __ns1__deleteDataSet * SOAP_FMAC4 soap_in___ns1__deleteDataSet SOAP_FMAC3 int SOAP_FMAC4 soap_put___ns1__deleteDataSet(struct soap *soap, const struct __ns1__deleteDataSet *a, const char *tag, const char *type) { - register int id = 0; + int id = 0; if (soap_out___ns1__deleteDataSet(soap, tag?tag:"-ns1:deleteDataSet", id, a, type)) return soap->error; return SOAP_OK; @@ -81658,7 +81658,7 @@ SOAP_FMAC3 struct __ns1__deleteDataSetResponse * SOAP_FMAC4 soap_in___ns1__delet SOAP_FMAC3 int SOAP_FMAC4 soap_put___ns1__deleteDataSetResponse(struct soap *soap, const struct __ns1__deleteDataSetResponse *a, const char *tag, const char *type) { - register int id = 0; + int id = 0; if (soap_out___ns1__deleteDataSetResponse(soap, tag?tag:"-ns1:deleteDataSetResponse", id, a, type)) return soap->error; return SOAP_OK; @@ -81754,7 +81754,7 @@ SOAP_FMAC3 struct __ns1__createDataSets * SOAP_FMAC4 soap_in___ns1__createDataSe SOAP_FMAC3 int SOAP_FMAC4 soap_put___ns1__createDataSets(struct soap *soap, const struct __ns1__createDataSets *a, const char *tag, const char *type) { - register int id = 0; + int id = 0; if (soap_out___ns1__createDataSets(soap, tag?tag:"-ns1:createDataSets", id, a, type)) return soap->error; return SOAP_OK; @@ -81850,7 +81850,7 @@ SOAP_FMAC3 struct __ns1__createDataSet * SOAP_FMAC4 soap_in___ns1__createDataSet SOAP_FMAC3 int SOAP_FMAC4 soap_put___ns1__createDataSet(struct soap *soap, const struct __ns1__createDataSet *a, const char *tag, const char *type) { - register int id = 0; + int id = 0; if (soap_out___ns1__createDataSet(soap, tag?tag:"-ns1:createDataSet", id, a, type)) return soap->error; return SOAP_OK; @@ -81946,7 +81946,7 @@ SOAP_FMAC3 struct __ns1__getDatasets * SOAP_FMAC4 soap_in___ns1__getDatasets(str SOAP_FMAC3 int SOAP_FMAC4 soap_put___ns1__getDatasets(struct soap *soap, const struct __ns1__getDatasets *a, const char *tag, const char *type) { - register int id = 0; + int id = 0; if (soap_out___ns1__getDatasets(soap, tag?tag:"-ns1:getDatasets", id, a, type)) return soap->error; return SOAP_OK; @@ -82042,7 +82042,7 @@ SOAP_FMAC3 struct __ns1__getDatasetIncludes * SOAP_FMAC4 soap_in___ns1__getDatas SOAP_FMAC3 int SOAP_FMAC4 soap_put___ns1__getDatasetIncludes(struct soap *soap, const struct __ns1__getDatasetIncludes *a, const char *tag, const char *type) { - register int id = 0; + int id = 0; if (soap_out___ns1__getDatasetIncludes(soap, tag?tag:"-ns1:getDatasetIncludes", id, a, type)) return soap->error; return SOAP_OK; @@ -82138,7 +82138,7 @@ SOAP_FMAC3 struct __ns1__getDataset * SOAP_FMAC4 soap_in___ns1__getDataset(struc SOAP_FMAC3 int SOAP_FMAC4 soap_put___ns1__getDataset(struct soap *soap, const struct __ns1__getDataset *a, const char *tag, const char *type) { - register int id = 0; + int id = 0; if (soap_out___ns1__getDataset(soap, tag?tag:"-ns1:getDataset", id, a, type)) return soap->error; return SOAP_OK; @@ -82234,7 +82234,7 @@ SOAP_FMAC3 struct __ns1__removeSampleParameter * SOAP_FMAC4 soap_in___ns1__remov SOAP_FMAC3 int SOAP_FMAC4 soap_put___ns1__removeSampleParameter(struct soap *soap, const struct __ns1__removeSampleParameter *a, const char *tag, const char *type) { - register int id = 0; + int id = 0; if (soap_out___ns1__removeSampleParameter(soap, tag?tag:"-ns1:removeSampleParameter", id, a, type)) return soap->error; return SOAP_OK; @@ -82333,7 +82333,7 @@ SOAP_FMAC3 struct __ns1__removeSampleParameterResponse * SOAP_FMAC4 soap_in___ns SOAP_FMAC3 int SOAP_FMAC4 soap_put___ns1__removeSampleParameterResponse(struct soap *soap, const struct __ns1__removeSampleParameterResponse *a, const char *tag, const char *type) { - register int id = 0; + int id = 0; if (soap_out___ns1__removeSampleParameterResponse(soap, tag?tag:"-ns1:removeSampleParameterResponse", id, a, type)) return soap->error; return SOAP_OK; @@ -82429,7 +82429,7 @@ SOAP_FMAC3 struct __ns1__removeSample * SOAP_FMAC4 soap_in___ns1__removeSample(s SOAP_FMAC3 int SOAP_FMAC4 soap_put___ns1__removeSample(struct soap *soap, const struct __ns1__removeSample *a, const char *tag, const char *type) { - register int id = 0; + int id = 0; if (soap_out___ns1__removeSample(soap, tag?tag:"-ns1:removeSample", id, a, type)) return soap->error; return SOAP_OK; @@ -82528,7 +82528,7 @@ SOAP_FMAC3 struct __ns1__removeSampleResponse * SOAP_FMAC4 soap_in___ns1__remove SOAP_FMAC3 int SOAP_FMAC4 soap_put___ns1__removeSampleResponse(struct soap *soap, const struct __ns1__removeSampleResponse *a, const char *tag, const char *type) { - register int id = 0; + int id = 0; if (soap_out___ns1__removeSampleResponse(soap, tag?tag:"-ns1:removeSampleResponse", id, a, type)) return soap->error; return SOAP_OK; @@ -82624,7 +82624,7 @@ SOAP_FMAC3 struct __ns1__removePublication * SOAP_FMAC4 soap_in___ns1__removePub SOAP_FMAC3 int SOAP_FMAC4 soap_put___ns1__removePublication(struct soap *soap, const struct __ns1__removePublication *a, const char *tag, const char *type) { - register int id = 0; + int id = 0; if (soap_out___ns1__removePublication(soap, tag?tag:"-ns1:removePublication", id, a, type)) return soap->error; return SOAP_OK; @@ -82723,7 +82723,7 @@ SOAP_FMAC3 struct __ns1__removePublicationResponse * SOAP_FMAC4 soap_in___ns1__r SOAP_FMAC3 int SOAP_FMAC4 soap_put___ns1__removePublicationResponse(struct soap *soap, const struct __ns1__removePublicationResponse *a, const char *tag, const char *type) { - register int id = 0; + int id = 0; if (soap_out___ns1__removePublicationResponse(soap, tag?tag:"-ns1:removePublicationResponse", id, a, type)) return soap->error; return SOAP_OK; @@ -82819,7 +82819,7 @@ SOAP_FMAC3 struct __ns1__removeInvestigator * SOAP_FMAC4 soap_in___ns1__removeIn SOAP_FMAC3 int SOAP_FMAC4 soap_put___ns1__removeInvestigator(struct soap *soap, const struct __ns1__removeInvestigator *a, const char *tag, const char *type) { - register int id = 0; + int id = 0; if (soap_out___ns1__removeInvestigator(soap, tag?tag:"-ns1:removeInvestigator", id, a, type)) return soap->error; return SOAP_OK; @@ -82918,7 +82918,7 @@ SOAP_FMAC3 struct __ns1__removeInvestigatorResponse * SOAP_FMAC4 soap_in___ns1__ SOAP_FMAC3 int SOAP_FMAC4 soap_put___ns1__removeInvestigatorResponse(struct soap *soap, const struct __ns1__removeInvestigatorResponse *a, const char *tag, const char *type) { - register int id = 0; + int id = 0; if (soap_out___ns1__removeInvestigatorResponse(soap, tag?tag:"-ns1:removeInvestigatorResponse", id, a, type)) return soap->error; return SOAP_OK; @@ -83014,7 +83014,7 @@ SOAP_FMAC3 struct __ns1__removeKeyword * SOAP_FMAC4 soap_in___ns1__removeKeyword SOAP_FMAC3 int SOAP_FMAC4 soap_put___ns1__removeKeyword(struct soap *soap, const struct __ns1__removeKeyword *a, const char *tag, const char *type) { - register int id = 0; + int id = 0; if (soap_out___ns1__removeKeyword(soap, tag?tag:"-ns1:removeKeyword", id, a, type)) return soap->error; return SOAP_OK; @@ -83113,7 +83113,7 @@ SOAP_FMAC3 struct __ns1__removeKeywordResponse * SOAP_FMAC4 soap_in___ns1__remov SOAP_FMAC3 int SOAP_FMAC4 soap_put___ns1__removeKeywordResponse(struct soap *soap, const struct __ns1__removeKeywordResponse *a, const char *tag, const char *type) { - register int id = 0; + int id = 0; if (soap_out___ns1__removeKeywordResponse(soap, tag?tag:"-ns1:removeKeywordResponse", id, a, type)) return soap->error; return SOAP_OK; @@ -83209,7 +83209,7 @@ SOAP_FMAC3 struct __ns1__modifySampleParameter * SOAP_FMAC4 soap_in___ns1__modif SOAP_FMAC3 int SOAP_FMAC4 soap_put___ns1__modifySampleParameter(struct soap *soap, const struct __ns1__modifySampleParameter *a, const char *tag, const char *type) { - register int id = 0; + int id = 0; if (soap_out___ns1__modifySampleParameter(soap, tag?tag:"-ns1:modifySampleParameter", id, a, type)) return soap->error; return SOAP_OK; @@ -83308,7 +83308,7 @@ SOAP_FMAC3 struct __ns1__modifySampleParameterResponse * SOAP_FMAC4 soap_in___ns SOAP_FMAC3 int SOAP_FMAC4 soap_put___ns1__modifySampleParameterResponse(struct soap *soap, const struct __ns1__modifySampleParameterResponse *a, const char *tag, const char *type) { - register int id = 0; + int id = 0; if (soap_out___ns1__modifySampleParameterResponse(soap, tag?tag:"-ns1:modifySampleParameterResponse", id, a, type)) return soap->error; return SOAP_OK; @@ -83404,7 +83404,7 @@ SOAP_FMAC3 struct __ns1__modifyPublication * SOAP_FMAC4 soap_in___ns1__modifyPub SOAP_FMAC3 int SOAP_FMAC4 soap_put___ns1__modifyPublication(struct soap *soap, const struct __ns1__modifyPublication *a, const char *tag, const char *type) { - register int id = 0; + int id = 0; if (soap_out___ns1__modifyPublication(soap, tag?tag:"-ns1:modifyPublication", id, a, type)) return soap->error; return SOAP_OK; @@ -83503,7 +83503,7 @@ SOAP_FMAC3 struct __ns1__modifyPublicationResponse * SOAP_FMAC4 soap_in___ns1__m SOAP_FMAC3 int SOAP_FMAC4 soap_put___ns1__modifyPublicationResponse(struct soap *soap, const struct __ns1__modifyPublicationResponse *a, const char *tag, const char *type) { - register int id = 0; + int id = 0; if (soap_out___ns1__modifyPublicationResponse(soap, tag?tag:"-ns1:modifyPublicationResponse", id, a, type)) return soap->error; return SOAP_OK; @@ -83599,7 +83599,7 @@ SOAP_FMAC3 struct __ns1__modifySample * SOAP_FMAC4 soap_in___ns1__modifySample(s SOAP_FMAC3 int SOAP_FMAC4 soap_put___ns1__modifySample(struct soap *soap, const struct __ns1__modifySample *a, const char *tag, const char *type) { - register int id = 0; + int id = 0; if (soap_out___ns1__modifySample(soap, tag?tag:"-ns1:modifySample", id, a, type)) return soap->error; return SOAP_OK; @@ -83698,7 +83698,7 @@ SOAP_FMAC3 struct __ns1__modifySampleResponse * SOAP_FMAC4 soap_in___ns1__modify SOAP_FMAC3 int SOAP_FMAC4 soap_put___ns1__modifySampleResponse(struct soap *soap, const struct __ns1__modifySampleResponse *a, const char *tag, const char *type) { - register int id = 0; + int id = 0; if (soap_out___ns1__modifySampleResponse(soap, tag?tag:"-ns1:modifySampleResponse", id, a, type)) return soap->error; return SOAP_OK; @@ -83794,7 +83794,7 @@ SOAP_FMAC3 struct __ns1__modifyInvestigator * SOAP_FMAC4 soap_in___ns1__modifyIn SOAP_FMAC3 int SOAP_FMAC4 soap_put___ns1__modifyInvestigator(struct soap *soap, const struct __ns1__modifyInvestigator *a, const char *tag, const char *type) { - register int id = 0; + int id = 0; if (soap_out___ns1__modifyInvestigator(soap, tag?tag:"-ns1:modifyInvestigator", id, a, type)) return soap->error; return SOAP_OK; @@ -83893,7 +83893,7 @@ SOAP_FMAC3 struct __ns1__modifyInvestigatorResponse * SOAP_FMAC4 soap_in___ns1__ SOAP_FMAC3 int SOAP_FMAC4 soap_put___ns1__modifyInvestigatorResponse(struct soap *soap, const struct __ns1__modifyInvestigatorResponse *a, const char *tag, const char *type) { - register int id = 0; + int id = 0; if (soap_out___ns1__modifyInvestigatorResponse(soap, tag?tag:"-ns1:modifyInvestigatorResponse", id, a, type)) return soap->error; return SOAP_OK; @@ -83989,7 +83989,7 @@ SOAP_FMAC3 struct __ns1__modifyInvestigation * SOAP_FMAC4 soap_in___ns1__modifyI SOAP_FMAC3 int SOAP_FMAC4 soap_put___ns1__modifyInvestigation(struct soap *soap, const struct __ns1__modifyInvestigation *a, const char *tag, const char *type) { - register int id = 0; + int id = 0; if (soap_out___ns1__modifyInvestigation(soap, tag?tag:"-ns1:modifyInvestigation", id, a, type)) return soap->error; return SOAP_OK; @@ -84088,7 +84088,7 @@ SOAP_FMAC3 struct __ns1__modifyInvestigationResponse * SOAP_FMAC4 soap_in___ns1_ SOAP_FMAC3 int SOAP_FMAC4 soap_put___ns1__modifyInvestigationResponse(struct soap *soap, const struct __ns1__modifyInvestigationResponse *a, const char *tag, const char *type) { - register int id = 0; + int id = 0; if (soap_out___ns1__modifyInvestigationResponse(soap, tag?tag:"-ns1:modifyInvestigationResponse", id, a, type)) return soap->error; return SOAP_OK; @@ -84184,7 +84184,7 @@ SOAP_FMAC3 struct __ns1__deleteSampleParameter * SOAP_FMAC4 soap_in___ns1__delet SOAP_FMAC3 int SOAP_FMAC4 soap_put___ns1__deleteSampleParameter(struct soap *soap, const struct __ns1__deleteSampleParameter *a, const char *tag, const char *type) { - register int id = 0; + int id = 0; if (soap_out___ns1__deleteSampleParameter(soap, tag?tag:"-ns1:deleteSampleParameter", id, a, type)) return soap->error; return SOAP_OK; @@ -84283,7 +84283,7 @@ SOAP_FMAC3 struct __ns1__deleteSampleParameterResponse * SOAP_FMAC4 soap_in___ns SOAP_FMAC3 int SOAP_FMAC4 soap_put___ns1__deleteSampleParameterResponse(struct soap *soap, const struct __ns1__deleteSampleParameterResponse *a, const char *tag, const char *type) { - register int id = 0; + int id = 0; if (soap_out___ns1__deleteSampleParameterResponse(soap, tag?tag:"-ns1:deleteSampleParameterResponse", id, a, type)) return soap->error; return SOAP_OK; @@ -84379,7 +84379,7 @@ SOAP_FMAC3 struct __ns1__deleteSample * SOAP_FMAC4 soap_in___ns1__deleteSample(s SOAP_FMAC3 int SOAP_FMAC4 soap_put___ns1__deleteSample(struct soap *soap, const struct __ns1__deleteSample *a, const char *tag, const char *type) { - register int id = 0; + int id = 0; if (soap_out___ns1__deleteSample(soap, tag?tag:"-ns1:deleteSample", id, a, type)) return soap->error; return SOAP_OK; @@ -84478,7 +84478,7 @@ SOAP_FMAC3 struct __ns1__deleteSampleResponse * SOAP_FMAC4 soap_in___ns1__delete SOAP_FMAC3 int SOAP_FMAC4 soap_put___ns1__deleteSampleResponse(struct soap *soap, const struct __ns1__deleteSampleResponse *a, const char *tag, const char *type) { - register int id = 0; + int id = 0; if (soap_out___ns1__deleteSampleResponse(soap, tag?tag:"-ns1:deleteSampleResponse", id, a, type)) return soap->error; return SOAP_OK; @@ -84574,7 +84574,7 @@ SOAP_FMAC3 struct __ns1__deletePublication * SOAP_FMAC4 soap_in___ns1__deletePub SOAP_FMAC3 int SOAP_FMAC4 soap_put___ns1__deletePublication(struct soap *soap, const struct __ns1__deletePublication *a, const char *tag, const char *type) { - register int id = 0; + int id = 0; if (soap_out___ns1__deletePublication(soap, tag?tag:"-ns1:deletePublication", id, a, type)) return soap->error; return SOAP_OK; @@ -84673,7 +84673,7 @@ SOAP_FMAC3 struct __ns1__deletePublicationResponse * SOAP_FMAC4 soap_in___ns1__d SOAP_FMAC3 int SOAP_FMAC4 soap_put___ns1__deletePublicationResponse(struct soap *soap, const struct __ns1__deletePublicationResponse *a, const char *tag, const char *type) { - register int id = 0; + int id = 0; if (soap_out___ns1__deletePublicationResponse(soap, tag?tag:"-ns1:deletePublicationResponse", id, a, type)) return soap->error; return SOAP_OK; @@ -84769,7 +84769,7 @@ SOAP_FMAC3 struct __ns1__deleteKeyword * SOAP_FMAC4 soap_in___ns1__deleteKeyword SOAP_FMAC3 int SOAP_FMAC4 soap_put___ns1__deleteKeyword(struct soap *soap, const struct __ns1__deleteKeyword *a, const char *tag, const char *type) { - register int id = 0; + int id = 0; if (soap_out___ns1__deleteKeyword(soap, tag?tag:"-ns1:deleteKeyword", id, a, type)) return soap->error; return SOAP_OK; @@ -84868,7 +84868,7 @@ SOAP_FMAC3 struct __ns1__deleteKeywordResponse * SOAP_FMAC4 soap_in___ns1__delet SOAP_FMAC3 int SOAP_FMAC4 soap_put___ns1__deleteKeywordResponse(struct soap *soap, const struct __ns1__deleteKeywordResponse *a, const char *tag, const char *type) { - register int id = 0; + int id = 0; if (soap_out___ns1__deleteKeywordResponse(soap, tag?tag:"-ns1:deleteKeywordResponse", id, a, type)) return soap->error; return SOAP_OK; @@ -84964,7 +84964,7 @@ SOAP_FMAC3 struct __ns1__deleteInvestigator * SOAP_FMAC4 soap_in___ns1__deleteIn SOAP_FMAC3 int SOAP_FMAC4 soap_put___ns1__deleteInvestigator(struct soap *soap, const struct __ns1__deleteInvestigator *a, const char *tag, const char *type) { - register int id = 0; + int id = 0; if (soap_out___ns1__deleteInvestigator(soap, tag?tag:"-ns1:deleteInvestigator", id, a, type)) return soap->error; return SOAP_OK; @@ -85063,7 +85063,7 @@ SOAP_FMAC3 struct __ns1__deleteInvestigatorResponse * SOAP_FMAC4 soap_in___ns1__ SOAP_FMAC3 int SOAP_FMAC4 soap_put___ns1__deleteInvestigatorResponse(struct soap *soap, const struct __ns1__deleteInvestigatorResponse *a, const char *tag, const char *type) { - register int id = 0; + int id = 0; if (soap_out___ns1__deleteInvestigatorResponse(soap, tag?tag:"-ns1:deleteInvestigatorResponse", id, a, type)) return soap->error; return SOAP_OK; @@ -85159,7 +85159,7 @@ SOAP_FMAC3 struct __ns1__addSampleParameter * SOAP_FMAC4 soap_in___ns1__addSampl SOAP_FMAC3 int SOAP_FMAC4 soap_put___ns1__addSampleParameter(struct soap *soap, const struct __ns1__addSampleParameter *a, const char *tag, const char *type) { - register int id = 0; + int id = 0; if (soap_out___ns1__addSampleParameter(soap, tag?tag:"-ns1:addSampleParameter", id, a, type)) return soap->error; return SOAP_OK; @@ -85255,7 +85255,7 @@ SOAP_FMAC3 struct __ns1__addPublication * SOAP_FMAC4 soap_in___ns1__addPublicati SOAP_FMAC3 int SOAP_FMAC4 soap_put___ns1__addPublication(struct soap *soap, const struct __ns1__addPublication *a, const char *tag, const char *type) { - register int id = 0; + int id = 0; if (soap_out___ns1__addPublication(soap, tag?tag:"-ns1:addPublication", id, a, type)) return soap->error; return SOAP_OK; @@ -85351,7 +85351,7 @@ SOAP_FMAC3 struct __ns1__addSample * SOAP_FMAC4 soap_in___ns1__addSample(struct SOAP_FMAC3 int SOAP_FMAC4 soap_put___ns1__addSample(struct soap *soap, const struct __ns1__addSample *a, const char *tag, const char *type) { - register int id = 0; + int id = 0; if (soap_out___ns1__addSample(soap, tag?tag:"-ns1:addSample", id, a, type)) return soap->error; return SOAP_OK; @@ -85447,7 +85447,7 @@ SOAP_FMAC3 struct __ns1__addInvestigator * SOAP_FMAC4 soap_in___ns1__addInvestig SOAP_FMAC3 int SOAP_FMAC4 soap_put___ns1__addInvestigator(struct soap *soap, const struct __ns1__addInvestigator *a, const char *tag, const char *type) { - register int id = 0; + int id = 0; if (soap_out___ns1__addInvestigator(soap, tag?tag:"-ns1:addInvestigator", id, a, type)) return soap->error; return SOAP_OK; @@ -85543,7 +85543,7 @@ SOAP_FMAC3 struct __ns1__addKeyword * SOAP_FMAC4 soap_in___ns1__addKeyword(struc SOAP_FMAC3 int SOAP_FMAC4 soap_put___ns1__addKeyword(struct soap *soap, const struct __ns1__addKeyword *a, const char *tag, const char *type) { - register int id = 0; + int id = 0; if (soap_out___ns1__addKeyword(soap, tag?tag:"-ns1:addKeyword", id, a, type)) return soap->error; return SOAP_OK; @@ -85639,7 +85639,7 @@ SOAP_FMAC3 struct __ns1__removeInvestigation * SOAP_FMAC4 soap_in___ns1__removeI SOAP_FMAC3 int SOAP_FMAC4 soap_put___ns1__removeInvestigation(struct soap *soap, const struct __ns1__removeInvestigation *a, const char *tag, const char *type) { - register int id = 0; + int id = 0; if (soap_out___ns1__removeInvestigation(soap, tag?tag:"-ns1:removeInvestigation", id, a, type)) return soap->error; return SOAP_OK; @@ -85738,7 +85738,7 @@ SOAP_FMAC3 struct __ns1__removeInvestigationResponse * SOAP_FMAC4 soap_in___ns1_ SOAP_FMAC3 int SOAP_FMAC4 soap_put___ns1__removeInvestigationResponse(struct soap *soap, const struct __ns1__removeInvestigationResponse *a, const char *tag, const char *type) { - register int id = 0; + int id = 0; if (soap_out___ns1__removeInvestigationResponse(soap, tag?tag:"-ns1:removeInvestigationResponse", id, a, type)) return soap->error; return SOAP_OK; @@ -85834,7 +85834,7 @@ SOAP_FMAC3 struct __ns1__deleteInvestigation * SOAP_FMAC4 soap_in___ns1__deleteI SOAP_FMAC3 int SOAP_FMAC4 soap_put___ns1__deleteInvestigation(struct soap *soap, const struct __ns1__deleteInvestigation *a, const char *tag, const char *type) { - register int id = 0; + int id = 0; if (soap_out___ns1__deleteInvestigation(soap, tag?tag:"-ns1:deleteInvestigation", id, a, type)) return soap->error; return SOAP_OK; @@ -85933,7 +85933,7 @@ SOAP_FMAC3 struct __ns1__deleteInvestigationResponse * SOAP_FMAC4 soap_in___ns1_ SOAP_FMAC3 int SOAP_FMAC4 soap_put___ns1__deleteInvestigationResponse(struct soap *soap, const struct __ns1__deleteInvestigationResponse *a, const char *tag, const char *type) { - register int id = 0; + int id = 0; if (soap_out___ns1__deleteInvestigationResponse(soap, tag?tag:"-ns1:deleteInvestigationResponse", id, a, type)) return soap->error; return SOAP_OK; @@ -86029,7 +86029,7 @@ SOAP_FMAC3 struct __ns1__createInvestigation * SOAP_FMAC4 soap_in___ns1__createI SOAP_FMAC3 int SOAP_FMAC4 soap_put___ns1__createInvestigation(struct soap *soap, const struct __ns1__createInvestigation *a, const char *tag, const char *type) { - register int id = 0; + int id = 0; if (soap_out___ns1__createInvestigation(soap, tag?tag:"-ns1:createInvestigation", id, a, type)) return soap->error; return SOAP_OK; @@ -86125,7 +86125,7 @@ SOAP_FMAC3 struct __ns1__getInvestigationsIncludes * SOAP_FMAC4 soap_in___ns1__g SOAP_FMAC3 int SOAP_FMAC4 soap_put___ns1__getInvestigationsIncludes(struct soap *soap, const struct __ns1__getInvestigationsIncludes *a, const char *tag, const char *type) { - register int id = 0; + int id = 0; if (soap_out___ns1__getInvestigationsIncludes(soap, tag?tag:"-ns1:getInvestigationsIncludes", id, a, type)) return soap->error; return SOAP_OK; @@ -86221,7 +86221,7 @@ SOAP_FMAC3 struct __ns1__getInvestigations * SOAP_FMAC4 soap_in___ns1__getInvest SOAP_FMAC3 int SOAP_FMAC4 soap_put___ns1__getInvestigations(struct soap *soap, const struct __ns1__getInvestigations *a, const char *tag, const char *type) { - register int id = 0; + int id = 0; if (soap_out___ns1__getInvestigations(soap, tag?tag:"-ns1:getInvestigations", id, a, type)) return soap->error; return SOAP_OK; @@ -86317,7 +86317,7 @@ SOAP_FMAC3 struct __ns1__getInvestigationIncludes * SOAP_FMAC4 soap_in___ns1__ge SOAP_FMAC3 int SOAP_FMAC4 soap_put___ns1__getInvestigationIncludes(struct soap *soap, const struct __ns1__getInvestigationIncludes *a, const char *tag, const char *type) { - register int id = 0; + int id = 0; if (soap_out___ns1__getInvestigationIncludes(soap, tag?tag:"-ns1:getInvestigationIncludes", id, a, type)) return soap->error; return SOAP_OK; @@ -86413,7 +86413,7 @@ SOAP_FMAC3 struct __ns1__getInvestigation * SOAP_FMAC4 soap_in___ns1__getInvesti SOAP_FMAC3 int SOAP_FMAC4 soap_put___ns1__getInvestigation(struct soap *soap, const struct __ns1__getInvestigation *a, const char *tag, const char *type) { - register int id = 0; + int id = 0; if (soap_out___ns1__getInvestigation(soap, tag?tag:"-ns1:getInvestigation", id, a, type)) return soap->error; return SOAP_OK; @@ -86509,7 +86509,7 @@ SOAP_FMAC3 struct __ns1__listDatafileFormats * SOAP_FMAC4 soap_in___ns1__listDat SOAP_FMAC3 int SOAP_FMAC4 soap_put___ns1__listDatafileFormats(struct soap *soap, const struct __ns1__listDatafileFormats *a, const char *tag, const char *type) { - register int id = 0; + int id = 0; if (soap_out___ns1__listDatafileFormats(soap, tag?tag:"-ns1:listDatafileFormats", id, a, type)) return soap->error; return SOAP_OK; @@ -86605,7 +86605,7 @@ SOAP_FMAC3 struct __ns1__searchByRunNumberPagination * SOAP_FMAC4 soap_in___ns1_ SOAP_FMAC3 int SOAP_FMAC4 soap_put___ns1__searchByRunNumberPagination(struct soap *soap, const struct __ns1__searchByRunNumberPagination *a, const char *tag, const char *type) { - register int id = 0; + int id = 0; if (soap_out___ns1__searchByRunNumberPagination(soap, tag?tag:"-ns1:searchByRunNumberPagination", id, a, type)) return soap->error; return SOAP_OK; @@ -86701,7 +86701,7 @@ SOAP_FMAC3 struct __ns1__searchByRunNumber * SOAP_FMAC4 soap_in___ns1__searchByR SOAP_FMAC3 int SOAP_FMAC4 soap_put___ns1__searchByRunNumber(struct soap *soap, const struct __ns1__searchByRunNumber *a, const char *tag, const char *type) { - register int id = 0; + int id = 0; if (soap_out___ns1__searchByRunNumber(soap, tag?tag:"-ns1:searchByRunNumber", id, a, type)) return soap->error; return SOAP_OK; @@ -86797,7 +86797,7 @@ SOAP_FMAC3 struct __ns1__listDatasetStatus * SOAP_FMAC4 soap_in___ns1__listDatas SOAP_FMAC3 int SOAP_FMAC4 soap_put___ns1__listDatasetStatus(struct soap *soap, const struct __ns1__listDatasetStatus *a, const char *tag, const char *type) { - register int id = 0; + int id = 0; if (soap_out___ns1__listDatasetStatus(soap, tag?tag:"-ns1:listDatasetStatus", id, a, type)) return soap->error; return SOAP_OK; @@ -86893,7 +86893,7 @@ SOAP_FMAC3 struct __ns1__listDatasetTypes * SOAP_FMAC4 soap_in___ns1__listDatase SOAP_FMAC3 int SOAP_FMAC4 soap_put___ns1__listDatasetTypes(struct soap *soap, const struct __ns1__listDatasetTypes *a, const char *tag, const char *type) { - register int id = 0; + int id = 0; if (soap_out___ns1__listDatasetTypes(soap, tag?tag:"-ns1:listDatasetTypes", id, a, type)) return soap->error; return SOAP_OK; @@ -86989,7 +86989,7 @@ SOAP_FMAC3 struct __ns1__searchDatasetsBySample * SOAP_FMAC4 soap_in___ns1__sear SOAP_FMAC3 int SOAP_FMAC4 soap_put___ns1__searchDatasetsBySample(struct soap *soap, const struct __ns1__searchDatasetsBySample *a, const char *tag, const char *type) { - register int id = 0; + int id = 0; if (soap_out___ns1__searchDatasetsBySample(soap, tag?tag:"-ns1:searchDatasetsBySample", id, a, type)) return soap->error; return SOAP_OK; @@ -87085,7 +87085,7 @@ SOAP_FMAC3 struct __ns1__searchSamplesBySampleName * SOAP_FMAC4 soap_in___ns1__s SOAP_FMAC3 int SOAP_FMAC4 soap_put___ns1__searchSamplesBySampleName(struct soap *soap, const struct __ns1__searchSamplesBySampleName *a, const char *tag, const char *type) { - register int id = 0; + int id = 0; if (soap_out___ns1__searchSamplesBySampleName(soap, tag?tag:"-ns1:searchSamplesBySampleName", id, a, type)) return soap->error; return SOAP_OK; @@ -87181,7 +87181,7 @@ SOAP_FMAC3 struct __ns1__listInvestigationTypes * SOAP_FMAC4 soap_in___ns1__list SOAP_FMAC3 int SOAP_FMAC4 soap_put___ns1__listInvestigationTypes(struct soap *soap, const struct __ns1__listInvestigationTypes *a, const char *tag, const char *type) { - register int id = 0; + int id = 0; if (soap_out___ns1__listInvestigationTypes(soap, tag?tag:"-ns1:listInvestigationTypes", id, a, type)) return soap->error; return SOAP_OK; @@ -87277,7 +87277,7 @@ SOAP_FMAC3 struct __ns1__getInstrumentsWithData * SOAP_FMAC4 soap_in___ns1__getI SOAP_FMAC3 int SOAP_FMAC4 soap_put___ns1__getInstrumentsWithData(struct soap *soap, const struct __ns1__getInstrumentsWithData *a, const char *tag, const char *type) { - register int id = 0; + int id = 0; if (soap_out___ns1__getInstrumentsWithData(soap, tag?tag:"-ns1:getInstrumentsWithData", id, a, type)) return soap->error; return SOAP_OK; @@ -87373,7 +87373,7 @@ SOAP_FMAC3 struct __ns1__getFacilityCyclesWithDataForInstrument * SOAP_FMAC4 soa SOAP_FMAC3 int SOAP_FMAC4 soap_put___ns1__getFacilityCyclesWithDataForInstrument(struct soap *soap, const struct __ns1__getFacilityCyclesWithDataForInstrument *a, const char *tag, const char *type) { - register int id = 0; + int id = 0; if (soap_out___ns1__getFacilityCyclesWithDataForInstrument(soap, tag?tag:"-ns1:getFacilityCyclesWithDataForInstrument", id, a, type)) return soap->error; return SOAP_OK; @@ -87469,7 +87469,7 @@ SOAP_FMAC3 struct __ns1__listFacilityCycles * SOAP_FMAC4 soap_in___ns1__listFaci SOAP_FMAC3 int SOAP_FMAC4 soap_put___ns1__listFacilityCycles(struct soap *soap, const struct __ns1__listFacilityCycles *a, const char *tag, const char *type) { - register int id = 0; + int id = 0; if (soap_out___ns1__listFacilityCycles(soap, tag?tag:"-ns1:listFacilityCycles", id, a, type)) return soap->error; return SOAP_OK; @@ -87565,7 +87565,7 @@ SOAP_FMAC3 struct __ns1__listParameters * SOAP_FMAC4 soap_in___ns1__listParamete SOAP_FMAC3 int SOAP_FMAC4 soap_put___ns1__listParameters(struct soap *soap, const struct __ns1__listParameters *a, const char *tag, const char *type) { - register int id = 0; + int id = 0; if (soap_out___ns1__listParameters(soap, tag?tag:"-ns1:listParameters", id, a, type)) return soap->error; return SOAP_OK; @@ -87661,7 +87661,7 @@ SOAP_FMAC3 struct __ns1__listRoles * SOAP_FMAC4 soap_in___ns1__listRoles(struct SOAP_FMAC3 int SOAP_FMAC4 soap_put___ns1__listRoles(struct soap *soap, const struct __ns1__listRoles *a, const char *tag, const char *type) { - register int id = 0; + int id = 0; if (soap_out___ns1__listRoles(soap, tag?tag:"-ns1:listRoles", id, a, type)) return soap->error; return SOAP_OK; @@ -87757,7 +87757,7 @@ SOAP_FMAC3 struct __ns1__getAllInstruments * SOAP_FMAC4 soap_in___ns1__getAllIns SOAP_FMAC3 int SOAP_FMAC4 soap_put___ns1__getAllInstruments(struct soap *soap, const struct __ns1__getAllInstruments *a, const char *tag, const char *type) { - register int id = 0; + int id = 0; if (soap_out___ns1__getAllInstruments(soap, tag?tag:"-ns1:getAllInstruments", id, a, type)) return soap->error; return SOAP_OK; @@ -87853,7 +87853,7 @@ SOAP_FMAC3 struct __ns1__listInstruments * SOAP_FMAC4 soap_in___ns1__listInstrum SOAP_FMAC3 int SOAP_FMAC4 soap_put___ns1__listInstruments(struct soap *soap, const struct __ns1__listInstruments *a, const char *tag, const char *type) { - register int id = 0; + int id = 0; if (soap_out___ns1__listInstruments(soap, tag?tag:"-ns1:listInstruments", id, a, type)) return soap->error; return SOAP_OK; @@ -87949,7 +87949,7 @@ SOAP_FMAC3 struct __ns1__searchByUserSurnamePagination * SOAP_FMAC4 soap_in___ns SOAP_FMAC3 int SOAP_FMAC4 soap_put___ns1__searchByUserSurnamePagination(struct soap *soap, const struct __ns1__searchByUserSurnamePagination *a, const char *tag, const char *type) { - register int id = 0; + int id = 0; if (soap_out___ns1__searchByUserSurnamePagination(soap, tag?tag:"-ns1:searchByUserSurnamePagination", id, a, type)) return soap->error; return SOAP_OK; @@ -88045,7 +88045,7 @@ SOAP_FMAC3 struct __ns1__searchByUserSurname * SOAP_FMAC4 soap_in___ns1__searchB SOAP_FMAC3 int SOAP_FMAC4 soap_put___ns1__searchByUserSurname(struct soap *soap, const struct __ns1__searchByUserSurname *a, const char *tag, const char *type) { - register int id = 0; + int id = 0; if (soap_out___ns1__searchByUserSurname(soap, tag?tag:"-ns1:searchByUserSurname", id, a, type)) return soap->error; return SOAP_OK; @@ -88141,7 +88141,7 @@ SOAP_FMAC3 struct __ns1__searchByUserIDPagination * SOAP_FMAC4 soap_in___ns1__se SOAP_FMAC3 int SOAP_FMAC4 soap_put___ns1__searchByUserIDPagination(struct soap *soap, const struct __ns1__searchByUserIDPagination *a, const char *tag, const char *type) { - register int id = 0; + int id = 0; if (soap_out___ns1__searchByUserIDPagination(soap, tag?tag:"-ns1:searchByUserIDPagination", id, a, type)) return soap->error; return SOAP_OK; @@ -88237,7 +88237,7 @@ SOAP_FMAC3 struct __ns1__searchByUserID * SOAP_FMAC4 soap_in___ns1__searchByUser SOAP_FMAC3 int SOAP_FMAC4 soap_put___ns1__searchByUserID(struct soap *soap, const struct __ns1__searchByUserID *a, const char *tag, const char *type) { - register int id = 0; + int id = 0; if (soap_out___ns1__searchByUserID(soap, tag?tag:"-ns1:searchByUserID", id, a, type)) return soap->error; return SOAP_OK; @@ -88333,7 +88333,7 @@ SOAP_FMAC3 struct __ns1__getMyInvestigationsIncludesPagination * SOAP_FMAC4 soap SOAP_FMAC3 int SOAP_FMAC4 soap_put___ns1__getMyInvestigationsIncludesPagination(struct soap *soap, const struct __ns1__getMyInvestigationsIncludesPagination *a, const char *tag, const char *type) { - register int id = 0; + int id = 0; if (soap_out___ns1__getMyInvestigationsIncludesPagination(soap, tag?tag:"-ns1:getMyInvestigationsIncludesPagination", id, a, type)) return soap->error; return SOAP_OK; @@ -88429,7 +88429,7 @@ SOAP_FMAC3 struct __ns1__getMyInvestigationsIncludes * SOAP_FMAC4 soap_in___ns1_ SOAP_FMAC3 int SOAP_FMAC4 soap_put___ns1__getMyInvestigationsIncludes(struct soap *soap, const struct __ns1__getMyInvestigationsIncludes *a, const char *tag, const char *type) { - register int id = 0; + int id = 0; if (soap_out___ns1__getMyInvestigationsIncludes(soap, tag?tag:"-ns1:getMyInvestigationsIncludes", id, a, type)) return soap->error; return SOAP_OK; @@ -88525,7 +88525,7 @@ SOAP_FMAC3 struct __ns1__getMyInvestigations * SOAP_FMAC4 soap_in___ns1__getMyIn SOAP_FMAC3 int SOAP_FMAC4 soap_put___ns1__getMyInvestigations(struct soap *soap, const struct __ns1__getMyInvestigations *a, const char *tag, const char *type) { - register int id = 0; + int id = 0; if (soap_out___ns1__getMyInvestigations(soap, tag?tag:"-ns1:getMyInvestigations", id, a, type)) return soap->error; return SOAP_OK; @@ -88621,7 +88621,7 @@ SOAP_FMAC3 struct __ns1__searchByKeywordsAll * SOAP_FMAC4 soap_in___ns1__searchB SOAP_FMAC3 int SOAP_FMAC4 soap_put___ns1__searchByKeywordsAll(struct soap *soap, const struct __ns1__searchByKeywordsAll *a, const char *tag, const char *type) { - register int id = 0; + int id = 0; if (soap_out___ns1__searchByKeywordsAll(soap, tag?tag:"-ns1:searchByKeywordsAll", id, a, type)) return soap->error; return SOAP_OK; @@ -88717,7 +88717,7 @@ SOAP_FMAC3 struct __ns1__searchByKeywords * SOAP_FMAC4 soap_in___ns1__searchByKe SOAP_FMAC3 int SOAP_FMAC4 soap_put___ns1__searchByKeywords(struct soap *soap, const struct __ns1__searchByKeywords *a, const char *tag, const char *type) { - register int id = 0; + int id = 0; if (soap_out___ns1__searchByKeywords(soap, tag?tag:"-ns1:searchByKeywords", id, a, type)) return soap->error; return SOAP_OK; @@ -88813,7 +88813,7 @@ SOAP_FMAC3 struct __ns1__searchByAdvancedPagination * SOAP_FMAC4 soap_in___ns1__ SOAP_FMAC3 int SOAP_FMAC4 soap_put___ns1__searchByAdvancedPagination(struct soap *soap, const struct __ns1__searchByAdvancedPagination *a, const char *tag, const char *type) { - register int id = 0; + int id = 0; if (soap_out___ns1__searchByAdvancedPagination(soap, tag?tag:"-ns1:searchByAdvancedPagination", id, a, type)) return soap->error; return SOAP_OK; @@ -88909,7 +88909,7 @@ SOAP_FMAC3 struct __ns1__searchByAdvanced * SOAP_FMAC4 soap_in___ns1__searchByAd SOAP_FMAC3 int SOAP_FMAC4 soap_put___ns1__searchByAdvanced(struct soap *soap, const struct __ns1__searchByAdvanced *a, const char *tag, const char *type) { - register int id = 0; + int id = 0; if (soap_out___ns1__searchByAdvanced(soap, tag?tag:"-ns1:searchByAdvanced", id, a, type)) return soap->error; return SOAP_OK; @@ -89005,7 +89005,7 @@ SOAP_FMAC3 struct __ns1__getAllKeywords * SOAP_FMAC4 soap_in___ns1__getAllKeywor SOAP_FMAC3 int SOAP_FMAC4 soap_put___ns1__getAllKeywords(struct soap *soap, const struct __ns1__getAllKeywords *a, const char *tag, const char *type) { - register int id = 0; + int id = 0; if (soap_out___ns1__getAllKeywords(soap, tag?tag:"-ns1:getAllKeywords", id, a, type)) return soap->error; return SOAP_OK; @@ -89101,7 +89101,7 @@ SOAP_FMAC3 struct __ns1__getKeywordsForUserType * SOAP_FMAC4 soap_in___ns1__getK SOAP_FMAC3 int SOAP_FMAC4 soap_put___ns1__getKeywordsForUserType(struct soap *soap, const struct __ns1__getKeywordsForUserType *a, const char *tag, const char *type) { - register int id = 0; + int id = 0; if (soap_out___ns1__getKeywordsForUserType(soap, tag?tag:"-ns1:getKeywordsForUserType", id, a, type)) return soap->error; return SOAP_OK; @@ -89197,7 +89197,7 @@ SOAP_FMAC3 struct __ns1__getKeywordsForUserMax * SOAP_FMAC4 soap_in___ns1__getKe SOAP_FMAC3 int SOAP_FMAC4 soap_put___ns1__getKeywordsForUserMax(struct soap *soap, const struct __ns1__getKeywordsForUserMax *a, const char *tag, const char *type) { - register int id = 0; + int id = 0; if (soap_out___ns1__getKeywordsForUserMax(soap, tag?tag:"-ns1:getKeywordsForUserMax", id, a, type)) return soap->error; return SOAP_OK; @@ -89293,7 +89293,7 @@ SOAP_FMAC3 struct __ns1__getKeywordsForUserStartWithMax * SOAP_FMAC4 soap_in___n SOAP_FMAC3 int SOAP_FMAC4 soap_put___ns1__getKeywordsForUserStartWithMax(struct soap *soap, const struct __ns1__getKeywordsForUserStartWithMax *a, const char *tag, const char *type) { - register int id = 0; + int id = 0; if (soap_out___ns1__getKeywordsForUserStartWithMax(soap, tag?tag:"-ns1:getKeywordsForUserStartWithMax", id, a, type)) return soap->error; return SOAP_OK; @@ -89389,7 +89389,7 @@ SOAP_FMAC3 struct __ns1__getKeywordsForUser * SOAP_FMAC4 soap_in___ns1__getKeywo SOAP_FMAC3 int SOAP_FMAC4 soap_put___ns1__getKeywordsForUser(struct soap *soap, const struct __ns1__getKeywordsForUser *a, const char *tag, const char *type) { - register int id = 0; + int id = 0; if (soap_out___ns1__getKeywordsForUser(soap, tag?tag:"-ns1:getKeywordsForUser", id, a, type)) return soap->error; return SOAP_OK; @@ -89485,7 +89485,7 @@ SOAP_FMAC3 struct __ns1__isSessionValid * SOAP_FMAC4 soap_in___ns1__isSessionVal SOAP_FMAC3 int SOAP_FMAC4 soap_put___ns1__isSessionValid(struct soap *soap, const struct __ns1__isSessionValid *a, const char *tag, const char *type) { - register int id = 0; + int id = 0; if (soap_out___ns1__isSessionValid(soap, tag?tag:"-ns1:isSessionValid", id, a, type)) return soap->error; return SOAP_OK; @@ -89581,7 +89581,7 @@ SOAP_FMAC3 struct __ns1__getUserDetails * SOAP_FMAC4 soap_in___ns1__getUserDetai SOAP_FMAC3 int SOAP_FMAC4 soap_put___ns1__getUserDetails(struct soap *soap, const struct __ns1__getUserDetails *a, const char *tag, const char *type) { - register int id = 0; + int id = 0; if (soap_out___ns1__getUserDetails(soap, tag?tag:"-ns1:getUserDetails", id, a, type)) return soap->error; return SOAP_OK; @@ -89677,7 +89677,7 @@ SOAP_FMAC3 struct __ns1__logout * SOAP_FMAC4 soap_in___ns1__logout(struct soap * SOAP_FMAC3 int SOAP_FMAC4 soap_put___ns1__logout(struct soap *soap, const struct __ns1__logout *a, const char *tag, const char *type) { - register int id = 0; + int id = 0; if (soap_out___ns1__logout(soap, tag?tag:"-ns1:logout", id, a, type)) return soap->error; return SOAP_OK; @@ -89773,7 +89773,7 @@ SOAP_FMAC3 struct __ns1__loginLifetime * SOAP_FMAC4 soap_in___ns1__loginLifetime SOAP_FMAC3 int SOAP_FMAC4 soap_put___ns1__loginLifetime(struct soap *soap, const struct __ns1__loginLifetime *a, const char *tag, const char *type) { - register int id = 0; + int id = 0; if (soap_out___ns1__loginLifetime(soap, tag?tag:"-ns1:loginLifetime", id, a, type)) return soap->error; return SOAP_OK; @@ -89869,7 +89869,7 @@ SOAP_FMAC3 struct __ns1__login * SOAP_FMAC4 soap_in___ns1__login(struct soap *so SOAP_FMAC3 int SOAP_FMAC4 soap_put___ns1__login(struct soap *soap, const struct __ns1__login *a, const char *tag, const char *type) { - register int id = 0; + int id = 0; if (soap_out___ns1__login(soap, tag?tag:"-ns1:login", id, a, type)) return soap->error; return SOAP_OK; @@ -90050,7 +90050,7 @@ SOAP_FMAC3 struct SOAP_ENV__Detail * SOAP_FMAC4 soap_in_SOAP_ENV__Detail(struct SOAP_FMAC3 int SOAP_FMAC4 soap_put_SOAP_ENV__Detail(struct soap *soap, const struct SOAP_ENV__Detail *a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_SOAP_ENV__Detail); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_SOAP_ENV__Detail); if (soap_out_SOAP_ENV__Detail(soap, tag?tag:"SOAP-ENV:Detail", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -90137,7 +90137,7 @@ SOAP_FMAC3 struct SOAP_ENV__Reason ** SOAP_FMAC4 soap_in_PointerToSOAP_ENV__Reas SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerToSOAP_ENV__Reason(struct soap *soap, struct SOAP_ENV__Reason *const*a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerToSOAP_ENV__Reason); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerToSOAP_ENV__Reason); if (soap_out_PointerToSOAP_ENV__Reason(soap, tag?tag:"SOAP-ENV:Reason", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -90194,7 +90194,7 @@ SOAP_FMAC3 struct SOAP_ENV__Detail ** SOAP_FMAC4 soap_in_PointerToSOAP_ENV__Deta SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerToSOAP_ENV__Detail(struct soap *soap, struct SOAP_ENV__Detail *const*a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerToSOAP_ENV__Detail); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerToSOAP_ENV__Detail); if (soap_out_PointerToSOAP_ENV__Detail(soap, tag?tag:"SOAP-ENV:Detail", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -90251,7 +90251,7 @@ SOAP_FMAC3 struct SOAP_ENV__Code ** SOAP_FMAC4 soap_in_PointerToSOAP_ENV__Code(s SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerToSOAP_ENV__Code(struct soap *soap, struct SOAP_ENV__Code *const*a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerToSOAP_ENV__Code); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerToSOAP_ENV__Code); if (soap_out_PointerToSOAP_ENV__Code(soap, tag?tag:"SOAP-ENV:Code", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -90310,7 +90310,7 @@ SOAP_FMAC3 ns1__searchFacilityUserByRestrictionResponse ** SOAP_FMAC4 soap_in_Po SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTons1__searchFacilityUserByRestrictionResponse(struct soap *soap, ns1__searchFacilityUserByRestrictionResponse *const*a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__searchFacilityUserByRestrictionResponse); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__searchFacilityUserByRestrictionResponse); if (soap_out_PointerTons1__searchFacilityUserByRestrictionResponse(soap, tag?tag:"ns1:searchFacilityUserByRestrictionResponse", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -90367,7 +90367,7 @@ SOAP_FMAC3 ns1__searchFacilityUserByRestriction ** SOAP_FMAC4 soap_in_PointerTon SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTons1__searchFacilityUserByRestriction(struct soap *soap, ns1__searchFacilityUserByRestriction *const*a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__searchFacilityUserByRestriction); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__searchFacilityUserByRestriction); if (soap_out_PointerTons1__searchFacilityUserByRestriction(soap, tag?tag:"ns1:searchFacilityUserByRestriction", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -90424,7 +90424,7 @@ SOAP_FMAC3 ns1__searchSampleByParameterLogicalResponse ** SOAP_FMAC4 soap_in_Poi SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTons1__searchSampleByParameterLogicalResponse(struct soap *soap, ns1__searchSampleByParameterLogicalResponse *const*a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__searchSampleByParameterLogicalResponse); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__searchSampleByParameterLogicalResponse); if (soap_out_PointerTons1__searchSampleByParameterLogicalResponse(soap, tag?tag:"ns1:searchSampleByParameterLogicalResponse", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -90481,7 +90481,7 @@ SOAP_FMAC3 ns1__searchSampleByParameterLogical ** SOAP_FMAC4 soap_in_PointerTons SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTons1__searchSampleByParameterLogical(struct soap *soap, ns1__searchSampleByParameterLogical *const*a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__searchSampleByParameterLogical); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__searchSampleByParameterLogical); if (soap_out_PointerTons1__searchSampleByParameterLogical(soap, tag?tag:"ns1:searchSampleByParameterLogical", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -90538,7 +90538,7 @@ SOAP_FMAC3 ns1__searchDatasetByParameterLogicalResponse ** SOAP_FMAC4 soap_in_Po SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTons1__searchDatasetByParameterLogicalResponse(struct soap *soap, ns1__searchDatasetByParameterLogicalResponse *const*a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__searchDatasetByParameterLogicalResponse); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__searchDatasetByParameterLogicalResponse); if (soap_out_PointerTons1__searchDatasetByParameterLogicalResponse(soap, tag?tag:"ns1:searchDatasetByParameterLogicalResponse", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -90595,7 +90595,7 @@ SOAP_FMAC3 ns1__searchDatasetByParameterLogical ** SOAP_FMAC4 soap_in_PointerTon SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTons1__searchDatasetByParameterLogical(struct soap *soap, ns1__searchDatasetByParameterLogical *const*a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__searchDatasetByParameterLogical); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__searchDatasetByParameterLogical); if (soap_out_PointerTons1__searchDatasetByParameterLogical(soap, tag?tag:"ns1:searchDatasetByParameterLogical", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -90652,7 +90652,7 @@ SOAP_FMAC3 ns1__searchDatafileByParameterLogicalResponse ** SOAP_FMAC4 soap_in_P SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTons1__searchDatafileByParameterLogicalResponse(struct soap *soap, ns1__searchDatafileByParameterLogicalResponse *const*a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__searchDatafileByParameterLogicalResponse); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__searchDatafileByParameterLogicalResponse); if (soap_out_PointerTons1__searchDatafileByParameterLogicalResponse(soap, tag?tag:"ns1:searchDatafileByParameterLogicalResponse", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -90709,7 +90709,7 @@ SOAP_FMAC3 ns1__searchDatafileByParameterLogical ** SOAP_FMAC4 soap_in_PointerTo SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTons1__searchDatafileByParameterLogical(struct soap *soap, ns1__searchDatafileByParameterLogical *const*a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__searchDatafileByParameterLogical); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__searchDatafileByParameterLogical); if (soap_out_PointerTons1__searchDatafileByParameterLogical(soap, tag?tag:"ns1:searchDatafileByParameterLogical", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -90766,7 +90766,7 @@ SOAP_FMAC3 ns1__searchInvestigationByParameterLogicalResponse ** SOAP_FMAC4 soap SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTons1__searchInvestigationByParameterLogicalResponse(struct soap *soap, ns1__searchInvestigationByParameterLogicalResponse *const*a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__searchInvestigationByParameterLogicalResponse); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__searchInvestigationByParameterLogicalResponse); if (soap_out_PointerTons1__searchInvestigationByParameterLogicalResponse(soap, tag?tag:"ns1:searchInvestigationByParameterLogicalResponse", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -90823,7 +90823,7 @@ SOAP_FMAC3 ns1__searchInvestigationByParameterLogical ** SOAP_FMAC4 soap_in_Poin SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTons1__searchInvestigationByParameterLogical(struct soap *soap, ns1__searchInvestigationByParameterLogical *const*a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__searchInvestigationByParameterLogical); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__searchInvestigationByParameterLogical); if (soap_out_PointerTons1__searchInvestigationByParameterLogical(soap, tag?tag:"ns1:searchInvestigationByParameterLogical", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -90880,7 +90880,7 @@ SOAP_FMAC3 ns1__searchDatafileByRestrictionLogicalResponse ** SOAP_FMAC4 soap_in SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTons1__searchDatafileByRestrictionLogicalResponse(struct soap *soap, ns1__searchDatafileByRestrictionLogicalResponse *const*a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__searchDatafileByRestrictionLogicalResponse); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__searchDatafileByRestrictionLogicalResponse); if (soap_out_PointerTons1__searchDatafileByRestrictionLogicalResponse(soap, tag?tag:"ns1:searchDatafileByRestrictionLogicalResponse", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -90937,7 +90937,7 @@ SOAP_FMAC3 ns1__searchDatafileByRestrictionLogical ** SOAP_FMAC4 soap_in_Pointer SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTons1__searchDatafileByRestrictionLogical(struct soap *soap, ns1__searchDatafileByRestrictionLogical *const*a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__searchDatafileByRestrictionLogical); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__searchDatafileByRestrictionLogical); if (soap_out_PointerTons1__searchDatafileByRestrictionLogical(soap, tag?tag:"ns1:searchDatafileByRestrictionLogical", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -90994,7 +90994,7 @@ SOAP_FMAC3 ns1__searchInvestigationByRestrictionLogicalResponse ** SOAP_FMAC4 so SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTons1__searchInvestigationByRestrictionLogicalResponse(struct soap *soap, ns1__searchInvestigationByRestrictionLogicalResponse *const*a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__searchInvestigationByRestrictionLogicalResponse); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__searchInvestigationByRestrictionLogicalResponse); if (soap_out_PointerTons1__searchInvestigationByRestrictionLogicalResponse(soap, tag?tag:"ns1:searchInvestigationByRestrictionLogicalResponse", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -91051,7 +91051,7 @@ SOAP_FMAC3 ns1__searchInvestigationByRestrictionLogical ** SOAP_FMAC4 soap_in_Po SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTons1__searchInvestigationByRestrictionLogical(struct soap *soap, ns1__searchInvestigationByRestrictionLogical *const*a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__searchInvestigationByRestrictionLogical); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__searchInvestigationByRestrictionLogical); if (soap_out_PointerTons1__searchInvestigationByRestrictionLogical(soap, tag?tag:"ns1:searchInvestigationByRestrictionLogical", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -91108,7 +91108,7 @@ SOAP_FMAC3 ns1__searchDatasetByRestrictionLogicalResponse ** SOAP_FMAC4 soap_in_ SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTons1__searchDatasetByRestrictionLogicalResponse(struct soap *soap, ns1__searchDatasetByRestrictionLogicalResponse *const*a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__searchDatasetByRestrictionLogicalResponse); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__searchDatasetByRestrictionLogicalResponse); if (soap_out_PointerTons1__searchDatasetByRestrictionLogicalResponse(soap, tag?tag:"ns1:searchDatasetByRestrictionLogicalResponse", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -91165,7 +91165,7 @@ SOAP_FMAC3 ns1__searchDatasetByRestrictionLogical ** SOAP_FMAC4 soap_in_PointerT SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTons1__searchDatasetByRestrictionLogical(struct soap *soap, ns1__searchDatasetByRestrictionLogical *const*a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__searchDatasetByRestrictionLogical); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__searchDatasetByRestrictionLogical); if (soap_out_PointerTons1__searchDatasetByRestrictionLogical(soap, tag?tag:"ns1:searchDatasetByRestrictionLogical", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -91222,7 +91222,7 @@ SOAP_FMAC3 ns1__searchSampleByRestrictionLogicalResponse ** SOAP_FMAC4 soap_in_P SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTons1__searchSampleByRestrictionLogicalResponse(struct soap *soap, ns1__searchSampleByRestrictionLogicalResponse *const*a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__searchSampleByRestrictionLogicalResponse); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__searchSampleByRestrictionLogicalResponse); if (soap_out_PointerTons1__searchSampleByRestrictionLogicalResponse(soap, tag?tag:"ns1:searchSampleByRestrictionLogicalResponse", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -91279,7 +91279,7 @@ SOAP_FMAC3 ns1__searchSampleByRestrictionLogical ** SOAP_FMAC4 soap_in_PointerTo SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTons1__searchSampleByRestrictionLogical(struct soap *soap, ns1__searchSampleByRestrictionLogical *const*a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__searchSampleByRestrictionLogical); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__searchSampleByRestrictionLogical); if (soap_out_PointerTons1__searchSampleByRestrictionLogical(soap, tag?tag:"ns1:searchSampleByRestrictionLogical", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -91336,7 +91336,7 @@ SOAP_FMAC3 ns1__searchSampleByRestrictionComparisonResponse ** SOAP_FMAC4 soap_i SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTons1__searchSampleByRestrictionComparisonResponse(struct soap *soap, ns1__searchSampleByRestrictionComparisonResponse *const*a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__searchSampleByRestrictionComparisonResponse); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__searchSampleByRestrictionComparisonResponse); if (soap_out_PointerTons1__searchSampleByRestrictionComparisonResponse(soap, tag?tag:"ns1:searchSampleByRestrictionComparisonResponse", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -91393,7 +91393,7 @@ SOAP_FMAC3 ns1__searchSampleByRestrictionComparison ** SOAP_FMAC4 soap_in_Pointe SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTons1__searchSampleByRestrictionComparison(struct soap *soap, ns1__searchSampleByRestrictionComparison *const*a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__searchSampleByRestrictionComparison); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__searchSampleByRestrictionComparison); if (soap_out_PointerTons1__searchSampleByRestrictionComparison(soap, tag?tag:"ns1:searchSampleByRestrictionComparison", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -91450,7 +91450,7 @@ SOAP_FMAC3 ns1__searchDatafileByRestrictionComparisonResponse ** SOAP_FMAC4 soap SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTons1__searchDatafileByRestrictionComparisonResponse(struct soap *soap, ns1__searchDatafileByRestrictionComparisonResponse *const*a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__searchDatafileByRestrictionComparisonResponse); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__searchDatafileByRestrictionComparisonResponse); if (soap_out_PointerTons1__searchDatafileByRestrictionComparisonResponse(soap, tag?tag:"ns1:searchDatafileByRestrictionComparisonResponse", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -91507,7 +91507,7 @@ SOAP_FMAC3 ns1__searchDatafileByRestrictionComparison ** SOAP_FMAC4 soap_in_Poin SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTons1__searchDatafileByRestrictionComparison(struct soap *soap, ns1__searchDatafileByRestrictionComparison *const*a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__searchDatafileByRestrictionComparison); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__searchDatafileByRestrictionComparison); if (soap_out_PointerTons1__searchDatafileByRestrictionComparison(soap, tag?tag:"ns1:searchDatafileByRestrictionComparison", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -91564,7 +91564,7 @@ SOAP_FMAC3 ns1__searchDatasetByRestrictionComparisonResponse ** SOAP_FMAC4 soap_ SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTons1__searchDatasetByRestrictionComparisonResponse(struct soap *soap, ns1__searchDatasetByRestrictionComparisonResponse *const*a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__searchDatasetByRestrictionComparisonResponse); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__searchDatasetByRestrictionComparisonResponse); if (soap_out_PointerTons1__searchDatasetByRestrictionComparisonResponse(soap, tag?tag:"ns1:searchDatasetByRestrictionComparisonResponse", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -91621,7 +91621,7 @@ SOAP_FMAC3 ns1__searchDatasetByRestrictionComparison ** SOAP_FMAC4 soap_in_Point SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTons1__searchDatasetByRestrictionComparison(struct soap *soap, ns1__searchDatasetByRestrictionComparison *const*a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__searchDatasetByRestrictionComparison); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__searchDatasetByRestrictionComparison); if (soap_out_PointerTons1__searchDatasetByRestrictionComparison(soap, tag?tag:"ns1:searchDatasetByRestrictionComparison", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -91678,7 +91678,7 @@ SOAP_FMAC3 ns1__searchInvestigationByRestrictionComparasionResponse ** SOAP_FMAC SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTons1__searchInvestigationByRestrictionComparasionResponse(struct soap *soap, ns1__searchInvestigationByRestrictionComparasionResponse *const*a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__searchInvestigationByRestrictionComparasionResponse); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__searchInvestigationByRestrictionComparasionResponse); if (soap_out_PointerTons1__searchInvestigationByRestrictionComparasionResponse(soap, tag?tag:"ns1:searchInvestigationByRestrictionComparasionResponse", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -91735,7 +91735,7 @@ SOAP_FMAC3 ns1__searchInvestigationByRestrictionComparasion ** SOAP_FMAC4 soap_i SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTons1__searchInvestigationByRestrictionComparasion(struct soap *soap, ns1__searchInvestigationByRestrictionComparasion *const*a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__searchInvestigationByRestrictionComparasion); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__searchInvestigationByRestrictionComparasion); if (soap_out_PointerTons1__searchInvestigationByRestrictionComparasion(soap, tag?tag:"ns1:searchInvestigationByRestrictionComparasion", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -91792,7 +91792,7 @@ SOAP_FMAC3 ns1__searchSampleByRestrictionResponse ** SOAP_FMAC4 soap_in_PointerT SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTons1__searchSampleByRestrictionResponse(struct soap *soap, ns1__searchSampleByRestrictionResponse *const*a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__searchSampleByRestrictionResponse); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__searchSampleByRestrictionResponse); if (soap_out_PointerTons1__searchSampleByRestrictionResponse(soap, tag?tag:"ns1:searchSampleByRestrictionResponse", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -91849,7 +91849,7 @@ SOAP_FMAC3 ns1__searchSampleByRestriction ** SOAP_FMAC4 soap_in_PointerTons1__se SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTons1__searchSampleByRestriction(struct soap *soap, ns1__searchSampleByRestriction *const*a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__searchSampleByRestriction); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__searchSampleByRestriction); if (soap_out_PointerTons1__searchSampleByRestriction(soap, tag?tag:"ns1:searchSampleByRestriction", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -91906,7 +91906,7 @@ SOAP_FMAC3 ns1__searchDatafileByRestrictionResponse ** SOAP_FMAC4 soap_in_Pointe SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTons1__searchDatafileByRestrictionResponse(struct soap *soap, ns1__searchDatafileByRestrictionResponse *const*a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__searchDatafileByRestrictionResponse); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__searchDatafileByRestrictionResponse); if (soap_out_PointerTons1__searchDatafileByRestrictionResponse(soap, tag?tag:"ns1:searchDatafileByRestrictionResponse", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -91963,7 +91963,7 @@ SOAP_FMAC3 ns1__searchDatafileByRestriction ** SOAP_FMAC4 soap_in_PointerTons1__ SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTons1__searchDatafileByRestriction(struct soap *soap, ns1__searchDatafileByRestriction *const*a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__searchDatafileByRestriction); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__searchDatafileByRestriction); if (soap_out_PointerTons1__searchDatafileByRestriction(soap, tag?tag:"ns1:searchDatafileByRestriction", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -92020,7 +92020,7 @@ SOAP_FMAC3 ns1__searchDatasetByRestrictionResponse ** SOAP_FMAC4 soap_in_Pointer SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTons1__searchDatasetByRestrictionResponse(struct soap *soap, ns1__searchDatasetByRestrictionResponse *const*a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__searchDatasetByRestrictionResponse); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__searchDatasetByRestrictionResponse); if (soap_out_PointerTons1__searchDatasetByRestrictionResponse(soap, tag?tag:"ns1:searchDatasetByRestrictionResponse", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -92077,7 +92077,7 @@ SOAP_FMAC3 ns1__searchDatasetByRestriction ** SOAP_FMAC4 soap_in_PointerTons1__s SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTons1__searchDatasetByRestriction(struct soap *soap, ns1__searchDatasetByRestriction *const*a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__searchDatasetByRestriction); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__searchDatasetByRestriction); if (soap_out_PointerTons1__searchDatasetByRestriction(soap, tag?tag:"ns1:searchDatasetByRestriction", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -92134,7 +92134,7 @@ SOAP_FMAC3 ns1__searchInvestigationByRestrictionResponse ** SOAP_FMAC4 soap_in_P SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTons1__searchInvestigationByRestrictionResponse(struct soap *soap, ns1__searchInvestigationByRestrictionResponse *const*a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__searchInvestigationByRestrictionResponse); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__searchInvestigationByRestrictionResponse); if (soap_out_PointerTons1__searchInvestigationByRestrictionResponse(soap, tag?tag:"ns1:searchInvestigationByRestrictionResponse", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -92191,7 +92191,7 @@ SOAP_FMAC3 ns1__searchInvestigationByRestriction ** SOAP_FMAC4 soap_in_PointerTo SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTons1__searchInvestigationByRestriction(struct soap *soap, ns1__searchInvestigationByRestriction *const*a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__searchInvestigationByRestriction); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__searchInvestigationByRestriction); if (soap_out_PointerTons1__searchInvestigationByRestriction(soap, tag?tag:"ns1:searchInvestigationByRestriction", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -92248,7 +92248,7 @@ SOAP_FMAC3 ns1__searchInvestigationByParameterRestrictionResponse ** SOAP_FMAC4 SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTons1__searchInvestigationByParameterRestrictionResponse(struct soap *soap, ns1__searchInvestigationByParameterRestrictionResponse *const*a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__searchInvestigationByParameterRestrictionResponse); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__searchInvestigationByParameterRestrictionResponse); if (soap_out_PointerTons1__searchInvestigationByParameterRestrictionResponse(soap, tag?tag:"ns1:searchInvestigationByParameterRestrictionResponse", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -92305,7 +92305,7 @@ SOAP_FMAC3 ns1__searchInvestigationByParameterRestriction ** SOAP_FMAC4 soap_in_ SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTons1__searchInvestigationByParameterRestriction(struct soap *soap, ns1__searchInvestigationByParameterRestriction *const*a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__searchInvestigationByParameterRestriction); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__searchInvestigationByParameterRestriction); if (soap_out_PointerTons1__searchInvestigationByParameterRestriction(soap, tag?tag:"ns1:searchInvestigationByParameterRestriction", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -92362,7 +92362,7 @@ SOAP_FMAC3 ns1__searchDatafileByParameterRestrictionResponse ** SOAP_FMAC4 soap_ SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTons1__searchDatafileByParameterRestrictionResponse(struct soap *soap, ns1__searchDatafileByParameterRestrictionResponse *const*a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__searchDatafileByParameterRestrictionResponse); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__searchDatafileByParameterRestrictionResponse); if (soap_out_PointerTons1__searchDatafileByParameterRestrictionResponse(soap, tag?tag:"ns1:searchDatafileByParameterRestrictionResponse", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -92419,7 +92419,7 @@ SOAP_FMAC3 ns1__searchDatafileByParameterRestriction ** SOAP_FMAC4 soap_in_Point SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTons1__searchDatafileByParameterRestriction(struct soap *soap, ns1__searchDatafileByParameterRestriction *const*a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__searchDatafileByParameterRestriction); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__searchDatafileByParameterRestriction); if (soap_out_PointerTons1__searchDatafileByParameterRestriction(soap, tag?tag:"ns1:searchDatafileByParameterRestriction", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -92476,7 +92476,7 @@ SOAP_FMAC3 ns1__searchSampleByParameterRestrictionResponse ** SOAP_FMAC4 soap_in SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTons1__searchSampleByParameterRestrictionResponse(struct soap *soap, ns1__searchSampleByParameterRestrictionResponse *const*a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__searchSampleByParameterRestrictionResponse); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__searchSampleByParameterRestrictionResponse); if (soap_out_PointerTons1__searchSampleByParameterRestrictionResponse(soap, tag?tag:"ns1:searchSampleByParameterRestrictionResponse", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -92533,7 +92533,7 @@ SOAP_FMAC3 ns1__searchSampleByParameterRestriction ** SOAP_FMAC4 soap_in_Pointer SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTons1__searchSampleByParameterRestriction(struct soap *soap, ns1__searchSampleByParameterRestriction *const*a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__searchSampleByParameterRestriction); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__searchSampleByParameterRestriction); if (soap_out_PointerTons1__searchSampleByParameterRestriction(soap, tag?tag:"ns1:searchSampleByParameterRestriction", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -92590,7 +92590,7 @@ SOAP_FMAC3 ns1__searchDatasetByParameterRestrictionResponse ** SOAP_FMAC4 soap_i SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTons1__searchDatasetByParameterRestrictionResponse(struct soap *soap, ns1__searchDatasetByParameterRestrictionResponse *const*a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__searchDatasetByParameterRestrictionResponse); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__searchDatasetByParameterRestrictionResponse); if (soap_out_PointerTons1__searchDatasetByParameterRestrictionResponse(soap, tag?tag:"ns1:searchDatasetByParameterRestrictionResponse", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -92647,7 +92647,7 @@ SOAP_FMAC3 ns1__searchDatasetByParameterRestriction ** SOAP_FMAC4 soap_in_Pointe SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTons1__searchDatasetByParameterRestriction(struct soap *soap, ns1__searchDatasetByParameterRestriction *const*a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__searchDatasetByParameterRestriction); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__searchDatasetByParameterRestriction); if (soap_out_PointerTons1__searchDatasetByParameterRestriction(soap, tag?tag:"ns1:searchDatasetByParameterRestriction", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -92704,7 +92704,7 @@ SOAP_FMAC3 ns1__getParameterByUnitsResponse ** SOAP_FMAC4 soap_in_PointerTons1__ SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTons1__getParameterByUnitsResponse(struct soap *soap, ns1__getParameterByUnitsResponse *const*a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__getParameterByUnitsResponse); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__getParameterByUnitsResponse); if (soap_out_PointerTons1__getParameterByUnitsResponse(soap, tag?tag:"ns1:getParameterByUnitsResponse", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -92761,7 +92761,7 @@ SOAP_FMAC3 ns1__getParameterByUnits ** SOAP_FMAC4 soap_in_PointerTons1__getParam SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTons1__getParameterByUnits(struct soap *soap, ns1__getParameterByUnits *const*a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__getParameterByUnits); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__getParameterByUnits); if (soap_out_PointerTons1__getParameterByUnits(soap, tag?tag:"ns1:getParameterByUnits", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -92818,7 +92818,7 @@ SOAP_FMAC3 ns1__getParameterByRestrictionResponse ** SOAP_FMAC4 soap_in_PointerT SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTons1__getParameterByRestrictionResponse(struct soap *soap, ns1__getParameterByRestrictionResponse *const*a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__getParameterByRestrictionResponse); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__getParameterByRestrictionResponse); if (soap_out_PointerTons1__getParameterByRestrictionResponse(soap, tag?tag:"ns1:getParameterByRestrictionResponse", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -92875,7 +92875,7 @@ SOAP_FMAC3 ns1__getParameterByRestriction ** SOAP_FMAC4 soap_in_PointerTons1__ge SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTons1__getParameterByRestriction(struct soap *soap, ns1__getParameterByRestriction *const*a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__getParameterByRestriction); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__getParameterByRestriction); if (soap_out_PointerTons1__getParameterByRestriction(soap, tag?tag:"ns1:getParameterByRestriction", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -92932,7 +92932,7 @@ SOAP_FMAC3 ns1__getParameterByNameResponse ** SOAP_FMAC4 soap_in_PointerTons1__g SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTons1__getParameterByNameResponse(struct soap *soap, ns1__getParameterByNameResponse *const*a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__getParameterByNameResponse); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__getParameterByNameResponse); if (soap_out_PointerTons1__getParameterByNameResponse(soap, tag?tag:"ns1:getParameterByNameResponse", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -92989,7 +92989,7 @@ SOAP_FMAC3 ns1__getParameterByName ** SOAP_FMAC4 soap_in_PointerTons1__getParame SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTons1__getParameterByName(struct soap *soap, ns1__getParameterByName *const*a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__getParameterByName); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__getParameterByName); if (soap_out_PointerTons1__getParameterByName(soap, tag?tag:"ns1:getParameterByName", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -93046,7 +93046,7 @@ SOAP_FMAC3 ns1__getParameterByNameUnitsResponse ** SOAP_FMAC4 soap_in_PointerTon SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTons1__getParameterByNameUnitsResponse(struct soap *soap, ns1__getParameterByNameUnitsResponse *const*a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__getParameterByNameUnitsResponse); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__getParameterByNameUnitsResponse); if (soap_out_PointerTons1__getParameterByNameUnitsResponse(soap, tag?tag:"ns1:getParameterByNameUnitsResponse", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -93103,7 +93103,7 @@ SOAP_FMAC3 ns1__getParameterByNameUnits ** SOAP_FMAC4 soap_in_PointerTons1__getP SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTons1__getParameterByNameUnits(struct soap *soap, ns1__getParameterByNameUnits *const*a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__getParameterByNameUnits); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__getParameterByNameUnits); if (soap_out_PointerTons1__getParameterByNameUnits(soap, tag?tag:"ns1:getParameterByNameUnits", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -93160,7 +93160,7 @@ SOAP_FMAC3 ns1__searchSampleByParameterResponse ** SOAP_FMAC4 soap_in_PointerTon SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTons1__searchSampleByParameterResponse(struct soap *soap, ns1__searchSampleByParameterResponse *const*a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__searchSampleByParameterResponse); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__searchSampleByParameterResponse); if (soap_out_PointerTons1__searchSampleByParameterResponse(soap, tag?tag:"ns1:searchSampleByParameterResponse", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -93217,7 +93217,7 @@ SOAP_FMAC3 ns1__searchSampleByParameter ** SOAP_FMAC4 soap_in_PointerTons1__sear SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTons1__searchSampleByParameter(struct soap *soap, ns1__searchSampleByParameter *const*a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__searchSampleByParameter); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__searchSampleByParameter); if (soap_out_PointerTons1__searchSampleByParameter(soap, tag?tag:"ns1:searchSampleByParameter", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -93274,7 +93274,7 @@ SOAP_FMAC3 ns1__searchDatasetByParameterResponse ** SOAP_FMAC4 soap_in_PointerTo SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTons1__searchDatasetByParameterResponse(struct soap *soap, ns1__searchDatasetByParameterResponse *const*a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__searchDatasetByParameterResponse); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__searchDatasetByParameterResponse); if (soap_out_PointerTons1__searchDatasetByParameterResponse(soap, tag?tag:"ns1:searchDatasetByParameterResponse", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -93331,7 +93331,7 @@ SOAP_FMAC3 ns1__searchDatasetByParameter ** SOAP_FMAC4 soap_in_PointerTons1__sea SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTons1__searchDatasetByParameter(struct soap *soap, ns1__searchDatasetByParameter *const*a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__searchDatasetByParameter); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__searchDatasetByParameter); if (soap_out_PointerTons1__searchDatasetByParameter(soap, tag?tag:"ns1:searchDatasetByParameter", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -93388,7 +93388,7 @@ SOAP_FMAC3 ns1__searchDatafileByParameterResponse ** SOAP_FMAC4 soap_in_PointerT SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTons1__searchDatafileByParameterResponse(struct soap *soap, ns1__searchDatafileByParameterResponse *const*a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__searchDatafileByParameterResponse); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__searchDatafileByParameterResponse); if (soap_out_PointerTons1__searchDatafileByParameterResponse(soap, tag?tag:"ns1:searchDatafileByParameterResponse", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -93445,7 +93445,7 @@ SOAP_FMAC3 ns1__searchDatafileByParameter ** SOAP_FMAC4 soap_in_PointerTons1__se SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTons1__searchDatafileByParameter(struct soap *soap, ns1__searchDatafileByParameter *const*a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__searchDatafileByParameter); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__searchDatafileByParameter); if (soap_out_PointerTons1__searchDatafileByParameter(soap, tag?tag:"ns1:searchDatafileByParameter", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -93502,7 +93502,7 @@ SOAP_FMAC3 ns1__searchInvestigationByParameterResponse ** SOAP_FMAC4 soap_in_Poi SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTons1__searchInvestigationByParameterResponse(struct soap *soap, ns1__searchInvestigationByParameterResponse *const*a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__searchInvestigationByParameterResponse); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__searchInvestigationByParameterResponse); if (soap_out_PointerTons1__searchInvestigationByParameterResponse(soap, tag?tag:"ns1:searchInvestigationByParameterResponse", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -93559,7 +93559,7 @@ SOAP_FMAC3 ns1__searchInvestigationByParameter ** SOAP_FMAC4 soap_in_PointerTons SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTons1__searchInvestigationByParameter(struct soap *soap, ns1__searchInvestigationByParameter *const*a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__searchInvestigationByParameter); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__searchInvestigationByParameter); if (soap_out_PointerTons1__searchInvestigationByParameter(soap, tag?tag:"ns1:searchInvestigationByParameter", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -93616,7 +93616,7 @@ SOAP_FMAC3 ns1__searchSampleByParameterComparisonResponse ** SOAP_FMAC4 soap_in_ SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTons1__searchSampleByParameterComparisonResponse(struct soap *soap, ns1__searchSampleByParameterComparisonResponse *const*a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__searchSampleByParameterComparisonResponse); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__searchSampleByParameterComparisonResponse); if (soap_out_PointerTons1__searchSampleByParameterComparisonResponse(soap, tag?tag:"ns1:searchSampleByParameterComparisonResponse", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -93673,7 +93673,7 @@ SOAP_FMAC3 ns1__searchSampleByParameterComparison ** SOAP_FMAC4 soap_in_PointerT SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTons1__searchSampleByParameterComparison(struct soap *soap, ns1__searchSampleByParameterComparison *const*a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__searchSampleByParameterComparison); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__searchSampleByParameterComparison); if (soap_out_PointerTons1__searchSampleByParameterComparison(soap, tag?tag:"ns1:searchSampleByParameterComparison", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -93730,7 +93730,7 @@ SOAP_FMAC3 ns1__searchDatasetByParameterComparisonResponse ** SOAP_FMAC4 soap_in SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTons1__searchDatasetByParameterComparisonResponse(struct soap *soap, ns1__searchDatasetByParameterComparisonResponse *const*a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__searchDatasetByParameterComparisonResponse); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__searchDatasetByParameterComparisonResponse); if (soap_out_PointerTons1__searchDatasetByParameterComparisonResponse(soap, tag?tag:"ns1:searchDatasetByParameterComparisonResponse", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -93787,7 +93787,7 @@ SOAP_FMAC3 ns1__searchDatasetByParameterComparison ** SOAP_FMAC4 soap_in_Pointer SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTons1__searchDatasetByParameterComparison(struct soap *soap, ns1__searchDatasetByParameterComparison *const*a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__searchDatasetByParameterComparison); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__searchDatasetByParameterComparison); if (soap_out_PointerTons1__searchDatasetByParameterComparison(soap, tag?tag:"ns1:searchDatasetByParameterComparison", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -93844,7 +93844,7 @@ SOAP_FMAC3 ns1__searchDatafileByParameterComparisonResponse ** SOAP_FMAC4 soap_i SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTons1__searchDatafileByParameterComparisonResponse(struct soap *soap, ns1__searchDatafileByParameterComparisonResponse *const*a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__searchDatafileByParameterComparisonResponse); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__searchDatafileByParameterComparisonResponse); if (soap_out_PointerTons1__searchDatafileByParameterComparisonResponse(soap, tag?tag:"ns1:searchDatafileByParameterComparisonResponse", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -93901,7 +93901,7 @@ SOAP_FMAC3 ns1__searchDatafileByParameterComparison ** SOAP_FMAC4 soap_in_Pointe SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTons1__searchDatafileByParameterComparison(struct soap *soap, ns1__searchDatafileByParameterComparison *const*a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__searchDatafileByParameterComparison); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__searchDatafileByParameterComparison); if (soap_out_PointerTons1__searchDatafileByParameterComparison(soap, tag?tag:"ns1:searchDatafileByParameterComparison", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -93958,7 +93958,7 @@ SOAP_FMAC3 ns1__searchInvestigationByParameterComparisonResponse ** SOAP_FMAC4 s SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTons1__searchInvestigationByParameterComparisonResponse(struct soap *soap, ns1__searchInvestigationByParameterComparisonResponse *const*a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__searchInvestigationByParameterComparisonResponse); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__searchInvestigationByParameterComparisonResponse); if (soap_out_PointerTons1__searchInvestigationByParameterComparisonResponse(soap, tag?tag:"ns1:searchInvestigationByParameterComparisonResponse", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -94015,7 +94015,7 @@ SOAP_FMAC3 ns1__searchInvestigationByParameterComparison ** SOAP_FMAC4 soap_in_P SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTons1__searchInvestigationByParameterComparison(struct soap *soap, ns1__searchInvestigationByParameterComparison *const*a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__searchInvestigationByParameterComparison); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__searchInvestigationByParameterComparison); if (soap_out_PointerTons1__searchInvestigationByParameterComparison(soap, tag?tag:"ns1:searchInvestigationByParameterComparison", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -94072,7 +94072,7 @@ SOAP_FMAC3 ns1__searchSampleByParameterConditionResponse ** SOAP_FMAC4 soap_in_P SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTons1__searchSampleByParameterConditionResponse(struct soap *soap, ns1__searchSampleByParameterConditionResponse *const*a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__searchSampleByParameterConditionResponse); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__searchSampleByParameterConditionResponse); if (soap_out_PointerTons1__searchSampleByParameterConditionResponse(soap, tag?tag:"ns1:searchSampleByParameterConditionResponse", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -94129,7 +94129,7 @@ SOAP_FMAC3 ns1__searchSampleByParameterCondition ** SOAP_FMAC4 soap_in_PointerTo SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTons1__searchSampleByParameterCondition(struct soap *soap, ns1__searchSampleByParameterCondition *const*a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__searchSampleByParameterCondition); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__searchSampleByParameterCondition); if (soap_out_PointerTons1__searchSampleByParameterCondition(soap, tag?tag:"ns1:searchSampleByParameterCondition", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -94186,7 +94186,7 @@ SOAP_FMAC3 ns1__searchDatasetByParameterConditionResponse ** SOAP_FMAC4 soap_in_ SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTons1__searchDatasetByParameterConditionResponse(struct soap *soap, ns1__searchDatasetByParameterConditionResponse *const*a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__searchDatasetByParameterConditionResponse); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__searchDatasetByParameterConditionResponse); if (soap_out_PointerTons1__searchDatasetByParameterConditionResponse(soap, tag?tag:"ns1:searchDatasetByParameterConditionResponse", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -94243,7 +94243,7 @@ SOAP_FMAC3 ns1__searchDatasetByParameterCondition ** SOAP_FMAC4 soap_in_PointerT SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTons1__searchDatasetByParameterCondition(struct soap *soap, ns1__searchDatasetByParameterCondition *const*a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__searchDatasetByParameterCondition); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__searchDatasetByParameterCondition); if (soap_out_PointerTons1__searchDatasetByParameterCondition(soap, tag?tag:"ns1:searchDatasetByParameterCondition", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -94300,7 +94300,7 @@ SOAP_FMAC3 ns1__searchDatafileByParameterConditionResponse ** SOAP_FMAC4 soap_in SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTons1__searchDatafileByParameterConditionResponse(struct soap *soap, ns1__searchDatafileByParameterConditionResponse *const*a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__searchDatafileByParameterConditionResponse); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__searchDatafileByParameterConditionResponse); if (soap_out_PointerTons1__searchDatafileByParameterConditionResponse(soap, tag?tag:"ns1:searchDatafileByParameterConditionResponse", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -94357,7 +94357,7 @@ SOAP_FMAC3 ns1__searchDatafileByParameterCondition ** SOAP_FMAC4 soap_in_Pointer SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTons1__searchDatafileByParameterCondition(struct soap *soap, ns1__searchDatafileByParameterCondition *const*a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__searchDatafileByParameterCondition); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__searchDatafileByParameterCondition); if (soap_out_PointerTons1__searchDatafileByParameterCondition(soap, tag?tag:"ns1:searchDatafileByParameterCondition", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -94414,7 +94414,7 @@ SOAP_FMAC3 ns1__searchInvestigationByParameterConditionResponse ** SOAP_FMAC4 so SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTons1__searchInvestigationByParameterConditionResponse(struct soap *soap, ns1__searchInvestigationByParameterConditionResponse *const*a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__searchInvestigationByParameterConditionResponse); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__searchInvestigationByParameterConditionResponse); if (soap_out_PointerTons1__searchInvestigationByParameterConditionResponse(soap, tag?tag:"ns1:searchInvestigationByParameterConditionResponse", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -94471,7 +94471,7 @@ SOAP_FMAC3 ns1__searchInvestigationByParameterCondition ** SOAP_FMAC4 soap_in_Po SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTons1__searchInvestigationByParameterCondition(struct soap *soap, ns1__searchInvestigationByParameterCondition *const*a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__searchInvestigationByParameterCondition); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__searchInvestigationByParameterCondition); if (soap_out_PointerTons1__searchInvestigationByParameterCondition(soap, tag?tag:"ns1:searchInvestigationByParameterCondition", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -94528,7 +94528,7 @@ SOAP_FMAC3 ns1__getFacilityUserByFederalIdResponse ** SOAP_FMAC4 soap_in_Pointer SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTons1__getFacilityUserByFederalIdResponse(struct soap *soap, ns1__getFacilityUserByFederalIdResponse *const*a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__getFacilityUserByFederalIdResponse); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__getFacilityUserByFederalIdResponse); if (soap_out_PointerTons1__getFacilityUserByFederalIdResponse(soap, tag?tag:"ns1:getFacilityUserByFederalIdResponse", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -94585,7 +94585,7 @@ SOAP_FMAC3 ns1__getFacilityUserByFederalId ** SOAP_FMAC4 soap_in_PointerTons1__g SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTons1__getFacilityUserByFederalId(struct soap *soap, ns1__getFacilityUserByFederalId *const*a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__getFacilityUserByFederalId); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__getFacilityUserByFederalId); if (soap_out_PointerTons1__getFacilityUserByFederalId(soap, tag?tag:"ns1:getFacilityUserByFederalId", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -94642,7 +94642,7 @@ SOAP_FMAC3 ns1__getFacilityUserByFacilityUserIdResponse ** SOAP_FMAC4 soap_in_Po SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTons1__getFacilityUserByFacilityUserIdResponse(struct soap *soap, ns1__getFacilityUserByFacilityUserIdResponse *const*a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__getFacilityUserByFacilityUserIdResponse); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__getFacilityUserByFacilityUserIdResponse); if (soap_out_PointerTons1__getFacilityUserByFacilityUserIdResponse(soap, tag?tag:"ns1:getFacilityUserByFacilityUserIdResponse", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -94699,7 +94699,7 @@ SOAP_FMAC3 ns1__getFacilityUserByFacilityUserId ** SOAP_FMAC4 soap_in_PointerTon SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTons1__getFacilityUserByFacilityUserId(struct soap *soap, ns1__getFacilityUserByFacilityUserId *const*a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__getFacilityUserByFacilityUserId); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__getFacilityUserByFacilityUserId); if (soap_out_PointerTons1__getFacilityUserByFacilityUserId(soap, tag?tag:"ns1:getFacilityUserByFacilityUserId", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -94756,7 +94756,7 @@ SOAP_FMAC3 ns1__getICATAPIVersionResponse ** SOAP_FMAC4 soap_in_PointerTons1__ge SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTons1__getICATAPIVersionResponse(struct soap *soap, ns1__getICATAPIVersionResponse *const*a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__getICATAPIVersionResponse); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__getICATAPIVersionResponse); if (soap_out_PointerTons1__getICATAPIVersionResponse(soap, tag?tag:"ns1:getICATAPIVersionResponse", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -94813,7 +94813,7 @@ SOAP_FMAC3 ns1__getICATAPIVersion ** SOAP_FMAC4 soap_in_PointerTons1__getICATAPI SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTons1__getICATAPIVersion(struct soap *soap, ns1__getICATAPIVersion *const*a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__getICATAPIVersion); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__getICATAPIVersion); if (soap_out_PointerTons1__getICATAPIVersion(soap, tag?tag:"ns1:getICATAPIVersion", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -94870,7 +94870,7 @@ SOAP_FMAC3 ns1__checkDatasetDownloadAccessResponse ** SOAP_FMAC4 soap_in_Pointer SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTons1__checkDatasetDownloadAccessResponse(struct soap *soap, ns1__checkDatasetDownloadAccessResponse *const*a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__checkDatasetDownloadAccessResponse); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__checkDatasetDownloadAccessResponse); if (soap_out_PointerTons1__checkDatasetDownloadAccessResponse(soap, tag?tag:"ns1:checkDatasetDownloadAccessResponse", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -94927,7 +94927,7 @@ SOAP_FMAC3 ns1__checkDatasetDownloadAccess ** SOAP_FMAC4 soap_in_PointerTons1__c SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTons1__checkDatasetDownloadAccess(struct soap *soap, ns1__checkDatasetDownloadAccess *const*a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__checkDatasetDownloadAccess); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__checkDatasetDownloadAccess); if (soap_out_PointerTons1__checkDatasetDownloadAccess(soap, tag?tag:"ns1:checkDatasetDownloadAccess", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -94984,7 +94984,7 @@ SOAP_FMAC3 ns1__checkDatafileDownloadAccessResponse ** SOAP_FMAC4 soap_in_Pointe SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTons1__checkDatafileDownloadAccessResponse(struct soap *soap, ns1__checkDatafileDownloadAccessResponse *const*a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__checkDatafileDownloadAccessResponse); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__checkDatafileDownloadAccessResponse); if (soap_out_PointerTons1__checkDatafileDownloadAccessResponse(soap, tag?tag:"ns1:checkDatafileDownloadAccessResponse", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -95041,7 +95041,7 @@ SOAP_FMAC3 ns1__checkDatafileDownloadAccess ** SOAP_FMAC4 soap_in_PointerTons1__ SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTons1__checkDatafileDownloadAccess(struct soap *soap, ns1__checkDatafileDownloadAccess *const*a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__checkDatafileDownloadAccess); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__checkDatafileDownloadAccess); if (soap_out_PointerTons1__checkDatafileDownloadAccess(soap, tag?tag:"ns1:checkDatafileDownloadAccess", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -95098,7 +95098,7 @@ SOAP_FMAC3 ns1__downloadDatafilesResponse ** SOAP_FMAC4 soap_in_PointerTons1__do SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTons1__downloadDatafilesResponse(struct soap *soap, ns1__downloadDatafilesResponse *const*a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__downloadDatafilesResponse); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__downloadDatafilesResponse); if (soap_out_PointerTons1__downloadDatafilesResponse(soap, tag?tag:"ns1:downloadDatafilesResponse", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -95155,7 +95155,7 @@ SOAP_FMAC3 ns1__downloadDatafiles ** SOAP_FMAC4 soap_in_PointerTons1__downloadDa SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTons1__downloadDatafiles(struct soap *soap, ns1__downloadDatafiles *const*a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__downloadDatafiles); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__downloadDatafiles); if (soap_out_PointerTons1__downloadDatafiles(soap, tag?tag:"ns1:downloadDatafiles", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -95212,7 +95212,7 @@ SOAP_FMAC3 ns1__downloadDatasetResponse ** SOAP_FMAC4 soap_in_PointerTons1__down SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTons1__downloadDatasetResponse(struct soap *soap, ns1__downloadDatasetResponse *const*a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__downloadDatasetResponse); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__downloadDatasetResponse); if (soap_out_PointerTons1__downloadDatasetResponse(soap, tag?tag:"ns1:downloadDatasetResponse", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -95269,7 +95269,7 @@ SOAP_FMAC3 ns1__downloadDataset ** SOAP_FMAC4 soap_in_PointerTons1__downloadData SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTons1__downloadDataset(struct soap *soap, ns1__downloadDataset *const*a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__downloadDataset); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__downloadDataset); if (soap_out_PointerTons1__downloadDataset(soap, tag?tag:"ns1:downloadDataset", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -95326,7 +95326,7 @@ SOAP_FMAC3 ns1__downloadDatafileResponse ** SOAP_FMAC4 soap_in_PointerTons1__dow SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTons1__downloadDatafileResponse(struct soap *soap, ns1__downloadDatafileResponse *const*a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__downloadDatafileResponse); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__downloadDatafileResponse); if (soap_out_PointerTons1__downloadDatafileResponse(soap, tag?tag:"ns1:downloadDatafileResponse", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -95383,7 +95383,7 @@ SOAP_FMAC3 ns1__downloadDatafile ** SOAP_FMAC4 soap_in_PointerTons1__downloadDat SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTons1__downloadDatafile(struct soap *soap, ns1__downloadDatafile *const*a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__downloadDatafile); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__downloadDatafile); if (soap_out_PointerTons1__downloadDatafile(soap, tag?tag:"ns1:downloadDatafile", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -95440,7 +95440,7 @@ SOAP_FMAC3 ns1__ingestMetadataResponse ** SOAP_FMAC4 soap_in_PointerTons1__inges SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTons1__ingestMetadataResponse(struct soap *soap, ns1__ingestMetadataResponse *const*a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__ingestMetadataResponse); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__ingestMetadataResponse); if (soap_out_PointerTons1__ingestMetadataResponse(soap, tag?tag:"ns1:ingestMetadataResponse", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -95497,7 +95497,7 @@ SOAP_FMAC3 ns1__ingestMetadata ** SOAP_FMAC4 soap_in_PointerTons1__ingestMetadat SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTons1__ingestMetadata(struct soap *soap, ns1__ingestMetadata *const*a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__ingestMetadata); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__ingestMetadata); if (soap_out_PointerTons1__ingestMetadata(soap, tag?tag:"ns1:ingestMetadata", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -95554,7 +95554,7 @@ SOAP_FMAC3 ns1__updateAuthorisationResponse ** SOAP_FMAC4 soap_in_PointerTons1__ SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTons1__updateAuthorisationResponse(struct soap *soap, ns1__updateAuthorisationResponse *const*a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__updateAuthorisationResponse); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__updateAuthorisationResponse); if (soap_out_PointerTons1__updateAuthorisationResponse(soap, tag?tag:"ns1:updateAuthorisationResponse", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -95611,7 +95611,7 @@ SOAP_FMAC3 ns1__updateAuthorisation ** SOAP_FMAC4 soap_in_PointerTons1__updateAu SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTons1__updateAuthorisation(struct soap *soap, ns1__updateAuthorisation *const*a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__updateAuthorisation); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__updateAuthorisation); if (soap_out_PointerTons1__updateAuthorisation(soap, tag?tag:"ns1:updateAuthorisation", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -95668,7 +95668,7 @@ SOAP_FMAC3 ns1__removeAuthorisationResponse ** SOAP_FMAC4 soap_in_PointerTons1__ SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTons1__removeAuthorisationResponse(struct soap *soap, ns1__removeAuthorisationResponse *const*a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__removeAuthorisationResponse); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__removeAuthorisationResponse); if (soap_out_PointerTons1__removeAuthorisationResponse(soap, tag?tag:"ns1:removeAuthorisationResponse", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -95725,7 +95725,7 @@ SOAP_FMAC3 ns1__removeAuthorisation ** SOAP_FMAC4 soap_in_PointerTons1__removeAu SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTons1__removeAuthorisation(struct soap *soap, ns1__removeAuthorisation *const*a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__removeAuthorisation); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__removeAuthorisation); if (soap_out_PointerTons1__removeAuthorisation(soap, tag?tag:"ns1:removeAuthorisation", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -95782,7 +95782,7 @@ SOAP_FMAC3 ns1__deleteAuthorisationResponse ** SOAP_FMAC4 soap_in_PointerTons1__ SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTons1__deleteAuthorisationResponse(struct soap *soap, ns1__deleteAuthorisationResponse *const*a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__deleteAuthorisationResponse); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__deleteAuthorisationResponse); if (soap_out_PointerTons1__deleteAuthorisationResponse(soap, tag?tag:"ns1:deleteAuthorisationResponse", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -95839,7 +95839,7 @@ SOAP_FMAC3 ns1__deleteAuthorisation ** SOAP_FMAC4 soap_in_PointerTons1__deleteAu SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTons1__deleteAuthorisation(struct soap *soap, ns1__deleteAuthorisation *const*a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__deleteAuthorisation); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__deleteAuthorisation); if (soap_out_PointerTons1__deleteAuthorisation(soap, tag?tag:"ns1:deleteAuthorisation", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -95896,7 +95896,7 @@ SOAP_FMAC3 ns1__addAuthorisationResponse ** SOAP_FMAC4 soap_in_PointerTons1__add SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTons1__addAuthorisationResponse(struct soap *soap, ns1__addAuthorisationResponse *const*a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__addAuthorisationResponse); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__addAuthorisationResponse); if (soap_out_PointerTons1__addAuthorisationResponse(soap, tag?tag:"ns1:addAuthorisationResponse", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -95953,7 +95953,7 @@ SOAP_FMAC3 ns1__addAuthorisation ** SOAP_FMAC4 soap_in_PointerTons1__addAuthoris SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTons1__addAuthorisation(struct soap *soap, ns1__addAuthorisation *const*a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__addAuthorisation); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__addAuthorisation); if (soap_out_PointerTons1__addAuthorisation(soap, tag?tag:"ns1:addAuthorisation", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -96010,7 +96010,7 @@ SOAP_FMAC3 ns1__getAuthorisationsResponse ** SOAP_FMAC4 soap_in_PointerTons1__ge SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTons1__getAuthorisationsResponse(struct soap *soap, ns1__getAuthorisationsResponse *const*a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__getAuthorisationsResponse); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__getAuthorisationsResponse); if (soap_out_PointerTons1__getAuthorisationsResponse(soap, tag?tag:"ns1:getAuthorisationsResponse", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -96067,7 +96067,7 @@ SOAP_FMAC3 ns1__getAuthorisations ** SOAP_FMAC4 soap_in_PointerTons1__getAuthori SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTons1__getAuthorisations(struct soap *soap, ns1__getAuthorisations *const*a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__getAuthorisations); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__getAuthorisations); if (soap_out_PointerTons1__getAuthorisations(soap, tag?tag:"ns1:getAuthorisations", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -96124,7 +96124,7 @@ SOAP_FMAC3 ns1__removeDataFileParameterResponse ** SOAP_FMAC4 soap_in_PointerTon SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTons1__removeDataFileParameterResponse(struct soap *soap, ns1__removeDataFileParameterResponse *const*a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__removeDataFileParameterResponse); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__removeDataFileParameterResponse); if (soap_out_PointerTons1__removeDataFileParameterResponse(soap, tag?tag:"ns1:removeDataFileParameterResponse", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -96181,7 +96181,7 @@ SOAP_FMAC3 ns1__removeDataFileParameter ** SOAP_FMAC4 soap_in_PointerTons1__remo SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTons1__removeDataFileParameter(struct soap *soap, ns1__removeDataFileParameter *const*a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__removeDataFileParameter); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__removeDataFileParameter); if (soap_out_PointerTons1__removeDataFileParameter(soap, tag?tag:"ns1:removeDataFileParameter", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -96238,7 +96238,7 @@ SOAP_FMAC3 ns1__removeDataFileResponse ** SOAP_FMAC4 soap_in_PointerTons1__remov SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTons1__removeDataFileResponse(struct soap *soap, ns1__removeDataFileResponse *const*a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__removeDataFileResponse); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__removeDataFileResponse); if (soap_out_PointerTons1__removeDataFileResponse(soap, tag?tag:"ns1:removeDataFileResponse", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -96295,7 +96295,7 @@ SOAP_FMAC3 ns1__removeDataFile ** SOAP_FMAC4 soap_in_PointerTons1__removeDataFil SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTons1__removeDataFile(struct soap *soap, ns1__removeDataFile *const*a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__removeDataFile); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__removeDataFile); if (soap_out_PointerTons1__removeDataFile(soap, tag?tag:"ns1:removeDataFile", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -96352,7 +96352,7 @@ SOAP_FMAC3 ns1__deleteDataFileParameterResponse ** SOAP_FMAC4 soap_in_PointerTon SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTons1__deleteDataFileParameterResponse(struct soap *soap, ns1__deleteDataFileParameterResponse *const*a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__deleteDataFileParameterResponse); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__deleteDataFileParameterResponse); if (soap_out_PointerTons1__deleteDataFileParameterResponse(soap, tag?tag:"ns1:deleteDataFileParameterResponse", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -96409,7 +96409,7 @@ SOAP_FMAC3 ns1__deleteDataFileParameter ** SOAP_FMAC4 soap_in_PointerTons1__dele SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTons1__deleteDataFileParameter(struct soap *soap, ns1__deleteDataFileParameter *const*a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__deleteDataFileParameter); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__deleteDataFileParameter); if (soap_out_PointerTons1__deleteDataFileParameter(soap, tag?tag:"ns1:deleteDataFileParameter", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -96466,7 +96466,7 @@ SOAP_FMAC3 ns1__modifyDataFileParameterResponse ** SOAP_FMAC4 soap_in_PointerTon SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTons1__modifyDataFileParameterResponse(struct soap *soap, ns1__modifyDataFileParameterResponse *const*a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__modifyDataFileParameterResponse); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__modifyDataFileParameterResponse); if (soap_out_PointerTons1__modifyDataFileParameterResponse(soap, tag?tag:"ns1:modifyDataFileParameterResponse", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -96523,7 +96523,7 @@ SOAP_FMAC3 ns1__modifyDataFileParameter ** SOAP_FMAC4 soap_in_PointerTons1__modi SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTons1__modifyDataFileParameter(struct soap *soap, ns1__modifyDataFileParameter *const*a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__modifyDataFileParameter); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__modifyDataFileParameter); if (soap_out_PointerTons1__modifyDataFileParameter(soap, tag?tag:"ns1:modifyDataFileParameter", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -96580,7 +96580,7 @@ SOAP_FMAC3 ns1__addDataFileParametersResponse ** SOAP_FMAC4 soap_in_PointerTons1 SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTons1__addDataFileParametersResponse(struct soap *soap, ns1__addDataFileParametersResponse *const*a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__addDataFileParametersResponse); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__addDataFileParametersResponse); if (soap_out_PointerTons1__addDataFileParametersResponse(soap, tag?tag:"ns1:addDataFileParametersResponse", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -96637,7 +96637,7 @@ SOAP_FMAC3 ns1__addDataFileParameters ** SOAP_FMAC4 soap_in_PointerTons1__addDat SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTons1__addDataFileParameters(struct soap *soap, ns1__addDataFileParameters *const*a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__addDataFileParameters); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__addDataFileParameters); if (soap_out_PointerTons1__addDataFileParameters(soap, tag?tag:"ns1:addDataFileParameters", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -96694,7 +96694,7 @@ SOAP_FMAC3 ns1__addDataFileParameterResponse ** SOAP_FMAC4 soap_in_PointerTons1_ SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTons1__addDataFileParameterResponse(struct soap *soap, ns1__addDataFileParameterResponse *const*a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__addDataFileParameterResponse); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__addDataFileParameterResponse); if (soap_out_PointerTons1__addDataFileParameterResponse(soap, tag?tag:"ns1:addDataFileParameterResponse", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -96751,7 +96751,7 @@ SOAP_FMAC3 ns1__addDataFileParameter ** SOAP_FMAC4 soap_in_PointerTons1__addData SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTons1__addDataFileParameter(struct soap *soap, ns1__addDataFileParameter *const*a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__addDataFileParameter); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__addDataFileParameter); if (soap_out_PointerTons1__addDataFileParameter(soap, tag?tag:"ns1:addDataFileParameter", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -96808,7 +96808,7 @@ SOAP_FMAC3 ns1__modifyDataFileResponse ** SOAP_FMAC4 soap_in_PointerTons1__modif SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTons1__modifyDataFileResponse(struct soap *soap, ns1__modifyDataFileResponse *const*a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__modifyDataFileResponse); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__modifyDataFileResponse); if (soap_out_PointerTons1__modifyDataFileResponse(soap, tag?tag:"ns1:modifyDataFileResponse", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -96865,7 +96865,7 @@ SOAP_FMAC3 ns1__modifyDataFile ** SOAP_FMAC4 soap_in_PointerTons1__modifyDataFil SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTons1__modifyDataFile(struct soap *soap, ns1__modifyDataFile *const*a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__modifyDataFile); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__modifyDataFile); if (soap_out_PointerTons1__modifyDataFile(soap, tag?tag:"ns1:modifyDataFile", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -96922,7 +96922,7 @@ SOAP_FMAC3 ns1__deleteDataFileResponse ** SOAP_FMAC4 soap_in_PointerTons1__delet SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTons1__deleteDataFileResponse(struct soap *soap, ns1__deleteDataFileResponse *const*a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__deleteDataFileResponse); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__deleteDataFileResponse); if (soap_out_PointerTons1__deleteDataFileResponse(soap, tag?tag:"ns1:deleteDataFileResponse", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -96979,7 +96979,7 @@ SOAP_FMAC3 ns1__deleteDataFile ** SOAP_FMAC4 soap_in_PointerTons1__deleteDataFil SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTons1__deleteDataFile(struct soap *soap, ns1__deleteDataFile *const*a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__deleteDataFile); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__deleteDataFile); if (soap_out_PointerTons1__deleteDataFile(soap, tag?tag:"ns1:deleteDataFile", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -97036,7 +97036,7 @@ SOAP_FMAC3 ns1__createDataFilesResponse ** SOAP_FMAC4 soap_in_PointerTons1__crea SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTons1__createDataFilesResponse(struct soap *soap, ns1__createDataFilesResponse *const*a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__createDataFilesResponse); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__createDataFilesResponse); if (soap_out_PointerTons1__createDataFilesResponse(soap, tag?tag:"ns1:createDataFilesResponse", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -97093,7 +97093,7 @@ SOAP_FMAC3 ns1__createDataFiles ** SOAP_FMAC4 soap_in_PointerTons1__createDataFi SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTons1__createDataFiles(struct soap *soap, ns1__createDataFiles *const*a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__createDataFiles); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__createDataFiles); if (soap_out_PointerTons1__createDataFiles(soap, tag?tag:"ns1:createDataFiles", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -97150,7 +97150,7 @@ SOAP_FMAC3 ns1__createDataFileResponse ** SOAP_FMAC4 soap_in_PointerTons1__creat SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTons1__createDataFileResponse(struct soap *soap, ns1__createDataFileResponse *const*a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__createDataFileResponse); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__createDataFileResponse); if (soap_out_PointerTons1__createDataFileResponse(soap, tag?tag:"ns1:createDataFileResponse", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -97207,7 +97207,7 @@ SOAP_FMAC3 ns1__createDataFile ** SOAP_FMAC4 soap_in_PointerTons1__createDataFil SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTons1__createDataFile(struct soap *soap, ns1__createDataFile *const*a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__createDataFile); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__createDataFile); if (soap_out_PointerTons1__createDataFile(soap, tag?tag:"ns1:createDataFile", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -97264,7 +97264,7 @@ SOAP_FMAC3 ns1__getDatafilesResponse ** SOAP_FMAC4 soap_in_PointerTons1__getData SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTons1__getDatafilesResponse(struct soap *soap, ns1__getDatafilesResponse *const*a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__getDatafilesResponse); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__getDatafilesResponse); if (soap_out_PointerTons1__getDatafilesResponse(soap, tag?tag:"ns1:getDatafilesResponse", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -97321,7 +97321,7 @@ SOAP_FMAC3 ns1__getDatafiles ** SOAP_FMAC4 soap_in_PointerTons1__getDatafiles(st SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTons1__getDatafiles(struct soap *soap, ns1__getDatafiles *const*a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__getDatafiles); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__getDatafiles); if (soap_out_PointerTons1__getDatafiles(soap, tag?tag:"ns1:getDatafiles", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -97378,7 +97378,7 @@ SOAP_FMAC3 ns1__getDatafileResponse ** SOAP_FMAC4 soap_in_PointerTons1__getDataf SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTons1__getDatafileResponse(struct soap *soap, ns1__getDatafileResponse *const*a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__getDatafileResponse); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__getDatafileResponse); if (soap_out_PointerTons1__getDatafileResponse(soap, tag?tag:"ns1:getDatafileResponse", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -97435,7 +97435,7 @@ SOAP_FMAC3 ns1__getDatafile ** SOAP_FMAC4 soap_in_PointerTons1__getDatafile(stru SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTons1__getDatafile(struct soap *soap, ns1__getDatafile *const*a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__getDatafile); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__getDatafile); if (soap_out_PointerTons1__getDatafile(soap, tag?tag:"ns1:getDatafile", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -97492,7 +97492,7 @@ SOAP_FMAC3 ns1__removeDataSetParameterResponse ** SOAP_FMAC4 soap_in_PointerTons SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTons1__removeDataSetParameterResponse(struct soap *soap, ns1__removeDataSetParameterResponse *const*a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__removeDataSetParameterResponse); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__removeDataSetParameterResponse); if (soap_out_PointerTons1__removeDataSetParameterResponse(soap, tag?tag:"ns1:removeDataSetParameterResponse", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -97549,7 +97549,7 @@ SOAP_FMAC3 ns1__removeDataSetParameter ** SOAP_FMAC4 soap_in_PointerTons1__remov SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTons1__removeDataSetParameter(struct soap *soap, ns1__removeDataSetParameter *const*a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__removeDataSetParameter); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__removeDataSetParameter); if (soap_out_PointerTons1__removeDataSetParameter(soap, tag?tag:"ns1:removeDataSetParameter", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -97606,7 +97606,7 @@ SOAP_FMAC3 ns1__removeDataSetResponse ** SOAP_FMAC4 soap_in_PointerTons1__remove SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTons1__removeDataSetResponse(struct soap *soap, ns1__removeDataSetResponse *const*a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__removeDataSetResponse); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__removeDataSetResponse); if (soap_out_PointerTons1__removeDataSetResponse(soap, tag?tag:"ns1:removeDataSetResponse", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -97663,7 +97663,7 @@ SOAP_FMAC3 ns1__removeDataSet ** SOAP_FMAC4 soap_in_PointerTons1__removeDataSet( SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTons1__removeDataSet(struct soap *soap, ns1__removeDataSet *const*a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__removeDataSet); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__removeDataSet); if (soap_out_PointerTons1__removeDataSet(soap, tag?tag:"ns1:removeDataSet", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -97720,7 +97720,7 @@ SOAP_FMAC3 ns1__addDataSetParametersResponse ** SOAP_FMAC4 soap_in_PointerTons1_ SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTons1__addDataSetParametersResponse(struct soap *soap, ns1__addDataSetParametersResponse *const*a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__addDataSetParametersResponse); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__addDataSetParametersResponse); if (soap_out_PointerTons1__addDataSetParametersResponse(soap, tag?tag:"ns1:addDataSetParametersResponse", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -97777,7 +97777,7 @@ SOAP_FMAC3 ns1__addDataSetParameters ** SOAP_FMAC4 soap_in_PointerTons1__addData SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTons1__addDataSetParameters(struct soap *soap, ns1__addDataSetParameters *const*a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__addDataSetParameters); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__addDataSetParameters); if (soap_out_PointerTons1__addDataSetParameters(soap, tag?tag:"ns1:addDataSetParameters", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -97834,7 +97834,7 @@ SOAP_FMAC3 ns1__addDataSetParameterResponse ** SOAP_FMAC4 soap_in_PointerTons1__ SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTons1__addDataSetParameterResponse(struct soap *soap, ns1__addDataSetParameterResponse *const*a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__addDataSetParameterResponse); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__addDataSetParameterResponse); if (soap_out_PointerTons1__addDataSetParameterResponse(soap, tag?tag:"ns1:addDataSetParameterResponse", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -97891,7 +97891,7 @@ SOAP_FMAC3 ns1__addDataSetParameter ** SOAP_FMAC4 soap_in_PointerTons1__addDataS SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTons1__addDataSetParameter(struct soap *soap, ns1__addDataSetParameter *const*a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__addDataSetParameter); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__addDataSetParameter); if (soap_out_PointerTons1__addDataSetParameter(soap, tag?tag:"ns1:addDataSetParameter", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -97948,7 +97948,7 @@ SOAP_FMAC3 ns1__setDataSetSampleResponse ** SOAP_FMAC4 soap_in_PointerTons1__set SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTons1__setDataSetSampleResponse(struct soap *soap, ns1__setDataSetSampleResponse *const*a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__setDataSetSampleResponse); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__setDataSetSampleResponse); if (soap_out_PointerTons1__setDataSetSampleResponse(soap, tag?tag:"ns1:setDataSetSampleResponse", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -98005,7 +98005,7 @@ SOAP_FMAC3 ns1__setDataSetSample ** SOAP_FMAC4 soap_in_PointerTons1__setDataSetS SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTons1__setDataSetSample(struct soap *soap, ns1__setDataSetSample *const*a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__setDataSetSample); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__setDataSetSample); if (soap_out_PointerTons1__setDataSetSample(soap, tag?tag:"ns1:setDataSetSample", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -98062,7 +98062,7 @@ SOAP_FMAC3 ns1__modifyDataSetParameterResponse ** SOAP_FMAC4 soap_in_PointerTons SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTons1__modifyDataSetParameterResponse(struct soap *soap, ns1__modifyDataSetParameterResponse *const*a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__modifyDataSetParameterResponse); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__modifyDataSetParameterResponse); if (soap_out_PointerTons1__modifyDataSetParameterResponse(soap, tag?tag:"ns1:modifyDataSetParameterResponse", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -98119,7 +98119,7 @@ SOAP_FMAC3 ns1__modifyDataSetParameter ** SOAP_FMAC4 soap_in_PointerTons1__modif SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTons1__modifyDataSetParameter(struct soap *soap, ns1__modifyDataSetParameter *const*a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__modifyDataSetParameter); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__modifyDataSetParameter); if (soap_out_PointerTons1__modifyDataSetParameter(soap, tag?tag:"ns1:modifyDataSetParameter", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -98176,7 +98176,7 @@ SOAP_FMAC3 ns1__modifyDataSetResponse ** SOAP_FMAC4 soap_in_PointerTons1__modify SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTons1__modifyDataSetResponse(struct soap *soap, ns1__modifyDataSetResponse *const*a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__modifyDataSetResponse); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__modifyDataSetResponse); if (soap_out_PointerTons1__modifyDataSetResponse(soap, tag?tag:"ns1:modifyDataSetResponse", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -98233,7 +98233,7 @@ SOAP_FMAC3 ns1__modifyDataSet ** SOAP_FMAC4 soap_in_PointerTons1__modifyDataSet( SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTons1__modifyDataSet(struct soap *soap, ns1__modifyDataSet *const*a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__modifyDataSet); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__modifyDataSet); if (soap_out_PointerTons1__modifyDataSet(soap, tag?tag:"ns1:modifyDataSet", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -98290,7 +98290,7 @@ SOAP_FMAC3 ns1__deleteDataSetParameterResponse ** SOAP_FMAC4 soap_in_PointerTons SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTons1__deleteDataSetParameterResponse(struct soap *soap, ns1__deleteDataSetParameterResponse *const*a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__deleteDataSetParameterResponse); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__deleteDataSetParameterResponse); if (soap_out_PointerTons1__deleteDataSetParameterResponse(soap, tag?tag:"ns1:deleteDataSetParameterResponse", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -98347,7 +98347,7 @@ SOAP_FMAC3 ns1__deleteDataSetParameter ** SOAP_FMAC4 soap_in_PointerTons1__delet SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTons1__deleteDataSetParameter(struct soap *soap, ns1__deleteDataSetParameter *const*a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__deleteDataSetParameter); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__deleteDataSetParameter); if (soap_out_PointerTons1__deleteDataSetParameter(soap, tag?tag:"ns1:deleteDataSetParameter", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -98404,7 +98404,7 @@ SOAP_FMAC3 ns1__deleteDataSetResponse ** SOAP_FMAC4 soap_in_PointerTons1__delete SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTons1__deleteDataSetResponse(struct soap *soap, ns1__deleteDataSetResponse *const*a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__deleteDataSetResponse); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__deleteDataSetResponse); if (soap_out_PointerTons1__deleteDataSetResponse(soap, tag?tag:"ns1:deleteDataSetResponse", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -98461,7 +98461,7 @@ SOAP_FMAC3 ns1__deleteDataSet ** SOAP_FMAC4 soap_in_PointerTons1__deleteDataSet( SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTons1__deleteDataSet(struct soap *soap, ns1__deleteDataSet *const*a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__deleteDataSet); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__deleteDataSet); if (soap_out_PointerTons1__deleteDataSet(soap, tag?tag:"ns1:deleteDataSet", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -98518,7 +98518,7 @@ SOAP_FMAC3 ns1__createDataSetsResponse ** SOAP_FMAC4 soap_in_PointerTons1__creat SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTons1__createDataSetsResponse(struct soap *soap, ns1__createDataSetsResponse *const*a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__createDataSetsResponse); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__createDataSetsResponse); if (soap_out_PointerTons1__createDataSetsResponse(soap, tag?tag:"ns1:createDataSetsResponse", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -98575,7 +98575,7 @@ SOAP_FMAC3 ns1__createDataSets ** SOAP_FMAC4 soap_in_PointerTons1__createDataSet SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTons1__createDataSets(struct soap *soap, ns1__createDataSets *const*a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__createDataSets); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__createDataSets); if (soap_out_PointerTons1__createDataSets(soap, tag?tag:"ns1:createDataSets", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -98632,7 +98632,7 @@ SOAP_FMAC3 ns1__createDataSetResponse ** SOAP_FMAC4 soap_in_PointerTons1__create SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTons1__createDataSetResponse(struct soap *soap, ns1__createDataSetResponse *const*a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__createDataSetResponse); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__createDataSetResponse); if (soap_out_PointerTons1__createDataSetResponse(soap, tag?tag:"ns1:createDataSetResponse", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -98689,7 +98689,7 @@ SOAP_FMAC3 ns1__createDataSet ** SOAP_FMAC4 soap_in_PointerTons1__createDataSet( SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTons1__createDataSet(struct soap *soap, ns1__createDataSet *const*a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__createDataSet); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__createDataSet); if (soap_out_PointerTons1__createDataSet(soap, tag?tag:"ns1:createDataSet", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -98746,7 +98746,7 @@ SOAP_FMAC3 ns1__getDatasetsResponse ** SOAP_FMAC4 soap_in_PointerTons1__getDatas SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTons1__getDatasetsResponse(struct soap *soap, ns1__getDatasetsResponse *const*a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__getDatasetsResponse); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__getDatasetsResponse); if (soap_out_PointerTons1__getDatasetsResponse(soap, tag?tag:"ns1:getDatasetsResponse", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -98803,7 +98803,7 @@ SOAP_FMAC3 ns1__getDatasets ** SOAP_FMAC4 soap_in_PointerTons1__getDatasets(stru SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTons1__getDatasets(struct soap *soap, ns1__getDatasets *const*a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__getDatasets); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__getDatasets); if (soap_out_PointerTons1__getDatasets(soap, tag?tag:"ns1:getDatasets", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -98860,7 +98860,7 @@ SOAP_FMAC3 ns1__getDatasetIncludesResponse ** SOAP_FMAC4 soap_in_PointerTons1__g SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTons1__getDatasetIncludesResponse(struct soap *soap, ns1__getDatasetIncludesResponse *const*a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__getDatasetIncludesResponse); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__getDatasetIncludesResponse); if (soap_out_PointerTons1__getDatasetIncludesResponse(soap, tag?tag:"ns1:getDatasetIncludesResponse", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -98917,7 +98917,7 @@ SOAP_FMAC3 ns1__getDatasetIncludes ** SOAP_FMAC4 soap_in_PointerTons1__getDatase SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTons1__getDatasetIncludes(struct soap *soap, ns1__getDatasetIncludes *const*a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__getDatasetIncludes); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__getDatasetIncludes); if (soap_out_PointerTons1__getDatasetIncludes(soap, tag?tag:"ns1:getDatasetIncludes", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -98974,7 +98974,7 @@ SOAP_FMAC3 ns1__getDatasetResponse ** SOAP_FMAC4 soap_in_PointerTons1__getDatase SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTons1__getDatasetResponse(struct soap *soap, ns1__getDatasetResponse *const*a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__getDatasetResponse); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__getDatasetResponse); if (soap_out_PointerTons1__getDatasetResponse(soap, tag?tag:"ns1:getDatasetResponse", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -99031,7 +99031,7 @@ SOAP_FMAC3 ns1__getDataset ** SOAP_FMAC4 soap_in_PointerTons1__getDataset(struct SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTons1__getDataset(struct soap *soap, ns1__getDataset *const*a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__getDataset); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__getDataset); if (soap_out_PointerTons1__getDataset(soap, tag?tag:"ns1:getDataset", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -99088,7 +99088,7 @@ SOAP_FMAC3 ns1__removeSampleParameterResponse ** SOAP_FMAC4 soap_in_PointerTons1 SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTons1__removeSampleParameterResponse(struct soap *soap, ns1__removeSampleParameterResponse *const*a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__removeSampleParameterResponse); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__removeSampleParameterResponse); if (soap_out_PointerTons1__removeSampleParameterResponse(soap, tag?tag:"ns1:removeSampleParameterResponse", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -99145,7 +99145,7 @@ SOAP_FMAC3 ns1__removeSampleParameter ** SOAP_FMAC4 soap_in_PointerTons1__remove SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTons1__removeSampleParameter(struct soap *soap, ns1__removeSampleParameter *const*a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__removeSampleParameter); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__removeSampleParameter); if (soap_out_PointerTons1__removeSampleParameter(soap, tag?tag:"ns1:removeSampleParameter", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -99202,7 +99202,7 @@ SOAP_FMAC3 ns1__removeSampleResponse ** SOAP_FMAC4 soap_in_PointerTons1__removeS SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTons1__removeSampleResponse(struct soap *soap, ns1__removeSampleResponse *const*a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__removeSampleResponse); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__removeSampleResponse); if (soap_out_PointerTons1__removeSampleResponse(soap, tag?tag:"ns1:removeSampleResponse", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -99259,7 +99259,7 @@ SOAP_FMAC3 ns1__removeSample ** SOAP_FMAC4 soap_in_PointerTons1__removeSample(st SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTons1__removeSample(struct soap *soap, ns1__removeSample *const*a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__removeSample); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__removeSample); if (soap_out_PointerTons1__removeSample(soap, tag?tag:"ns1:removeSample", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -99316,7 +99316,7 @@ SOAP_FMAC3 ns1__removePublicationResponse ** SOAP_FMAC4 soap_in_PointerTons1__re SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTons1__removePublicationResponse(struct soap *soap, ns1__removePublicationResponse *const*a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__removePublicationResponse); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__removePublicationResponse); if (soap_out_PointerTons1__removePublicationResponse(soap, tag?tag:"ns1:removePublicationResponse", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -99373,7 +99373,7 @@ SOAP_FMAC3 ns1__removePublication ** SOAP_FMAC4 soap_in_PointerTons1__removePubl SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTons1__removePublication(struct soap *soap, ns1__removePublication *const*a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__removePublication); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__removePublication); if (soap_out_PointerTons1__removePublication(soap, tag?tag:"ns1:removePublication", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -99430,7 +99430,7 @@ SOAP_FMAC3 ns1__removeInvestigatorResponse ** SOAP_FMAC4 soap_in_PointerTons1__r SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTons1__removeInvestigatorResponse(struct soap *soap, ns1__removeInvestigatorResponse *const*a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__removeInvestigatorResponse); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__removeInvestigatorResponse); if (soap_out_PointerTons1__removeInvestigatorResponse(soap, tag?tag:"ns1:removeInvestigatorResponse", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -99487,7 +99487,7 @@ SOAP_FMAC3 ns1__removeInvestigator ** SOAP_FMAC4 soap_in_PointerTons1__removeInv SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTons1__removeInvestigator(struct soap *soap, ns1__removeInvestigator *const*a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__removeInvestigator); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__removeInvestigator); if (soap_out_PointerTons1__removeInvestigator(soap, tag?tag:"ns1:removeInvestigator", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -99544,7 +99544,7 @@ SOAP_FMAC3 ns1__removeKeywordResponse ** SOAP_FMAC4 soap_in_PointerTons1__remove SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTons1__removeKeywordResponse(struct soap *soap, ns1__removeKeywordResponse *const*a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__removeKeywordResponse); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__removeKeywordResponse); if (soap_out_PointerTons1__removeKeywordResponse(soap, tag?tag:"ns1:removeKeywordResponse", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -99601,7 +99601,7 @@ SOAP_FMAC3 ns1__removeKeyword ** SOAP_FMAC4 soap_in_PointerTons1__removeKeyword( SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTons1__removeKeyword(struct soap *soap, ns1__removeKeyword *const*a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__removeKeyword); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__removeKeyword); if (soap_out_PointerTons1__removeKeyword(soap, tag?tag:"ns1:removeKeyword", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -99658,7 +99658,7 @@ SOAP_FMAC3 ns1__modifySampleParameterResponse ** SOAP_FMAC4 soap_in_PointerTons1 SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTons1__modifySampleParameterResponse(struct soap *soap, ns1__modifySampleParameterResponse *const*a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__modifySampleParameterResponse); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__modifySampleParameterResponse); if (soap_out_PointerTons1__modifySampleParameterResponse(soap, tag?tag:"ns1:modifySampleParameterResponse", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -99715,7 +99715,7 @@ SOAP_FMAC3 ns1__modifySampleParameter ** SOAP_FMAC4 soap_in_PointerTons1__modify SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTons1__modifySampleParameter(struct soap *soap, ns1__modifySampleParameter *const*a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__modifySampleParameter); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__modifySampleParameter); if (soap_out_PointerTons1__modifySampleParameter(soap, tag?tag:"ns1:modifySampleParameter", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -99772,7 +99772,7 @@ SOAP_FMAC3 ns1__modifyPublicationResponse ** SOAP_FMAC4 soap_in_PointerTons1__mo SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTons1__modifyPublicationResponse(struct soap *soap, ns1__modifyPublicationResponse *const*a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__modifyPublicationResponse); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__modifyPublicationResponse); if (soap_out_PointerTons1__modifyPublicationResponse(soap, tag?tag:"ns1:modifyPublicationResponse", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -99829,7 +99829,7 @@ SOAP_FMAC3 ns1__modifyPublication ** SOAP_FMAC4 soap_in_PointerTons1__modifyPubl SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTons1__modifyPublication(struct soap *soap, ns1__modifyPublication *const*a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__modifyPublication); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__modifyPublication); if (soap_out_PointerTons1__modifyPublication(soap, tag?tag:"ns1:modifyPublication", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -99886,7 +99886,7 @@ SOAP_FMAC3 ns1__modifySampleResponse ** SOAP_FMAC4 soap_in_PointerTons1__modifyS SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTons1__modifySampleResponse(struct soap *soap, ns1__modifySampleResponse *const*a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__modifySampleResponse); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__modifySampleResponse); if (soap_out_PointerTons1__modifySampleResponse(soap, tag?tag:"ns1:modifySampleResponse", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -99943,7 +99943,7 @@ SOAP_FMAC3 ns1__modifySample ** SOAP_FMAC4 soap_in_PointerTons1__modifySample(st SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTons1__modifySample(struct soap *soap, ns1__modifySample *const*a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__modifySample); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__modifySample); if (soap_out_PointerTons1__modifySample(soap, tag?tag:"ns1:modifySample", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -100000,7 +100000,7 @@ SOAP_FMAC3 ns1__modifyInvestigatorResponse ** SOAP_FMAC4 soap_in_PointerTons1__m SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTons1__modifyInvestigatorResponse(struct soap *soap, ns1__modifyInvestigatorResponse *const*a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__modifyInvestigatorResponse); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__modifyInvestigatorResponse); if (soap_out_PointerTons1__modifyInvestigatorResponse(soap, tag?tag:"ns1:modifyInvestigatorResponse", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -100057,7 +100057,7 @@ SOAP_FMAC3 ns1__modifyInvestigator ** SOAP_FMAC4 soap_in_PointerTons1__modifyInv SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTons1__modifyInvestigator(struct soap *soap, ns1__modifyInvestigator *const*a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__modifyInvestigator); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__modifyInvestigator); if (soap_out_PointerTons1__modifyInvestigator(soap, tag?tag:"ns1:modifyInvestigator", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -100114,7 +100114,7 @@ SOAP_FMAC3 ns1__modifyInvestigationResponse ** SOAP_FMAC4 soap_in_PointerTons1__ SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTons1__modifyInvestigationResponse(struct soap *soap, ns1__modifyInvestigationResponse *const*a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__modifyInvestigationResponse); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__modifyInvestigationResponse); if (soap_out_PointerTons1__modifyInvestigationResponse(soap, tag?tag:"ns1:modifyInvestigationResponse", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -100171,7 +100171,7 @@ SOAP_FMAC3 ns1__modifyInvestigation ** SOAP_FMAC4 soap_in_PointerTons1__modifyIn SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTons1__modifyInvestigation(struct soap *soap, ns1__modifyInvestigation *const*a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__modifyInvestigation); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__modifyInvestigation); if (soap_out_PointerTons1__modifyInvestigation(soap, tag?tag:"ns1:modifyInvestigation", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -100228,7 +100228,7 @@ SOAP_FMAC3 ns1__deleteSampleParameterResponse ** SOAP_FMAC4 soap_in_PointerTons1 SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTons1__deleteSampleParameterResponse(struct soap *soap, ns1__deleteSampleParameterResponse *const*a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__deleteSampleParameterResponse); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__deleteSampleParameterResponse); if (soap_out_PointerTons1__deleteSampleParameterResponse(soap, tag?tag:"ns1:deleteSampleParameterResponse", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -100285,7 +100285,7 @@ SOAP_FMAC3 ns1__deleteSampleParameter ** SOAP_FMAC4 soap_in_PointerTons1__delete SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTons1__deleteSampleParameter(struct soap *soap, ns1__deleteSampleParameter *const*a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__deleteSampleParameter); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__deleteSampleParameter); if (soap_out_PointerTons1__deleteSampleParameter(soap, tag?tag:"ns1:deleteSampleParameter", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -100342,7 +100342,7 @@ SOAP_FMAC3 ns1__deleteSampleResponse ** SOAP_FMAC4 soap_in_PointerTons1__deleteS SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTons1__deleteSampleResponse(struct soap *soap, ns1__deleteSampleResponse *const*a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__deleteSampleResponse); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__deleteSampleResponse); if (soap_out_PointerTons1__deleteSampleResponse(soap, tag?tag:"ns1:deleteSampleResponse", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -100399,7 +100399,7 @@ SOAP_FMAC3 ns1__deleteSample ** SOAP_FMAC4 soap_in_PointerTons1__deleteSample(st SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTons1__deleteSample(struct soap *soap, ns1__deleteSample *const*a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__deleteSample); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__deleteSample); if (soap_out_PointerTons1__deleteSample(soap, tag?tag:"ns1:deleteSample", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -100456,7 +100456,7 @@ SOAP_FMAC3 ns1__deletePublicationResponse ** SOAP_FMAC4 soap_in_PointerTons1__de SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTons1__deletePublicationResponse(struct soap *soap, ns1__deletePublicationResponse *const*a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__deletePublicationResponse); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__deletePublicationResponse); if (soap_out_PointerTons1__deletePublicationResponse(soap, tag?tag:"ns1:deletePublicationResponse", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -100513,7 +100513,7 @@ SOAP_FMAC3 ns1__deletePublication ** SOAP_FMAC4 soap_in_PointerTons1__deletePubl SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTons1__deletePublication(struct soap *soap, ns1__deletePublication *const*a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__deletePublication); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__deletePublication); if (soap_out_PointerTons1__deletePublication(soap, tag?tag:"ns1:deletePublication", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -100570,7 +100570,7 @@ SOAP_FMAC3 ns1__deleteKeywordResponse ** SOAP_FMAC4 soap_in_PointerTons1__delete SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTons1__deleteKeywordResponse(struct soap *soap, ns1__deleteKeywordResponse *const*a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__deleteKeywordResponse); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__deleteKeywordResponse); if (soap_out_PointerTons1__deleteKeywordResponse(soap, tag?tag:"ns1:deleteKeywordResponse", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -100627,7 +100627,7 @@ SOAP_FMAC3 ns1__deleteKeyword ** SOAP_FMAC4 soap_in_PointerTons1__deleteKeyword( SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTons1__deleteKeyword(struct soap *soap, ns1__deleteKeyword *const*a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__deleteKeyword); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__deleteKeyword); if (soap_out_PointerTons1__deleteKeyword(soap, tag?tag:"ns1:deleteKeyword", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -100684,7 +100684,7 @@ SOAP_FMAC3 ns1__deleteInvestigatorResponse ** SOAP_FMAC4 soap_in_PointerTons1__d SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTons1__deleteInvestigatorResponse(struct soap *soap, ns1__deleteInvestigatorResponse *const*a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__deleteInvestigatorResponse); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__deleteInvestigatorResponse); if (soap_out_PointerTons1__deleteInvestigatorResponse(soap, tag?tag:"ns1:deleteInvestigatorResponse", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -100741,7 +100741,7 @@ SOAP_FMAC3 ns1__deleteInvestigator ** SOAP_FMAC4 soap_in_PointerTons1__deleteInv SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTons1__deleteInvestigator(struct soap *soap, ns1__deleteInvestigator *const*a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__deleteInvestigator); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__deleteInvestigator); if (soap_out_PointerTons1__deleteInvestigator(soap, tag?tag:"ns1:deleteInvestigator", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -100798,7 +100798,7 @@ SOAP_FMAC3 ns1__addSampleParameterResponse ** SOAP_FMAC4 soap_in_PointerTons1__a SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTons1__addSampleParameterResponse(struct soap *soap, ns1__addSampleParameterResponse *const*a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__addSampleParameterResponse); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__addSampleParameterResponse); if (soap_out_PointerTons1__addSampleParameterResponse(soap, tag?tag:"ns1:addSampleParameterResponse", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -100855,7 +100855,7 @@ SOAP_FMAC3 ns1__addSampleParameter ** SOAP_FMAC4 soap_in_PointerTons1__addSample SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTons1__addSampleParameter(struct soap *soap, ns1__addSampleParameter *const*a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__addSampleParameter); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__addSampleParameter); if (soap_out_PointerTons1__addSampleParameter(soap, tag?tag:"ns1:addSampleParameter", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -100912,7 +100912,7 @@ SOAP_FMAC3 ns1__addPublicationResponse ** SOAP_FMAC4 soap_in_PointerTons1__addPu SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTons1__addPublicationResponse(struct soap *soap, ns1__addPublicationResponse *const*a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__addPublicationResponse); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__addPublicationResponse); if (soap_out_PointerTons1__addPublicationResponse(soap, tag?tag:"ns1:addPublicationResponse", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -100969,7 +100969,7 @@ SOAP_FMAC3 ns1__addPublication ** SOAP_FMAC4 soap_in_PointerTons1__addPublicatio SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTons1__addPublication(struct soap *soap, ns1__addPublication *const*a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__addPublication); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__addPublication); if (soap_out_PointerTons1__addPublication(soap, tag?tag:"ns1:addPublication", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -101026,7 +101026,7 @@ SOAP_FMAC3 ns1__addSampleResponse ** SOAP_FMAC4 soap_in_PointerTons1__addSampleR SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTons1__addSampleResponse(struct soap *soap, ns1__addSampleResponse *const*a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__addSampleResponse); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__addSampleResponse); if (soap_out_PointerTons1__addSampleResponse(soap, tag?tag:"ns1:addSampleResponse", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -101083,7 +101083,7 @@ SOAP_FMAC3 ns1__addSample ** SOAP_FMAC4 soap_in_PointerTons1__addSample(struct s SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTons1__addSample(struct soap *soap, ns1__addSample *const*a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__addSample); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__addSample); if (soap_out_PointerTons1__addSample(soap, tag?tag:"ns1:addSample", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -101140,7 +101140,7 @@ SOAP_FMAC3 ns1__addInvestigatorResponse ** SOAP_FMAC4 soap_in_PointerTons1__addI SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTons1__addInvestigatorResponse(struct soap *soap, ns1__addInvestigatorResponse *const*a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__addInvestigatorResponse); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__addInvestigatorResponse); if (soap_out_PointerTons1__addInvestigatorResponse(soap, tag?tag:"ns1:addInvestigatorResponse", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -101197,7 +101197,7 @@ SOAP_FMAC3 ns1__addInvestigator ** SOAP_FMAC4 soap_in_PointerTons1__addInvestiga SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTons1__addInvestigator(struct soap *soap, ns1__addInvestigator *const*a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__addInvestigator); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__addInvestigator); if (soap_out_PointerTons1__addInvestigator(soap, tag?tag:"ns1:addInvestigator", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -101254,7 +101254,7 @@ SOAP_FMAC3 ns1__addKeywordResponse ** SOAP_FMAC4 soap_in_PointerTons1__addKeywor SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTons1__addKeywordResponse(struct soap *soap, ns1__addKeywordResponse *const*a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__addKeywordResponse); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__addKeywordResponse); if (soap_out_PointerTons1__addKeywordResponse(soap, tag?tag:"ns1:addKeywordResponse", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -101311,7 +101311,7 @@ SOAP_FMAC3 ns1__addKeyword ** SOAP_FMAC4 soap_in_PointerTons1__addKeyword(struct SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTons1__addKeyword(struct soap *soap, ns1__addKeyword *const*a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__addKeyword); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__addKeyword); if (soap_out_PointerTons1__addKeyword(soap, tag?tag:"ns1:addKeyword", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -101368,7 +101368,7 @@ SOAP_FMAC3 ns1__removeInvestigationResponse ** SOAP_FMAC4 soap_in_PointerTons1__ SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTons1__removeInvestigationResponse(struct soap *soap, ns1__removeInvestigationResponse *const*a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__removeInvestigationResponse); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__removeInvestigationResponse); if (soap_out_PointerTons1__removeInvestigationResponse(soap, tag?tag:"ns1:removeInvestigationResponse", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -101425,7 +101425,7 @@ SOAP_FMAC3 ns1__removeInvestigation ** SOAP_FMAC4 soap_in_PointerTons1__removeIn SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTons1__removeInvestigation(struct soap *soap, ns1__removeInvestigation *const*a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__removeInvestigation); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__removeInvestigation); if (soap_out_PointerTons1__removeInvestigation(soap, tag?tag:"ns1:removeInvestigation", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -101482,7 +101482,7 @@ SOAP_FMAC3 ns1__deleteInvestigationResponse ** SOAP_FMAC4 soap_in_PointerTons1__ SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTons1__deleteInvestigationResponse(struct soap *soap, ns1__deleteInvestigationResponse *const*a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__deleteInvestigationResponse); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__deleteInvestigationResponse); if (soap_out_PointerTons1__deleteInvestigationResponse(soap, tag?tag:"ns1:deleteInvestigationResponse", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -101539,7 +101539,7 @@ SOAP_FMAC3 ns1__deleteInvestigation ** SOAP_FMAC4 soap_in_PointerTons1__deleteIn SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTons1__deleteInvestigation(struct soap *soap, ns1__deleteInvestigation *const*a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__deleteInvestigation); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__deleteInvestigation); if (soap_out_PointerTons1__deleteInvestigation(soap, tag?tag:"ns1:deleteInvestigation", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -101596,7 +101596,7 @@ SOAP_FMAC3 ns1__createInvestigationResponse ** SOAP_FMAC4 soap_in_PointerTons1__ SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTons1__createInvestigationResponse(struct soap *soap, ns1__createInvestigationResponse *const*a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__createInvestigationResponse); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__createInvestigationResponse); if (soap_out_PointerTons1__createInvestigationResponse(soap, tag?tag:"ns1:createInvestigationResponse", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -101653,7 +101653,7 @@ SOAP_FMAC3 ns1__createInvestigation ** SOAP_FMAC4 soap_in_PointerTons1__createIn SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTons1__createInvestigation(struct soap *soap, ns1__createInvestigation *const*a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__createInvestigation); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__createInvestigation); if (soap_out_PointerTons1__createInvestigation(soap, tag?tag:"ns1:createInvestigation", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -101710,7 +101710,7 @@ SOAP_FMAC3 ns1__getInvestigationsIncludesResponse ** SOAP_FMAC4 soap_in_PointerT SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTons1__getInvestigationsIncludesResponse(struct soap *soap, ns1__getInvestigationsIncludesResponse *const*a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__getInvestigationsIncludesResponse); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__getInvestigationsIncludesResponse); if (soap_out_PointerTons1__getInvestigationsIncludesResponse(soap, tag?tag:"ns1:getInvestigationsIncludesResponse", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -101767,7 +101767,7 @@ SOAP_FMAC3 ns1__getInvestigationsIncludes ** SOAP_FMAC4 soap_in_PointerTons1__ge SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTons1__getInvestigationsIncludes(struct soap *soap, ns1__getInvestigationsIncludes *const*a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__getInvestigationsIncludes); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__getInvestigationsIncludes); if (soap_out_PointerTons1__getInvestigationsIncludes(soap, tag?tag:"ns1:getInvestigationsIncludes", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -101824,7 +101824,7 @@ SOAP_FMAC3 ns1__getInvestigationsResponse ** SOAP_FMAC4 soap_in_PointerTons1__ge SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTons1__getInvestigationsResponse(struct soap *soap, ns1__getInvestigationsResponse *const*a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__getInvestigationsResponse); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__getInvestigationsResponse); if (soap_out_PointerTons1__getInvestigationsResponse(soap, tag?tag:"ns1:getInvestigationsResponse", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -101881,7 +101881,7 @@ SOAP_FMAC3 ns1__getInvestigations ** SOAP_FMAC4 soap_in_PointerTons1__getInvesti SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTons1__getInvestigations(struct soap *soap, ns1__getInvestigations *const*a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__getInvestigations); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__getInvestigations); if (soap_out_PointerTons1__getInvestigations(soap, tag?tag:"ns1:getInvestigations", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -101938,7 +101938,7 @@ SOAP_FMAC3 ns1__getInvestigationIncludesResponse ** SOAP_FMAC4 soap_in_PointerTo SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTons1__getInvestigationIncludesResponse(struct soap *soap, ns1__getInvestigationIncludesResponse *const*a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__getInvestigationIncludesResponse); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__getInvestigationIncludesResponse); if (soap_out_PointerTons1__getInvestigationIncludesResponse(soap, tag?tag:"ns1:getInvestigationIncludesResponse", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -101995,7 +101995,7 @@ SOAP_FMAC3 ns1__getInvestigationIncludes ** SOAP_FMAC4 soap_in_PointerTons1__get SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTons1__getInvestigationIncludes(struct soap *soap, ns1__getInvestigationIncludes *const*a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__getInvestigationIncludes); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__getInvestigationIncludes); if (soap_out_PointerTons1__getInvestigationIncludes(soap, tag?tag:"ns1:getInvestigationIncludes", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -102052,7 +102052,7 @@ SOAP_FMAC3 ns1__getInvestigationResponse ** SOAP_FMAC4 soap_in_PointerTons1__get SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTons1__getInvestigationResponse(struct soap *soap, ns1__getInvestigationResponse *const*a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__getInvestigationResponse); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__getInvestigationResponse); if (soap_out_PointerTons1__getInvestigationResponse(soap, tag?tag:"ns1:getInvestigationResponse", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -102109,7 +102109,7 @@ SOAP_FMAC3 ns1__getInvestigation ** SOAP_FMAC4 soap_in_PointerTons1__getInvestig SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTons1__getInvestigation(struct soap *soap, ns1__getInvestigation *const*a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__getInvestigation); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__getInvestigation); if (soap_out_PointerTons1__getInvestigation(soap, tag?tag:"ns1:getInvestigation", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -102166,7 +102166,7 @@ SOAP_FMAC3 ns1__listDatafileFormatsResponse ** SOAP_FMAC4 soap_in_PointerTons1__ SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTons1__listDatafileFormatsResponse(struct soap *soap, ns1__listDatafileFormatsResponse *const*a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__listDatafileFormatsResponse); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__listDatafileFormatsResponse); if (soap_out_PointerTons1__listDatafileFormatsResponse(soap, tag?tag:"ns1:listDatafileFormatsResponse", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -102223,7 +102223,7 @@ SOAP_FMAC3 ns1__listDatafileFormats ** SOAP_FMAC4 soap_in_PointerTons1__listData SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTons1__listDatafileFormats(struct soap *soap, ns1__listDatafileFormats *const*a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__listDatafileFormats); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__listDatafileFormats); if (soap_out_PointerTons1__listDatafileFormats(soap, tag?tag:"ns1:listDatafileFormats", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -102280,7 +102280,7 @@ SOAP_FMAC3 ns1__searchByRunNumberPaginationResponse ** SOAP_FMAC4 soap_in_Pointe SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTons1__searchByRunNumberPaginationResponse(struct soap *soap, ns1__searchByRunNumberPaginationResponse *const*a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__searchByRunNumberPaginationResponse); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__searchByRunNumberPaginationResponse); if (soap_out_PointerTons1__searchByRunNumberPaginationResponse(soap, tag?tag:"ns1:searchByRunNumberPaginationResponse", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -102337,7 +102337,7 @@ SOAP_FMAC3 ns1__searchByRunNumberPagination ** SOAP_FMAC4 soap_in_PointerTons1__ SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTons1__searchByRunNumberPagination(struct soap *soap, ns1__searchByRunNumberPagination *const*a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__searchByRunNumberPagination); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__searchByRunNumberPagination); if (soap_out_PointerTons1__searchByRunNumberPagination(soap, tag?tag:"ns1:searchByRunNumberPagination", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -102394,7 +102394,7 @@ SOAP_FMAC3 ns1__searchByRunNumberResponse ** SOAP_FMAC4 soap_in_PointerTons1__se SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTons1__searchByRunNumberResponse(struct soap *soap, ns1__searchByRunNumberResponse *const*a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__searchByRunNumberResponse); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__searchByRunNumberResponse); if (soap_out_PointerTons1__searchByRunNumberResponse(soap, tag?tag:"ns1:searchByRunNumberResponse", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -102451,7 +102451,7 @@ SOAP_FMAC3 ns1__searchByRunNumber ** SOAP_FMAC4 soap_in_PointerTons1__searchByRu SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTons1__searchByRunNumber(struct soap *soap, ns1__searchByRunNumber *const*a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__searchByRunNumber); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__searchByRunNumber); if (soap_out_PointerTons1__searchByRunNumber(soap, tag?tag:"ns1:searchByRunNumber", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -102508,7 +102508,7 @@ SOAP_FMAC3 ns1__listDatasetStatusResponse ** SOAP_FMAC4 soap_in_PointerTons1__li SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTons1__listDatasetStatusResponse(struct soap *soap, ns1__listDatasetStatusResponse *const*a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__listDatasetStatusResponse); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__listDatasetStatusResponse); if (soap_out_PointerTons1__listDatasetStatusResponse(soap, tag?tag:"ns1:listDatasetStatusResponse", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -102565,7 +102565,7 @@ SOAP_FMAC3 ns1__listDatasetStatus ** SOAP_FMAC4 soap_in_PointerTons1__listDatase SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTons1__listDatasetStatus(struct soap *soap, ns1__listDatasetStatus *const*a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__listDatasetStatus); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__listDatasetStatus); if (soap_out_PointerTons1__listDatasetStatus(soap, tag?tag:"ns1:listDatasetStatus", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -102622,7 +102622,7 @@ SOAP_FMAC3 ns1__listDatasetTypesResponse ** SOAP_FMAC4 soap_in_PointerTons1__lis SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTons1__listDatasetTypesResponse(struct soap *soap, ns1__listDatasetTypesResponse *const*a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__listDatasetTypesResponse); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__listDatasetTypesResponse); if (soap_out_PointerTons1__listDatasetTypesResponse(soap, tag?tag:"ns1:listDatasetTypesResponse", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -102679,7 +102679,7 @@ SOAP_FMAC3 ns1__listDatasetTypes ** SOAP_FMAC4 soap_in_PointerTons1__listDataset SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTons1__listDatasetTypes(struct soap *soap, ns1__listDatasetTypes *const*a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__listDatasetTypes); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__listDatasetTypes); if (soap_out_PointerTons1__listDatasetTypes(soap, tag?tag:"ns1:listDatasetTypes", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -102736,7 +102736,7 @@ SOAP_FMAC3 ns1__searchDatasetsBySampleResponse ** SOAP_FMAC4 soap_in_PointerTons SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTons1__searchDatasetsBySampleResponse(struct soap *soap, ns1__searchDatasetsBySampleResponse *const*a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__searchDatasetsBySampleResponse); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__searchDatasetsBySampleResponse); if (soap_out_PointerTons1__searchDatasetsBySampleResponse(soap, tag?tag:"ns1:searchDatasetsBySampleResponse", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -102793,7 +102793,7 @@ SOAP_FMAC3 ns1__searchDatasetsBySample ** SOAP_FMAC4 soap_in_PointerTons1__searc SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTons1__searchDatasetsBySample(struct soap *soap, ns1__searchDatasetsBySample *const*a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__searchDatasetsBySample); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__searchDatasetsBySample); if (soap_out_PointerTons1__searchDatasetsBySample(soap, tag?tag:"ns1:searchDatasetsBySample", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -102850,7 +102850,7 @@ SOAP_FMAC3 ns1__searchSamplesBySampleNameResponse ** SOAP_FMAC4 soap_in_PointerT SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTons1__searchSamplesBySampleNameResponse(struct soap *soap, ns1__searchSamplesBySampleNameResponse *const*a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__searchSamplesBySampleNameResponse); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__searchSamplesBySampleNameResponse); if (soap_out_PointerTons1__searchSamplesBySampleNameResponse(soap, tag?tag:"ns1:searchSamplesBySampleNameResponse", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -102907,7 +102907,7 @@ SOAP_FMAC3 ns1__searchSamplesBySampleName ** SOAP_FMAC4 soap_in_PointerTons1__se SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTons1__searchSamplesBySampleName(struct soap *soap, ns1__searchSamplesBySampleName *const*a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__searchSamplesBySampleName); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__searchSamplesBySampleName); if (soap_out_PointerTons1__searchSamplesBySampleName(soap, tag?tag:"ns1:searchSamplesBySampleName", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -102964,7 +102964,7 @@ SOAP_FMAC3 ns1__listInvestigationTypesResponse ** SOAP_FMAC4 soap_in_PointerTons SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTons1__listInvestigationTypesResponse(struct soap *soap, ns1__listInvestigationTypesResponse *const*a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__listInvestigationTypesResponse); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__listInvestigationTypesResponse); if (soap_out_PointerTons1__listInvestigationTypesResponse(soap, tag?tag:"ns1:listInvestigationTypesResponse", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -103021,7 +103021,7 @@ SOAP_FMAC3 ns1__listInvestigationTypes ** SOAP_FMAC4 soap_in_PointerTons1__listI SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTons1__listInvestigationTypes(struct soap *soap, ns1__listInvestigationTypes *const*a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__listInvestigationTypes); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__listInvestigationTypes); if (soap_out_PointerTons1__listInvestigationTypes(soap, tag?tag:"ns1:listInvestigationTypes", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -103078,7 +103078,7 @@ SOAP_FMAC3 ns1__getInstrumentsWithDataResponse ** SOAP_FMAC4 soap_in_PointerTons SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTons1__getInstrumentsWithDataResponse(struct soap *soap, ns1__getInstrumentsWithDataResponse *const*a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__getInstrumentsWithDataResponse); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__getInstrumentsWithDataResponse); if (soap_out_PointerTons1__getInstrumentsWithDataResponse(soap, tag?tag:"ns1:getInstrumentsWithDataResponse", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -103135,7 +103135,7 @@ SOAP_FMAC3 ns1__getInstrumentsWithData ** SOAP_FMAC4 soap_in_PointerTons1__getIn SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTons1__getInstrumentsWithData(struct soap *soap, ns1__getInstrumentsWithData *const*a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__getInstrumentsWithData); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__getInstrumentsWithData); if (soap_out_PointerTons1__getInstrumentsWithData(soap, tag?tag:"ns1:getInstrumentsWithData", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -103192,7 +103192,7 @@ SOAP_FMAC3 ns1__getFacilityCyclesWithDataForInstrumentResponse ** SOAP_FMAC4 soa SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTons1__getFacilityCyclesWithDataForInstrumentResponse(struct soap *soap, ns1__getFacilityCyclesWithDataForInstrumentResponse *const*a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__getFacilityCyclesWithDataForInstrumentResponse); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__getFacilityCyclesWithDataForInstrumentResponse); if (soap_out_PointerTons1__getFacilityCyclesWithDataForInstrumentResponse(soap, tag?tag:"ns1:getFacilityCyclesWithDataForInstrumentResponse", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -103249,7 +103249,7 @@ SOAP_FMAC3 ns1__getFacilityCyclesWithDataForInstrument ** SOAP_FMAC4 soap_in_Poi SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTons1__getFacilityCyclesWithDataForInstrument(struct soap *soap, ns1__getFacilityCyclesWithDataForInstrument *const*a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__getFacilityCyclesWithDataForInstrument); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__getFacilityCyclesWithDataForInstrument); if (soap_out_PointerTons1__getFacilityCyclesWithDataForInstrument(soap, tag?tag:"ns1:getFacilityCyclesWithDataForInstrument", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -103306,7 +103306,7 @@ SOAP_FMAC3 ns1__listFacilityCyclesResponse ** SOAP_FMAC4 soap_in_PointerTons1__l SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTons1__listFacilityCyclesResponse(struct soap *soap, ns1__listFacilityCyclesResponse *const*a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__listFacilityCyclesResponse); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__listFacilityCyclesResponse); if (soap_out_PointerTons1__listFacilityCyclesResponse(soap, tag?tag:"ns1:listFacilityCyclesResponse", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -103363,7 +103363,7 @@ SOAP_FMAC3 ns1__listFacilityCycles ** SOAP_FMAC4 soap_in_PointerTons1__listFacil SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTons1__listFacilityCycles(struct soap *soap, ns1__listFacilityCycles *const*a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__listFacilityCycles); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__listFacilityCycles); if (soap_out_PointerTons1__listFacilityCycles(soap, tag?tag:"ns1:listFacilityCycles", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -103420,7 +103420,7 @@ SOAP_FMAC3 ns1__listParametersResponse ** SOAP_FMAC4 soap_in_PointerTons1__listP SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTons1__listParametersResponse(struct soap *soap, ns1__listParametersResponse *const*a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__listParametersResponse); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__listParametersResponse); if (soap_out_PointerTons1__listParametersResponse(soap, tag?tag:"ns1:listParametersResponse", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -103477,7 +103477,7 @@ SOAP_FMAC3 ns1__listParameters ** SOAP_FMAC4 soap_in_PointerTons1__listParameter SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTons1__listParameters(struct soap *soap, ns1__listParameters *const*a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__listParameters); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__listParameters); if (soap_out_PointerTons1__listParameters(soap, tag?tag:"ns1:listParameters", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -103534,7 +103534,7 @@ SOAP_FMAC3 ns1__listRolesResponse ** SOAP_FMAC4 soap_in_PointerTons1__listRolesR SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTons1__listRolesResponse(struct soap *soap, ns1__listRolesResponse *const*a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__listRolesResponse); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__listRolesResponse); if (soap_out_PointerTons1__listRolesResponse(soap, tag?tag:"ns1:listRolesResponse", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -103591,7 +103591,7 @@ SOAP_FMAC3 ns1__listRoles ** SOAP_FMAC4 soap_in_PointerTons1__listRoles(struct s SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTons1__listRoles(struct soap *soap, ns1__listRoles *const*a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__listRoles); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__listRoles); if (soap_out_PointerTons1__listRoles(soap, tag?tag:"ns1:listRoles", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -103648,7 +103648,7 @@ SOAP_FMAC3 ns1__getAllInstrumentsResponse ** SOAP_FMAC4 soap_in_PointerTons1__ge SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTons1__getAllInstrumentsResponse(struct soap *soap, ns1__getAllInstrumentsResponse *const*a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__getAllInstrumentsResponse); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__getAllInstrumentsResponse); if (soap_out_PointerTons1__getAllInstrumentsResponse(soap, tag?tag:"ns1:getAllInstrumentsResponse", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -103705,7 +103705,7 @@ SOAP_FMAC3 ns1__getAllInstruments ** SOAP_FMAC4 soap_in_PointerTons1__getAllInst SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTons1__getAllInstruments(struct soap *soap, ns1__getAllInstruments *const*a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__getAllInstruments); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__getAllInstruments); if (soap_out_PointerTons1__getAllInstruments(soap, tag?tag:"ns1:getAllInstruments", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -103762,7 +103762,7 @@ SOAP_FMAC3 ns1__listInstrumentsResponse ** SOAP_FMAC4 soap_in_PointerTons1__list SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTons1__listInstrumentsResponse(struct soap *soap, ns1__listInstrumentsResponse *const*a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__listInstrumentsResponse); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__listInstrumentsResponse); if (soap_out_PointerTons1__listInstrumentsResponse(soap, tag?tag:"ns1:listInstrumentsResponse", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -103819,7 +103819,7 @@ SOAP_FMAC3 ns1__listInstruments ** SOAP_FMAC4 soap_in_PointerTons1__listInstrume SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTons1__listInstruments(struct soap *soap, ns1__listInstruments *const*a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__listInstruments); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__listInstruments); if (soap_out_PointerTons1__listInstruments(soap, tag?tag:"ns1:listInstruments", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -103876,7 +103876,7 @@ SOAP_FMAC3 ns1__searchByUserSurnamePaginationResponse ** SOAP_FMAC4 soap_in_Poin SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTons1__searchByUserSurnamePaginationResponse(struct soap *soap, ns1__searchByUserSurnamePaginationResponse *const*a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__searchByUserSurnamePaginationResponse); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__searchByUserSurnamePaginationResponse); if (soap_out_PointerTons1__searchByUserSurnamePaginationResponse(soap, tag?tag:"ns1:searchByUserSurnamePaginationResponse", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -103933,7 +103933,7 @@ SOAP_FMAC3 ns1__searchByUserSurnamePagination ** SOAP_FMAC4 soap_in_PointerTons1 SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTons1__searchByUserSurnamePagination(struct soap *soap, ns1__searchByUserSurnamePagination *const*a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__searchByUserSurnamePagination); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__searchByUserSurnamePagination); if (soap_out_PointerTons1__searchByUserSurnamePagination(soap, tag?tag:"ns1:searchByUserSurnamePagination", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -103990,7 +103990,7 @@ SOAP_FMAC3 ns1__searchByUserSurnameResponse ** SOAP_FMAC4 soap_in_PointerTons1__ SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTons1__searchByUserSurnameResponse(struct soap *soap, ns1__searchByUserSurnameResponse *const*a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__searchByUserSurnameResponse); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__searchByUserSurnameResponse); if (soap_out_PointerTons1__searchByUserSurnameResponse(soap, tag?tag:"ns1:searchByUserSurnameResponse", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -104047,7 +104047,7 @@ SOAP_FMAC3 ns1__searchByUserSurname ** SOAP_FMAC4 soap_in_PointerTons1__searchBy SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTons1__searchByUserSurname(struct soap *soap, ns1__searchByUserSurname *const*a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__searchByUserSurname); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__searchByUserSurname); if (soap_out_PointerTons1__searchByUserSurname(soap, tag?tag:"ns1:searchByUserSurname", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -104104,7 +104104,7 @@ SOAP_FMAC3 ns1__searchByUserIDPaginationResponse ** SOAP_FMAC4 soap_in_PointerTo SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTons1__searchByUserIDPaginationResponse(struct soap *soap, ns1__searchByUserIDPaginationResponse *const*a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__searchByUserIDPaginationResponse); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__searchByUserIDPaginationResponse); if (soap_out_PointerTons1__searchByUserIDPaginationResponse(soap, tag?tag:"ns1:searchByUserIDPaginationResponse", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -104161,7 +104161,7 @@ SOAP_FMAC3 ns1__searchByUserIDPagination ** SOAP_FMAC4 soap_in_PointerTons1__sea SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTons1__searchByUserIDPagination(struct soap *soap, ns1__searchByUserIDPagination *const*a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__searchByUserIDPagination); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__searchByUserIDPagination); if (soap_out_PointerTons1__searchByUserIDPagination(soap, tag?tag:"ns1:searchByUserIDPagination", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -104218,7 +104218,7 @@ SOAP_FMAC3 ns1__searchByUserIDResponse ** SOAP_FMAC4 soap_in_PointerTons1__searc SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTons1__searchByUserIDResponse(struct soap *soap, ns1__searchByUserIDResponse *const*a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__searchByUserIDResponse); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__searchByUserIDResponse); if (soap_out_PointerTons1__searchByUserIDResponse(soap, tag?tag:"ns1:searchByUserIDResponse", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -104275,7 +104275,7 @@ SOAP_FMAC3 ns1__searchByUserID ** SOAP_FMAC4 soap_in_PointerTons1__searchByUserI SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTons1__searchByUserID(struct soap *soap, ns1__searchByUserID *const*a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__searchByUserID); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__searchByUserID); if (soap_out_PointerTons1__searchByUserID(soap, tag?tag:"ns1:searchByUserID", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -104332,7 +104332,7 @@ SOAP_FMAC3 ns1__getMyInvestigationsIncludesPaginationResponse ** SOAP_FMAC4 soap SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTons1__getMyInvestigationsIncludesPaginationResponse(struct soap *soap, ns1__getMyInvestigationsIncludesPaginationResponse *const*a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__getMyInvestigationsIncludesPaginationResponse); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__getMyInvestigationsIncludesPaginationResponse); if (soap_out_PointerTons1__getMyInvestigationsIncludesPaginationResponse(soap, tag?tag:"ns1:getMyInvestigationsIncludesPaginationResponse", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -104389,7 +104389,7 @@ SOAP_FMAC3 ns1__getMyInvestigationsIncludesPagination ** SOAP_FMAC4 soap_in_Poin SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTons1__getMyInvestigationsIncludesPagination(struct soap *soap, ns1__getMyInvestigationsIncludesPagination *const*a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__getMyInvestigationsIncludesPagination); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__getMyInvestigationsIncludesPagination); if (soap_out_PointerTons1__getMyInvestigationsIncludesPagination(soap, tag?tag:"ns1:getMyInvestigationsIncludesPagination", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -104446,7 +104446,7 @@ SOAP_FMAC3 ns1__getMyInvestigationsIncludesResponse ** SOAP_FMAC4 soap_in_Pointe SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTons1__getMyInvestigationsIncludesResponse(struct soap *soap, ns1__getMyInvestigationsIncludesResponse *const*a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__getMyInvestigationsIncludesResponse); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__getMyInvestigationsIncludesResponse); if (soap_out_PointerTons1__getMyInvestigationsIncludesResponse(soap, tag?tag:"ns1:getMyInvestigationsIncludesResponse", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -104503,7 +104503,7 @@ SOAP_FMAC3 ns1__getMyInvestigationsIncludes ** SOAP_FMAC4 soap_in_PointerTons1__ SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTons1__getMyInvestigationsIncludes(struct soap *soap, ns1__getMyInvestigationsIncludes *const*a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__getMyInvestigationsIncludes); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__getMyInvestigationsIncludes); if (soap_out_PointerTons1__getMyInvestigationsIncludes(soap, tag?tag:"ns1:getMyInvestigationsIncludes", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -104560,7 +104560,7 @@ SOAP_FMAC3 ns1__getMyInvestigationsResponse ** SOAP_FMAC4 soap_in_PointerTons1__ SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTons1__getMyInvestigationsResponse(struct soap *soap, ns1__getMyInvestigationsResponse *const*a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__getMyInvestigationsResponse); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__getMyInvestigationsResponse); if (soap_out_PointerTons1__getMyInvestigationsResponse(soap, tag?tag:"ns1:getMyInvestigationsResponse", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -104617,7 +104617,7 @@ SOAP_FMAC3 ns1__getMyInvestigations ** SOAP_FMAC4 soap_in_PointerTons1__getMyInv SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTons1__getMyInvestigations(struct soap *soap, ns1__getMyInvestigations *const*a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__getMyInvestigations); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__getMyInvestigations); if (soap_out_PointerTons1__getMyInvestigations(soap, tag?tag:"ns1:getMyInvestigations", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -104674,7 +104674,7 @@ SOAP_FMAC3 ns1__searchByKeywordsAllResponse ** SOAP_FMAC4 soap_in_PointerTons1__ SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTons1__searchByKeywordsAllResponse(struct soap *soap, ns1__searchByKeywordsAllResponse *const*a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__searchByKeywordsAllResponse); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__searchByKeywordsAllResponse); if (soap_out_PointerTons1__searchByKeywordsAllResponse(soap, tag?tag:"ns1:searchByKeywordsAllResponse", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -104731,7 +104731,7 @@ SOAP_FMAC3 ns1__searchByKeywordsAll ** SOAP_FMAC4 soap_in_PointerTons1__searchBy SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTons1__searchByKeywordsAll(struct soap *soap, ns1__searchByKeywordsAll *const*a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__searchByKeywordsAll); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__searchByKeywordsAll); if (soap_out_PointerTons1__searchByKeywordsAll(soap, tag?tag:"ns1:searchByKeywordsAll", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -104788,7 +104788,7 @@ SOAP_FMAC3 ns1__searchByKeywordsResponse ** SOAP_FMAC4 soap_in_PointerTons1__sea SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTons1__searchByKeywordsResponse(struct soap *soap, ns1__searchByKeywordsResponse *const*a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__searchByKeywordsResponse); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__searchByKeywordsResponse); if (soap_out_PointerTons1__searchByKeywordsResponse(soap, tag?tag:"ns1:searchByKeywordsResponse", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -104845,7 +104845,7 @@ SOAP_FMAC3 ns1__searchByKeywords ** SOAP_FMAC4 soap_in_PointerTons1__searchByKey SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTons1__searchByKeywords(struct soap *soap, ns1__searchByKeywords *const*a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__searchByKeywords); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__searchByKeywords); if (soap_out_PointerTons1__searchByKeywords(soap, tag?tag:"ns1:searchByKeywords", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -104902,7 +104902,7 @@ SOAP_FMAC3 ns1__searchByAdvancedPaginationResponse ** SOAP_FMAC4 soap_in_Pointer SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTons1__searchByAdvancedPaginationResponse(struct soap *soap, ns1__searchByAdvancedPaginationResponse *const*a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__searchByAdvancedPaginationResponse); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__searchByAdvancedPaginationResponse); if (soap_out_PointerTons1__searchByAdvancedPaginationResponse(soap, tag?tag:"ns1:searchByAdvancedPaginationResponse", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -104959,7 +104959,7 @@ SOAP_FMAC3 ns1__searchByAdvancedPagination ** SOAP_FMAC4 soap_in_PointerTons1__s SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTons1__searchByAdvancedPagination(struct soap *soap, ns1__searchByAdvancedPagination *const*a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__searchByAdvancedPagination); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__searchByAdvancedPagination); if (soap_out_PointerTons1__searchByAdvancedPagination(soap, tag?tag:"ns1:searchByAdvancedPagination", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -105016,7 +105016,7 @@ SOAP_FMAC3 ns1__searchByAdvancedResponse ** SOAP_FMAC4 soap_in_PointerTons1__sea SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTons1__searchByAdvancedResponse(struct soap *soap, ns1__searchByAdvancedResponse *const*a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__searchByAdvancedResponse); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__searchByAdvancedResponse); if (soap_out_PointerTons1__searchByAdvancedResponse(soap, tag?tag:"ns1:searchByAdvancedResponse", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -105073,7 +105073,7 @@ SOAP_FMAC3 ns1__searchByAdvanced ** SOAP_FMAC4 soap_in_PointerTons1__searchByAdv SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTons1__searchByAdvanced(struct soap *soap, ns1__searchByAdvanced *const*a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__searchByAdvanced); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__searchByAdvanced); if (soap_out_PointerTons1__searchByAdvanced(soap, tag?tag:"ns1:searchByAdvanced", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -105130,7 +105130,7 @@ SOAP_FMAC3 ns1__getAllKeywordsResponse ** SOAP_FMAC4 soap_in_PointerTons1__getAl SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTons1__getAllKeywordsResponse(struct soap *soap, ns1__getAllKeywordsResponse *const*a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__getAllKeywordsResponse); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__getAllKeywordsResponse); if (soap_out_PointerTons1__getAllKeywordsResponse(soap, tag?tag:"ns1:getAllKeywordsResponse", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -105187,7 +105187,7 @@ SOAP_FMAC3 ns1__getAllKeywords ** SOAP_FMAC4 soap_in_PointerTons1__getAllKeyword SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTons1__getAllKeywords(struct soap *soap, ns1__getAllKeywords *const*a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__getAllKeywords); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__getAllKeywords); if (soap_out_PointerTons1__getAllKeywords(soap, tag?tag:"ns1:getAllKeywords", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -105244,7 +105244,7 @@ SOAP_FMAC3 ns1__getKeywordsForUserTypeResponse ** SOAP_FMAC4 soap_in_PointerTons SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTons1__getKeywordsForUserTypeResponse(struct soap *soap, ns1__getKeywordsForUserTypeResponse *const*a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__getKeywordsForUserTypeResponse); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__getKeywordsForUserTypeResponse); if (soap_out_PointerTons1__getKeywordsForUserTypeResponse(soap, tag?tag:"ns1:getKeywordsForUserTypeResponse", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -105301,7 +105301,7 @@ SOAP_FMAC3 ns1__getKeywordsForUserType ** SOAP_FMAC4 soap_in_PointerTons1__getKe SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTons1__getKeywordsForUserType(struct soap *soap, ns1__getKeywordsForUserType *const*a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__getKeywordsForUserType); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__getKeywordsForUserType); if (soap_out_PointerTons1__getKeywordsForUserType(soap, tag?tag:"ns1:getKeywordsForUserType", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -105358,7 +105358,7 @@ SOAP_FMAC3 ns1__getKeywordsForUserMaxResponse ** SOAP_FMAC4 soap_in_PointerTons1 SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTons1__getKeywordsForUserMaxResponse(struct soap *soap, ns1__getKeywordsForUserMaxResponse *const*a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__getKeywordsForUserMaxResponse); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__getKeywordsForUserMaxResponse); if (soap_out_PointerTons1__getKeywordsForUserMaxResponse(soap, tag?tag:"ns1:getKeywordsForUserMaxResponse", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -105415,7 +105415,7 @@ SOAP_FMAC3 ns1__getKeywordsForUserMax ** SOAP_FMAC4 soap_in_PointerTons1__getKey SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTons1__getKeywordsForUserMax(struct soap *soap, ns1__getKeywordsForUserMax *const*a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__getKeywordsForUserMax); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__getKeywordsForUserMax); if (soap_out_PointerTons1__getKeywordsForUserMax(soap, tag?tag:"ns1:getKeywordsForUserMax", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -105472,7 +105472,7 @@ SOAP_FMAC3 ns1__getKeywordsForUserStartWithMaxResponse ** SOAP_FMAC4 soap_in_Poi SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTons1__getKeywordsForUserStartWithMaxResponse(struct soap *soap, ns1__getKeywordsForUserStartWithMaxResponse *const*a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__getKeywordsForUserStartWithMaxResponse); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__getKeywordsForUserStartWithMaxResponse); if (soap_out_PointerTons1__getKeywordsForUserStartWithMaxResponse(soap, tag?tag:"ns1:getKeywordsForUserStartWithMaxResponse", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -105529,7 +105529,7 @@ SOAP_FMAC3 ns1__getKeywordsForUserStartWithMax ** SOAP_FMAC4 soap_in_PointerTons SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTons1__getKeywordsForUserStartWithMax(struct soap *soap, ns1__getKeywordsForUserStartWithMax *const*a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__getKeywordsForUserStartWithMax); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__getKeywordsForUserStartWithMax); if (soap_out_PointerTons1__getKeywordsForUserStartWithMax(soap, tag?tag:"ns1:getKeywordsForUserStartWithMax", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -105586,7 +105586,7 @@ SOAP_FMAC3 ns1__getKeywordsForUserResponse ** SOAP_FMAC4 soap_in_PointerTons1__g SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTons1__getKeywordsForUserResponse(struct soap *soap, ns1__getKeywordsForUserResponse *const*a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__getKeywordsForUserResponse); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__getKeywordsForUserResponse); if (soap_out_PointerTons1__getKeywordsForUserResponse(soap, tag?tag:"ns1:getKeywordsForUserResponse", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -105643,7 +105643,7 @@ SOAP_FMAC3 ns1__getKeywordsForUser ** SOAP_FMAC4 soap_in_PointerTons1__getKeywor SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTons1__getKeywordsForUser(struct soap *soap, ns1__getKeywordsForUser *const*a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__getKeywordsForUser); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__getKeywordsForUser); if (soap_out_PointerTons1__getKeywordsForUser(soap, tag?tag:"ns1:getKeywordsForUser", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -105700,7 +105700,7 @@ SOAP_FMAC3 ns1__isSessionValidResponse ** SOAP_FMAC4 soap_in_PointerTons1__isSes SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTons1__isSessionValidResponse(struct soap *soap, ns1__isSessionValidResponse *const*a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__isSessionValidResponse); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__isSessionValidResponse); if (soap_out_PointerTons1__isSessionValidResponse(soap, tag?tag:"ns1:isSessionValidResponse", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -105757,7 +105757,7 @@ SOAP_FMAC3 ns1__isSessionValid ** SOAP_FMAC4 soap_in_PointerTons1__isSessionVali SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTons1__isSessionValid(struct soap *soap, ns1__isSessionValid *const*a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__isSessionValid); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__isSessionValid); if (soap_out_PointerTons1__isSessionValid(soap, tag?tag:"ns1:isSessionValid", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -105814,7 +105814,7 @@ SOAP_FMAC3 ns3__getUserDetailsResponse ** SOAP_FMAC4 soap_in_PointerTons3__getUs SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTons3__getUserDetailsResponse(struct soap *soap, ns3__getUserDetailsResponse *const*a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons3__getUserDetailsResponse); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons3__getUserDetailsResponse); if (soap_out_PointerTons3__getUserDetailsResponse(soap, tag?tag:"ns3:getUserDetailsResponse", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -105871,7 +105871,7 @@ SOAP_FMAC3 ns3__getUserDetails ** SOAP_FMAC4 soap_in_PointerTons3__getUserDetail SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTons3__getUserDetails(struct soap *soap, ns3__getUserDetails *const*a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons3__getUserDetails); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons3__getUserDetails); if (soap_out_PointerTons3__getUserDetails(soap, tag?tag:"ns3:getUserDetails", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -105928,7 +105928,7 @@ SOAP_FMAC3 ns1__logoutResponse ** SOAP_FMAC4 soap_in_PointerTons1__logoutRespons SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTons1__logoutResponse(struct soap *soap, ns1__logoutResponse *const*a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__logoutResponse); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__logoutResponse); if (soap_out_PointerTons1__logoutResponse(soap, tag?tag:"ns1:logoutResponse", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -105985,7 +105985,7 @@ SOAP_FMAC3 ns1__logout ** SOAP_FMAC4 soap_in_PointerTons1__logout(struct soap *s SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTons1__logout(struct soap *soap, ns1__logout *const*a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__logout); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__logout); if (soap_out_PointerTons1__logout(soap, tag?tag:"ns1:logout", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -106042,7 +106042,7 @@ SOAP_FMAC3 ns1__loginLifetimeResponse ** SOAP_FMAC4 soap_in_PointerTons1__loginL SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTons1__loginLifetimeResponse(struct soap *soap, ns1__loginLifetimeResponse *const*a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__loginLifetimeResponse); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__loginLifetimeResponse); if (soap_out_PointerTons1__loginLifetimeResponse(soap, tag?tag:"ns1:loginLifetimeResponse", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -106099,7 +106099,7 @@ SOAP_FMAC3 ns1__loginLifetime ** SOAP_FMAC4 soap_in_PointerTons1__loginLifetime( SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTons1__loginLifetime(struct soap *soap, ns1__loginLifetime *const*a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__loginLifetime); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__loginLifetime); if (soap_out_PointerTons1__loginLifetime(soap, tag?tag:"ns1:loginLifetime", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -106156,7 +106156,7 @@ SOAP_FMAC3 ns1__loginResponse ** SOAP_FMAC4 soap_in_PointerTons1__loginResponse( SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTons1__loginResponse(struct soap *soap, ns1__loginResponse *const*a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__loginResponse); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__loginResponse); if (soap_out_PointerTons1__loginResponse(soap, tag?tag:"ns1:loginResponse", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -106213,7 +106213,7 @@ SOAP_FMAC3 ns1__login ** SOAP_FMAC4 soap_in_PointerTons1__login(struct soap *soa SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTons1__login(struct soap *soap, ns1__login *const*a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__login); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__login); if (soap_out_PointerTons1__login(soap, tag?tag:"ns1:login", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -106270,7 +106270,7 @@ SOAP_FMAC3 ns3__ValidationException ** SOAP_FMAC4 soap_in_PointerTons3__Validati SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTons3__ValidationException(struct soap *soap, ns3__ValidationException *const*a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons3__ValidationException); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons3__ValidationException); if (soap_out_PointerTons3__ValidationException(soap, tag?tag:"ns3:ValidationException", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -106327,7 +106327,7 @@ SOAP_FMAC3 ns3__SessionException ** SOAP_FMAC4 soap_in_PointerTons3__SessionExce SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTons3__SessionException(struct soap *soap, ns3__SessionException *const*a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons3__SessionException); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons3__SessionException); if (soap_out_PointerTons3__SessionException(soap, tag?tag:"ns3:SessionException", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -106384,7 +106384,7 @@ SOAP_FMAC3 ns3__NoSuchUserException ** SOAP_FMAC4 soap_in_PointerTons3__NoSuchUs SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTons3__NoSuchUserException(struct soap *soap, ns3__NoSuchUserException *const*a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons3__NoSuchUserException); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons3__NoSuchUserException); if (soap_out_PointerTons3__NoSuchUserException(soap, tag?tag:"ns3:NoSuchUserException", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -106441,7 +106441,7 @@ SOAP_FMAC3 ns3__NoSuchObjectFoundException ** SOAP_FMAC4 soap_in_PointerTons3__N SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTons3__NoSuchObjectFoundException(struct soap *soap, ns3__NoSuchObjectFoundException *const*a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons3__NoSuchObjectFoundException); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons3__NoSuchObjectFoundException); if (soap_out_PointerTons3__NoSuchObjectFoundException(soap, tag?tag:"ns3:NoSuchObjectFoundException", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -106498,7 +106498,7 @@ SOAP_FMAC3 ns1__InsufficientPrivilegesException ** SOAP_FMAC4 soap_in_PointerTon SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTons1__InsufficientPrivilegesException(struct soap *soap, ns1__InsufficientPrivilegesException *const*a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__InsufficientPrivilegesException); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__InsufficientPrivilegesException); if (soap_out_PointerTons1__InsufficientPrivilegesException(soap, tag?tag:"ns1:InsufficientPrivilegesException", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -106555,7 +106555,7 @@ SOAP_FMAC3 ns1__ICATAPIException ** SOAP_FMAC4 soap_in_PointerTons1__ICATAPIExce SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTons1__ICATAPIException(struct soap *soap, ns1__ICATAPIException *const*a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__ICATAPIException); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__ICATAPIException); if (soap_out_PointerTons1__ICATAPIException(soap, tag?tag:"ns1:ICATAPIException", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -106607,7 +106607,7 @@ SOAP_FMAC3 enum ns1__parameterType ** SOAP_FMAC4 soap_in_PointerTons1__parameter SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTons1__parameterType(struct soap *soap, enum ns1__parameterType *const*a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__parameterType); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__parameterType); if (soap_out_PointerTons1__parameterType(soap, tag?tag:"ns1:parameterType", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -106659,7 +106659,7 @@ SOAP_FMAC3 enum ns1__comparisonOperator ** SOAP_FMAC4 soap_in_PointerTons1__comp SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTons1__comparisonOperator(struct soap *soap, enum ns1__comparisonOperator *const*a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__comparisonOperator); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__comparisonOperator); if (soap_out_PointerTons1__comparisonOperator(soap, tag?tag:"ns1:comparisonOperator", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -106711,7 +106711,7 @@ SOAP_FMAC3 enum ns1__logicalOperator ** SOAP_FMAC4 soap_in_PointerTons1__logical SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTons1__logicalOperator(struct soap *soap, enum ns1__logicalOperator *const*a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__logicalOperator); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__logicalOperator); if (soap_out_PointerTons1__logicalOperator(soap, tag?tag:"ns1:logicalOperator", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -106768,7 +106768,7 @@ SOAP_FMAC3 ns1__shiftPK ** SOAP_FMAC4 soap_in_PointerTons1__shiftPK(struct soap SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTons1__shiftPK(struct soap *soap, ns1__shiftPK *const*a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__shiftPK); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__shiftPK); if (soap_out_PointerTons1__shiftPK(soap, tag?tag:"ns1:shiftPK", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -106825,7 +106825,7 @@ SOAP_FMAC3 ns1__shift ** SOAP_FMAC4 soap_in_PointerTons1__shift(struct soap *soa SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTons1__shift(struct soap *soap, ns1__shift *const*a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__shift); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__shift); if (soap_out_PointerTons1__shift(soap, tag?tag:"ns1:shift", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -106882,7 +106882,7 @@ SOAP_FMAC3 ns1__parameterPK ** SOAP_FMAC4 soap_in_PointerTons1__parameterPK(stru SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTons1__parameterPK(struct soap *soap, ns1__parameterPK *const*a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__parameterPK); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__parameterPK); if (soap_out_PointerTons1__parameterPK(soap, tag?tag:"ns1:parameterPK", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -106939,7 +106939,7 @@ SOAP_FMAC3 ns1__relatedDatafilesPK ** SOAP_FMAC4 soap_in_PointerTons1__relatedDa SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTons1__relatedDatafilesPK(struct soap *soap, ns1__relatedDatafilesPK *const*a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__relatedDatafilesPK); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__relatedDatafilesPK); if (soap_out_PointerTons1__relatedDatafilesPK(soap, tag?tag:"ns1:relatedDatafilesPK", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -106996,7 +106996,7 @@ SOAP_FMAC3 ns1__datafileFormatPK ** SOAP_FMAC4 soap_in_PointerTons1__datafileFor SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTons1__datafileFormatPK(struct soap *soap, ns1__datafileFormatPK *const*a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__datafileFormatPK); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__datafileFormatPK); if (soap_out_PointerTons1__datafileFormatPK(soap, tag?tag:"ns1:datafileFormatPK", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -107053,7 +107053,7 @@ SOAP_FMAC3 ns1__relatedDatafiles ** SOAP_FMAC4 soap_in_PointerTons1__relatedData SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTons1__relatedDatafiles(struct soap *soap, ns1__relatedDatafiles *const*a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__relatedDatafiles); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__relatedDatafiles); if (soap_out_PointerTons1__relatedDatafiles(soap, tag?tag:"ns1:relatedDatafiles", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -107105,7 +107105,7 @@ SOAP_FMAC3 enum ns1__parameterValueType ** SOAP_FMAC4 soap_in_PointerTons1__para SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTons1__parameterValueType(struct soap *soap, enum ns1__parameterValueType *const*a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__parameterValueType); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__parameterValueType); if (soap_out_PointerTons1__parameterValueType(soap, tag?tag:"ns1:parameterValueType", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -107157,7 +107157,7 @@ SOAP_FMAC3 enum ns1__sampleInclude ** SOAP_FMAC4 soap_in_PointerTons1__sampleInc SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTons1__sampleInclude(struct soap *soap, enum ns1__sampleInclude *const*a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__sampleInclude); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__sampleInclude); if (soap_out_PointerTons1__sampleInclude(soap, tag?tag:"ns1:sampleInclude", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -107209,7 +107209,7 @@ SOAP_FMAC3 enum ns1__restrictionAttributes ** SOAP_FMAC4 soap_in_PointerTons1__r SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTons1__restrictionAttributes(struct soap *soap, enum ns1__restrictionAttributes *const*a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__restrictionAttributes); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__restrictionAttributes); if (soap_out_PointerTons1__restrictionAttributes(soap, tag?tag:"ns1:restrictionAttributes", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -107261,7 +107261,7 @@ SOAP_FMAC3 int ** SOAP_FMAC4 soap_in_PointerToint(struct soap *soap, const char SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerToint(struct soap *soap, int *const*a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerToint); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerToint); if (soap_out_PointerToint(soap, tag?tag:"int", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -107313,7 +107313,7 @@ SOAP_FMAC3 enum ns1__datafileInclude ** SOAP_FMAC4 soap_in_PointerTons1__datafil SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTons1__datafileInclude(struct soap *soap, enum ns1__datafileInclude *const*a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__datafileInclude); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__datafileInclude); if (soap_out_PointerTons1__datafileInclude(soap, tag?tag:"ns1:datafileInclude", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -107370,7 +107370,7 @@ SOAP_FMAC3 ns1__userDetails ** SOAP_FMAC4 soap_in_PointerTons1__userDetails(stru SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTons1__userDetails(struct soap *soap, ns1__userDetails *const*a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__userDetails); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__userDetails); if (soap_out_PointerTons1__userDetails(soap, tag?tag:"ns1:userDetails", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -107422,7 +107422,7 @@ SOAP_FMAC3 enum ns1__datasetInclude ** SOAP_FMAC4 soap_in_PointerTons1__datasetI SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTons1__datasetInclude(struct soap *soap, enum ns1__datasetInclude *const*a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__datasetInclude); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__datasetInclude); if (soap_out_PointerTons1__datasetInclude(soap, tag?tag:"ns1:datasetInclude", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -107479,7 +107479,7 @@ SOAP_FMAC3 ns1__datafileFormat ** SOAP_FMAC4 soap_in_PointerTons1__datafileForma SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTons1__datafileFormat(struct soap *soap, ns1__datafileFormat *const*a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__datafileFormat); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__datafileFormat); if (soap_out_PointerTons1__datafileFormat(soap, tag?tag:"ns1:datafileFormat", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -107531,7 +107531,7 @@ SOAP_FMAC3 double ** SOAP_FMAC4 soap_in_PointerTodouble(struct soap *soap, const SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTodouble(struct soap *soap, double *const*a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTodouble); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTodouble); if (soap_out_PointerTodouble(soap, tag?tag:"double", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -107583,7 +107583,7 @@ SOAP_FMAC3 time_t ** SOAP_FMAC4 soap_in_PointerTotime(struct soap *soap, const c SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTotime(struct soap *soap, time_t *const*a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTotime); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTotime); if (soap_out_PointerTotime(soap, tag?tag:"dateTime", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -107640,7 +107640,7 @@ SOAP_FMAC3 ns1__advancedSearchDetails ** SOAP_FMAC4 soap_in_PointerTons1__advanc SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTons1__advancedSearchDetails(struct soap *soap, ns1__advancedSearchDetails *const*a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__advancedSearchDetails); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__advancedSearchDetails); if (soap_out_PointerTons1__advancedSearchDetails(soap, tag?tag:"ns1:advancedSearchDetails", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -107697,7 +107697,7 @@ SOAP_FMAC3 ns1__icatAuthorisation ** SOAP_FMAC4 soap_in_PointerTons1__icatAuthor SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTons1__icatAuthorisation(struct soap *soap, ns1__icatAuthorisation *const*a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__icatAuthorisation); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__icatAuthorisation); if (soap_out_PointerTons1__icatAuthorisation(soap, tag?tag:"ns1:icatAuthorisation", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -107749,7 +107749,7 @@ SOAP_FMAC3 enum ns1__elementType ** SOAP_FMAC4 soap_in_PointerTons1__elementType SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTons1__elementType(struct soap *soap, enum ns1__elementType *const*a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__elementType); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__elementType); if (soap_out_PointerTons1__elementType(soap, tag?tag:"ns1:elementType", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -107806,7 +107806,7 @@ SOAP_FMAC3 ns1__keyword ** SOAP_FMAC4 soap_in_PointerTons1__keyword(struct soap SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTons1__keyword(struct soap *soap, ns1__keyword *const*a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__keyword); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__keyword); if (soap_out_PointerTons1__keyword(soap, tag?tag:"ns1:keyword", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -107863,7 +107863,7 @@ SOAP_FMAC3 ns1__datasetParameter ** SOAP_FMAC4 soap_in_PointerTons1__datasetPara SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTons1__datasetParameter(struct soap *soap, ns1__datasetParameter *const*a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__datasetParameter); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__datasetParameter); if (soap_out_PointerTons1__datasetParameter(soap, tag?tag:"ns1:datasetParameter", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -107920,7 +107920,7 @@ SOAP_FMAC3 ns1__sampleParameterPK ** SOAP_FMAC4 soap_in_PointerTons1__samplePara SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTons1__sampleParameterPK(struct soap *soap, ns1__sampleParameterPK *const*a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__sampleParameterPK); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__sampleParameterPK); if (soap_out_PointerTons1__sampleParameterPK(soap, tag?tag:"ns1:sampleParameterPK", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -107977,7 +107977,7 @@ SOAP_FMAC3 ns1__investigator ** SOAP_FMAC4 soap_in_PointerTons1__investigator(st SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTons1__investigator(struct soap *soap, ns1__investigator *const*a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__investigator); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__investigator); if (soap_out_PointerTons1__investigator(soap, tag?tag:"ns1:investigator", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -108034,7 +108034,7 @@ SOAP_FMAC3 ns1__datafileParameterPK ** SOAP_FMAC4 soap_in_PointerTons1__datafile SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTons1__datafileParameterPK(struct soap *soap, ns1__datafileParameterPK *const*a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__datafileParameterPK); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__datafileParameterPK); if (soap_out_PointerTons1__datafileParameterPK(soap, tag?tag:"ns1:datafileParameterPK", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -108091,7 +108091,7 @@ SOAP_FMAC3 ns1__publication ** SOAP_FMAC4 soap_in_PointerTons1__publication(stru SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTons1__publication(struct soap *soap, ns1__publication *const*a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__publication); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__publication); if (soap_out_PointerTons1__publication(soap, tag?tag:"ns1:publication", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -108148,7 +108148,7 @@ SOAP_FMAC3 ns1__datasetParameterPK ** SOAP_FMAC4 soap_in_PointerTons1__datasetPa SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTons1__datasetParameterPK(struct soap *soap, ns1__datasetParameterPK *const*a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__datasetParameterPK); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__datasetParameterPK); if (soap_out_PointerTons1__datasetParameterPK(soap, tag?tag:"ns1:datasetParameterPK", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -108200,7 +108200,7 @@ SOAP_FMAC3 enum ns1__investigationInclude ** SOAP_FMAC4 soap_in_PointerTons1__in SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTons1__investigationInclude(struct soap *soap, enum ns1__investigationInclude *const*a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__investigationInclude); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__investigationInclude); if (soap_out_PointerTons1__investigationInclude(soap, tag?tag:"ns1:investigationInclude", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -108257,7 +108257,7 @@ SOAP_FMAC3 ns1__keywordDetails ** SOAP_FMAC4 soap_in_PointerTons1__keywordDetail SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTons1__keywordDetails(struct soap *soap, ns1__keywordDetails *const*a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__keywordDetails); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__keywordDetails); if (soap_out_PointerTons1__keywordDetails(soap, tag?tag:"ns1:keywordDetails", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -108314,7 +108314,7 @@ SOAP_FMAC3 ns1__investigation ** SOAP_FMAC4 soap_in_PointerTons1__investigation( SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTons1__investigation(struct soap *soap, ns1__investigation *const*a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__investigation); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__investigation); if (soap_out_PointerTons1__investigation(soap, tag?tag:"ns1:investigation", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -108371,7 +108371,7 @@ SOAP_FMAC3 ns1__downloadInfo ** SOAP_FMAC4 soap_in_PointerTons1__downloadInfo(st SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTons1__downloadInfo(struct soap *soap, ns1__downloadInfo *const*a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__downloadInfo); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__downloadInfo); if (soap_out_PointerTons1__downloadInfo(soap, tag?tag:"ns1:downloadInfo", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -108428,7 +108428,7 @@ SOAP_FMAC3 ns1__sampleParameter ** SOAP_FMAC4 soap_in_PointerTons1__sampleParame SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTons1__sampleParameter(struct soap *soap, ns1__sampleParameter *const*a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__sampleParameter); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__sampleParameter); if (soap_out_PointerTons1__sampleParameter(soap, tag?tag:"ns1:sampleParameter", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -108485,7 +108485,7 @@ SOAP_FMAC3 ns1__parameterComparisonCondition ** SOAP_FMAC4 soap_in_PointerTons1_ SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTons1__parameterComparisonCondition(struct soap *soap, ns1__parameterComparisonCondition *const*a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__parameterComparisonCondition); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__parameterComparisonCondition); if (soap_out_PointerTons1__parameterComparisonCondition(soap, tag?tag:"ns1:parameterComparisonCondition", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -108542,7 +108542,7 @@ SOAP_FMAC3 ns1__parameterSearch ** SOAP_FMAC4 soap_in_PointerTons1__parameterSea SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTons1__parameterSearch(struct soap *soap, ns1__parameterSearch *const*a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__parameterSearch); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__parameterSearch); if (soap_out_PointerTons1__parameterSearch(soap, tag?tag:"ns1:parameterSearch", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -108594,7 +108594,7 @@ SOAP_FMAC3 enum ns1__keywordType ** SOAP_FMAC4 soap_in_PointerTons1__keywordType SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTons1__keywordType(struct soap *soap, enum ns1__keywordType *const*a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__keywordType); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__keywordType); if (soap_out_PointerTons1__keywordType(soap, tag?tag:"ns1:keywordType", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -108651,7 +108651,7 @@ SOAP_FMAC3 ns1__dataset ** SOAP_FMAC4 soap_in_PointerTons1__dataset(struct soap SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTons1__dataset(struct soap *soap, ns1__dataset *const*a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__dataset); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__dataset); if (soap_out_PointerTons1__dataset(soap, tag?tag:"ns1:dataset", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -108708,7 +108708,7 @@ SOAP_FMAC3 ns1__keywordPK ** SOAP_FMAC4 soap_in_PointerTons1__keywordPK(struct s SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTons1__keywordPK(struct soap *soap, ns1__keywordPK *const*a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__keywordPK); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__keywordPK); if (soap_out_PointerTons1__keywordPK(soap, tag?tag:"ns1:keywordPK", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -108765,7 +108765,7 @@ SOAP_FMAC3 ns1__investigatorPK ** SOAP_FMAC4 soap_in_PointerTons1__investigatorP SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTons1__investigatorPK(struct soap *soap, ns1__investigatorPK *const*a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__investigatorPK); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__investigatorPK); if (soap_out_PointerTons1__investigatorPK(soap, tag?tag:"ns1:investigatorPK", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -108822,7 +108822,7 @@ SOAP_FMAC3 ns1__instrument ** SOAP_FMAC4 soap_in_PointerTons1__instrument(struct SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTons1__instrument(struct soap *soap, ns1__instrument *const*a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__instrument); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__instrument); if (soap_out_PointerTons1__instrument(soap, tag?tag:"ns1:instrument", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -108879,7 +108879,7 @@ SOAP_FMAC3 ns1__datafileParameter ** SOAP_FMAC4 soap_in_PointerTons1__datafilePa SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTons1__datafileParameter(struct soap *soap, ns1__datafileParameter *const*a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__datafileParameter); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__datafileParameter); if (soap_out_PointerTons1__datafileParameter(soap, tag?tag:"ns1:datafileParameter", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -108936,7 +108936,7 @@ SOAP_FMAC3 ns1__facilityCycle ** SOAP_FMAC4 soap_in_PointerTons1__facilityCycle( SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTons1__facilityCycle(struct soap *soap, ns1__facilityCycle *const*a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__facilityCycle); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__facilityCycle); if (soap_out_PointerTons1__facilityCycle(soap, tag?tag:"ns1:facilityCycle", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -108993,7 +108993,7 @@ SOAP_FMAC3 ns1__parameter ** SOAP_FMAC4 soap_in_PointerTons1__parameter(struct s SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTons1__parameter(struct soap *soap, ns1__parameter *const*a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__parameter); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__parameter); if (soap_out_PointerTons1__parameter(soap, tag?tag:"ns1:parameter", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -109050,7 +109050,7 @@ SOAP_FMAC3 ns1__parameterLogicalCondition ** SOAP_FMAC4 soap_in_PointerTons1__pa SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTons1__parameterLogicalCondition(struct soap *soap, ns1__parameterLogicalCondition *const*a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__parameterLogicalCondition); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__parameterLogicalCondition); if (soap_out_PointerTons1__parameterLogicalCondition(soap, tag?tag:"ns1:parameterLogicalCondition", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -109107,7 +109107,7 @@ SOAP_FMAC3 ns1__datafile ** SOAP_FMAC4 soap_in_PointerTons1__datafile(struct soa SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTons1__datafile(struct soap *soap, ns1__datafile *const*a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__datafile); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__datafile); if (soap_out_PointerTons1__datafile(soap, tag?tag:"ns1:datafile", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -109159,7 +109159,7 @@ SOAP_FMAC3 LONG64 ** SOAP_FMAC4 soap_in_PointerToLONG64(struct soap *soap, const SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerToLONG64(struct soap *soap, LONG64 *const*a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerToLONG64); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerToLONG64); if (soap_out_PointerToLONG64(soap, tag?tag:"long", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -109216,7 +109216,7 @@ SOAP_FMAC3 ns1__restrictionComparisonCondition ** SOAP_FMAC4 soap_in_PointerTons SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTons1__restrictionComparisonCondition(struct soap *soap, ns1__restrictionComparisonCondition *const*a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__restrictionComparisonCondition); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__restrictionComparisonCondition); if (soap_out_PointerTons1__restrictionComparisonCondition(soap, tag?tag:"ns1:restrictionComparisonCondition", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -109273,7 +109273,7 @@ SOAP_FMAC3 ns1__sample ** SOAP_FMAC4 soap_in_PointerTons1__sample(struct soap *s SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTons1__sample(struct soap *soap, ns1__sample *const*a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__sample); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__sample); if (soap_out_PointerTons1__sample(soap, tag?tag:"ns1:sample", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -109330,7 +109330,7 @@ SOAP_FMAC3 ns1__icatRole ** SOAP_FMAC4 soap_in_PointerTons1__icatRole(struct soa SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTons1__icatRole(struct soap *soap, ns1__icatRole *const*a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__icatRole); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__icatRole); if (soap_out_PointerTons1__icatRole(soap, tag?tag:"ns1:icatRole", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -109387,7 +109387,7 @@ SOAP_FMAC3 ns1__facilityUser ** SOAP_FMAC4 soap_in_PointerTons1__facilityUser(st SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTons1__facilityUser(struct soap *soap, ns1__facilityUser *const*a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__facilityUser); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__facilityUser); if (soap_out_PointerTons1__facilityUser(soap, tag?tag:"ns1:facilityUser", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -109452,7 +109452,7 @@ SOAP_FMAC3 ns1__restrictionCondition ** SOAP_FMAC4 soap_in_PointerTons1__restric SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTons1__restrictionCondition(struct soap *soap, ns1__restrictionCondition *const*a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__restrictionCondition); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__restrictionCondition); if (soap_out_PointerTons1__restrictionCondition(soap, tag?tag:"ns1:restrictionCondition", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -109521,7 +109521,7 @@ SOAP_FMAC3 ns1__parameterCondition ** SOAP_FMAC4 soap_in_PointerTons1__parameter SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTons1__parameterCondition(struct soap *soap, ns1__parameterCondition *const*a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__parameterCondition); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__parameterCondition); if (soap_out_PointerTons1__parameterCondition(soap, tag?tag:"ns1:parameterCondition", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -110962,7 +110962,7 @@ SOAP_FMAC3 xsd__anyType ** SOAP_FMAC4 soap_in_PointerToxsd__anyType(struct soap SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerToxsd__anyType(struct soap *soap, xsd__anyType *const*a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerToxsd__anyType); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerToxsd__anyType); if (soap_out_PointerToxsd__anyType(soap, tag?tag:"xsd:anyType", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -111019,7 +111019,7 @@ SOAP_FMAC3 ns1__restrictionLogicalCondition ** SOAP_FMAC4 soap_in_PointerTons1__ SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTons1__restrictionLogicalCondition(struct soap *soap, ns1__restrictionLogicalCondition *const*a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__restrictionLogicalCondition); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTons1__restrictionLogicalCondition); if (soap_out_PointerTons1__restrictionLogicalCondition(soap, tag?tag:"ns1:restrictionLogicalCondition", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -111072,7 +111072,7 @@ SOAP_FMAC3 std::string ** SOAP_FMAC4 soap_in_PointerTostd__string(struct soap *s SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTostd__string(struct soap *soap, std::string *const*a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTostd__string); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_PointerTostd__string); if (soap_out_PointerTostd__string(soap, tag?tag:"string", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -111106,7 +111106,7 @@ SOAP_FMAC3 char * * SOAP_FMAC4 soap_in__QName(struct soap *soap, const char *tag SOAP_FMAC3 int SOAP_FMAC4 soap_put__QName(struct soap *soap, char *const*a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3__QName); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3__QName); if (soap_out__QName(soap, tag?tag:"byte", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -111150,7 +111150,7 @@ SOAP_FMAC3 char * * SOAP_FMAC4 soap_in_string(struct soap *soap, const char *tag SOAP_FMAC3 int SOAP_FMAC4 soap_put_string(struct soap *soap, char *const*a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_string); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat3_string); if (soap_out_string(soap, tag?tag:"byte", id, a, type)) return soap->error; return soap_putindependent(soap); diff --git a/Code/Mantid/Framework/ICat/src/ICat4/GSoapGenerated/ICat4C.cpp b/Code/Mantid/Framework/ICat/src/ICat4/GSoapGenerated/ICat4C.cpp index 6f731c7a20c1..fddc908cbbf7 100644 --- a/Code/Mantid/Framework/ICat/src/ICat4/GSoapGenerated/ICat4C.cpp +++ b/Code/Mantid/Framework/ICat/src/ICat4/GSoapGenerated/ICat4C.cpp @@ -4080,7 +4080,7 @@ SOAP_FMAC3 char * SOAP_FMAC4 soap_in_byte(struct soap *soap, const char *tag, ch SOAP_FMAC3 int SOAP_FMAC4 soap_put_byte(struct soap *soap, const char *a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat4_byte); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat4_byte); if (soap_out_byte(soap, tag?tag:"byte", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -4117,7 +4117,7 @@ SOAP_FMAC3 int * SOAP_FMAC4 soap_in_int(struct soap *soap, const char *tag, int SOAP_FMAC3 int SOAP_FMAC4 soap_put_int(struct soap *soap, const int *a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat4_int); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat4_int); if (soap_out_int(soap, tag?tag:"int", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -4154,7 +4154,7 @@ SOAP_FMAC3 LONG64 * SOAP_FMAC4 soap_in_LONG64(struct soap *soap, const char *tag SOAP_FMAC3 int SOAP_FMAC4 soap_put_LONG64(struct soap *soap, const LONG64 *a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat4_LONG64); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat4_LONG64); if (soap_out_LONG64(soap, tag?tag:"long", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -4191,7 +4191,7 @@ SOAP_FMAC3 double * SOAP_FMAC4 soap_in_double(struct soap *soap, const char *tag SOAP_FMAC3 int SOAP_FMAC4 soap_put_double(struct soap *soap, const double *a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat4_double); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat4_double); if (soap_out_double(soap, tag?tag:"double", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -4228,7 +4228,7 @@ SOAP_FMAC3 time_t * SOAP_FMAC4 soap_in_time(struct soap *soap, const char *tag, SOAP_FMAC3 int SOAP_FMAC4 soap_put_time(struct soap *soap, const time_t *a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat4_time); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat4_time); if (soap_out_time(soap, tag?tag:"dateTime", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -4311,7 +4311,7 @@ SOAP_FMAC3 enum ns1__accessType * SOAP_FMAC4 soap_in_ns1__accessType(struct soap SOAP_FMAC3 int SOAP_FMAC4 soap_put_ns1__accessType(struct soap *soap, const enum ns1__accessType *a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat4_ns1__accessType); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat4_ns1__accessType); if (soap_out_ns1__accessType(soap, tag?tag:"ns1:accessType", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -4393,7 +4393,7 @@ SOAP_FMAC3 enum ns1__relType * SOAP_FMAC4 soap_in_ns1__relType(struct soap *soap SOAP_FMAC3 int SOAP_FMAC4 soap_put_ns1__relType(struct soap *soap, const enum ns1__relType *a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat4_ns1__relType); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat4_ns1__relType); if (soap_out_ns1__relType(soap, tag?tag:"ns1:relType", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -4475,7 +4475,7 @@ SOAP_FMAC3 enum ns1__parameterValueType * SOAP_FMAC4 soap_in_ns1__parameterValue SOAP_FMAC3 int SOAP_FMAC4 soap_put_ns1__parameterValueType(struct soap *soap, const enum ns1__parameterValueType *a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat4_ns1__parameterValueType); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat4_ns1__parameterValueType); if (soap_out_ns1__parameterValueType(soap, tag?tag:"ns1:parameterValueType", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -4558,7 +4558,7 @@ SOAP_FMAC3 enum ns1__studyStatus * SOAP_FMAC4 soap_in_ns1__studyStatus(struct so SOAP_FMAC3 int SOAP_FMAC4 soap_put_ns1__studyStatus(struct soap *soap, const enum ns1__studyStatus *a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat4_ns1__studyStatus); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat4_ns1__studyStatus); if (soap_out_ns1__studyStatus(soap, tag?tag:"ns1:studyStatus", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -4644,7 +4644,7 @@ SOAP_FMAC3 enum ns1__icatExceptionType * SOAP_FMAC4 soap_in_ns1__icatExceptionTy SOAP_FMAC3 int SOAP_FMAC4 soap_put_ns1__icatExceptionType(struct soap *soap, const enum ns1__icatExceptionType *a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat4_ns1__icatExceptionType); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat4_ns1__icatExceptionType); if (soap_out_ns1__icatExceptionType(soap, tag?tag:"ns1:icatExceptionType", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -4728,7 +4728,7 @@ SOAP_FMAC3 bool * SOAP_FMAC4 soap_in_bool(struct soap *soap, const char *tag, bo SOAP_FMAC3 int SOAP_FMAC4 soap_put_bool(struct soap *soap, const bool *a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat4_bool); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat4_bool); if (soap_out_bool(soap, tag?tag:"boolean", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -4830,7 +4830,7 @@ SOAP_FMAC3 _ns1__login_credentials_entry * SOAP_FMAC4 soap_in__ns1__login_creden int _ns1__login_credentials_entry::soap_put(struct soap *soap, const char *tag, const char *type) const { - register int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat4__ns1__login_credentials_entry); + int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat4__ns1__login_credentials_entry); if (this->soap_out(soap, tag?tag:"ns1:login-credentials-entry", id, type)) return soap->error; return soap_putindependent(soap); @@ -4954,7 +4954,7 @@ SOAP_FMAC3 _ns1__login_credentials * SOAP_FMAC4 soap_in__ns1__login_credentials( int _ns1__login_credentials::soap_put(struct soap *soap, const char *tag, const char *type) const { - register int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat4__ns1__login_credentials); + int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat4__ns1__login_credentials); if (this->soap_out(soap, tag?tag:"ns1:login-credentials", id, type)) return soap->error; return soap_putindependent(soap); @@ -5056,7 +5056,7 @@ SOAP_FMAC3 ns1__accessType_ * SOAP_FMAC4 soap_in_ns1__accessType_(struct soap *s int ns1__accessType_::soap_put(struct soap *soap, const char *tag, const char *type) const { - register int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat4_ns1__accessType_); + int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat4_ns1__accessType_); if (this->soap_out(soap, tag?tag:"ns1:accessType", id, type)) return soap->error; return soap_putindependent(soap); @@ -5162,7 +5162,7 @@ SOAP_FMAC3 ns1__relType_ * SOAP_FMAC4 soap_in_ns1__relType_(struct soap *soap, c int ns1__relType_::soap_put(struct soap *soap, const char *tag, const char *type) const { - register int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat4_ns1__relType_); + int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat4_ns1__relType_); if (this->soap_out(soap, tag?tag:"ns1:relType", id, type)) return soap->error; return soap_putindependent(soap); @@ -5268,7 +5268,7 @@ SOAP_FMAC3 ns1__parameterValueType_ * SOAP_FMAC4 soap_in_ns1__parameterValueType int ns1__parameterValueType_::soap_put(struct soap *soap, const char *tag, const char *type) const { - register int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat4_ns1__parameterValueType_); + int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat4_ns1__parameterValueType_); if (this->soap_out(soap, tag?tag:"ns1:parameterValueType", id, type)) return soap->error; return soap_putindependent(soap); @@ -5374,7 +5374,7 @@ SOAP_FMAC3 ns1__studyStatus_ * SOAP_FMAC4 soap_in_ns1__studyStatus_(struct soap int ns1__studyStatus_::soap_put(struct soap *soap, const char *tag, const char *type) const { - register int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat4_ns1__studyStatus_); + int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat4_ns1__studyStatus_); if (this->soap_out(soap, tag?tag:"ns1:studyStatus", id, type)) return soap->error; return soap_putindependent(soap); @@ -5480,7 +5480,7 @@ SOAP_FMAC3 ns1__icatExceptionType_ * SOAP_FMAC4 soap_in_ns1__icatExceptionType_( int ns1__icatExceptionType_::soap_put(struct soap *soap, const char *tag, const char *type) const { - register int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat4_ns1__icatExceptionType_); + int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat4_ns1__icatExceptionType_); if (this->soap_out(soap, tag?tag:"ns1:icatExceptionType", id, type)) return soap->error; return soap_putindependent(soap); @@ -5625,7 +5625,7 @@ SOAP_FMAC3 ns1__getRemainingMinutesResponse * SOAP_FMAC4 soap_in_ns1__getRemaini int ns1__getRemainingMinutesResponse::soap_put(struct soap *soap, const char *tag, const char *type) const { - register int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat4_ns1__getRemainingMinutesResponse); + int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat4_ns1__getRemainingMinutesResponse); if (this->soap_out(soap, tag?tag:"ns1:getRemainingMinutesResponse", id, type)) return soap->error; return soap_putindependent(soap); @@ -5766,7 +5766,7 @@ SOAP_FMAC3 ns1__getRemainingMinutes * SOAP_FMAC4 soap_in_ns1__getRemainingMinute int ns1__getRemainingMinutes::soap_put(struct soap *soap, const char *tag, const char *type) const { - register int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat4_ns1__getRemainingMinutes); + int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat4_ns1__getRemainingMinutes); if (this->soap_out(soap, tag?tag:"ns1:getRemainingMinutes", id, type)) return soap->error; return soap_putindependent(soap); @@ -5870,7 +5870,7 @@ SOAP_FMAC3 ns1__logoutResponse * SOAP_FMAC4 soap_in_ns1__logoutResponse(struct s int ns1__logoutResponse::soap_put(struct soap *soap, const char *tag, const char *type) const { - register int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat4_ns1__logoutResponse); + int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat4_ns1__logoutResponse); if (this->soap_out(soap, tag?tag:"ns1:logoutResponse", id, type)) return soap->error; return soap_putindependent(soap); @@ -6011,7 +6011,7 @@ SOAP_FMAC3 ns1__logout * SOAP_FMAC4 soap_in_ns1__logout(struct soap *soap, const int ns1__logout::soap_put(struct soap *soap, const char *tag, const char *type) const { - register int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat4_ns1__logout); + int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat4_ns1__logout); if (this->soap_out(soap, tag?tag:"ns1:logout", id, type)) return soap->error; return soap_putindependent(soap); @@ -6149,7 +6149,7 @@ SOAP_FMAC3 ns1__searchResponse * SOAP_FMAC4 soap_in_ns1__searchResponse(struct s int ns1__searchResponse::soap_put(struct soap *soap, const char *tag, const char *type) const { - register int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat4_ns1__searchResponse); + int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat4_ns1__searchResponse); if (this->soap_out(soap, tag?tag:"ns1:searchResponse", id, type)) return soap->error; return soap_putindependent(soap); @@ -6300,7 +6300,7 @@ SOAP_FMAC3 ns1__search * SOAP_FMAC4 soap_in_ns1__search(struct soap *soap, const int ns1__search::soap_put(struct soap *soap, const char *tag, const char *type) const { - register int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat4_ns1__search); + int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat4_ns1__search); if (this->soap_out(soap, tag?tag:"ns1:search", id, type)) return soap->error; return soap_putindependent(soap); @@ -6444,7 +6444,7 @@ SOAP_FMAC3 ns1__isAccessAllowedResponse * SOAP_FMAC4 soap_in_ns1__isAccessAllowe int ns1__isAccessAllowedResponse::soap_put(struct soap *soap, const char *tag, const char *type) const { - register int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat4_ns1__isAccessAllowedResponse); + int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat4_ns1__isAccessAllowedResponse); if (this->soap_out(soap, tag?tag:"ns1:isAccessAllowedResponse", id, type)) return soap->error; return soap_putindependent(soap); @@ -6605,7 +6605,7 @@ SOAP_FMAC3 ns1__isAccessAllowed * SOAP_FMAC4 soap_in_ns1__isAccessAllowed(struct int ns1__isAccessAllowed::soap_put(struct soap *soap, const char *tag, const char *type) const { - register int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat4_ns1__isAccessAllowed); + int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat4_ns1__isAccessAllowed); if (this->soap_out(soap, tag?tag:"ns1:isAccessAllowed", id, type)) return soap->error; return soap_putindependent(soap); @@ -6709,7 +6709,7 @@ SOAP_FMAC3 ns1__deleteResponse * SOAP_FMAC4 soap_in_ns1__deleteResponse(struct s int ns1__deleteResponse::soap_put(struct soap *soap, const char *tag, const char *type) const { - register int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat4_ns1__deleteResponse); + int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat4_ns1__deleteResponse); if (this->soap_out(soap, tag?tag:"ns1:deleteResponse", id, type)) return soap->error; return soap_putindependent(soap); @@ -6860,7 +6860,7 @@ SOAP_FMAC3 ns1__delete * SOAP_FMAC4 soap_in_ns1__delete(struct soap *soap, const int ns1__delete::soap_put(struct soap *soap, const char *tag, const char *type) const { - register int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat4_ns1__delete); + int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat4_ns1__delete); if (this->soap_out(soap, tag?tag:"ns1:delete", id, type)) return soap->error; return soap_putindependent(soap); @@ -6998,7 +6998,7 @@ SOAP_FMAC3 ns1__searchTextResponse * SOAP_FMAC4 soap_in_ns1__searchTextResponse( int ns1__searchTextResponse::soap_put(struct soap *soap, const char *tag, const char *type) const { - register int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat4_ns1__searchTextResponse); + int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat4_ns1__searchTextResponse); if (this->soap_out(soap, tag?tag:"ns1:searchTextResponse", id, type)) return soap->error; return soap_putindependent(soap); @@ -7173,7 +7173,7 @@ SOAP_FMAC3 ns1__searchText * SOAP_FMAC4 soap_in_ns1__searchText(struct soap *soa int ns1__searchText::soap_put(struct soap *soap, const char *tag, const char *type) const { - register int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat4_ns1__searchText); + int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat4_ns1__searchText); if (this->soap_out(soap, tag?tag:"ns1:searchText", id, type)) return soap->error; return soap_putindependent(soap); @@ -7277,7 +7277,7 @@ SOAP_FMAC3 ns1__luceneCommitResponse * SOAP_FMAC4 soap_in_ns1__luceneCommitRespo int ns1__luceneCommitResponse::soap_put(struct soap *soap, const char *tag, const char *type) const { - register int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat4_ns1__luceneCommitResponse); + int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat4_ns1__luceneCommitResponse); if (this->soap_out(soap, tag?tag:"ns1:luceneCommitResponse", id, type)) return soap->error; return soap_putindependent(soap); @@ -7418,7 +7418,7 @@ SOAP_FMAC3 ns1__luceneCommit * SOAP_FMAC4 soap_in_ns1__luceneCommit(struct soap int ns1__luceneCommit::soap_put(struct soap *soap, const char *tag, const char *type) const { - register int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat4_ns1__luceneCommit); + int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat4_ns1__luceneCommit); if (this->soap_out(soap, tag?tag:"ns1:luceneCommit", id, type)) return soap->error; return soap_putindependent(soap); @@ -7612,7 +7612,7 @@ SOAP_FMAC3 ns1__entityField * SOAP_FMAC4 soap_in_ns1__entityField(struct soap *s int ns1__entityField::soap_put(struct soap *soap, const char *tag, const char *type) const { - register int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat4_ns1__entityField); + int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat4_ns1__entityField); if (this->soap_out(soap, tag?tag:"ns1:entityField", id, type)) return soap->error; return soap_putindependent(soap); @@ -7750,7 +7750,7 @@ SOAP_FMAC3 ns1__constraint * SOAP_FMAC4 soap_in_ns1__constraint(struct soap *soa int ns1__constraint::soap_put(struct soap *soap, const char *tag, const char *type) const { - register int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat4_ns1__constraint); + int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat4_ns1__constraint); if (this->soap_out(soap, tag?tag:"ns1:constraint", id, type)) return soap->error; return soap_putindependent(soap); @@ -7905,7 +7905,7 @@ SOAP_FMAC3 ns1__entityInfo * SOAP_FMAC4 soap_in_ns1__entityInfo(struct soap *soa int ns1__entityInfo::soap_put(struct soap *soap, const char *tag, const char *type) const { - register int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat4_ns1__entityInfo); + int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat4_ns1__entityInfo); if (this->soap_out(soap, tag?tag:"ns1:entityInfo", id, type)) return soap->error; return soap_putindependent(soap); @@ -8046,7 +8046,7 @@ SOAP_FMAC3 ns1__getEntityInfoResponse * SOAP_FMAC4 soap_in_ns1__getEntityInfoRes int ns1__getEntityInfoResponse::soap_put(struct soap *soap, const char *tag, const char *type) const { - register int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat4_ns1__getEntityInfoResponse); + int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat4_ns1__getEntityInfoResponse); if (this->soap_out(soap, tag?tag:"ns1:getEntityInfoResponse", id, type)) return soap->error; return soap_putindependent(soap); @@ -8187,7 +8187,7 @@ SOAP_FMAC3 ns1__getEntityInfo * SOAP_FMAC4 soap_in_ns1__getEntityInfo(struct soa int ns1__getEntityInfo::soap_put(struct soap *soap, const char *tag, const char *type) const { - register int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat4_ns1__getEntityInfo); + int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat4_ns1__getEntityInfo); if (this->soap_out(soap, tag?tag:"ns1:getEntityInfo", id, type)) return soap->error; return soap_putindependent(soap); @@ -8291,7 +8291,7 @@ SOAP_FMAC3 ns1__dummyResponse * SOAP_FMAC4 soap_in_ns1__dummyResponse(struct soa int ns1__dummyResponse::soap_put(struct soap *soap, const char *tag, const char *type) const { - register int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat4_ns1__dummyResponse); + int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat4_ns1__dummyResponse); if (this->soap_out(soap, tag?tag:"ns1:dummyResponse", id, type)) return soap->error; return soap_putindependent(soap); @@ -8484,7 +8484,7 @@ SOAP_FMAC3 ns1__publicStep * SOAP_FMAC4 soap_in_ns1__publicStep(struct soap *soa int ns1__publicStep::soap_put(struct soap *soap, const char *tag, const char *type) const { - register int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat4_ns1__publicStep); + int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat4_ns1__publicStep); if (this->soap_out(soap, tag?tag:"ns1:publicStep", id, type)) return soap->error; return soap_putindependent(soap); @@ -8711,7 +8711,7 @@ SOAP_FMAC3 ns1__log * SOAP_FMAC4 soap_in_ns1__log(struct soap *soap, const char int ns1__log::soap_put(struct soap *soap, const char *tag, const char *type) const { - register int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat4_ns1__log); + int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat4_ns1__log); if (this->soap_out(soap, tag?tag:"ns1:log", id, type)) return soap->error; return soap_putindependent(soap); @@ -8914,7 +8914,7 @@ SOAP_FMAC3 ns1__relatedDatafile * SOAP_FMAC4 soap_in_ns1__relatedDatafile(struct int ns1__relatedDatafile::soap_put(struct soap *soap, const char *tag, const char *type) const { - register int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat4_ns1__relatedDatafile); + int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat4_ns1__relatedDatafile); if (this->soap_out(soap, tag?tag:"ns1:relatedDatafile", id, type)) return soap->error; return soap_putindependent(soap); @@ -9127,7 +9127,7 @@ SOAP_FMAC3 ns1__shift * SOAP_FMAC4 soap_in_ns1__shift(struct soap *soap, const c int ns1__shift::soap_put(struct soap *soap, const char *tag, const char *type) const { - register int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat4_ns1__shift); + int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat4_ns1__shift); if (this->soap_out(soap, tag?tag:"ns1:shift", id, type)) return soap->error; return soap_putindependent(soap); @@ -9360,7 +9360,7 @@ SOAP_FMAC3 ns1__publication * SOAP_FMAC4 soap_in_ns1__publication(struct soap *s int ns1__publication::soap_put(struct soap *soap, const char *tag, const char *type) const { - register int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat4_ns1__publication); + int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat4_ns1__publication); if (this->soap_out(soap, tag?tag:"ns1:publication", id, type)) return soap->error; return soap_putindependent(soap); @@ -9553,7 +9553,7 @@ SOAP_FMAC3 ns1__keyword * SOAP_FMAC4 soap_in_ns1__keyword(struct soap *soap, con int ns1__keyword::soap_put(struct soap *soap, const char *tag, const char *type) const { - register int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat4_ns1__keyword); + int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat4_ns1__keyword); if (this->soap_out(soap, tag?tag:"ns1:keyword", id, type)) return soap->error; return soap_putindependent(soap); @@ -9773,7 +9773,7 @@ SOAP_FMAC3 ns1__sampleType * SOAP_FMAC4 soap_in_ns1__sampleType(struct soap *soa int ns1__sampleType::soap_put(struct soap *soap, const char *tag, const char *type) const { - register int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat4_ns1__sampleType); + int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat4_ns1__sampleType); if (this->soap_out(soap, tag?tag:"ns1:sampleType", id, type)) return soap->error; return soap_putindependent(soap); @@ -9990,7 +9990,7 @@ SOAP_FMAC3 ns1__sample * SOAP_FMAC4 soap_in_ns1__sample(struct soap *soap, const int ns1__sample::soap_put(struct soap *soap, const char *tag, const char *type) const { - register int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat4_ns1__sample); + int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat4_ns1__sample); if (this->soap_out(soap, tag?tag:"ns1:sample", id, type)) return soap->error; return soap_putindependent(soap); @@ -10231,7 +10231,7 @@ SOAP_FMAC3 ns1__sampleParameter * SOAP_FMAC4 soap_in_ns1__sampleParameter(struct int ns1__sampleParameter::soap_put(struct soap *soap, const char *tag, const char *type) const { - register int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat4_ns1__sampleParameter); + int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat4_ns1__sampleParameter); if (this->soap_out(soap, tag?tag:"ns1:sampleParameter", id, type)) return soap->error; return soap_putindependent(soap); @@ -10424,7 +10424,7 @@ SOAP_FMAC3 ns1__permissibleStringValue * SOAP_FMAC4 soap_in_ns1__permissibleStri int ns1__permissibleStringValue::soap_put(struct soap *soap, const char *tag, const char *type) const { - register int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat4_ns1__permissibleStringValue); + int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat4_ns1__permissibleStringValue); if (this->soap_out(soap, tag?tag:"ns1:permissibleStringValue", id, type)) return soap->error; return soap_putindependent(soap); @@ -10665,7 +10665,7 @@ SOAP_FMAC3 ns1__investigationParameter * SOAP_FMAC4 soap_in_ns1__investigationPa int ns1__investigationParameter::soap_put(struct soap *soap, const char *tag, const char *type) const { - register int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat4_ns1__investigationParameter); + int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat4_ns1__investigationParameter); if (this->soap_out(soap, tag?tag:"ns1:investigationParameter", id, type)) return soap->error; return soap_putindependent(soap); @@ -10906,7 +10906,7 @@ SOAP_FMAC3 ns1__datasetParameter * SOAP_FMAC4 soap_in_ns1__datasetParameter(stru int ns1__datasetParameter::soap_put(struct soap *soap, const char *tag, const char *type) const { - register int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat4_ns1__datasetParameter); + int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat4_ns1__datasetParameter); if (this->soap_out(soap, tag?tag:"ns1:datasetParameter", id, type)) return soap->error; return soap_putindependent(soap); @@ -11147,7 +11147,7 @@ SOAP_FMAC3 ns1__datafileParameter * SOAP_FMAC4 soap_in_ns1__datafileParameter(st int ns1__datafileParameter::soap_put(struct soap *soap, const char *tag, const char *type) const { - register int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat4_ns1__datafileParameter); + int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat4_ns1__datafileParameter); if (this->soap_out(soap, tag?tag:"ns1:datafileParameter", id, type)) return soap->error; return soap_putindependent(soap); @@ -11390,7 +11390,7 @@ SOAP_FMAC3 ns1__parameter * SOAP_FMAC4 soap_in_ns1__parameter(struct soap *soap, int ns1__parameter::soap_put(struct soap *soap, const char *tag, const char *type) const { - register int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat4_ns1__parameter); + int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat4_ns1__parameter); if (this->soap_out(soap, tag?tag:"ns1:parameter", id, type)) return soap->error; return soap_putindependent(soap); @@ -11736,7 +11736,7 @@ SOAP_FMAC3 ns1__dataCollectionParameter * SOAP_FMAC4 soap_in_ns1__dataCollection int ns1__dataCollectionParameter::soap_put(struct soap *soap, const char *tag, const char *type) const { - register int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat4_ns1__dataCollectionParameter); + int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat4_ns1__dataCollectionParameter); if (this->soap_out(soap, tag?tag:"ns1:dataCollectionParameter", id, type)) return soap->error; return soap_putindependent(soap); @@ -12098,7 +12098,7 @@ SOAP_FMAC3 ns1__parameterType * SOAP_FMAC4 soap_in_ns1__parameterType(struct soa int ns1__parameterType::soap_put(struct soap *soap, const char *tag, const char *type) const { - register int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat4_ns1__parameterType); + int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat4_ns1__parameterType); if (this->soap_out(soap, tag?tag:"ns1:parameterType", id, type)) return soap->error; return soap_putindependent(soap); @@ -12308,7 +12308,7 @@ SOAP_FMAC3 ns1__investigationType * SOAP_FMAC4 soap_in_ns1__investigationType(st int ns1__investigationType::soap_put(struct soap *soap, const char *tag, const char *type) const { - register int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat4_ns1__investigationType); + int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat4_ns1__investigationType); if (this->soap_out(soap, tag?tag:"ns1:investigationType", id, type)) return soap->error; return soap_putindependent(soap); @@ -12501,7 +12501,7 @@ SOAP_FMAC3 ns1__investigationInstrument * SOAP_FMAC4 soap_in_ns1__investigationI int ns1__investigationInstrument::soap_put(struct soap *soap, const char *tag, const char *type) const { - register int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat4_ns1__investigationInstrument); + int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat4_ns1__investigationInstrument); if (this->soap_out(soap, tag?tag:"ns1:investigationInstrument", id, type)) return soap->error; return soap_putindependent(soap); @@ -12704,7 +12704,7 @@ SOAP_FMAC3 ns1__rule * SOAP_FMAC4 soap_in_ns1__rule(struct soap *soap, const cha int ns1__rule::soap_put(struct soap *soap, const char *tag, const char *type) const { - register int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat4_ns1__rule); + int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat4_ns1__rule); if (this->soap_out(soap, tag?tag:"ns1:rule", id, type)) return soap->error; return soap_putindependent(soap); @@ -12901,7 +12901,7 @@ SOAP_FMAC3 ns1__grouping * SOAP_FMAC4 soap_in_ns1__grouping(struct soap *soap, c int ns1__grouping::soap_put(struct soap *soap, const char *tag, const char *type) const { - register int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat4_ns1__grouping); + int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat4_ns1__grouping); if (this->soap_out(soap, tag?tag:"ns1:grouping", id, type)) return soap->error; return soap_putindependent(soap); @@ -13094,7 +13094,7 @@ SOAP_FMAC3 ns1__userGroup * SOAP_FMAC4 soap_in_ns1__userGroup(struct soap *soap, int ns1__userGroup::soap_put(struct soap *soap, const char *tag, const char *type) const { - register int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat4_ns1__userGroup); + int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat4_ns1__userGroup); if (this->soap_out(soap, tag?tag:"ns1:userGroup", id, type)) return soap->error; return soap_putindependent(soap); @@ -13287,7 +13287,7 @@ SOAP_FMAC3 ns1__studyInvestigation * SOAP_FMAC4 soap_in_ns1__studyInvestigation( int ns1__studyInvestigation::soap_put(struct soap *soap, const char *tag, const char *type) const { - register int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat4_ns1__studyInvestigation); + int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat4_ns1__studyInvestigation); if (this->soap_out(soap, tag?tag:"ns1:studyInvestigation", id, type)) return soap->error; return soap_putindependent(soap); @@ -13517,7 +13517,7 @@ SOAP_FMAC3 ns1__study * SOAP_FMAC4 soap_in_ns1__study(struct soap *soap, const c int ns1__study::soap_put(struct soap *soap, const char *tag, const char *type) const { - register int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat4_ns1__study); + int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat4_ns1__study); if (this->soap_out(soap, tag?tag:"ns1:study", id, type)) return soap->error; return soap_putindependent(soap); @@ -13720,7 +13720,7 @@ SOAP_FMAC3 ns1__investigationUser * SOAP_FMAC4 soap_in_ns1__investigationUser(st int ns1__investigationUser::soap_put(struct soap *soap, const char *tag, const char *type) const { - register int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat4_ns1__investigationUser); + int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat4_ns1__investigationUser); if (this->soap_out(soap, tag?tag:"ns1:investigationUser", id, type)) return soap->error; return soap_putindependent(soap); @@ -13941,7 +13941,7 @@ SOAP_FMAC3 ns1__user * SOAP_FMAC4 soap_in_ns1__user(struct soap *soap, const cha int ns1__user::soap_put(struct soap *soap, const char *tag, const char *type) const { - register int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat4_ns1__user); + int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat4_ns1__user); if (this->soap_out(soap, tag?tag:"ns1:user", id, type)) return soap->error; return soap_putindependent(soap); @@ -14134,7 +14134,7 @@ SOAP_FMAC3 ns1__instrumentScientist * SOAP_FMAC4 soap_in_ns1__instrumentScientis int ns1__instrumentScientist::soap_put(struct soap *soap, const char *tag, const char *type) const { - register int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat4_ns1__instrumentScientist); + int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat4_ns1__instrumentScientist); if (this->soap_out(soap, tag?tag:"ns1:instrumentScientist", id, type)) return soap->error; return soap_putindependent(soap); @@ -14381,7 +14381,7 @@ SOAP_FMAC3 ns1__instrument * SOAP_FMAC4 soap_in_ns1__instrument(struct soap *soa int ns1__instrument::soap_put(struct soap *soap, const char *tag, const char *type) const { - register int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat4_ns1__instrument); + int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat4_ns1__instrument); if (this->soap_out(soap, tag?tag:"ns1:instrument", id, type)) return soap->error; return soap_putindependent(soap); @@ -14604,7 +14604,7 @@ SOAP_FMAC3 ns1__facilityCycle * SOAP_FMAC4 soap_in_ns1__facilityCycle(struct soa int ns1__facilityCycle::soap_put(struct soap *soap, const char *tag, const char *type) const { - register int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat4_ns1__facilityCycle); + int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat4_ns1__facilityCycle); if (this->soap_out(soap, tag?tag:"ns1:facilityCycle", id, type)) return soap->error; return soap_putindependent(soap); @@ -14814,7 +14814,7 @@ SOAP_FMAC3 ns1__datasetType * SOAP_FMAC4 soap_in_ns1__datasetType(struct soap *s int ns1__datasetType::soap_put(struct soap *soap, const char *tag, const char *type) const { - register int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat4_ns1__datasetType); + int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat4_ns1__datasetType); if (this->soap_out(soap, tag?tag:"ns1:datasetType", id, type)) return soap->error; return soap_putindependent(soap); @@ -15044,7 +15044,7 @@ SOAP_FMAC3 ns1__datafileFormat * SOAP_FMAC4 soap_in_ns1__datafileFormat(struct s int ns1__datafileFormat::soap_put(struct soap *soap, const char *tag, const char *type) const { - register int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat4_ns1__datafileFormat); + int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat4_ns1__datafileFormat); if (this->soap_out(soap, tag?tag:"ns1:datafileFormat", id, type)) return soap->error; return soap_putindependent(soap); @@ -15257,7 +15257,7 @@ SOAP_FMAC3 ns1__job * SOAP_FMAC4 soap_in_ns1__job(struct soap *soap, const char int ns1__job::soap_put(struct soap *soap, const char *tag, const char *type) const { - register int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat4_ns1__job); + int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat4_ns1__job); if (this->soap_out(soap, tag?tag:"ns1:job", id, type)) return soap->error; return soap_putindependent(soap); @@ -15467,7 +15467,7 @@ SOAP_FMAC3 ns1__application * SOAP_FMAC4 soap_in_ns1__application(struct soap *s int ns1__application::soap_put(struct soap *soap, const char *tag, const char *type) const { - register int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat4_ns1__application); + int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat4_ns1__application); if (this->soap_out(soap, tag?tag:"ns1:application", id, type)) return soap->error; return soap_putindependent(soap); @@ -15753,7 +15753,7 @@ SOAP_FMAC3 ns1__facility * SOAP_FMAC4 soap_in_ns1__facility(struct soap *soap, c int ns1__facility::soap_put(struct soap *soap, const char *tag, const char *type) const { - register int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat4_ns1__facility); + int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat4_ns1__facility); if (this->soap_out(soap, tag?tag:"ns1:facility", id, type)) return soap->error; return soap_putindependent(soap); @@ -16089,7 +16089,7 @@ SOAP_FMAC3 ns1__investigation * SOAP_FMAC4 soap_in_ns1__investigation(struct soa int ns1__investigation::soap_put(struct soap *soap, const char *tag, const char *type) const { - register int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat4_ns1__investigation); + int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat4_ns1__investigation); if (this->soap_out(soap, tag?tag:"ns1:investigation", id, type)) return soap->error; return soap_putindependent(soap); @@ -16386,7 +16386,7 @@ SOAP_FMAC3 ns1__dataset * SOAP_FMAC4 soap_in_ns1__dataset(struct soap *soap, con int ns1__dataset::soap_put(struct soap *soap, const char *tag, const char *type) const { - register int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat4_ns1__dataset); + int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat4_ns1__dataset); if (this->soap_out(soap, tag?tag:"ns1:dataset", id, type)) return soap->error; return soap_putindependent(soap); @@ -16579,7 +16579,7 @@ SOAP_FMAC3 ns1__dataCollectionDataset * SOAP_FMAC4 soap_in_ns1__dataCollectionDa int ns1__dataCollectionDataset::soap_put(struct soap *soap, const char *tag, const char *type) const { - register int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat4_ns1__dataCollectionDataset); + int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat4_ns1__dataCollectionDataset); if (this->soap_out(soap, tag?tag:"ns1:dataCollectionDataset", id, type)) return soap->error; return soap_putindependent(soap); @@ -16787,7 +16787,7 @@ SOAP_FMAC3 ns1__dataCollection * SOAP_FMAC4 soap_in_ns1__dataCollection(struct s int ns1__dataCollection::soap_put(struct soap *soap, const char *tag, const char *type) const { - register int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat4_ns1__dataCollection); + int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat4_ns1__dataCollection); if (this->soap_out(soap, tag?tag:"ns1:dataCollection", id, type)) return soap->error; return soap_putindependent(soap); @@ -16980,7 +16980,7 @@ SOAP_FMAC3 ns1__dataCollectionDatafile * SOAP_FMAC4 soap_in_ns1__dataCollectionD int ns1__dataCollectionDatafile::soap_put(struct soap *soap, const char *tag, const char *type) const { - register int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat4_ns1__dataCollectionDatafile); + int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat4_ns1__dataCollectionDatafile); if (this->soap_out(soap, tag?tag:"ns1:dataCollectionDatafile", id, type)) return soap->error; return soap_putindependent(soap); @@ -17281,7 +17281,7 @@ SOAP_FMAC3 ns1__datafile * SOAP_FMAC4 soap_in_ns1__datafile(struct soap *soap, c int ns1__datafile::soap_put(struct soap *soap, const char *tag, const char *type) const { - register int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat4_ns1__datafile); + int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat4_ns1__datafile); if (this->soap_out(soap, tag?tag:"ns1:datafile", id, type)) return soap->error; return soap_putindependent(soap); @@ -17752,7 +17752,7 @@ SOAP_FMAC3 ns1__dummy * SOAP_FMAC4 soap_in_ns1__dummy(struct soap *soap, const c int ns1__dummy::soap_put(struct soap *soap, const char *tag, const char *type) const { - register int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat4_ns1__dummy); + int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat4_ns1__dummy); if (this->soap_out(soap, tag?tag:"ns1:dummy", id, type)) return soap->error; return soap_putindependent(soap); @@ -17893,7 +17893,7 @@ SOAP_FMAC3 ns1__loginResponse * SOAP_FMAC4 soap_in_ns1__loginResponse(struct soa int ns1__loginResponse::soap_put(struct soap *soap, const char *tag, const char *type) const { - register int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat4_ns1__loginResponse); + int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat4_ns1__loginResponse); if (this->soap_out(soap, tag?tag:"ns1:loginResponse", id, type)) return soap->error; return soap_putindependent(soap); @@ -18048,7 +18048,7 @@ SOAP_FMAC3 ns1__login * SOAP_FMAC4 soap_in_ns1__login(struct soap *soap, const c int ns1__login::soap_put(struct soap *soap, const char *tag, const char *type) const { - register int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat4_ns1__login); + int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat4_ns1__login); if (this->soap_out(soap, tag?tag:"ns1:login", id, type)) return soap->error; return soap_putindependent(soap); @@ -18152,7 +18152,7 @@ SOAP_FMAC3 ns1__refreshResponse * SOAP_FMAC4 soap_in_ns1__refreshResponse(struct int ns1__refreshResponse::soap_put(struct soap *soap, const char *tag, const char *type) const { - register int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat4_ns1__refreshResponse); + int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat4_ns1__refreshResponse); if (this->soap_out(soap, tag?tag:"ns1:refreshResponse", id, type)) return soap->error; return soap_putindependent(soap); @@ -18293,7 +18293,7 @@ SOAP_FMAC3 ns1__refresh * SOAP_FMAC4 soap_in_ns1__refresh(struct soap *soap, con int ns1__refresh::soap_put(struct soap *soap, const char *tag, const char *type) const { - register int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat4_ns1__refresh); + int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat4_ns1__refresh); if (this->soap_out(soap, tag?tag:"ns1:refresh", id, type)) return soap->error; return soap_putindependent(soap); @@ -18434,7 +18434,7 @@ SOAP_FMAC3 ns1__getUserNameResponse * SOAP_FMAC4 soap_in_ns1__getUserNameRespons int ns1__getUserNameResponse::soap_put(struct soap *soap, const char *tag, const char *type) const { - register int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat4_ns1__getUserNameResponse); + int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat4_ns1__getUserNameResponse); if (this->soap_out(soap, tag?tag:"ns1:getUserNameResponse", id, type)) return soap->error; return soap_putindependent(soap); @@ -18575,7 +18575,7 @@ SOAP_FMAC3 ns1__getUserName * SOAP_FMAC4 soap_in_ns1__getUserName(struct soap *s int ns1__getUserName::soap_put(struct soap *soap, const char *tag, const char *type) const { - register int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat4_ns1__getUserName); + int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat4_ns1__getUserName); if (this->soap_out(soap, tag?tag:"ns1:getUserName", id, type)) return soap->error; return soap_putindependent(soap); @@ -18679,7 +18679,7 @@ SOAP_FMAC3 ns1__deleteManyResponse * SOAP_FMAC4 soap_in_ns1__deleteManyResponse( int ns1__deleteManyResponse::soap_put(struct soap *soap, const char *tag, const char *type) const { - register int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat4_ns1__deleteManyResponse); + int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat4_ns1__deleteManyResponse); if (this->soap_out(soap, tag?tag:"ns1:deleteManyResponse", id, type)) return soap->error; return soap_putindependent(soap); @@ -18827,7 +18827,7 @@ SOAP_FMAC3 ns1__deleteMany * SOAP_FMAC4 soap_in_ns1__deleteMany(struct soap *soa int ns1__deleteMany::soap_put(struct soap *soap, const char *tag, const char *type) const { - register int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat4_ns1__deleteMany); + int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat4_ns1__deleteMany); if (this->soap_out(soap, tag?tag:"ns1:deleteMany", id, type)) return soap->error; return soap_putindependent(soap); @@ -18931,7 +18931,7 @@ SOAP_FMAC3 ns1__updateResponse * SOAP_FMAC4 soap_in_ns1__updateResponse(struct s int ns1__updateResponse::soap_put(struct soap *soap, const char *tag, const char *type) const { - register int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat4_ns1__updateResponse); + int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat4_ns1__updateResponse); if (this->soap_out(soap, tag?tag:"ns1:updateResponse", id, type)) return soap->error; return soap_putindependent(soap); @@ -19082,7 +19082,7 @@ SOAP_FMAC3 ns1__update * SOAP_FMAC4 soap_in_ns1__update(struct soap *soap, const int ns1__update::soap_put(struct soap *soap, const char *tag, const char *type) const { - register int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat4_ns1__update); + int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat4_ns1__update); if (this->soap_out(soap, tag?tag:"ns1:update", id, type)) return soap->error; return soap_putindependent(soap); @@ -19220,7 +19220,7 @@ SOAP_FMAC3 ns1__luceneGetPopulatingResponse * SOAP_FMAC4 soap_in_ns1__luceneGetP int ns1__luceneGetPopulatingResponse::soap_put(struct soap *soap, const char *tag, const char *type) const { - register int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat4_ns1__luceneGetPopulatingResponse); + int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat4_ns1__luceneGetPopulatingResponse); if (this->soap_out(soap, tag?tag:"ns1:luceneGetPopulatingResponse", id, type)) return soap->error; return soap_putindependent(soap); @@ -19361,7 +19361,7 @@ SOAP_FMAC3 ns1__luceneGetPopulating * SOAP_FMAC4 soap_in_ns1__luceneGetPopulatin int ns1__luceneGetPopulating::soap_put(struct soap *soap, const char *tag, const char *type) const { - register int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat4_ns1__luceneGetPopulating); + int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat4_ns1__luceneGetPopulating); if (this->soap_out(soap, tag?tag:"ns1:luceneGetPopulating", id, type)) return soap->error; return soap_putindependent(soap); @@ -19502,7 +19502,7 @@ SOAP_FMAC3 ns1__getApiVersionResponse * SOAP_FMAC4 soap_in_ns1__getApiVersionRes int ns1__getApiVersionResponse::soap_put(struct soap *soap, const char *tag, const char *type) const { - register int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat4_ns1__getApiVersionResponse); + int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat4_ns1__getApiVersionResponse); if (this->soap_out(soap, tag?tag:"ns1:getApiVersionResponse", id, type)) return soap->error; return soap_putindependent(soap); @@ -19606,7 +19606,7 @@ SOAP_FMAC3 ns1__getApiVersion * SOAP_FMAC4 soap_in_ns1__getApiVersion(struct soa int ns1__getApiVersion::soap_put(struct soap *soap, const char *tag, const char *type) const { - register int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat4_ns1__getApiVersion); + int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat4_ns1__getApiVersion); if (this->soap_out(soap, tag?tag:"ns1:getApiVersion", id, type)) return soap->error; return soap_putindependent(soap); @@ -19744,7 +19744,7 @@ SOAP_FMAC3 ns1__getEntityNamesResponse * SOAP_FMAC4 soap_in_ns1__getEntityNamesR int ns1__getEntityNamesResponse::soap_put(struct soap *soap, const char *tag, const char *type) const { - register int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat4_ns1__getEntityNamesResponse); + int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat4_ns1__getEntityNamesResponse); if (this->soap_out(soap, tag?tag:"ns1:getEntityNamesResponse", id, type)) return soap->error; return soap_putindependent(soap); @@ -19848,7 +19848,7 @@ SOAP_FMAC3 ns1__getEntityNames * SOAP_FMAC4 soap_in_ns1__getEntityNames(struct s int ns1__getEntityNames::soap_put(struct soap *soap, const char *tag, const char *type) const { - register int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat4_ns1__getEntityNames); + int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat4_ns1__getEntityNames); if (this->soap_out(soap, tag?tag:"ns1:getEntityNames", id, type)) return soap->error; return soap_putindependent(soap); @@ -19989,7 +19989,7 @@ SOAP_FMAC3 ns1__getResponse * SOAP_FMAC4 soap_in_ns1__getResponse(struct soap *s int ns1__getResponse::soap_put(struct soap *soap, const char *tag, const char *type) const { - register int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat4_ns1__getResponse); + int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat4_ns1__getResponse); if (this->soap_out(soap, tag?tag:"ns1:getResponse", id, type)) return soap->error; return soap_putindependent(soap); @@ -20154,7 +20154,7 @@ SOAP_FMAC3 ns1__get * SOAP_FMAC4 soap_in_ns1__get(struct soap *soap, const char int ns1__get::soap_put(struct soap *soap, const char *tag, const char *type) const { - register int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat4_ns1__get); + int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat4_ns1__get); if (this->soap_out(soap, tag?tag:"ns1:get", id, type)) return soap->error; return soap_putindependent(soap); @@ -20258,7 +20258,7 @@ SOAP_FMAC3 ns1__lucenePopulateResponse * SOAP_FMAC4 soap_in_ns1__lucenePopulateR int ns1__lucenePopulateResponse::soap_put(struct soap *soap, const char *tag, const char *type) const { - register int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat4_ns1__lucenePopulateResponse); + int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat4_ns1__lucenePopulateResponse); if (this->soap_out(soap, tag?tag:"ns1:lucenePopulateResponse", id, type)) return soap->error; return soap_putindependent(soap); @@ -20409,7 +20409,7 @@ SOAP_FMAC3 ns1__lucenePopulate * SOAP_FMAC4 soap_in_ns1__lucenePopulate(struct s int ns1__lucenePopulate::soap_put(struct soap *soap, const char *tag, const char *type) const { - register int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat4_ns1__lucenePopulate); + int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat4_ns1__lucenePopulate); if (this->soap_out(soap, tag?tag:"ns1:lucenePopulate", id, type)) return soap->error; return soap_putindependent(soap); @@ -20547,7 +20547,7 @@ SOAP_FMAC3 ns1__luceneSearchResponse * SOAP_FMAC4 soap_in_ns1__luceneSearchRespo int ns1__luceneSearchResponse::soap_put(struct soap *soap, const char *tag, const char *type) const { - register int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat4_ns1__luceneSearchResponse); + int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat4_ns1__luceneSearchResponse); if (this->soap_out(soap, tag?tag:"ns1:luceneSearchResponse", id, type)) return soap->error; return soap_putindependent(soap); @@ -20722,7 +20722,7 @@ SOAP_FMAC3 ns1__luceneSearch * SOAP_FMAC4 soap_in_ns1__luceneSearch(struct soap int ns1__luceneSearch::soap_put(struct soap *soap, const char *tag, const char *type) const { - register int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat4_ns1__luceneSearch); + int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat4_ns1__luceneSearch); if (this->soap_out(soap, tag?tag:"ns1:luceneSearch", id, type)) return soap->error; return soap_putindependent(soap); @@ -20860,7 +20860,7 @@ SOAP_FMAC3 ns1__getPropertiesResponse * SOAP_FMAC4 soap_in_ns1__getPropertiesRes int ns1__getPropertiesResponse::soap_put(struct soap *soap, const char *tag, const char *type) const { - register int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat4_ns1__getPropertiesResponse); + int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat4_ns1__getPropertiesResponse); if (this->soap_out(soap, tag?tag:"ns1:getPropertiesResponse", id, type)) return soap->error; return soap_putindependent(soap); @@ -21001,7 +21001,7 @@ SOAP_FMAC3 ns1__getProperties * SOAP_FMAC4 soap_in_ns1__getProperties(struct soa int ns1__getProperties::soap_put(struct soap *soap, const char *tag, const char *type) const { - register int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat4_ns1__getProperties); + int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat4_ns1__getProperties); if (this->soap_out(soap, tag?tag:"ns1:getProperties", id, type)) return soap->error; return soap_putindependent(soap); @@ -21146,7 +21146,7 @@ SOAP_FMAC3 ns1__createResponse * SOAP_FMAC4 soap_in_ns1__createResponse(struct s int ns1__createResponse::soap_put(struct soap *soap, const char *tag, const char *type) const { - register int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat4_ns1__createResponse); + int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat4_ns1__createResponse); if (this->soap_out(soap, tag?tag:"ns1:createResponse", id, type)) return soap->error; return soap_putindependent(soap); @@ -21297,7 +21297,7 @@ SOAP_FMAC3 ns1__create * SOAP_FMAC4 soap_in_ns1__create(struct soap *soap, const int ns1__create::soap_put(struct soap *soap, const char *tag, const char *type) const { - register int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat4_ns1__create); + int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat4_ns1__create); if (this->soap_out(soap, tag?tag:"ns1:create", id, type)) return soap->error; return soap_putindependent(soap); @@ -21435,7 +21435,7 @@ SOAP_FMAC3 ns1__createManyResponse * SOAP_FMAC4 soap_in_ns1__createManyResponse( int ns1__createManyResponse::soap_put(struct soap *soap, const char *tag, const char *type) const { - register int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat4_ns1__createManyResponse); + int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat4_ns1__createManyResponse); if (this->soap_out(soap, tag?tag:"ns1:createManyResponse", id, type)) return soap->error; return soap_putindependent(soap); @@ -21616,7 +21616,7 @@ SOAP_FMAC3 ns1__entityBaseBean * SOAP_FMAC4 soap_in_ns1__entityBaseBean(struct s int ns1__entityBaseBean::soap_put(struct soap *soap, const char *tag, const char *type) const { - register int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat4_ns1__entityBaseBean); + int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat4_ns1__entityBaseBean); if (this->soap_out(soap, tag?tag:"ns1:entityBaseBean", id, type)) return soap->error; return soap_putindependent(soap); @@ -22583,7 +22583,7 @@ SOAP_FMAC3 ns1__createMany * SOAP_FMAC4 soap_in_ns1__createMany(struct soap *soa int ns1__createMany::soap_put(struct soap *soap, const char *tag, const char *type) const { - register int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat4_ns1__createMany); + int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat4_ns1__createMany); if (this->soap_out(soap, tag?tag:"ns1:createMany", id, type)) return soap->error; return soap_putindependent(soap); @@ -22748,7 +22748,7 @@ SOAP_FMAC3 ns1__IcatException * SOAP_FMAC4 soap_in_ns1__IcatException(struct soa int ns1__IcatException::soap_put(struct soap *soap, const char *tag, const char *type) const { - register int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat4_ns1__IcatException); + int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat4_ns1__IcatException); if (this->soap_out(soap, tag?tag:"ns1:IcatException", id, type)) return soap->error; return soap_putindependent(soap); @@ -22852,7 +22852,7 @@ SOAP_FMAC3 ns1__luceneClearResponse * SOAP_FMAC4 soap_in_ns1__luceneClearRespons int ns1__luceneClearResponse::soap_put(struct soap *soap, const char *tag, const char *type) const { - register int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat4_ns1__luceneClearResponse); + int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat4_ns1__luceneClearResponse); if (this->soap_out(soap, tag?tag:"ns1:luceneClearResponse", id, type)) return soap->error; return soap_putindependent(soap); @@ -22993,7 +22993,7 @@ SOAP_FMAC3 ns1__luceneClear * SOAP_FMAC4 soap_in_ns1__luceneClear(struct soap *s int ns1__luceneClear::soap_put(struct soap *soap, const char *tag, const char *type) const { - register int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat4_ns1__luceneClear); + int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat4_ns1__luceneClear); if (this->soap_out(soap, tag?tag:"ns1:luceneClear", id, type)) return soap->error; return soap_putindependent(soap); @@ -23092,7 +23092,7 @@ SOAP_FMAC3 std::string * SOAP_FMAC4 soap_in_std__string(struct soap *soap, const SOAP_FMAC3 int SOAP_FMAC4 soap_put_std__string(struct soap *soap, const std::string *a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat4_std__string); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat4_std__string); if (soap_out_std__string(soap, tag?tag:"string", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -23190,7 +23190,7 @@ SOAP_FMAC3 xsd__string * SOAP_FMAC4 soap_in_xsd__string(struct soap *soap, const int xsd__string::soap_put(struct soap *soap, const char *tag, const char *type) const { - register int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat4_xsd__string); + int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat4_xsd__string); if (this->soap_out(soap, tag?tag:"xsd:string", id, type)) return soap->error; return soap_putindependent(soap); @@ -23296,7 +23296,7 @@ SOAP_FMAC3 xsd__long * SOAP_FMAC4 soap_in_xsd__long(struct soap *soap, const cha int xsd__long::soap_put(struct soap *soap, const char *tag, const char *type) const { - register int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat4_xsd__long); + int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat4_xsd__long); if (this->soap_out(soap, tag?tag:"xsd:long", id, type)) return soap->error; return soap_putindependent(soap); @@ -23402,7 +23402,7 @@ SOAP_FMAC3 xsd__int * SOAP_FMAC4 soap_in_xsd__int(struct soap *soap, const char int xsd__int::soap_put(struct soap *soap, const char *tag, const char *type) const { - register int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat4_xsd__int); + int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat4_xsd__int); if (this->soap_out(soap, tag?tag:"xsd:int", id, type)) return soap->error; return soap_putindependent(soap); @@ -23508,7 +23508,7 @@ SOAP_FMAC3 xsd__double * SOAP_FMAC4 soap_in_xsd__double(struct soap *soap, const int xsd__double::soap_put(struct soap *soap, const char *tag, const char *type) const { - register int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat4_xsd__double); + int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat4_xsd__double); if (this->soap_out(soap, tag?tag:"xsd:double", id, type)) return soap->error; return soap_putindependent(soap); @@ -23614,7 +23614,7 @@ SOAP_FMAC3 xsd__dateTime * SOAP_FMAC4 soap_in_xsd__dateTime(struct soap *soap, c int xsd__dateTime::soap_put(struct soap *soap, const char *tag, const char *type) const { - register int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat4_xsd__dateTime); + int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat4_xsd__dateTime); if (this->soap_out(soap, tag?tag:"xsd:dateTime", id, type)) return soap->error; return soap_putindependent(soap); @@ -23719,7 +23719,7 @@ SOAP_FMAC3 xsd__boolean * SOAP_FMAC4 soap_in_xsd__boolean(struct soap *soap, con int xsd__boolean::soap_put(struct soap *soap, const char *tag, const char *type) const { - register int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat4_xsd__boolean); + int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat4_xsd__boolean); if (this->soap_out(soap, tag?tag:"xsd:boolean", id, type)) return soap->error; return soap_putindependent(soap); @@ -23824,7 +23824,7 @@ SOAP_FMAC3 xsd__anyType * SOAP_FMAC4 soap_in_xsd__anyType(struct soap *soap, con int xsd__anyType::soap_put(struct soap *soap, const char *tag, const char *type) const { - register int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat4_xsd__anyType); + int id = soap_embed(soap, (void*)this, NULL, 0, tag, SOAP_TYPE_ICat4_xsd__anyType); if (this->soap_out(soap, tag?tag:"xsd:anyType", id, type)) return soap->error; return soap_putindependent(soap); @@ -26185,7 +26185,7 @@ SOAP_FMAC3 struct SOAP_ENV__Fault * SOAP_FMAC4 soap_in_SOAP_ENV__Fault(struct so SOAP_FMAC3 int SOAP_FMAC4 soap_put_SOAP_ENV__Fault(struct soap *soap, const struct SOAP_ENV__Fault *a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat4_SOAP_ENV__Fault); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat4_SOAP_ENV__Fault); if (soap_out_SOAP_ENV__Fault(soap, tag?tag:"SOAP-ENV:Fault", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -26297,7 +26297,7 @@ SOAP_FMAC3 struct SOAP_ENV__Reason * SOAP_FMAC4 soap_in_SOAP_ENV__Reason(struct SOAP_FMAC3 int SOAP_FMAC4 soap_put_SOAP_ENV__Reason(struct soap *soap, const struct SOAP_ENV__Reason *a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat4_SOAP_ENV__Reason); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat4_SOAP_ENV__Reason); if (soap_out_SOAP_ENV__Reason(soap, tag?tag:"SOAP-ENV:Reason", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -26418,7 +26418,7 @@ SOAP_FMAC3 struct SOAP_ENV__Code * SOAP_FMAC4 soap_in_SOAP_ENV__Code(struct soap SOAP_FMAC3 int SOAP_FMAC4 soap_put_SOAP_ENV__Code(struct soap *soap, const struct SOAP_ENV__Code *a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat4_SOAP_ENV__Code); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat4_SOAP_ENV__Code); if (soap_out_SOAP_ENV__Code(soap, tag?tag:"SOAP-ENV:Code", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -26518,7 +26518,7 @@ SOAP_FMAC3 struct SOAP_ENV__Header * SOAP_FMAC4 soap_in_SOAP_ENV__Header(struct SOAP_FMAC3 int SOAP_FMAC4 soap_put_SOAP_ENV__Header(struct soap *soap, const struct SOAP_ENV__Header *a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat4_SOAP_ENV__Header); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat4_SOAP_ENV__Header); if (soap_out_SOAP_ENV__Header(soap, tag?tag:"SOAP-ENV:Header", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -26616,7 +26616,7 @@ SOAP_FMAC3 struct __ns1__getEntityInfo * SOAP_FMAC4 soap_in___ns1__getEntityInfo SOAP_FMAC3 int SOAP_FMAC4 soap_put___ns1__getEntityInfo(struct soap *soap, const struct __ns1__getEntityInfo *a, const char *tag, const char *type) { - register int id = 0; + int id = 0; if (soap_out___ns1__getEntityInfo(soap, tag?tag:"-ns1:getEntityInfo", id, a, type)) return soap->error; return SOAP_OK; @@ -26712,7 +26712,7 @@ SOAP_FMAC3 struct __ns1__deleteMany * SOAP_FMAC4 soap_in___ns1__deleteMany(struc SOAP_FMAC3 int SOAP_FMAC4 soap_put___ns1__deleteMany(struct soap *soap, const struct __ns1__deleteMany *a, const char *tag, const char *type) { - register int id = 0; + int id = 0; if (soap_out___ns1__deleteMany(soap, tag?tag:"-ns1:deleteMany", id, a, type)) return soap->error; return SOAP_OK; @@ -26811,7 +26811,7 @@ SOAP_FMAC3 struct __ns1__deleteManyResponse * SOAP_FMAC4 soap_in___ns1__deleteMa SOAP_FMAC3 int SOAP_FMAC4 soap_put___ns1__deleteManyResponse(struct soap *soap, const struct __ns1__deleteManyResponse *a, const char *tag, const char *type) { - register int id = 0; + int id = 0; if (soap_out___ns1__deleteManyResponse(soap, tag?tag:"-ns1:deleteManyResponse", id, a, type)) return soap->error; return SOAP_OK; @@ -26907,7 +26907,7 @@ SOAP_FMAC3 struct __ns1__createMany * SOAP_FMAC4 soap_in___ns1__createMany(struc SOAP_FMAC3 int SOAP_FMAC4 soap_put___ns1__createMany(struct soap *soap, const struct __ns1__createMany *a, const char *tag, const char *type) { - register int id = 0; + int id = 0; if (soap_out___ns1__createMany(soap, tag?tag:"-ns1:createMany", id, a, type)) return soap->error; return SOAP_OK; @@ -27003,7 +27003,7 @@ SOAP_FMAC3 struct __ns1__luceneGetPopulating * SOAP_FMAC4 soap_in___ns1__luceneG SOAP_FMAC3 int SOAP_FMAC4 soap_put___ns1__luceneGetPopulating(struct soap *soap, const struct __ns1__luceneGetPopulating *a, const char *tag, const char *type) { - register int id = 0; + int id = 0; if (soap_out___ns1__luceneGetPopulating(soap, tag?tag:"-ns1:luceneGetPopulating", id, a, type)) return soap->error; return SOAP_OK; @@ -27099,7 +27099,7 @@ SOAP_FMAC3 struct __ns1__luceneSearch * SOAP_FMAC4 soap_in___ns1__luceneSearch(s SOAP_FMAC3 int SOAP_FMAC4 soap_put___ns1__luceneSearch(struct soap *soap, const struct __ns1__luceneSearch *a, const char *tag, const char *type) { - register int id = 0; + int id = 0; if (soap_out___ns1__luceneSearch(soap, tag?tag:"-ns1:luceneSearch", id, a, type)) return soap->error; return SOAP_OK; @@ -27195,7 +27195,7 @@ SOAP_FMAC3 struct __ns1__luceneCommit * SOAP_FMAC4 soap_in___ns1__luceneCommit(s SOAP_FMAC3 int SOAP_FMAC4 soap_put___ns1__luceneCommit(struct soap *soap, const struct __ns1__luceneCommit *a, const char *tag, const char *type) { - register int id = 0; + int id = 0; if (soap_out___ns1__luceneCommit(soap, tag?tag:"-ns1:luceneCommit", id, a, type)) return soap->error; return SOAP_OK; @@ -27294,7 +27294,7 @@ SOAP_FMAC3 struct __ns1__luceneCommitResponse * SOAP_FMAC4 soap_in___ns1__lucene SOAP_FMAC3 int SOAP_FMAC4 soap_put___ns1__luceneCommitResponse(struct soap *soap, const struct __ns1__luceneCommitResponse *a, const char *tag, const char *type) { - register int id = 0; + int id = 0; if (soap_out___ns1__luceneCommitResponse(soap, tag?tag:"-ns1:luceneCommitResponse", id, a, type)) return soap->error; return SOAP_OK; @@ -27390,7 +27390,7 @@ SOAP_FMAC3 struct __ns1__luceneClear * SOAP_FMAC4 soap_in___ns1__luceneClear(str SOAP_FMAC3 int SOAP_FMAC4 soap_put___ns1__luceneClear(struct soap *soap, const struct __ns1__luceneClear *a, const char *tag, const char *type) { - register int id = 0; + int id = 0; if (soap_out___ns1__luceneClear(soap, tag?tag:"-ns1:luceneClear", id, a, type)) return soap->error; return SOAP_OK; @@ -27489,7 +27489,7 @@ SOAP_FMAC3 struct __ns1__luceneClearResponse * SOAP_FMAC4 soap_in___ns1__luceneC SOAP_FMAC3 int SOAP_FMAC4 soap_put___ns1__luceneClearResponse(struct soap *soap, const struct __ns1__luceneClearResponse *a, const char *tag, const char *type) { - register int id = 0; + int id = 0; if (soap_out___ns1__luceneClearResponse(soap, tag?tag:"-ns1:luceneClearResponse", id, a, type)) return soap->error; return SOAP_OK; @@ -27585,7 +27585,7 @@ SOAP_FMAC3 struct __ns1__lucenePopulate * SOAP_FMAC4 soap_in___ns1__lucenePopula SOAP_FMAC3 int SOAP_FMAC4 soap_put___ns1__lucenePopulate(struct soap *soap, const struct __ns1__lucenePopulate *a, const char *tag, const char *type) { - register int id = 0; + int id = 0; if (soap_out___ns1__lucenePopulate(soap, tag?tag:"-ns1:lucenePopulate", id, a, type)) return soap->error; return SOAP_OK; @@ -27684,7 +27684,7 @@ SOAP_FMAC3 struct __ns1__lucenePopulateResponse * SOAP_FMAC4 soap_in___ns1__luce SOAP_FMAC3 int SOAP_FMAC4 soap_put___ns1__lucenePopulateResponse(struct soap *soap, const struct __ns1__lucenePopulateResponse *a, const char *tag, const char *type) { - register int id = 0; + int id = 0; if (soap_out___ns1__lucenePopulateResponse(soap, tag?tag:"-ns1:lucenePopulateResponse", id, a, type)) return soap->error; return SOAP_OK; @@ -27780,7 +27780,7 @@ SOAP_FMAC3 struct __ns1__isAccessAllowed * SOAP_FMAC4 soap_in___ns1__isAccessAll SOAP_FMAC3 int SOAP_FMAC4 soap_put___ns1__isAccessAllowed(struct soap *soap, const struct __ns1__isAccessAllowed *a, const char *tag, const char *type) { - register int id = 0; + int id = 0; if (soap_out___ns1__isAccessAllowed(soap, tag?tag:"-ns1:isAccessAllowed", id, a, type)) return soap->error; return SOAP_OK; @@ -27876,7 +27876,7 @@ SOAP_FMAC3 struct __ns1__searchText * SOAP_FMAC4 soap_in___ns1__searchText(struc SOAP_FMAC3 int SOAP_FMAC4 soap_put___ns1__searchText(struct soap *soap, const struct __ns1__searchText *a, const char *tag, const char *type) { - register int id = 0; + int id = 0; if (soap_out___ns1__searchText(soap, tag?tag:"-ns1:searchText", id, a, type)) return soap->error; return SOAP_OK; @@ -27972,7 +27972,7 @@ SOAP_FMAC3 struct __ns1__getRemainingMinutes * SOAP_FMAC4 soap_in___ns1__getRema SOAP_FMAC3 int SOAP_FMAC4 soap_put___ns1__getRemainingMinutes(struct soap *soap, const struct __ns1__getRemainingMinutes *a, const char *tag, const char *type) { - register int id = 0; + int id = 0; if (soap_out___ns1__getRemainingMinutes(soap, tag?tag:"-ns1:getRemainingMinutes", id, a, type)) return soap->error; return SOAP_OK; @@ -28068,7 +28068,7 @@ SOAP_FMAC3 struct __ns1__logout * SOAP_FMAC4 soap_in___ns1__logout(struct soap * SOAP_FMAC3 int SOAP_FMAC4 soap_put___ns1__logout(struct soap *soap, const struct __ns1__logout *a, const char *tag, const char *type) { - register int id = 0; + int id = 0; if (soap_out___ns1__logout(soap, tag?tag:"-ns1:logout", id, a, type)) return soap->error; return SOAP_OK; @@ -28167,7 +28167,7 @@ SOAP_FMAC3 struct __ns1__logoutResponse * SOAP_FMAC4 soap_in___ns1__logoutRespon SOAP_FMAC3 int SOAP_FMAC4 soap_put___ns1__logoutResponse(struct soap *soap, const struct __ns1__logoutResponse *a, const char *tag, const char *type) { - register int id = 0; + int id = 0; if (soap_out___ns1__logoutResponse(soap, tag?tag:"-ns1:logoutResponse", id, a, type)) return soap->error; return SOAP_OK; @@ -28263,7 +28263,7 @@ SOAP_FMAC3 struct __ns1__dummy * SOAP_FMAC4 soap_in___ns1__dummy(struct soap *so SOAP_FMAC3 int SOAP_FMAC4 soap_put___ns1__dummy(struct soap *soap, const struct __ns1__dummy *a, const char *tag, const char *type) { - register int id = 0; + int id = 0; if (soap_out___ns1__dummy(soap, tag?tag:"-ns1:dummy", id, a, type)) return soap->error; return SOAP_OK; @@ -28362,7 +28362,7 @@ SOAP_FMAC3 struct __ns1__dummyResponse * SOAP_FMAC4 soap_in___ns1__dummyResponse SOAP_FMAC3 int SOAP_FMAC4 soap_put___ns1__dummyResponse(struct soap *soap, const struct __ns1__dummyResponse *a, const char *tag, const char *type) { - register int id = 0; + int id = 0; if (soap_out___ns1__dummyResponse(soap, tag?tag:"-ns1:dummyResponse", id, a, type)) return soap->error; return SOAP_OK; @@ -28458,7 +28458,7 @@ SOAP_FMAC3 struct __ns1__refresh * SOAP_FMAC4 soap_in___ns1__refresh(struct soap SOAP_FMAC3 int SOAP_FMAC4 soap_put___ns1__refresh(struct soap *soap, const struct __ns1__refresh *a, const char *tag, const char *type) { - register int id = 0; + int id = 0; if (soap_out___ns1__refresh(soap, tag?tag:"-ns1:refresh", id, a, type)) return soap->error; return SOAP_OK; @@ -28557,7 +28557,7 @@ SOAP_FMAC3 struct __ns1__refreshResponse * SOAP_FMAC4 soap_in___ns1__refreshResp SOAP_FMAC3 int SOAP_FMAC4 soap_put___ns1__refreshResponse(struct soap *soap, const struct __ns1__refreshResponse *a, const char *tag, const char *type) { - register int id = 0; + int id = 0; if (soap_out___ns1__refreshResponse(soap, tag?tag:"-ns1:refreshResponse", id, a, type)) return soap->error; return SOAP_OK; @@ -28653,7 +28653,7 @@ SOAP_FMAC3 struct __ns1__getEntityNames * SOAP_FMAC4 soap_in___ns1__getEntityNam SOAP_FMAC3 int SOAP_FMAC4 soap_put___ns1__getEntityNames(struct soap *soap, const struct __ns1__getEntityNames *a, const char *tag, const char *type) { - register int id = 0; + int id = 0; if (soap_out___ns1__getEntityNames(soap, tag?tag:"-ns1:getEntityNames", id, a, type)) return soap->error; return SOAP_OK; @@ -28749,7 +28749,7 @@ SOAP_FMAC3 struct __ns1__getApiVersion * SOAP_FMAC4 soap_in___ns1__getApiVersion SOAP_FMAC3 int SOAP_FMAC4 soap_put___ns1__getApiVersion(struct soap *soap, const struct __ns1__getApiVersion *a, const char *tag, const char *type) { - register int id = 0; + int id = 0; if (soap_out___ns1__getApiVersion(soap, tag?tag:"-ns1:getApiVersion", id, a, type)) return soap->error; return SOAP_OK; @@ -28845,7 +28845,7 @@ SOAP_FMAC3 struct __ns1__update * SOAP_FMAC4 soap_in___ns1__update(struct soap * SOAP_FMAC3 int SOAP_FMAC4 soap_put___ns1__update(struct soap *soap, const struct __ns1__update *a, const char *tag, const char *type) { - register int id = 0; + int id = 0; if (soap_out___ns1__update(soap, tag?tag:"-ns1:update", id, a, type)) return soap->error; return SOAP_OK; @@ -28944,7 +28944,7 @@ SOAP_FMAC3 struct __ns1__updateResponse * SOAP_FMAC4 soap_in___ns1__updateRespon SOAP_FMAC3 int SOAP_FMAC4 soap_put___ns1__updateResponse(struct soap *soap, const struct __ns1__updateResponse *a, const char *tag, const char *type) { - register int id = 0; + int id = 0; if (soap_out___ns1__updateResponse(soap, tag?tag:"-ns1:updateResponse", id, a, type)) return soap->error; return SOAP_OK; @@ -29040,7 +29040,7 @@ SOAP_FMAC3 struct __ns1__create * SOAP_FMAC4 soap_in___ns1__create(struct soap * SOAP_FMAC3 int SOAP_FMAC4 soap_put___ns1__create(struct soap *soap, const struct __ns1__create *a, const char *tag, const char *type) { - register int id = 0; + int id = 0; if (soap_out___ns1__create(soap, tag?tag:"-ns1:create", id, a, type)) return soap->error; return SOAP_OK; @@ -29136,7 +29136,7 @@ SOAP_FMAC3 struct __ns1__search * SOAP_FMAC4 soap_in___ns1__search(struct soap * SOAP_FMAC3 int SOAP_FMAC4 soap_put___ns1__search(struct soap *soap, const struct __ns1__search *a, const char *tag, const char *type) { - register int id = 0; + int id = 0; if (soap_out___ns1__search(soap, tag?tag:"-ns1:search", id, a, type)) return soap->error; return SOAP_OK; @@ -29232,7 +29232,7 @@ SOAP_FMAC3 struct __ns1__delete * SOAP_FMAC4 soap_in___ns1__delete(struct soap * SOAP_FMAC3 int SOAP_FMAC4 soap_put___ns1__delete(struct soap *soap, const struct __ns1__delete *a, const char *tag, const char *type) { - register int id = 0; + int id = 0; if (soap_out___ns1__delete(soap, tag?tag:"-ns1:delete", id, a, type)) return soap->error; return SOAP_OK; @@ -29331,7 +29331,7 @@ SOAP_FMAC3 struct __ns1__deleteResponse * SOAP_FMAC4 soap_in___ns1__deleteRespon SOAP_FMAC3 int SOAP_FMAC4 soap_put___ns1__deleteResponse(struct soap *soap, const struct __ns1__deleteResponse *a, const char *tag, const char *type) { - register int id = 0; + int id = 0; if (soap_out___ns1__deleteResponse(soap, tag?tag:"-ns1:deleteResponse", id, a, type)) return soap->error; return SOAP_OK; @@ -29427,7 +29427,7 @@ SOAP_FMAC3 struct __ns1__getProperties * SOAP_FMAC4 soap_in___ns1__getProperties SOAP_FMAC3 int SOAP_FMAC4 soap_put___ns1__getProperties(struct soap *soap, const struct __ns1__getProperties *a, const char *tag, const char *type) { - register int id = 0; + int id = 0; if (soap_out___ns1__getProperties(soap, tag?tag:"-ns1:getProperties", id, a, type)) return soap->error; return SOAP_OK; @@ -29523,7 +29523,7 @@ SOAP_FMAC3 struct __ns1__get * SOAP_FMAC4 soap_in___ns1__get(struct soap *soap, SOAP_FMAC3 int SOAP_FMAC4 soap_put___ns1__get(struct soap *soap, const struct __ns1__get *a, const char *tag, const char *type) { - register int id = 0; + int id = 0; if (soap_out___ns1__get(soap, tag?tag:"-ns1:get", id, a, type)) return soap->error; return SOAP_OK; @@ -29619,7 +29619,7 @@ SOAP_FMAC3 struct __ns1__getUserName * SOAP_FMAC4 soap_in___ns1__getUserName(str SOAP_FMAC3 int SOAP_FMAC4 soap_put___ns1__getUserName(struct soap *soap, const struct __ns1__getUserName *a, const char *tag, const char *type) { - register int id = 0; + int id = 0; if (soap_out___ns1__getUserName(soap, tag?tag:"-ns1:getUserName", id, a, type)) return soap->error; return SOAP_OK; @@ -29715,7 +29715,7 @@ SOAP_FMAC3 struct __ns1__login * SOAP_FMAC4 soap_in___ns1__login(struct soap *so SOAP_FMAC3 int SOAP_FMAC4 soap_put___ns1__login(struct soap *soap, const struct __ns1__login *a, const char *tag, const char *type) { - register int id = 0; + int id = 0; if (soap_out___ns1__login(soap, tag?tag:"-ns1:login", id, a, type)) return soap->error; return SOAP_OK; @@ -29846,7 +29846,7 @@ SOAP_FMAC3 struct SOAP_ENV__Detail * SOAP_FMAC4 soap_in_SOAP_ENV__Detail(struct SOAP_FMAC3 int SOAP_FMAC4 soap_put_SOAP_ENV__Detail(struct soap *soap, const struct SOAP_ENV__Detail *a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat4_SOAP_ENV__Detail); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat4_SOAP_ENV__Detail); if (soap_out_SOAP_ENV__Detail(soap, tag?tag:"SOAP-ENV:Detail", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -29933,7 +29933,7 @@ SOAP_FMAC3 struct SOAP_ENV__Reason ** SOAP_FMAC4 soap_in_PointerToSOAP_ENV__Reas SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerToSOAP_ENV__Reason(struct soap *soap, struct SOAP_ENV__Reason *const*a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat4_PointerToSOAP_ENV__Reason); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat4_PointerToSOAP_ENV__Reason); if (soap_out_PointerToSOAP_ENV__Reason(soap, tag?tag:"SOAP-ENV:Reason", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -29990,7 +29990,7 @@ SOAP_FMAC3 struct SOAP_ENV__Detail ** SOAP_FMAC4 soap_in_PointerToSOAP_ENV__Deta SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerToSOAP_ENV__Detail(struct soap *soap, struct SOAP_ENV__Detail *const*a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat4_PointerToSOAP_ENV__Detail); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat4_PointerToSOAP_ENV__Detail); if (soap_out_PointerToSOAP_ENV__Detail(soap, tag?tag:"SOAP-ENV:Detail", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -30047,7 +30047,7 @@ SOAP_FMAC3 struct SOAP_ENV__Code ** SOAP_FMAC4 soap_in_PointerToSOAP_ENV__Code(s SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerToSOAP_ENV__Code(struct soap *soap, struct SOAP_ENV__Code *const*a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat4_PointerToSOAP_ENV__Code); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat4_PointerToSOAP_ENV__Code); if (soap_out_PointerToSOAP_ENV__Code(soap, tag?tag:"SOAP-ENV:Code", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -30106,7 +30106,7 @@ SOAP_FMAC3 ns1__getEntityInfoResponse ** SOAP_FMAC4 soap_in_PointerTons1__getEnt SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTons1__getEntityInfoResponse(struct soap *soap, ns1__getEntityInfoResponse *const*a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat4_PointerTons1__getEntityInfoResponse); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat4_PointerTons1__getEntityInfoResponse); if (soap_out_PointerTons1__getEntityInfoResponse(soap, tag?tag:"ns1:getEntityInfoResponse", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -30163,7 +30163,7 @@ SOAP_FMAC3 ns1__getEntityInfo ** SOAP_FMAC4 soap_in_PointerTons1__getEntityInfo( SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTons1__getEntityInfo(struct soap *soap, ns1__getEntityInfo *const*a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat4_PointerTons1__getEntityInfo); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat4_PointerTons1__getEntityInfo); if (soap_out_PointerTons1__getEntityInfo(soap, tag?tag:"ns1:getEntityInfo", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -30220,7 +30220,7 @@ SOAP_FMAC3 ns1__deleteManyResponse ** SOAP_FMAC4 soap_in_PointerTons1__deleteMan SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTons1__deleteManyResponse(struct soap *soap, ns1__deleteManyResponse *const*a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat4_PointerTons1__deleteManyResponse); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat4_PointerTons1__deleteManyResponse); if (soap_out_PointerTons1__deleteManyResponse(soap, tag?tag:"ns1:deleteManyResponse", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -30277,7 +30277,7 @@ SOAP_FMAC3 ns1__deleteMany ** SOAP_FMAC4 soap_in_PointerTons1__deleteMany(struct SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTons1__deleteMany(struct soap *soap, ns1__deleteMany *const*a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat4_PointerTons1__deleteMany); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat4_PointerTons1__deleteMany); if (soap_out_PointerTons1__deleteMany(soap, tag?tag:"ns1:deleteMany", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -30334,7 +30334,7 @@ SOAP_FMAC3 ns1__createManyResponse ** SOAP_FMAC4 soap_in_PointerTons1__createMan SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTons1__createManyResponse(struct soap *soap, ns1__createManyResponse *const*a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat4_PointerTons1__createManyResponse); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat4_PointerTons1__createManyResponse); if (soap_out_PointerTons1__createManyResponse(soap, tag?tag:"ns1:createManyResponse", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -30391,7 +30391,7 @@ SOAP_FMAC3 ns1__createMany ** SOAP_FMAC4 soap_in_PointerTons1__createMany(struct SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTons1__createMany(struct soap *soap, ns1__createMany *const*a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat4_PointerTons1__createMany); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat4_PointerTons1__createMany); if (soap_out_PointerTons1__createMany(soap, tag?tag:"ns1:createMany", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -30448,7 +30448,7 @@ SOAP_FMAC3 ns1__luceneGetPopulatingResponse ** SOAP_FMAC4 soap_in_PointerTons1__ SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTons1__luceneGetPopulatingResponse(struct soap *soap, ns1__luceneGetPopulatingResponse *const*a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat4_PointerTons1__luceneGetPopulatingResponse); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat4_PointerTons1__luceneGetPopulatingResponse); if (soap_out_PointerTons1__luceneGetPopulatingResponse(soap, tag?tag:"ns1:luceneGetPopulatingResponse", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -30505,7 +30505,7 @@ SOAP_FMAC3 ns1__luceneGetPopulating ** SOAP_FMAC4 soap_in_PointerTons1__luceneGe SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTons1__luceneGetPopulating(struct soap *soap, ns1__luceneGetPopulating *const*a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat4_PointerTons1__luceneGetPopulating); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat4_PointerTons1__luceneGetPopulating); if (soap_out_PointerTons1__luceneGetPopulating(soap, tag?tag:"ns1:luceneGetPopulating", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -30562,7 +30562,7 @@ SOAP_FMAC3 ns1__luceneSearchResponse ** SOAP_FMAC4 soap_in_PointerTons1__luceneS SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTons1__luceneSearchResponse(struct soap *soap, ns1__luceneSearchResponse *const*a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat4_PointerTons1__luceneSearchResponse); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat4_PointerTons1__luceneSearchResponse); if (soap_out_PointerTons1__luceneSearchResponse(soap, tag?tag:"ns1:luceneSearchResponse", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -30619,7 +30619,7 @@ SOAP_FMAC3 ns1__luceneSearch ** SOAP_FMAC4 soap_in_PointerTons1__luceneSearch(st SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTons1__luceneSearch(struct soap *soap, ns1__luceneSearch *const*a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat4_PointerTons1__luceneSearch); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat4_PointerTons1__luceneSearch); if (soap_out_PointerTons1__luceneSearch(soap, tag?tag:"ns1:luceneSearch", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -30676,7 +30676,7 @@ SOAP_FMAC3 ns1__luceneCommitResponse ** SOAP_FMAC4 soap_in_PointerTons1__luceneC SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTons1__luceneCommitResponse(struct soap *soap, ns1__luceneCommitResponse *const*a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat4_PointerTons1__luceneCommitResponse); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat4_PointerTons1__luceneCommitResponse); if (soap_out_PointerTons1__luceneCommitResponse(soap, tag?tag:"ns1:luceneCommitResponse", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -30733,7 +30733,7 @@ SOAP_FMAC3 ns1__luceneCommit ** SOAP_FMAC4 soap_in_PointerTons1__luceneCommit(st SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTons1__luceneCommit(struct soap *soap, ns1__luceneCommit *const*a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat4_PointerTons1__luceneCommit); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat4_PointerTons1__luceneCommit); if (soap_out_PointerTons1__luceneCommit(soap, tag?tag:"ns1:luceneCommit", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -30790,7 +30790,7 @@ SOAP_FMAC3 ns1__luceneClearResponse ** SOAP_FMAC4 soap_in_PointerTons1__luceneCl SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTons1__luceneClearResponse(struct soap *soap, ns1__luceneClearResponse *const*a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat4_PointerTons1__luceneClearResponse); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat4_PointerTons1__luceneClearResponse); if (soap_out_PointerTons1__luceneClearResponse(soap, tag?tag:"ns1:luceneClearResponse", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -30847,7 +30847,7 @@ SOAP_FMAC3 ns1__luceneClear ** SOAP_FMAC4 soap_in_PointerTons1__luceneClear(stru SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTons1__luceneClear(struct soap *soap, ns1__luceneClear *const*a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat4_PointerTons1__luceneClear); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat4_PointerTons1__luceneClear); if (soap_out_PointerTons1__luceneClear(soap, tag?tag:"ns1:luceneClear", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -30904,7 +30904,7 @@ SOAP_FMAC3 ns1__lucenePopulateResponse ** SOAP_FMAC4 soap_in_PointerTons1__lucen SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTons1__lucenePopulateResponse(struct soap *soap, ns1__lucenePopulateResponse *const*a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat4_PointerTons1__lucenePopulateResponse); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat4_PointerTons1__lucenePopulateResponse); if (soap_out_PointerTons1__lucenePopulateResponse(soap, tag?tag:"ns1:lucenePopulateResponse", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -30961,7 +30961,7 @@ SOAP_FMAC3 ns1__lucenePopulate ** SOAP_FMAC4 soap_in_PointerTons1__lucenePopulat SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTons1__lucenePopulate(struct soap *soap, ns1__lucenePopulate *const*a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat4_PointerTons1__lucenePopulate); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat4_PointerTons1__lucenePopulate); if (soap_out_PointerTons1__lucenePopulate(soap, tag?tag:"ns1:lucenePopulate", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -31018,7 +31018,7 @@ SOAP_FMAC3 ns1__isAccessAllowedResponse ** SOAP_FMAC4 soap_in_PointerTons1__isAc SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTons1__isAccessAllowedResponse(struct soap *soap, ns1__isAccessAllowedResponse *const*a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat4_PointerTons1__isAccessAllowedResponse); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat4_PointerTons1__isAccessAllowedResponse); if (soap_out_PointerTons1__isAccessAllowedResponse(soap, tag?tag:"ns1:isAccessAllowedResponse", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -31075,7 +31075,7 @@ SOAP_FMAC3 ns1__isAccessAllowed ** SOAP_FMAC4 soap_in_PointerTons1__isAccessAllo SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTons1__isAccessAllowed(struct soap *soap, ns1__isAccessAllowed *const*a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat4_PointerTons1__isAccessAllowed); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat4_PointerTons1__isAccessAllowed); if (soap_out_PointerTons1__isAccessAllowed(soap, tag?tag:"ns1:isAccessAllowed", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -31132,7 +31132,7 @@ SOAP_FMAC3 ns1__searchTextResponse ** SOAP_FMAC4 soap_in_PointerTons1__searchTex SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTons1__searchTextResponse(struct soap *soap, ns1__searchTextResponse *const*a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat4_PointerTons1__searchTextResponse); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat4_PointerTons1__searchTextResponse); if (soap_out_PointerTons1__searchTextResponse(soap, tag?tag:"ns1:searchTextResponse", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -31189,7 +31189,7 @@ SOAP_FMAC3 ns1__searchText ** SOAP_FMAC4 soap_in_PointerTons1__searchText(struct SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTons1__searchText(struct soap *soap, ns1__searchText *const*a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat4_PointerTons1__searchText); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat4_PointerTons1__searchText); if (soap_out_PointerTons1__searchText(soap, tag?tag:"ns1:searchText", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -31246,7 +31246,7 @@ SOAP_FMAC3 ns1__getRemainingMinutesResponse ** SOAP_FMAC4 soap_in_PointerTons1__ SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTons1__getRemainingMinutesResponse(struct soap *soap, ns1__getRemainingMinutesResponse *const*a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat4_PointerTons1__getRemainingMinutesResponse); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat4_PointerTons1__getRemainingMinutesResponse); if (soap_out_PointerTons1__getRemainingMinutesResponse(soap, tag?tag:"ns1:getRemainingMinutesResponse", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -31303,7 +31303,7 @@ SOAP_FMAC3 ns1__getRemainingMinutes ** SOAP_FMAC4 soap_in_PointerTons1__getRemai SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTons1__getRemainingMinutes(struct soap *soap, ns1__getRemainingMinutes *const*a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat4_PointerTons1__getRemainingMinutes); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat4_PointerTons1__getRemainingMinutes); if (soap_out_PointerTons1__getRemainingMinutes(soap, tag?tag:"ns1:getRemainingMinutes", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -31360,7 +31360,7 @@ SOAP_FMAC3 ns1__logoutResponse ** SOAP_FMAC4 soap_in_PointerTons1__logoutRespons SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTons1__logoutResponse(struct soap *soap, ns1__logoutResponse *const*a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat4_PointerTons1__logoutResponse); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat4_PointerTons1__logoutResponse); if (soap_out_PointerTons1__logoutResponse(soap, tag?tag:"ns1:logoutResponse", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -31417,7 +31417,7 @@ SOAP_FMAC3 ns1__logout ** SOAP_FMAC4 soap_in_PointerTons1__logout(struct soap *s SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTons1__logout(struct soap *soap, ns1__logout *const*a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat4_PointerTons1__logout); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat4_PointerTons1__logout); if (soap_out_PointerTons1__logout(soap, tag?tag:"ns1:logout", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -31474,7 +31474,7 @@ SOAP_FMAC3 ns1__dummyResponse ** SOAP_FMAC4 soap_in_PointerTons1__dummyResponse( SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTons1__dummyResponse(struct soap *soap, ns1__dummyResponse *const*a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat4_PointerTons1__dummyResponse); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat4_PointerTons1__dummyResponse); if (soap_out_PointerTons1__dummyResponse(soap, tag?tag:"ns1:dummyResponse", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -31531,7 +31531,7 @@ SOAP_FMAC3 ns1__dummy ** SOAP_FMAC4 soap_in_PointerTons1__dummy(struct soap *soa SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTons1__dummy(struct soap *soap, ns1__dummy *const*a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat4_PointerTons1__dummy); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat4_PointerTons1__dummy); if (soap_out_PointerTons1__dummy(soap, tag?tag:"ns1:dummy", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -31588,7 +31588,7 @@ SOAP_FMAC3 ns1__refreshResponse ** SOAP_FMAC4 soap_in_PointerTons1__refreshRespo SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTons1__refreshResponse(struct soap *soap, ns1__refreshResponse *const*a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat4_PointerTons1__refreshResponse); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat4_PointerTons1__refreshResponse); if (soap_out_PointerTons1__refreshResponse(soap, tag?tag:"ns1:refreshResponse", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -31645,7 +31645,7 @@ SOAP_FMAC3 ns1__refresh ** SOAP_FMAC4 soap_in_PointerTons1__refresh(struct soap SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTons1__refresh(struct soap *soap, ns1__refresh *const*a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat4_PointerTons1__refresh); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat4_PointerTons1__refresh); if (soap_out_PointerTons1__refresh(soap, tag?tag:"ns1:refresh", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -31702,7 +31702,7 @@ SOAP_FMAC3 ns1__getEntityNamesResponse ** SOAP_FMAC4 soap_in_PointerTons1__getEn SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTons1__getEntityNamesResponse(struct soap *soap, ns1__getEntityNamesResponse *const*a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat4_PointerTons1__getEntityNamesResponse); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat4_PointerTons1__getEntityNamesResponse); if (soap_out_PointerTons1__getEntityNamesResponse(soap, tag?tag:"ns1:getEntityNamesResponse", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -31759,7 +31759,7 @@ SOAP_FMAC3 ns1__getEntityNames ** SOAP_FMAC4 soap_in_PointerTons1__getEntityName SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTons1__getEntityNames(struct soap *soap, ns1__getEntityNames *const*a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat4_PointerTons1__getEntityNames); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat4_PointerTons1__getEntityNames); if (soap_out_PointerTons1__getEntityNames(soap, tag?tag:"ns1:getEntityNames", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -31816,7 +31816,7 @@ SOAP_FMAC3 ns1__getApiVersionResponse ** SOAP_FMAC4 soap_in_PointerTons1__getApi SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTons1__getApiVersionResponse(struct soap *soap, ns1__getApiVersionResponse *const*a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat4_PointerTons1__getApiVersionResponse); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat4_PointerTons1__getApiVersionResponse); if (soap_out_PointerTons1__getApiVersionResponse(soap, tag?tag:"ns1:getApiVersionResponse", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -31873,7 +31873,7 @@ SOAP_FMAC3 ns1__getApiVersion ** SOAP_FMAC4 soap_in_PointerTons1__getApiVersion( SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTons1__getApiVersion(struct soap *soap, ns1__getApiVersion *const*a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat4_PointerTons1__getApiVersion); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat4_PointerTons1__getApiVersion); if (soap_out_PointerTons1__getApiVersion(soap, tag?tag:"ns1:getApiVersion", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -31930,7 +31930,7 @@ SOAP_FMAC3 ns1__updateResponse ** SOAP_FMAC4 soap_in_PointerTons1__updateRespons SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTons1__updateResponse(struct soap *soap, ns1__updateResponse *const*a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat4_PointerTons1__updateResponse); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat4_PointerTons1__updateResponse); if (soap_out_PointerTons1__updateResponse(soap, tag?tag:"ns1:updateResponse", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -31987,7 +31987,7 @@ SOAP_FMAC3 ns1__update ** SOAP_FMAC4 soap_in_PointerTons1__update(struct soap *s SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTons1__update(struct soap *soap, ns1__update *const*a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat4_PointerTons1__update); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat4_PointerTons1__update); if (soap_out_PointerTons1__update(soap, tag?tag:"ns1:update", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -32044,7 +32044,7 @@ SOAP_FMAC3 ns1__createResponse ** SOAP_FMAC4 soap_in_PointerTons1__createRespons SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTons1__createResponse(struct soap *soap, ns1__createResponse *const*a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat4_PointerTons1__createResponse); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat4_PointerTons1__createResponse); if (soap_out_PointerTons1__createResponse(soap, tag?tag:"ns1:createResponse", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -32101,7 +32101,7 @@ SOAP_FMAC3 ns1__create ** SOAP_FMAC4 soap_in_PointerTons1__create(struct soap *s SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTons1__create(struct soap *soap, ns1__create *const*a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat4_PointerTons1__create); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat4_PointerTons1__create); if (soap_out_PointerTons1__create(soap, tag?tag:"ns1:create", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -32158,7 +32158,7 @@ SOAP_FMAC3 ns1__searchResponse ** SOAP_FMAC4 soap_in_PointerTons1__searchRespons SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTons1__searchResponse(struct soap *soap, ns1__searchResponse *const*a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat4_PointerTons1__searchResponse); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat4_PointerTons1__searchResponse); if (soap_out_PointerTons1__searchResponse(soap, tag?tag:"ns1:searchResponse", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -32215,7 +32215,7 @@ SOAP_FMAC3 ns1__search ** SOAP_FMAC4 soap_in_PointerTons1__search(struct soap *s SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTons1__search(struct soap *soap, ns1__search *const*a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat4_PointerTons1__search); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat4_PointerTons1__search); if (soap_out_PointerTons1__search(soap, tag?tag:"ns1:search", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -32272,7 +32272,7 @@ SOAP_FMAC3 ns1__deleteResponse ** SOAP_FMAC4 soap_in_PointerTons1__deleteRespons SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTons1__deleteResponse(struct soap *soap, ns1__deleteResponse *const*a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat4_PointerTons1__deleteResponse); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat4_PointerTons1__deleteResponse); if (soap_out_PointerTons1__deleteResponse(soap, tag?tag:"ns1:deleteResponse", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -32329,7 +32329,7 @@ SOAP_FMAC3 ns1__delete ** SOAP_FMAC4 soap_in_PointerTons1__delete(struct soap *s SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTons1__delete(struct soap *soap, ns1__delete *const*a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat4_PointerTons1__delete); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat4_PointerTons1__delete); if (soap_out_PointerTons1__delete(soap, tag?tag:"ns1:delete", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -32386,7 +32386,7 @@ SOAP_FMAC3 ns1__getPropertiesResponse ** SOAP_FMAC4 soap_in_PointerTons1__getPro SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTons1__getPropertiesResponse(struct soap *soap, ns1__getPropertiesResponse *const*a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat4_PointerTons1__getPropertiesResponse); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat4_PointerTons1__getPropertiesResponse); if (soap_out_PointerTons1__getPropertiesResponse(soap, tag?tag:"ns1:getPropertiesResponse", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -32443,7 +32443,7 @@ SOAP_FMAC3 ns1__getProperties ** SOAP_FMAC4 soap_in_PointerTons1__getProperties( SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTons1__getProperties(struct soap *soap, ns1__getProperties *const*a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat4_PointerTons1__getProperties); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat4_PointerTons1__getProperties); if (soap_out_PointerTons1__getProperties(soap, tag?tag:"ns1:getProperties", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -32500,7 +32500,7 @@ SOAP_FMAC3 ns1__getResponse ** SOAP_FMAC4 soap_in_PointerTons1__getResponse(stru SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTons1__getResponse(struct soap *soap, ns1__getResponse *const*a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat4_PointerTons1__getResponse); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat4_PointerTons1__getResponse); if (soap_out_PointerTons1__getResponse(soap, tag?tag:"ns1:getResponse", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -32557,7 +32557,7 @@ SOAP_FMAC3 ns1__get ** SOAP_FMAC4 soap_in_PointerTons1__get(struct soap *soap, c SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTons1__get(struct soap *soap, ns1__get *const*a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat4_PointerTons1__get); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat4_PointerTons1__get); if (soap_out_PointerTons1__get(soap, tag?tag:"ns1:get", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -32614,7 +32614,7 @@ SOAP_FMAC3 ns1__getUserNameResponse ** SOAP_FMAC4 soap_in_PointerTons1__getUserN SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTons1__getUserNameResponse(struct soap *soap, ns1__getUserNameResponse *const*a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat4_PointerTons1__getUserNameResponse); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat4_PointerTons1__getUserNameResponse); if (soap_out_PointerTons1__getUserNameResponse(soap, tag?tag:"ns1:getUserNameResponse", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -32671,7 +32671,7 @@ SOAP_FMAC3 ns1__getUserName ** SOAP_FMAC4 soap_in_PointerTons1__getUserName(stru SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTons1__getUserName(struct soap *soap, ns1__getUserName *const*a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat4_PointerTons1__getUserName); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat4_PointerTons1__getUserName); if (soap_out_PointerTons1__getUserName(soap, tag?tag:"ns1:getUserName", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -32728,7 +32728,7 @@ SOAP_FMAC3 ns1__loginResponse ** SOAP_FMAC4 soap_in_PointerTons1__loginResponse( SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTons1__loginResponse(struct soap *soap, ns1__loginResponse *const*a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat4_PointerTons1__loginResponse); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat4_PointerTons1__loginResponse); if (soap_out_PointerTons1__loginResponse(soap, tag?tag:"ns1:loginResponse", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -32785,7 +32785,7 @@ SOAP_FMAC3 ns1__login ** SOAP_FMAC4 soap_in_PointerTons1__login(struct soap *soa SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTons1__login(struct soap *soap, ns1__login *const*a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat4_PointerTons1__login); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat4_PointerTons1__login); if (soap_out_PointerTons1__login(soap, tag?tag:"ns1:login", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -32842,7 +32842,7 @@ SOAP_FMAC3 ns1__IcatException ** SOAP_FMAC4 soap_in_PointerTons1__IcatException( SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTons1__IcatException(struct soap *soap, ns1__IcatException *const*a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat4_PointerTons1__IcatException); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat4_PointerTons1__IcatException); if (soap_out_PointerTons1__IcatException(soap, tag?tag:"ns1:IcatException", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -32894,7 +32894,7 @@ SOAP_FMAC3 enum ns1__parameterValueType ** SOAP_FMAC4 soap_in_PointerTons1__para SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTons1__parameterValueType(struct soap *soap, enum ns1__parameterValueType *const*a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat4_PointerTons1__parameterValueType); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat4_PointerTons1__parameterValueType); if (soap_out_PointerTons1__parameterValueType(soap, tag?tag:"ns1:parameterValueType", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -32951,7 +32951,7 @@ SOAP_FMAC3 ns1__permissibleStringValue ** SOAP_FMAC4 soap_in_PointerTons1__permi SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTons1__permissibleStringValue(struct soap *soap, ns1__permissibleStringValue *const*a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat4_PointerTons1__permissibleStringValue); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat4_PointerTons1__permissibleStringValue); if (soap_out_PointerTons1__permissibleStringValue(soap, tag?tag:"ns1:permissibleStringValue", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -33003,7 +33003,7 @@ SOAP_FMAC3 double ** SOAP_FMAC4 soap_in_PointerTodouble(struct soap *soap, const SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTodouble(struct soap *soap, double *const*a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat4_PointerTodouble); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat4_PointerTodouble); if (soap_out_PointerTodouble(soap, tag?tag:"double", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -33060,7 +33060,7 @@ SOAP_FMAC3 ns1__rule ** SOAP_FMAC4 soap_in_PointerTons1__rule(struct soap *soap, SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTons1__rule(struct soap *soap, ns1__rule *const*a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat4_PointerTons1__rule); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat4_PointerTons1__rule); if (soap_out_PointerTons1__rule(soap, tag?tag:"ns1:rule", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -33117,7 +33117,7 @@ SOAP_FMAC3 ns1__sampleType ** SOAP_FMAC4 soap_in_PointerTons1__sampleType(struct SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTons1__sampleType(struct soap *soap, ns1__sampleType *const*a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat4_PointerTons1__sampleType); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat4_PointerTons1__sampleType); if (soap_out_PointerTons1__sampleType(soap, tag?tag:"ns1:sampleType", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -33174,7 +33174,7 @@ SOAP_FMAC3 ns1__investigationParameter ** SOAP_FMAC4 soap_in_PointerTons1__inves SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTons1__investigationParameter(struct soap *soap, ns1__investigationParameter *const*a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat4_PointerTons1__investigationParameter); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat4_PointerTons1__investigationParameter); if (soap_out_PointerTons1__investigationParameter(soap, tag?tag:"ns1:investigationParameter", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -33231,7 +33231,7 @@ SOAP_FMAC3 ns1__investigationInstrument ** SOAP_FMAC4 soap_in_PointerTons1__inve SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTons1__investigationInstrument(struct soap *soap, ns1__investigationInstrument *const*a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat4_PointerTons1__investigationInstrument); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat4_PointerTons1__investigationInstrument); if (soap_out_PointerTons1__investigationInstrument(soap, tag?tag:"ns1:investigationInstrument", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -33283,7 +33283,7 @@ SOAP_FMAC3 enum ns1__accessType ** SOAP_FMAC4 soap_in_PointerTons1__accessType(s SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTons1__accessType(struct soap *soap, enum ns1__accessType *const*a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat4_PointerTons1__accessType); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat4_PointerTons1__accessType); if (soap_out_PointerTons1__accessType(soap, tag?tag:"ns1:accessType", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -33752,7 +33752,7 @@ SOAP_FMAC3 xsd__anyType ** SOAP_FMAC4 soap_in_PointerToxsd__anyType(struct soap SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerToxsd__anyType(struct soap *soap, xsd__anyType *const*a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat4_PointerToxsd__anyType); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat4_PointerToxsd__anyType); if (soap_out_PointerToxsd__anyType(soap, tag?tag:"xsd:anyType", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -33804,7 +33804,7 @@ SOAP_FMAC3 int ** SOAP_FMAC4 soap_in_PointerToint(struct soap *soap, const char SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerToint(struct soap *soap, int *const*a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat4_PointerToint); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat4_PointerToint); if (soap_out_PointerToint(soap, tag?tag:"int", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -33856,7 +33856,7 @@ SOAP_FMAC3 enum ns1__relType ** SOAP_FMAC4 soap_in_PointerTons1__relType(struct SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTons1__relType(struct soap *soap, enum ns1__relType *const*a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat4_PointerTons1__relType); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat4_PointerTons1__relType); if (soap_out_PointerTons1__relType(soap, tag?tag:"ns1:relType", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -33913,7 +33913,7 @@ SOAP_FMAC3 ns1__entityField ** SOAP_FMAC4 soap_in_PointerTons1__entityField(stru SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTons1__entityField(struct soap *soap, ns1__entityField *const*a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat4_PointerTons1__entityField); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat4_PointerTons1__entityField); if (soap_out_PointerTons1__entityField(soap, tag?tag:"ns1:entityField", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -33970,7 +33970,7 @@ SOAP_FMAC3 ns1__constraint ** SOAP_FMAC4 soap_in_PointerTons1__constraint(struct SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTons1__constraint(struct soap *soap, ns1__constraint *const*a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat4_PointerTons1__constraint); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat4_PointerTons1__constraint); if (soap_out_PointerTons1__constraint(soap, tag?tag:"ns1:constraint", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -34027,7 +34027,7 @@ SOAP_FMAC3 ns1__entityInfo ** SOAP_FMAC4 soap_in_PointerTons1__entityInfo(struct SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTons1__entityInfo(struct soap *soap, ns1__entityInfo *const*a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat4_PointerTons1__entityInfo); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat4_PointerTons1__entityInfo); if (soap_out_PointerTons1__entityInfo(soap, tag?tag:"ns1:entityInfo", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -34084,7 +34084,7 @@ SOAP_FMAC3 ns1__publicStep ** SOAP_FMAC4 soap_in_PointerTons1__publicStep(struct SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTons1__publicStep(struct soap *soap, ns1__publicStep *const*a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat4_PointerTons1__publicStep); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat4_PointerTons1__publicStep); if (soap_out_PointerTons1__publicStep(soap, tag?tag:"ns1:publicStep", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -34141,7 +34141,7 @@ SOAP_FMAC3 ns1__log ** SOAP_FMAC4 soap_in_PointerTons1__log(struct soap *soap, c SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTons1__log(struct soap *soap, ns1__log *const*a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat4_PointerTons1__log); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat4_PointerTons1__log); if (soap_out_PointerTons1__log(soap, tag?tag:"ns1:log", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -34198,7 +34198,7 @@ SOAP_FMAC3 ns1__userGroup ** SOAP_FMAC4 soap_in_PointerTons1__userGroup(struct s SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTons1__userGroup(struct soap *soap, ns1__userGroup *const*a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat4_PointerTons1__userGroup); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat4_PointerTons1__userGroup); if (soap_out_PointerTons1__userGroup(soap, tag?tag:"ns1:userGroup", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -34255,7 +34255,7 @@ SOAP_FMAC3 ns1__grouping ** SOAP_FMAC4 soap_in_PointerTons1__grouping(struct soa SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTons1__grouping(struct soap *soap, ns1__grouping *const*a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat4_PointerTons1__grouping); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat4_PointerTons1__grouping); if (soap_out_PointerTons1__grouping(soap, tag?tag:"ns1:grouping", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -34312,7 +34312,7 @@ SOAP_FMAC3 ns1__dataCollectionDatafile ** SOAP_FMAC4 soap_in_PointerTons1__dataC SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTons1__dataCollectionDatafile(struct soap *soap, ns1__dataCollectionDatafile *const*a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat4_PointerTons1__dataCollectionDatafile); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat4_PointerTons1__dataCollectionDatafile); if (soap_out_PointerTons1__dataCollectionDatafile(soap, tag?tag:"ns1:dataCollectionDatafile", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -34369,7 +34369,7 @@ SOAP_FMAC3 ns1__dataCollectionDataset ** SOAP_FMAC4 soap_in_PointerTons1__dataCo SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTons1__dataCollectionDataset(struct soap *soap, ns1__dataCollectionDataset *const*a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat4_PointerTons1__dataCollectionDataset); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat4_PointerTons1__dataCollectionDataset); if (soap_out_PointerTons1__dataCollectionDataset(soap, tag?tag:"ns1:dataCollectionDataset", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -34426,7 +34426,7 @@ SOAP_FMAC3 ns1__dataCollectionParameter ** SOAP_FMAC4 soap_in_PointerTons1__data SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTons1__dataCollectionParameter(struct soap *soap, ns1__dataCollectionParameter *const*a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat4_PointerTons1__dataCollectionParameter); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat4_PointerTons1__dataCollectionParameter); if (soap_out_PointerTons1__dataCollectionParameter(soap, tag?tag:"ns1:dataCollectionParameter", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -34483,7 +34483,7 @@ SOAP_FMAC3 ns1__dataCollection ** SOAP_FMAC4 soap_in_PointerTons1__dataCollectio SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTons1__dataCollection(struct soap *soap, ns1__dataCollection *const*a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat4_PointerTons1__dataCollection); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat4_PointerTons1__dataCollection); if (soap_out_PointerTons1__dataCollection(soap, tag?tag:"ns1:dataCollection", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -34540,7 +34540,7 @@ SOAP_FMAC3 ns1__job ** SOAP_FMAC4 soap_in_PointerTons1__job(struct soap *soap, c SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTons1__job(struct soap *soap, ns1__job *const*a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat4_PointerTons1__job); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat4_PointerTons1__job); if (soap_out_PointerTons1__job(soap, tag?tag:"ns1:job", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -34597,7 +34597,7 @@ SOAP_FMAC3 ns1__application ** SOAP_FMAC4 soap_in_PointerTons1__application(stru SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTons1__application(struct soap *soap, ns1__application *const*a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat4_PointerTons1__application); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat4_PointerTons1__application); if (soap_out_PointerTons1__application(soap, tag?tag:"ns1:application", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -34649,7 +34649,7 @@ SOAP_FMAC3 enum ns1__studyStatus ** SOAP_FMAC4 soap_in_PointerTons1__studyStatus SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTons1__studyStatus(struct soap *soap, enum ns1__studyStatus *const*a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat4_PointerTons1__studyStatus); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat4_PointerTons1__studyStatus); if (soap_out_PointerTons1__studyStatus(soap, tag?tag:"ns1:studyStatus", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -34706,7 +34706,7 @@ SOAP_FMAC3 ns1__studyInvestigation ** SOAP_FMAC4 soap_in_PointerTons1__studyInve SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTons1__studyInvestigation(struct soap *soap, ns1__studyInvestigation *const*a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat4_PointerTons1__studyInvestigation); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat4_PointerTons1__studyInvestigation); if (soap_out_PointerTons1__studyInvestigation(soap, tag?tag:"ns1:studyInvestigation", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -34763,7 +34763,7 @@ SOAP_FMAC3 ns1__study ** SOAP_FMAC4 soap_in_PointerTons1__study(struct soap *soa SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTons1__study(struct soap *soap, ns1__study *const*a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat4_PointerTons1__study); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat4_PointerTons1__study); if (soap_out_PointerTons1__study(soap, tag?tag:"ns1:study", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -34820,7 +34820,7 @@ SOAP_FMAC3 ns1__shift ** SOAP_FMAC4 soap_in_PointerTons1__shift(struct soap *soa SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTons1__shift(struct soap *soap, ns1__shift *const*a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat4_PointerTons1__shift); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat4_PointerTons1__shift); if (soap_out_PointerTons1__shift(soap, tag?tag:"ns1:shift", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -34877,7 +34877,7 @@ SOAP_FMAC3 ns1__sampleParameter ** SOAP_FMAC4 soap_in_PointerTons1__sampleParame SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTons1__sampleParameter(struct soap *soap, ns1__sampleParameter *const*a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat4_PointerTons1__sampleParameter); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat4_PointerTons1__sampleParameter); if (soap_out_PointerTons1__sampleParameter(soap, tag?tag:"ns1:sampleParameter", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -34934,7 +34934,7 @@ SOAP_FMAC3 ns1__sample ** SOAP_FMAC4 soap_in_PointerTons1__sample(struct soap *s SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTons1__sample(struct soap *soap, ns1__sample *const*a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat4_PointerTons1__sample); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat4_PointerTons1__sample); if (soap_out_PointerTons1__sample(soap, tag?tag:"ns1:sample", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -34991,7 +34991,7 @@ SOAP_FMAC3 ns1__relatedDatafile ** SOAP_FMAC4 soap_in_PointerTons1__relatedDataf SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTons1__relatedDatafile(struct soap *soap, ns1__relatedDatafile *const*a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat4_PointerTons1__relatedDatafile); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat4_PointerTons1__relatedDatafile); if (soap_out_PointerTons1__relatedDatafile(soap, tag?tag:"ns1:relatedDatafile", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -35048,7 +35048,7 @@ SOAP_FMAC3 ns1__publication ** SOAP_FMAC4 soap_in_PointerTons1__publication(stru SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTons1__publication(struct soap *soap, ns1__publication *const*a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat4_PointerTons1__publication); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat4_PointerTons1__publication); if (soap_out_PointerTons1__publication(soap, tag?tag:"ns1:publication", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -35105,7 +35105,7 @@ SOAP_FMAC3 ns1__parameterType ** SOAP_FMAC4 soap_in_PointerTons1__parameterType( SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTons1__parameterType(struct soap *soap, ns1__parameterType *const*a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat4_PointerTons1__parameterType); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat4_PointerTons1__parameterType); if (soap_out_PointerTons1__parameterType(soap, tag?tag:"ns1:parameterType", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -35162,7 +35162,7 @@ SOAP_FMAC3 ns1__keyword ** SOAP_FMAC4 soap_in_PointerTons1__keyword(struct soap SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTons1__keyword(struct soap *soap, ns1__keyword *const*a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat4_PointerTons1__keyword); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat4_PointerTons1__keyword); if (soap_out_PointerTons1__keyword(soap, tag?tag:"ns1:keyword", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -35219,7 +35219,7 @@ SOAP_FMAC3 ns1__investigationUser ** SOAP_FMAC4 soap_in_PointerTons1__investigat SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTons1__investigationUser(struct soap *soap, ns1__investigationUser *const*a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat4_PointerTons1__investigationUser); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat4_PointerTons1__investigationUser); if (soap_out_PointerTons1__investigationUser(soap, tag?tag:"ns1:investigationUser", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -35276,7 +35276,7 @@ SOAP_FMAC3 ns1__investigationType ** SOAP_FMAC4 soap_in_PointerTons1__investigat SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTons1__investigationType(struct soap *soap, ns1__investigationType *const*a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat4_PointerTons1__investigationType); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat4_PointerTons1__investigationType); if (soap_out_PointerTons1__investigationType(soap, tag?tag:"ns1:investigationType", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -35333,7 +35333,7 @@ SOAP_FMAC3 ns1__investigation ** SOAP_FMAC4 soap_in_PointerTons1__investigation( SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTons1__investigation(struct soap *soap, ns1__investigation *const*a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat4_PointerTons1__investigation); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat4_PointerTons1__investigation); if (soap_out_PointerTons1__investigation(soap, tag?tag:"ns1:investigation", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -35390,7 +35390,7 @@ SOAP_FMAC3 ns1__instrument ** SOAP_FMAC4 soap_in_PointerTons1__instrument(struct SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTons1__instrument(struct soap *soap, ns1__instrument *const*a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat4_PointerTons1__instrument); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat4_PointerTons1__instrument); if (soap_out_PointerTons1__instrument(soap, tag?tag:"ns1:instrument", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -35447,7 +35447,7 @@ SOAP_FMAC3 ns1__user ** SOAP_FMAC4 soap_in_PointerTons1__user(struct soap *soap, SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTons1__user(struct soap *soap, ns1__user *const*a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat4_PointerTons1__user); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat4_PointerTons1__user); if (soap_out_PointerTons1__user(soap, tag?tag:"ns1:user", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -35504,7 +35504,7 @@ SOAP_FMAC3 ns1__instrumentScientist ** SOAP_FMAC4 soap_in_PointerTons1__instrume SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTons1__instrumentScientist(struct soap *soap, ns1__instrumentScientist *const*a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat4_PointerTons1__instrumentScientist); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat4_PointerTons1__instrumentScientist); if (soap_out_PointerTons1__instrumentScientist(soap, tag?tag:"ns1:instrumentScientist", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -35561,7 +35561,7 @@ SOAP_FMAC3 ns1__facilityCycle ** SOAP_FMAC4 soap_in_PointerTons1__facilityCycle( SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTons1__facilityCycle(struct soap *soap, ns1__facilityCycle *const*a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat4_PointerTons1__facilityCycle); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat4_PointerTons1__facilityCycle); if (soap_out_PointerTons1__facilityCycle(soap, tag?tag:"ns1:facilityCycle", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -35618,7 +35618,7 @@ SOAP_FMAC3 ns1__facility ** SOAP_FMAC4 soap_in_PointerTons1__facility(struct soa SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTons1__facility(struct soap *soap, ns1__facility *const*a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat4_PointerTons1__facility); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat4_PointerTons1__facility); if (soap_out_PointerTons1__facility(soap, tag?tag:"ns1:facility", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -35675,7 +35675,7 @@ SOAP_FMAC3 ns1__datasetType ** SOAP_FMAC4 soap_in_PointerTons1__datasetType(stru SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTons1__datasetType(struct soap *soap, ns1__datasetType *const*a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat4_PointerTons1__datasetType); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat4_PointerTons1__datasetType); if (soap_out_PointerTons1__datasetType(soap, tag?tag:"ns1:datasetType", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -35732,7 +35732,7 @@ SOAP_FMAC3 ns1__datasetParameter ** SOAP_FMAC4 soap_in_PointerTons1__datasetPara SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTons1__datasetParameter(struct soap *soap, ns1__datasetParameter *const*a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat4_PointerTons1__datasetParameter); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat4_PointerTons1__datasetParameter); if (soap_out_PointerTons1__datasetParameter(soap, tag?tag:"ns1:datasetParameter", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -35789,7 +35789,7 @@ SOAP_FMAC3 ns1__dataset ** SOAP_FMAC4 soap_in_PointerTons1__dataset(struct soap SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTons1__dataset(struct soap *soap, ns1__dataset *const*a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat4_PointerTons1__dataset); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat4_PointerTons1__dataset); if (soap_out_PointerTons1__dataset(soap, tag?tag:"ns1:dataset", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -35846,7 +35846,7 @@ SOAP_FMAC3 ns1__datafileParameter ** SOAP_FMAC4 soap_in_PointerTons1__datafilePa SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTons1__datafileParameter(struct soap *soap, ns1__datafileParameter *const*a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat4_PointerTons1__datafileParameter); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat4_PointerTons1__datafileParameter); if (soap_out_PointerTons1__datafileParameter(soap, tag?tag:"ns1:datafileParameter", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -35903,7 +35903,7 @@ SOAP_FMAC3 ns1__datafileFormat ** SOAP_FMAC4 soap_in_PointerTons1__datafileForma SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTons1__datafileFormat(struct soap *soap, ns1__datafileFormat *const*a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat4_PointerTons1__datafileFormat); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat4_PointerTons1__datafileFormat); if (soap_out_PointerTons1__datafileFormat(soap, tag?tag:"ns1:datafileFormat", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -35960,7 +35960,7 @@ SOAP_FMAC3 ns1__datafile ** SOAP_FMAC4 soap_in_PointerTons1__datafile(struct soa SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTons1__datafile(struct soap *soap, ns1__datafile *const*a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat4_PointerTons1__datafile); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat4_PointerTons1__datafile); if (soap_out_PointerTons1__datafile(soap, tag?tag:"ns1:datafile", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -36006,7 +36006,7 @@ SOAP_FMAC3 std::vector<_ns1__login_credentials_entry >** SOAP_FMAC4 soap_in_Poin SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTostd__vectorTemplateOf_ns1__login_credentials_entry(struct soap *soap, std::vector<_ns1__login_credentials_entry >*const*a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat4_PointerTostd__vectorTemplateOf_ns1__login_credentials_entry); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat4_PointerTostd__vectorTemplateOf_ns1__login_credentials_entry); if (soap_out_PointerTostd__vectorTemplateOf_ns1__login_credentials_entry(soap, tag?tag:"", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -36058,7 +36058,7 @@ SOAP_FMAC3 LONG64 ** SOAP_FMAC4 soap_in_PointerToLONG64(struct soap *soap, const SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerToLONG64(struct soap *soap, LONG64 *const*a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat4_PointerToLONG64); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat4_PointerToLONG64); if (soap_out_PointerToLONG64(soap, tag?tag:"long", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -36110,7 +36110,7 @@ SOAP_FMAC3 time_t ** SOAP_FMAC4 soap_in_PointerTotime(struct soap *soap, const c SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTotime(struct soap *soap, time_t *const*a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat4_PointerTotime); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat4_PointerTotime); if (soap_out_PointerTotime(soap, tag?tag:"dateTime", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -36323,7 +36323,7 @@ SOAP_FMAC3 ns1__entityBaseBean ** SOAP_FMAC4 soap_in_PointerTons1__entityBaseBea SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTons1__entityBaseBean(struct soap *soap, ns1__entityBaseBean *const*a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat4_PointerTons1__entityBaseBean); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat4_PointerTons1__entityBaseBean); if (soap_out_PointerTons1__entityBaseBean(soap, tag?tag:"ns1:entityBaseBean", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -36375,7 +36375,7 @@ SOAP_FMAC3 enum ns1__icatExceptionType ** SOAP_FMAC4 soap_in_PointerTons1__icatE SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTons1__icatExceptionType(struct soap *soap, enum ns1__icatExceptionType *const*a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat4_PointerTons1__icatExceptionType); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat4_PointerTons1__icatExceptionType); if (soap_out_PointerTons1__icatExceptionType(soap, tag?tag:"ns1:icatExceptionType", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -36428,7 +36428,7 @@ SOAP_FMAC3 std::string ** SOAP_FMAC4 soap_in_PointerTostd__string(struct soap *s SOAP_FMAC3 int SOAP_FMAC4 soap_put_PointerTostd__string(struct soap *soap, std::string *const*a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat4_PointerTostd__string); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat4_PointerTostd__string); if (soap_out_PointerTostd__string(soap, tag?tag:"string", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -36462,7 +36462,7 @@ SOAP_FMAC3 char * * SOAP_FMAC4 soap_in__QName(struct soap *soap, const char *tag SOAP_FMAC3 int SOAP_FMAC4 soap_put__QName(struct soap *soap, char *const*a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat4__QName); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat4__QName); if (soap_out__QName(soap, tag?tag:"byte", id, a, type)) return soap->error; return soap_putindependent(soap); @@ -36506,7 +36506,7 @@ SOAP_FMAC3 char * * SOAP_FMAC4 soap_in_string(struct soap *soap, const char *tag SOAP_FMAC3 int SOAP_FMAC4 soap_put_string(struct soap *soap, char *const*a, const char *tag, const char *type) { - register int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat4_string); + int id = soap_embed(soap, (void*)a, NULL, 0, tag, SOAP_TYPE_ICat4_string); if (soap_out_string(soap, tag?tag:"byte", id, a, type)) return soap->error; return soap_putindependent(soap); diff --git a/Code/Mantid/Framework/Kernel/CMakeLists.txt b/Code/Mantid/Framework/Kernel/CMakeLists.txt index eb69cdb6b0b6..c76df1829da6 100644 --- a/Code/Mantid/Framework/Kernel/CMakeLists.txt +++ b/Code/Mantid/Framework/Kernel/CMakeLists.txt @@ -11,8 +11,8 @@ set ( SRC_FILES src/ConfigService.cpp src/DataItem.cpp src/DateAndTime.cpp - src/DateValidator.cpp src/DateTimeValidator.cpp + src/DateValidator.cpp src/DeltaEMode.cpp src/DirectoryValidator.cpp src/DiskBuffer.cpp @@ -65,6 +65,7 @@ set ( SRC_FILES src/PropertyManager.cpp src/PropertyManagerOwner.cpp src/PropertyWithValue.cpp + src/ProxyInfo.cpp src/PseudoRandomNumberGenerator.cpp src/Quat.cpp src/ReadLock.cpp @@ -129,8 +130,8 @@ set ( INC_FILES inc/MantidKernel/DataItem.h inc/MantidKernel/DataService.h inc/MantidKernel/DateAndTime.h - inc/MantidKernel/DateValidator.h inc/MantidKernel/DateTimeValidator.h + inc/MantidKernel/DateValidator.h inc/MantidKernel/DeltaEMode.h inc/MantidKernel/DirectoryValidator.h inc/MantidKernel/DiskBuffer.h @@ -185,6 +186,7 @@ set ( INC_FILES inc/MantidKernel/MultiThreaded.h inc/MantidKernel/NDPseudoRandomNumberGenerator.h inc/MantidKernel/NDRandomNumberGenerator.h + inc/MantidKernel/NetworkProxy.h inc/MantidKernel/NeutronAtom.h inc/MantidKernel/NexusDescriptor.h inc/MantidKernel/NullValidator.h @@ -197,6 +199,7 @@ set ( INC_FILES inc/MantidKernel/PropertyManager.h inc/MantidKernel/PropertyManagerOwner.h inc/MantidKernel/PropertyWithValue.h + inc/MantidKernel/ProxyInfo.h inc/MantidKernel/PseudoRandomNumberGenerator.h inc/MantidKernel/QuasiRandomNumberSequence.h inc/MantidKernel/Quat.h @@ -310,6 +313,7 @@ set ( TEST_FILES PropertyManagerTest.h PropertyTest.h PropertyWithValueTest.h + ProxyInfoTest.h QuatTest.h ReadLockTest.h RebinHistogramTest.h @@ -344,6 +348,16 @@ set ( TEST_FILES WriteLockTest.h ) +if ( ${CMAKE_SYSTEM_NAME} MATCHES "Darwin") + LIST( APPEND SRC_FILES src/NetworkProxyOSX.cpp ) + SET( NETWORK_LIBRARIES "-framework SystemConfiguration" "-framework CoreFoundation" "-framework CoreServices") +elseif (${CMAKE_SYSTEM_NAME} MATCHES "Windows") + LIST( APPEND SRC_FILES src/NetworkProxyWin.cpp ) + SET( NETWORK_LIBRARIES Winhttp ) +else() + LIST( APPEND SRC_FILES src/NetworkProxyLinux.cpp ) +endif() + if(UNITY_BUILD) include(UnityBuild) enable_unity_build(Kernel SRC_FILES SRC_UNITY_IGNORE_FILES 10) @@ -362,7 +376,7 @@ set_target_properties ( Kernel PROPERTIES OUTPUT_NAME MantidKernel # Add to the 'Framework' group in VS set_property ( TARGET Kernel PROPERTY FOLDER "MantidFramework" ) -target_link_libraries ( Kernel ${MANTIDLIBS} ${GSL_LIBRARIES} ${NEXUS_LIBRARIES} ) +target_link_libraries ( Kernel ${MANTIDLIBS} ${GSL_LIBRARIES} ${NEXUS_LIBRARIES} ${NETWORK_LIBRARIES} ) if ( WIN32 ) target_link_libraries ( Kernel Psapi.lib ) # For memory usage queries endif() diff --git a/Code/Mantid/Framework/Kernel/inc/MantidKernel/ConfigService.h b/Code/Mantid/Framework/Kernel/inc/MantidKernel/ConfigService.h index a03863097527..62f8ebbc6412 100644 --- a/Code/Mantid/Framework/Kernel/inc/MantidKernel/ConfigService.h +++ b/Code/Mantid/Framework/Kernel/inc/MantidKernel/ConfigService.h @@ -158,6 +158,8 @@ namespace Mantid std::string getCurrentDir() const; /// Returns the system's temp directory std::string getTempDir(); + /// Returns the system's appdata directory + std::string getAppDataDir(); //Return the executable path std::string getDirectoryOfExecutable() const; //Return the full path to the executable @@ -184,6 +186,8 @@ namespace Mantid /// Get the list of user search paths const std::vector& getUserSearchDirs() const; /// Get instrument search directory + const std::vector& getInstrumentDirectories() const; + /// Get instrument search directory const std::string getInstrumentDirectory() const; //@} @@ -249,13 +253,17 @@ namespace Mantid /// Create the storage of the data search directories void cacheDataSearchPaths(); /// Create the storage of the user search directories - void cacheUserSearchPaths(); + void cacheUserSearchPaths(); + /// Create the storage of the instrument directories + void cacheInstrumentPaths(); /// Returns true if the path is in the data search list bool isInDataSearchList(const std::string & path) const; /// Empty the list of facilities, deleting the FacilityInfo objects in the process void clearFacilities(); /// Set the PV_PLUGIN_PATH to point at this version of Mantid. void setParaViewPluginPath() const; + /// Verifies the directory exists and add it to the back of the directory list if valid + bool addDirectoryifExists(const std::string& directoryName, std::vector& directoryList); // Forward declaration of inner class template @@ -288,6 +296,8 @@ namespace Mantid std::vector m_DataSearchDirs; /// Store a list of user search paths std::vector m_UserSearchDirs; + /// Store a list of instrument directory paths + std::vector m_InstrumentDirs; /// A map of facilities to instruments std::map > m_instr_prefixes; @@ -298,7 +308,7 @@ namespace Mantid }; /// Forward declaration of a specialisation of SingletonHolder for AlgorithmFactoryImpl (needed for dllexport/dllimport) and a typedef for it. -#ifdef __APPLE__ +#if defined(__APPLE__) && defined(__INTEL_COMPILER) inline #endif template class MANTID_KERNEL_DLL Mantid::Kernel::SingletonHolder; diff --git a/Code/Mantid/Framework/Kernel/inc/MantidKernel/IPropertyManager.h b/Code/Mantid/Framework/Kernel/inc/MantidKernel/IPropertyManager.h index 6471493ec615..9b0fca9e6528 100644 --- a/Code/Mantid/Framework/Kernel/inc/MantidKernel/IPropertyManager.h +++ b/Code/Mantid/Framework/Kernel/inc/MantidKernel/IPropertyManager.h @@ -131,6 +131,9 @@ class MANTID_KERNEL_DLL IPropertyManager return this; } + /// Update values of the existing properties. + void updatePropertyValues( const IPropertyManager &other ); + /// Return the property manager serialized as a string. virtual std::string asString(bool withDefaultValues = false, char separator=',') const = 0; @@ -152,6 +155,9 @@ class MANTID_KERNEL_DLL IPropertyManager if (prop) prop->setGroup(group); } + /// Get the list of managed properties in a given group. + std::vector< Property*> getPropertiesInGroup(const std::string& group) const; + virtual void filterByTime(const DateAndTime &/*start*/, const DateAndTime &/*stop*/) = 0; virtual void splitByTime(std::vector& /*splitter*/, std::vector< PropertyManager * >/* outputs*/) const = 0; virtual void filterByProperty(const TimeSeriesProperty & /*filte*/) =0; diff --git a/Code/Mantid/Framework/Kernel/inc/MantidKernel/LibraryManager.h b/Code/Mantid/Framework/Kernel/inc/MantidKernel/LibraryManager.h index 5c15752e795c..3c211ca6150a 100644 --- a/Code/Mantid/Framework/Kernel/inc/MantidKernel/LibraryManager.h +++ b/Code/Mantid/Framework/Kernel/inc/MantidKernel/LibraryManager.h @@ -71,7 +71,7 @@ namespace Mantid }; ///Forward declaration of a specialisation of SingletonHolder for LibraryManagerImpl (needed for dllexport/dllimport) and a typedef for it. -#ifdef __APPLE__ +#if defined(__APPLE__) && defined(__INTEL_COMPILER) inline #endif template class MANTID_KERNEL_DLL Mantid::Kernel::SingletonHolder; diff --git a/Code/Mantid/Framework/Kernel/inc/MantidKernel/MultiThreaded.h b/Code/Mantid/Framework/Kernel/inc/MantidKernel/MultiThreaded.h index 4acfe47da395..422352698487 100644 --- a/Code/Mantid/Framework/Kernel/inc/MantidKernel/MultiThreaded.h +++ b/Code/Mantid/Framework/Kernel/inc/MantidKernel/MultiThreaded.h @@ -25,6 +25,42 @@ namespace Kernel #define PRAGMA(x) _Pragma(#x) #endif //_MSC_VER + +/** Begins a block to skip processing is the algorithm has been interupted + * Note the end of the block if not defined that must be added by including + * PARALLEL_END_INTERUPT_REGION at the end of the loop + */ +#define PARALLEL_START_INTERUPT_REGION \ + if (!m_parallelException && !m_cancel) { \ + try { + +/** Ends a block to skip processing is the algorithm has been interupted + * Note the start of the block if not defined that must be added by including + * PARALLEL_START_INTERUPT_REGION at the start of the loop + */ +#define PARALLEL_END_INTERUPT_REGION \ + } /* End of try block in PARALLEL_START_INTERUPT_REGION */ \ + catch(std::exception &ex) { \ + if (!m_parallelException) \ + { \ + m_parallelException = true; \ + g_log.error() << this->name() << ": " << ex.what() << "\n"; \ + } \ + } \ + catch(...) { m_parallelException = true; } \ + } // End of if block in PARALLEL_START_INTERUPT_REGION + +/** Adds a check after a Parallel region to see if it was interupted + */ +#define PARALLEL_CHECK_INTERUPT_REGION \ + if (m_parallelException) \ + { \ + g_log.debug("Exception thrown in parallel region"); \ + throw std::runtime_error(this->name()+": error (see log)"); \ + } \ + interruption_point(); + + // _OPENMP is automatically defined if openMP support is enabled in the compiler. #ifdef _OPENMP @@ -92,40 +128,6 @@ namespace Kernel #define IF_NOT_PARALLEL \ if (omp_get_num_threads() == 1) -/** Begins a block to skip processing is the algorithm has been interupted -* Note the end of the block if not defined that must be added by including -* PARALLEL_END_INTERUPT_REGION at the end of the loop -*/ -#define PARALLEL_START_INTERUPT_REGION \ - if (!m_parallelException && !m_cancel) { \ - try { - -/** Ends a block to skip processing is the algorithm has been interupted -* Note the start of the block if not defined that must be added by including -* PARALLEL_START_INTERUPT_REGION at the start of the loop -*/ -#define PARALLEL_END_INTERUPT_REGION \ - } /* End of try block in PARALLEL_START_INTERUPT_REGION */ \ - catch(std::exception &ex) { \ - if (!m_parallelException) \ - { \ - m_parallelException = true; \ - g_log.error() << this->name() << ": " << ex.what() << "\n"; \ - } \ - } \ - catch(...) { m_parallelException = true; } \ - } // End of if block in PARALLEL_START_INTERUPT_REGION - -/** Adds a check after a Parallel region to see if it was interupted -*/ -#define PARALLEL_CHECK_INTERUPT_REGION \ - if (m_parallelException) \ - { \ - g_log.debug("Exception thrown in parallel region"); \ - throw std::runtime_error(this->name()+": error (see log)"); \ - } \ - interruption_point(); - /** Specifies that the next code line or block will only allow one thread through at a time */ #define PARALLEL_CRITICAL(name) \ @@ -178,9 +180,6 @@ namespace Kernel #define PARALLEL_FOR3(workspace1, workspace2, workspace3) #define IF_PARALLEL if (false) #define IF_NOT_PARALLEL -#define PARALLEL_START_INTERUPT_REGION -#define PARALLEL_END_INTERUPT_REGION -#define PARALLEL_CHECK_INTERUPT_REGION #define PARALLEL_CRITICAL(name) #define PARALLEL_ATOMIC #define PARALLEL_THREAD_NUMBER 0 diff --git a/Code/Mantid/Framework/Kernel/inc/MantidKernel/NetworkProxy.h b/Code/Mantid/Framework/Kernel/inc/MantidKernel/NetworkProxy.h new file mode 100644 index 000000000000..299d80b4037c --- /dev/null +++ b/Code/Mantid/Framework/Kernel/inc/MantidKernel/NetworkProxy.h @@ -0,0 +1,59 @@ +#ifndef MANTID_KERNEL_NETWORKPROXY_H_ +#define MANTID_KERNEL_NETWORKPROXY_H_ + +#include "MantidKernel/System.h" +#include "MantidKernel/ProxyInfo.h" +#include "MantidKernel/Logger.h" + + +namespace Mantid +{ +namespace Kernel +{ + + /** NetworkProxy : Network proxy utility for getting network proxy information. + + Copyright © 2014 ISIS Rutherford Appleton Laboratory & NScD Oak Ridge National Laboratory + + This file is part of Mantid. + + Mantid is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + Mantid is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + + File change history is stored at: + Code Documentation is available at: + */ + class DLLExport NetworkProxy + { + public: + /// Constructor + NetworkProxy(); + + /// Get http proxy information. + ProxyInfo getHttpProxy(const std::string& targetURLString); + + /// Destructor + virtual ~NetworkProxy(); + + private: + + /// Logger object + Mantid::Kernel::Logger m_logger; + + }; + + +} // namespace Kernel +} // namespace Mantid + +#endif /* MANTID_KERNEL_NETWORKPROXY_H_ */ diff --git a/Code/Mantid/Framework/Kernel/inc/MantidKernel/PhysicalConstants.h b/Code/Mantid/Framework/Kernel/inc/MantidKernel/PhysicalConstants.h index c4c59f7bad30..fa19d947a330 100644 --- a/Code/Mantid/Framework/Kernel/inc/MantidKernel/PhysicalConstants.h +++ b/Code/Mantid/Framework/Kernel/inc/MantidKernel/PhysicalConstants.h @@ -16,7 +16,7 @@ namespace Mantid @author Russell Taylor, Tessella Support Services plc @date 30/10/2007 - + Copyright © 2007-2010 ISIS Rutherford Appleton Laboratory & NScD Oak Ridge National Laboratory This file is part of Mantid. @@ -34,7 +34,7 @@ namespace Mantid You should have received a copy of the GNU General Public License along with this program. If not, see . - File change history is stored at: . + File change history is stored at: . Code Documentation is available at: */ namespace PhysicalConstants @@ -52,16 +52,19 @@ namespace PhysicalConstants /** Standard acceleration due to gravity. Precise value in ms-2. */ static const double g = 9.80665; - + /** Mass of the neutron in kg. Taken from on 30/10/2007. */ static const double NeutronMass = 1.674927211e-27; /** Mass of the neutron in AMU. Taken from on 02/01/2013. */ static const double NeutronMassAMU = 1.008664916; + /** AMU in kg. Taken from on 10/09/2014. */ + static const double AtomicMassUnit = 1.660538921e-27; + /** 1 meV in Joules. Taken from on 28/03/2008. */ static const double meV = 1.602176487e-22; - + /** 1 meV in wavenumber (cm-1). Taken from on 02/04/2008. */ static const double meVtoWavenumber = 8.06554465; @@ -74,10 +77,10 @@ namespace PhysicalConstants /** Muon lifetime. Taken from MuLan experiment on 08/12/2008. */ static const double MuonLifetime = 2.197019e-6; - /** Standard atmospheric pressure in kPa. + /** Standard atmospheric pressure in kPa. * Taken from on 01/12/2010 **/ static const double StandardAtmosphere = 101.325; - + /** Boltzmann Constant in meV/K * Taken from on 10/07/2012 */ diff --git a/Code/Mantid/Framework/Kernel/inc/MantidKernel/Property.h b/Code/Mantid/Framework/Kernel/inc/MantidKernel/Property.h index f12efa4e6013..c173c6952ed9 100644 --- a/Code/Mantid/Framework/Kernel/inc/MantidKernel/Property.h +++ b/Code/Mantid/Framework/Kernel/inc/MantidKernel/Property.h @@ -217,8 +217,13 @@ class MANTID_KERNEL_DLL Property bool m_remember; }; - /// Return the name corresponding to the mangled string given by typeid - MANTID_KERNEL_DLL std::string getUnmangledTypeName(const std::type_info& type); +/// Compares this to another property for equality +MANTID_KERNEL_DLL bool operator==( const Mantid::Kernel::Property & lhs, const Mantid::Kernel::Property & rhs ); +/// Compares this to another property for inequality +MANTID_KERNEL_DLL bool operator!=( const Mantid::Kernel::Property & lhs, const Mantid::Kernel::Property & rhs ); + +/// Return the name corresponding to the mangled string given by typeid +MANTID_KERNEL_DLL std::string getUnmangledTypeName(const std::type_info& type); } // namespace Kernel } // namespace Mantid diff --git a/Code/Mantid/Framework/Kernel/inc/MantidKernel/PropertyWithValue.h b/Code/Mantid/Framework/Kernel/inc/MantidKernel/PropertyWithValue.h index 35ad67d7241e..6a7eca0b2148 100644 --- a/Code/Mantid/Framework/Kernel/inc/MantidKernel/PropertyWithValue.h +++ b/Code/Mantid/Framework/Kernel/inc/MantidKernel/PropertyWithValue.h @@ -219,7 +219,7 @@ void toValue(const std::string& strvalue, std::vector >& value, c PROPERTYWITHVALUE_TOVALUE(long); PROPERTYWITHVALUE_TOVALUE(uint32_t); PROPERTYWITHVALUE_TOVALUE(uint64_t); - #ifdef __INTEL_COMPILER + #if defined(__INTEL_COMPILER) || defined(__clang__) PROPERTYWITHVALUE_TOVALUE(unsigned long); #endif @@ -331,6 +331,28 @@ class DLLExport PropertyWithValue : public Property return toString(m_value); } + /** + * Deep comparison. + * @param rhs The other property to compare to. + * @return true if the are equal. + */ + virtual bool operator==(const PropertyWithValue & rhs) const + { + if (this->name() != rhs.name()) + return false; + return (m_value == rhs.m_value); + } + + /** + * Deep comparison (not equal). + * @param rhs The other property to compare to. + * @return true if the are not equal. + */ + virtual bool operator!=(const PropertyWithValue & rhs) const + { + return !(*this == rhs); + } + /** Get the size of the property. */ virtual int size() const diff --git a/Code/Mantid/Framework/Kernel/inc/MantidKernel/ProxyInfo.h b/Code/Mantid/Framework/Kernel/inc/MantidKernel/ProxyInfo.h new file mode 100644 index 000000000000..014f95d16c99 --- /dev/null +++ b/Code/Mantid/Framework/Kernel/inc/MantidKernel/ProxyInfo.h @@ -0,0 +1,58 @@ +#ifndef MANTID_KERNEL_PROXYINFO_H_ +#define MANTID_KERNEL_PROXYINFO_H_ + +#include "MantidKernel/System.h" +#include + +namespace Mantid +{ + namespace Kernel + { + + /** ProxyInfo : Container for carrying around network proxy information + + Copyright © 2014 ISIS Rutherford Appleton Laboratory & NScD Oak Ridge National Laboratory + + This file is part of Mantid. + + Mantid is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + Mantid is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + + File change history is stored at: + Code Documentation is available at: + */ + class DLLExport ProxyInfo + { + private: + std::string m_host; + int m_port; + bool m_isHttpProxy; + bool m_isEmptyProxy; + + public: + virtual ~ProxyInfo(); + ProxyInfo(); + ProxyInfo(const ProxyInfo& other); + ProxyInfo& operator=(const ProxyInfo& other); + ProxyInfo(const std::string& host, const int port, const bool isHttpProxy); + std::string host() const; + int port() const; + bool isHttpProxy() const; + bool emptyProxy() const; + + }; + + } // namespace Kernel +} // namespace Mantid + +#endif /* MANTID_KERNEL_PROXYINFO_H_ */ diff --git a/Code/Mantid/Framework/Kernel/inc/MantidKernel/ThreadSafeLogStream.h b/Code/Mantid/Framework/Kernel/inc/MantidKernel/ThreadSafeLogStream.h index b3af77fff585..efdb8635265e 100644 --- a/Code/Mantid/Framework/Kernel/inc/MantidKernel/ThreadSafeLogStream.h +++ b/Code/Mantid/Framework/Kernel/inc/MantidKernel/ThreadSafeLogStream.h @@ -19,6 +19,7 @@ #include #include +#include namespace Mantid { @@ -73,6 +74,8 @@ class MANTID_KERNEL_DLL ThreadSafeLogStreamBuf: public Poco::LogStreamBuf private: /// Store a map of thread indices to messages std::map m_messages; + /// mutex protecting logstream + Poco::FastMutex m_mutex; }; diff --git a/Code/Mantid/Framework/Kernel/inc/MantidKernel/TimeSeriesProperty.h b/Code/Mantid/Framework/Kernel/inc/MantidKernel/TimeSeriesProperty.h index 3c319b653981..4edcdb703847 100644 --- a/Code/Mantid/Framework/Kernel/inc/MantidKernel/TimeSeriesProperty.h +++ b/Code/Mantid/Framework/Kernel/inc/MantidKernel/TimeSeriesProperty.h @@ -158,6 +158,10 @@ namespace Mantid virtual bool operator==( const TimeSeriesProperty & right ) const; ///Deep comparison (not equal). virtual bool operator!=(const TimeSeriesProperty & right ) const; + /// Deep comparison + virtual bool operator==( const Property & right ) const; + ///Deep comparison (not equal). + virtual bool operator!=(const Property & right ) const; /// Set name of property void setName(const std::string name); diff --git a/Code/Mantid/Framework/Kernel/inc/MantidKernel/TypedValidator.h b/Code/Mantid/Framework/Kernel/inc/MantidKernel/TypedValidator.h index 9ce4bff5dd01..8e51b7141e1a 100644 --- a/Code/Mantid/Framework/Kernel/inc/MantidKernel/TypedValidator.h +++ b/Code/Mantid/Framework/Kernel/inc/MantidKernel/TypedValidator.h @@ -113,7 +113,13 @@ namespace Mantid */ ElementType_sptr extractValue(const boost::any & value) const { +// Despite the name and hash code being identical, operator== is returning false in Release mode +// with clang and libc++. The simplest workaround is to compare hash codes. +#ifdef __clang__ + if( value.type().hash_code() == m_dataitemTypeID.hash_code() ) +#else if( value.type() == m_dataitemTypeID ) +#endif { return extractFromDataItem(value); } diff --git a/Code/Mantid/Framework/Kernel/inc/MantidKernel/Utils.h b/Code/Mantid/Framework/Kernel/inc/MantidKernel/Utils.h index a70e64e610f5..5d31b211d6b4 100644 --- a/Code/Mantid/Framework/Kernel/inc/MantidKernel/Utils.h +++ b/Code/Mantid/Framework/Kernel/inc/MantidKernel/Utils.h @@ -50,6 +50,34 @@ namespace Utils return (r > 0.0) ? std::floor(r + 0.5) : std::ceil(r - 0.5); } + //------------------------------------------------------------------------------------------------ + /** Custom rounding method for a double->double because none is + * portable in C++ (!) + * + * @param r :: floating point value to round + * @param f :: number of significant figures to preserve + * @return r rounded to f significant figures + */ + inline double roundToSF(double r, int f) + { + double factor = pow(10.0, f - ceil(log10(fabs(r)))); + return rounddbl(r * factor) / factor; + } + + //------------------------------------------------------------------------------------------------ + /** Custom rounding method for a double->double because none is + * portable in C++ (!) + * + * @param r :: floating point value to round + * @param d :: number of digits after decimal point to preserve + * @return r rounded to d decimal places + */ + inline double roundToDP(double r, int d) + { + double m = pow(10.0, d); + return (int)r + (1.0/m) * rounddbl((r - (int)r) * m); + } + namespace NestedForLoop { diff --git a/Code/Mantid/Framework/Kernel/src/ANN/ANN.cpp b/Code/Mantid/Framework/Kernel/src/ANN/ANN.cpp index 3cedb6f6a6f0..0a3f2b5dd37b 100644 --- a/Code/Mantid/Framework/Kernel/src/ANN/ANN.cpp +++ b/Code/Mantid/Framework/Kernel/src/ANN/ANN.cpp @@ -48,9 +48,9 @@ ANNdist annDist( // interpoint squared distance ANNpoint p, ANNpoint q) { - register int d; - register ANNcoord diff; - register ANNcoord dist; + int d; + ANNcoord diff; + ANNcoord dist; dist = 0; for (d = 0; d < dim; d++) { diff --git a/Code/Mantid/Framework/Kernel/src/ANN/kd_fix_rad_search.cpp b/Code/Mantid/Framework/Kernel/src/ANN/kd_fix_rad_search.cpp index 87eb757d7b15..6098bb427d76 100644 --- a/Code/Mantid/Framework/Kernel/src/ANN/kd_fix_rad_search.cpp +++ b/Code/Mantid/Framework/Kernel/src/ANN/kd_fix_rad_search.cpp @@ -147,11 +147,11 @@ void ANNkd_split::ann_FR_search(ANNdist box_dist) void ANNkd_leaf::ann_FR_search(ANNdist box_dist) { - register ANNdist dist; // distance to data point - register ANNcoord* pp; // data coordinate pointer - register ANNcoord* qq; // query coordinate pointer - register ANNcoord t; - register int d; + ANNdist dist; // distance to data point + ANNcoord* pp; // data coordinate pointer + ANNcoord* qq; // query coordinate pointer + ANNcoord t; + int d; for (int i = 0; i < n_pts; i++) { // check points in bucket diff --git a/Code/Mantid/Framework/Kernel/src/ANN/kd_pr_search.cpp b/Code/Mantid/Framework/Kernel/src/ANN/kd_pr_search.cpp index be1ca1d450c4..6a45a37dc373 100644 --- a/Code/Mantid/Framework/Kernel/src/ANN/kd_pr_search.cpp +++ b/Code/Mantid/Framework/Kernel/src/ANN/kd_pr_search.cpp @@ -188,12 +188,12 @@ void ANNkd_split::ann_pri_search(ANNdist box_dist) void ANNkd_leaf::ann_pri_search(ANNdist box_dist) { - register ANNdist dist; // distance to data point - register ANNcoord* pp; // data coordinate pointer - register ANNcoord* qq; // query coordinate pointer - register ANNdist min_dist; // distance to k-th closest point - register ANNcoord t; - register int d; + ANNdist dist; // distance to data point + ANNcoord* pp; // data coordinate pointer + ANNcoord* qq; // query coordinate pointer + ANNdist min_dist; // distance to k-th closest point + ANNcoord t; + int d; min_dist = ANNprPointMK->max_key(); // k-th smallest distance so far diff --git a/Code/Mantid/Framework/Kernel/src/ANN/kd_search.cpp b/Code/Mantid/Framework/Kernel/src/ANN/kd_search.cpp index 5004ef798c16..1641f33bec02 100644 --- a/Code/Mantid/Framework/Kernel/src/ANN/kd_search.cpp +++ b/Code/Mantid/Framework/Kernel/src/ANN/kd_search.cpp @@ -171,12 +171,12 @@ void ANNkd_split::ann_search(ANNdist box_dist) void ANNkd_leaf::ann_search(ANNdist box_dist) { - register ANNdist dist; // distance to data point - register ANNcoord* pp; // data coordinate pointer - register ANNcoord* qq; // query coordinate pointer - register ANNdist min_dist; // distance to k-th closest point - register ANNcoord t; - register int d; + ANNdist dist; // distance to data point + ANNcoord* pp; // data coordinate pointer + ANNcoord* qq; // query coordinate pointer + ANNdist min_dist; // distance to k-th closest point + ANNcoord t; + int d; min_dist = ANNkdPointMK->max_key(); // k-th smallest distance so far diff --git a/Code/Mantid/Framework/Kernel/src/ANN/kd_util.cpp b/Code/Mantid/Framework/Kernel/src/ANN/kd_util.cpp index b96ea3659860..791d023df7c3 100644 --- a/Code/Mantid/Framework/Kernel/src/ANN/kd_util.cpp +++ b/Code/Mantid/Framework/Kernel/src/ANN/kd_util.cpp @@ -127,10 +127,10 @@ ANNdist annBoxDistance( // compute distance from point to box const ANNpoint hi, // high point of box int dim) // dimension of space { - register ANNdist dist = 0.0; // sum of squared distances - register ANNdist t; + ANNdist dist = 0.0; // sum of squared distances + ANNdist t; - for (register int d = 0; d < dim; d++) { + for ( int d = 0; d < dim; d++) { if (q[d] < lo[d]) { // q is left of box t = ANNdist(lo[d]) - ANNdist(q[d]); dist = ANN_SUM(dist, ANN_POW(t)); @@ -238,8 +238,8 @@ void annMedianSplit( int l = 0; // left end of current subarray int r = n-1; // right end of current subarray while (l < r) { - register int i = (r+l)/2; // select middle as pivot - register int k; + int i = (r+l)/2; // select middle as pivot + int k; if (PA(i,d) > PA(r,d)) // make sure last > pivot PASWAP(i,r) diff --git a/Code/Mantid/Framework/Kernel/src/ANN/pr_queue.h b/Code/Mantid/Framework/Kernel/src/ANN/pr_queue.h index 1e2b75898476..952cd98014f9 100644 --- a/Code/Mantid/Framework/Kernel/src/ANN/pr_queue.h +++ b/Code/Mantid/Framework/Kernel/src/ANN/pr_queue.h @@ -86,9 +86,9 @@ class ANNpr_queue { PQinfo inf) // item info { if (++n > max_size) annError("Priority queue overflow.", ANNabort); - register int r = n; + int r = n; while (r > 1) { // sift up new item - register int p = r/2; + int p = r/2; ANN_FLOP(1) // increment floating ops if (pq[p].key <= kv) // in proper order break; @@ -105,9 +105,9 @@ class ANNpr_queue { { kv = pq[1].key; // key of min item inf = pq[1].info; // information of min item - register PQkey kn = pq[n--].key;// last item in queue - register int p = 1; // p points to item out of position - register int r = p<<1; // left child of p + PQkey kn = pq[n--].key;// last item in queue + int p = 1; // p points to item out of position + int r = p<<1; // left child of p while (r <= n) { // while r is still within the heap ANN_FLOP(2) // increment floating ops // set r to smaller child of p diff --git a/Code/Mantid/Framework/Kernel/src/ANN/pr_queue_k.h b/Code/Mantid/Framework/Kernel/src/ANN/pr_queue_k.h index b1991a05b2a3..f3b55efd36a7 100644 --- a/Code/Mantid/Framework/Kernel/src/ANN/pr_queue_k.h +++ b/Code/Mantid/Framework/Kernel/src/ANN/pr_queue_k.h @@ -100,7 +100,7 @@ class ANNmin_k { PQKkey kv, // key value PQKinfo inf) // item info { - register int i; + int i; // slide larger values up for (i = n; i > 0; i--) { if (mk[i-1].key > kv) diff --git a/Code/Mantid/Framework/Kernel/src/ConfigService.cpp b/Code/Mantid/Framework/Kernel/src/ConfigService.cpp index a8c19760fe57..1cc770bb01f5 100644 --- a/Code/Mantid/Framework/Kernel/src/ConfigService.cpp +++ b/Code/Mantid/Framework/Kernel/src/ConfigService.cpp @@ -1,6 +1,7 @@ //---------------------------------------------------------------------- // Includes //---------------------------------------------------------------------- + #include "MantidKernel/ConfigService.h" #include "MantidKernel/MantidVersion.h" #include "MantidKernel/ParaViewVersion.h" @@ -32,6 +33,7 @@ #include #include + #include #include #include @@ -46,6 +48,7 @@ #include #endif + namespace Mantid { /** @@ -179,7 +182,7 @@ ConfigServiceImpl::ConfigServiceImpl() : #else m_user_properties_file_name("Mantid.user.properties"), #endif - m_DataSearchDirs(), m_UserSearchDirs(), m_instr_prefixes(), m_removedFlag("@@REMOVED@@") + m_DataSearchDirs(), m_UserSearchDirs(), m_InstrumentDirs(), m_instr_prefixes(), m_removedFlag("@@REMOVED@@") { //getting at system details m_pSysConfig = new WrappedObject ; @@ -215,13 +218,20 @@ ConfigServiceImpl::ConfigServiceImpl() : } } + //Assert that the appdata and the instrument subdirectory exists + std::string appDataDir = getAppDataDir(); + Poco::Path path(appDataDir); + path.pushDirectory("instrument"); + Poco::File file(path); + //createdirectories will fail gracefully if it is already present + file.createDirectories(); + //Fill the list of possible relative path keys that may require conversion to absolute paths m_ConfigPaths.insert(std::make_pair("mantidqt.python_interfaces_directory", true)); m_ConfigPaths.insert(std::make_pair("plugins.directory", true)); m_ConfigPaths.insert(std::make_pair("pvplugins.directory", true)); m_ConfigPaths.insert(std::make_pair("mantidqt.plugins.directory", true)); m_ConfigPaths.insert(std::make_pair("instrumentDefinition.directory", true)); - m_ConfigPaths.insert(std::make_pair("parameterDefinition.directory", true)); m_ConfigPaths.insert(std::make_pair("groupingFiles.directory", true)); m_ConfigPaths.insert(std::make_pair("maskFiles.directory", true)); m_ConfigPaths.insert(std::make_pair("colormaps.directory", true)); @@ -718,6 +728,8 @@ void ConfigServiceImpl::createUserPropertiesFile() const filestr << std::endl; filestr << "## Show invisible workspaces" << std::endl; filestr << "#MantidOptions.InvisibleWorkspaces=0" << std::endl; + filestr << "## Re-use plot instances for different plot types" << std::endl; + filestr << "#MantidOptions.ReusePlotInstances=Off" << std::endl; filestr << std::endl; filestr << "## Uncomment to disable use of OpenGL to render unwrapped instrument views" << std::endl; filestr << "#MantidOptions.InstrumentView.UseOpenGL=Off" << std::endl; @@ -820,6 +832,7 @@ void ConfigServiceImpl::updateConfig(const std::string& filename, const bool app cacheDataSearchPaths(); appendDataSearchDir(getString("defaultsave.directory")); cacheUserSearchPaths(); + cacheInstrumentPaths(); } } @@ -1128,6 +1141,10 @@ void ConfigServiceImpl::setString(const std::string & key, const std::string & v else if (key == "usersearch.directories") { cacheUserSearchPaths(); + } + else if (key == "instrumentDefinition.directory") + { + cacheInstrumentPaths(); } else if (key == "defaultsave.directory") { @@ -1251,6 +1268,28 @@ std::string ConfigServiceImpl::getTempDir() return m_pSysConfig->getString("system.tempDir"); } +/** Gets the absolute path of the appdata directory +* +* @returns The absolute path of the appdata directory +*/ +std::string ConfigServiceImpl::getAppDataDir() +{ + const std::string applicationName = "mantid"; +#if POCO_OS == POCO_OS_WINDOWS_NT + const std::string vendorName = "mantidproject"; + std::string appdata = std::getenv("APPDATA"); + Poco::Path path(appdata); + path.makeDirectory(); + path.pushDirectory(vendorName); + path.pushDirectory(applicationName); + return path.toString(); +#else //linux and mac + Poco::Path path(Poco::Path::home()); + path.pushDirectory("." + applicationName); + return path.toString(); +#endif +} + /** * Get the directory containing the program executable * @returns A string containing the path of the directory @@ -1501,26 +1540,84 @@ const std::vector& ConfigServiceImpl::getUserSearchDirs() const } /** - * Return the search directory for XML instrument definition files (IDFs) - * @returns Full path of instrument search directory + * Return the search directories for XML instrument definition files (IDFs) + * @returns An ordered list of paths for instrument searching + */ +const std::vector& ConfigServiceImpl::getInstrumentDirectories() const +{ + return m_InstrumentDirs; +} + +/** + * Return the base search directories for XML instrument definition files (IDFs) + * @returns a last entry of getInstrumentDirectories */ const std::string ConfigServiceImpl::getInstrumentDirectory() const { - // Determine the search directory for XML instrument definition files (IDFs) - std::string directoryName = getString("instrumentDefinition.directory"); - if (directoryName.empty()) - { - // This is the assumed deployment directory for IDFs, where we need to be relative to the - // directory of the executable, not the current working directory. - directoryName = Poco::Path(getPropertiesDir()).resolve("../instrument").toString(); - } + return m_InstrumentDirs[m_InstrumentDirs.size()-1]; +} + +/** + * Fills the internal cache of instrument definition directories + */ +void ConfigServiceImpl::cacheInstrumentPaths() +{ + m_InstrumentDirs.clear(); + Poco::Path path(getAppDataDir()); + path.makeDirectory(); + path.pushDirectory("instrument"); + std::string appdatadir = path.toString(); + addDirectoryifExists(appdatadir,m_InstrumentDirs); + +#ifndef _WIN32 + std::string etcdatadir = "/etc/mantid/instrument"; + addDirectoryifExists(etcdatadir,m_InstrumentDirs); +#endif + + // Determine the search directory for XML instrument definition files (IDFs) + std::string directoryName = getString("instrumentDefinition.directory"); + if (directoryName.empty()) + { + // This is the assumed deployment directory for IDFs, where we need to be relative to the + // directory of the executable, not the current working directory. + directoryName = Poco::Path(getPropertiesDir()).resolve("../instrument").toString(); + } + addDirectoryifExists(directoryName,m_InstrumentDirs); +} + - if (!Poco::File(directoryName).isDirectory()) + +/** + * Verifies the directory exists and add it to the back of the directory list if valid + * @param directoryName the directory name to add + * @param directoryList the list to add the directory to + * @returns true if the directory was valid and added to the list + */ +bool ConfigServiceImpl::addDirectoryifExists(const std::string& directoryName, std::vector& directoryList) +{ + try { - g_log.error("Unable to locate instrument search directory at: " + directoryName); + if (Poco::File(directoryName).isDirectory()) + { + directoryList.push_back(directoryName); + return true; + } + else + { + g_log.information("Unable to locate directory at: " + directoryName); + return false; + } } - - return directoryName; + catch (Poco::PathNotFoundException&) + { + g_log.information("Unable to locate directory at: " + directoryName); + return false; + } + catch (Poco::FileNotFoundException&) + { + g_log.information("Unable to locate directory at: " + directoryName); + return false; + } } /** diff --git a/Code/Mantid/Framework/Kernel/src/DirectoryValidator.cpp b/Code/Mantid/Framework/Kernel/src/DirectoryValidator.cpp index d0c2daa5b4c0..1592a9c581eb 100644 --- a/Code/Mantid/Framework/Kernel/src/DirectoryValidator.cpp +++ b/Code/Mantid/Framework/Kernel/src/DirectoryValidator.cpp @@ -1,5 +1,6 @@ #include "MantidKernel/DirectoryValidator.h" #include +#include #include #include #include @@ -51,10 +52,17 @@ std::string DirectoryValidator::checkValidity(const std::string& value) const //If the path is required to exist check it is there if ( m_testExist ) { - if ( value.empty() || !Poco::File(value).exists() ) - return "Directory \"" + value + "\" not found"; - if (!Poco::File(value).isDirectory()) - return "Directory \"" + value + "\" specified is actually a file"; + try + { + if ( value.empty() || !Poco::File(value).exists() ) + return "Directory \"" + value + "\" not found"; + if (!Poco::File(value).isDirectory()) + return "Directory \"" + value + "\" specified is actually a file"; + } + catch ( Poco::FileException & ) + { + return "Error accessing directory \"" + value + "\""; + } } //Otherwise we are okay, file extensions are just a suggestion so no validation on them is necessary diff --git a/Code/Mantid/Framework/Kernel/src/IPropertyManager.cpp b/Code/Mantid/Framework/Kernel/src/IPropertyManager.cpp index f70189255f26..bebb3b70edbb 100644 --- a/Code/Mantid/Framework/Kernel/src/IPropertyManager.cpp +++ b/Code/Mantid/Framework/Kernel/src/IPropertyManager.cpp @@ -29,7 +29,6 @@ namespace Mantid { namespace Kernel { - // This template implementation has been left in because although you can't assign to an existing string // via the getProperty() method, you can construct a local variable by saying, // e.g.: std::string s = getProperty("myProperty") @@ -68,6 +67,45 @@ namespace Mantid return false; } + /** + * Set values of the properties existing in this manager to the values of + * properties with the same name in another manger. + * @param other A property manager to copy property values from. + */ + void IPropertyManager::updatePropertyValues( const IPropertyManager &other ) + { + auto props = this->getProperties(); + for (auto prop = props.begin(); prop != props.end(); ++prop) + { + const std::string propName = (**prop).name(); + if ( other.existsProperty(propName) ) + { + (**prop).setValueFromProperty( *other.getPointerToProperty( propName ) ); + } + } + } + + /** + * Get all properties in a group. + * @param group Name of a group. + */ + std::vector< Property*> IPropertyManager::getPropertiesInGroup(const std::string& group) const + { + auto props = getProperties(); + for(auto prop = props.begin(); prop != props.end(); ) + { + if ( (**prop).getGroup() == group ) + { + ++prop; + } + else + { + prop = props.erase( prop ); + } + } + return props; + } + // Definitions for TypedValue cast operators // Have to come after getValue definitions above to keep MSVS2010 happy IPropertyManager::TypedValue::operator int16_t () { return pm.getValue(prop); } diff --git a/Code/Mantid/Framework/Kernel/src/MagneticFormFactorTable.cpp b/Code/Mantid/Framework/Kernel/src/MagneticFormFactorTable.cpp index d06a93ad2053..9125c8df5e68 100644 --- a/Code/Mantid/Framework/Kernel/src/MagneticFormFactorTable.cpp +++ b/Code/Mantid/Framework/Kernel/src/MagneticFormFactorTable.cpp @@ -22,7 +22,7 @@ namespace Mantid /** * Returns an interpolated form factor for the given \f$Q^2\f$ value - * @param qsqr :: \f$Q^2\f$ in \f$\AA^{-2}\f$ + * @param qsqr :: \f$Q^2\f$ in \f$\mbox{\AA}^{-2}\f$ * @return The interpolated value */ double MagneticFormFactorTable::value(const double qsqr) const diff --git a/Code/Mantid/Framework/Kernel/src/MagneticIon.cpp b/Code/Mantid/Framework/Kernel/src/MagneticIon.cpp index 36d4e61a513a..d549f815b0d1 100644 --- a/Code/Mantid/Framework/Kernel/src/MagneticIon.cpp +++ b/Code/Mantid/Framework/Kernel/src/MagneticIon.cpp @@ -28,9 +28,9 @@ namespace Mantid } /** - * Returns the value of the form factor for the given \f$Q^2\f$ in \f$\AA^-2\f$ taking into account the + * Returns the value of the form factor for the given \f$Q^2\f$ in \f$\mbox{\AA}^-2\f$ taking into account the * number of terms given by the value of j & l - * @param qsqr :: The square of the momentum transfer in \f$\AA^-2\f$ + * @param qsqr :: The square of the momentum transfer in \f$\mbox{\AA}^-2\f$ * @param j :: The total angular momentum * @param l :: The orbital angular momentum * @return diff --git a/Code/Mantid/Framework/Kernel/src/Memory.cpp b/Code/Mantid/Framework/Kernel/src/Memory.cpp index dfa5b19a7341..3175d21e9fd5 100644 --- a/Code/Mantid/Framework/Kernel/src/Memory.cpp +++ b/Code/Mantid/Framework/Kernel/src/Memory.cpp @@ -6,13 +6,13 @@ #include #ifdef USE_TCMALLOC -#include "google/malloc_extension.h" +#include "gperftools/malloc_extension.h" #endif #ifdef __linux__ #include #include - #include + #include #endif #ifdef __APPLE__ #include diff --git a/Code/Mantid/Framework/Kernel/src/NetworkProxyLinux.cpp b/Code/Mantid/Framework/Kernel/src/NetworkProxyLinux.cpp new file mode 100644 index 000000000000..bb39f0ca278e --- /dev/null +++ b/Code/Mantid/Framework/Kernel/src/NetworkProxyLinux.cpp @@ -0,0 +1,40 @@ +#include "MantidKernel/NetworkProxy.h" +#include + +namespace Mantid +{ + namespace Kernel + { + + //---------------------------------------------------------------------------------------------- + /** Constructor + */ + NetworkProxy::NetworkProxy() : + m_logger("network_proxy_logger_generic") + { + } + + //---------------------------------------------------------------------------------------------- + /** Destructor + */ + NetworkProxy::~NetworkProxy() + { + } + + ProxyInfo NetworkProxy::getHttpProxy(const std::string&) + { + ProxyInfo proxyInfo; // NoProxy. + char * proxy_var = getenv("http_proxy"); + if (proxy_var == 0) + proxy_var = getenv("HTTP_PROXY"); + + if (proxy_var != 0) + { + Poco::URI uri_p(proxy_var); + proxyInfo = ProxyInfo(uri_p.getHost(), uri_p.getPort(), true /*http proxy*/); + } + return proxyInfo; + } + + } // namespace Kernel +} // namespace Mantid diff --git a/Code/Mantid/Framework/Kernel/src/NetworkProxyOSX.cpp b/Code/Mantid/Framework/Kernel/src/NetworkProxyOSX.cpp new file mode 100644 index 000000000000..4ec9182a22ab --- /dev/null +++ b/Code/Mantid/Framework/Kernel/src/NetworkProxyOSX.cpp @@ -0,0 +1,276 @@ +// Compile on OSX only. +#if defined(__APPLE__) + +#include "MantidKernel/NetworkProxy.h" +#include +#include +#include +#include +#include +#include +#include + +namespace Mantid +{ + namespace Kernel + { + + /** + * Helper function to convert CFStringRefs to std::string + * @param stringRef : CRFStringRef variable + * @return std::string + */ + std::string toString(CFStringRef stringRef) + { + std::string buffer; + const int max_size = 1000; + buffer.resize(max_size); + CFStringGetCString(stringRef, &buffer[0], max_size, kCFStringEncodingUTF8); + // Strip out whitespace + std::stringstream trimmer; + trimmer << buffer; + buffer.clear(); + trimmer >> buffer; + return buffer; + } + + /** + * Helper enums. + */ + enum ProxyType + { + DefaultProxy, Socks5Proxy, NoProxy, HttpProxy, HttpCachingProxy, FtpCachingProxy + }; + + /// Typedef Collection of proxy information. + typedef std::vector ProxyInfoVec; + + /** + * Extract proxy information from a CFDistionaryRef + * @param dict : CFDictionary item + * @return ProxyInfo object. + */ + ProxyInfo proxyFromDictionary(CFDictionaryRef dict) + { + ProxyInfo proxyInfo; + ProxyType proxyType = NoProxy; + + CFStringRef cfProxyType = (CFStringRef) CFDictionaryGetValue(dict, kCFProxyTypeKey); + + if (CFStringCompare(cfProxyType, kCFProxyTypeFTP, 0) == kCFCompareEqualTo) + { + proxyType = FtpCachingProxy; + } + else if (CFStringCompare(cfProxyType, kCFProxyTypeHTTP, 0) == kCFCompareEqualTo) + { + proxyType = HttpProxy; + } + else if (CFStringCompare(cfProxyType, kCFProxyTypeHTTPS, 0) == kCFCompareEqualTo) + { + proxyType = HttpProxy; + } + else if (CFStringCompare(cfProxyType, kCFProxyTypeSOCKS, 0) == kCFCompareEqualTo) + { + proxyType = Socks5Proxy; + } + + int port = 0; + std::string hostName = toString((CFStringRef) CFDictionaryGetValue(dict, kCFProxyHostNameKey)); + CFNumberRef portNumber = (CFNumberRef) CFDictionaryGetValue(dict, kCFProxyPortNumberKey); + if (portNumber) + { + CFNumberGetValue(portNumber, kCFNumberSInt16Type, &port); + } + if (proxyType != NoProxy) + { + proxyInfo = ProxyInfo(hostName, port, proxyType == HttpProxy); + } + + return proxyInfo; + } + + /** + * Get proxy information from a proxy script. + * @param dict : Dictionary to search through. + * @param targetURLString : Target remote URL + * @param logger : Log object + * @return Collection of proxy information. + */ + ProxyInfoVec proxyInformationFromPac(CFDictionaryRef dict, const std::string& targetURLString, Logger& logger ) + { + ProxyInfoVec proxyInfoVec; + + // is there a PAC enabled? If so, use it first. + CFNumberRef pacEnabled; + if ((pacEnabled = (CFNumberRef) CFDictionaryGetValue(dict, kSCPropNetProxiesProxyAutoConfigEnable))) + { + int enabled; + if (CFNumberGetValue(pacEnabled, kCFNumberIntType, &enabled) && enabled) + { + // PAC is enabled + CFStringRef cfPacLocation = (CFStringRef) CFDictionaryGetValue(dict, + kSCPropNetProxiesProxyAutoConfigURLString); + CFDataRef pacData; + CFURLRef pacURL = CFURLCreateWithString(kCFAllocatorDefault, cfPacLocation, NULL); + SInt32 errorCode; + if (!CFURLCreateDataAndPropertiesFromResource(kCFAllocatorDefault, pacURL, &pacData, NULL, + NULL, &errorCode)) + { + logger.debug() << "Unable to get the PAC script at " << toString(cfPacLocation) << "Error code: " << errorCode << std::endl; + return proxyInfoVec; + } + + CFStringRef pacScript = CFStringCreateFromExternalRepresentation(kCFAllocatorDefault, pacData, + kCFStringEncodingISOLatin1); + + CFURLRef targetURL = CFURLCreateWithBytes(kCFAllocatorDefault, + (UInt8*) targetURLString.c_str(), targetURLString.size(), kCFStringEncodingUTF8, NULL); + if (!targetURL) + { + logger.debug("Problem with Target URI for proxy script"); + return proxyInfoVec; + } + + CFErrorRef pacError; + CFArrayRef proxies = CFNetworkCopyProxiesForAutoConfigurationScript(pacScript, targetURL, + &pacError); + + if (!proxies) + { + std::string pacLocation = toString(cfPacLocation); + CFStringRef pacErrorDescription = CFErrorCopyDescription(pacError); + logger.debug() << "Execution of PAC script at \"%s\" failed: %s" << pacLocation << toString(pacErrorDescription) << std::endl; + } + + CFIndex size = CFArrayGetCount(proxies); + for (CFIndex i = 0; i < size; ++i) + { + CFDictionaryRef proxy = (CFDictionaryRef) CFArrayGetValueAtIndex(proxies, i); + proxyInfoVec.push_back(proxyFromDictionary(proxy)); + } + } + } + return proxyInfoVec; + } + + /** + * Proxy from dictionary. + * @param dict + * @param type + * @param enableKey + * @param hostKey + * @param portKey + * @return return Proxy object. + */ + ProxyInfo proxyFromDictionary(CFDictionaryRef dict, ProxyType type, CFStringRef enableKey, + CFStringRef hostKey, CFStringRef portKey) + { + ProxyInfo proxyInfo; + CFNumberRef protoEnabled; + CFNumberRef protoPort; + CFStringRef protoHost; + if (enableKey && (protoEnabled = (CFNumberRef) CFDictionaryGetValue(dict, enableKey)) + && (protoHost = (CFStringRef) CFDictionaryGetValue(dict, hostKey)) && (protoPort = + (CFNumberRef) CFDictionaryGetValue(dict, portKey))) + { + int enabled; + if (CFNumberGetValue(protoEnabled, kCFNumberIntType, &enabled) && enabled) + { + std::string host = toString(protoHost); + + int port; + CFNumberGetValue(protoPort, kCFNumberIntType, &port); + proxyInfo = ProxyInfo(host, port, HttpProxy); + } + } + + // proxy not enabled + return proxyInfo; + } + + /** + * Specifially look for http proxy settings. + * @param dict : + * @return Return the proxy info object. + */ + ProxyInfo httpProxyFromSystem(CFDictionaryRef dict) + { + ProxyInfo tempProxy = proxyFromDictionary(dict, HttpProxy, kSCPropNetProxiesHTTPEnable, + kSCPropNetProxiesHTTPProxy, kSCPropNetProxiesHTTPPort); + + return tempProxy; + } + + /** + * Find the http proxy. + * Look through the proxy settings script first. + * @param targetURLString : Target remote URL string + * @param logger : ref to log object. + * @return Proxy object. + */ + ProxyInfo findHttpProxy(const std::string& targetURLString, Mantid::Kernel::Logger& logger) + { + ProxyInfo httpProxy; + CFDictionaryRef dict = SCDynamicStoreCopyProxies(NULL); + if (!dict) + { + logger.debug("ScriptRepository SCDynamicStoreCopyProxies returned NULL"); + } + + // Query the proxy pac first. + ProxyInfoVec info = proxyInformationFromPac(dict, targetURLString, logger); + + bool foundHttpProxy = false; + for (ProxyInfoVec::iterator it = info.begin(); it != info.end(); ++it) + { + ProxyInfo proxyInfo = *it; + if (proxyInfo.isHttpProxy()) + { + foundHttpProxy = true; + httpProxy = *it; + break; + } + } + // Query the http proxy settings second. + if (!foundHttpProxy) + { + ProxyInfo tempProxy = httpProxyFromSystem(dict); + if (tempProxy.isHttpProxy()) + { + httpProxy = tempProxy; + foundHttpProxy = true; + } + } + + if (!foundHttpProxy) + { + logger.debug("ScriptRepositry. No system HTTP Proxy set!"); + } + + return httpProxy; + + } + + //---------------------------------------------------------------------------------------------- + /** Constructor + */ + NetworkProxy::NetworkProxy() : m_logger("network_proxy_logger_osx") + { + } + + //---------------------------------------------------------------------------------------------- + /** Destructor + */ + NetworkProxy::~NetworkProxy() + { + } + + ProxyInfo NetworkProxy::getHttpProxy(const std::string& targetURLString) + { + return findHttpProxy(targetURLString, m_logger); + } + + } // namespace Kernel +} // namespace Mantid + +#endif diff --git a/Code/Mantid/Framework/Kernel/src/NetworkProxyWin.cpp b/Code/Mantid/Framework/Kernel/src/NetworkProxyWin.cpp new file mode 100644 index 000000000000..eaab5392359d --- /dev/null +++ b/Code/Mantid/Framework/Kernel/src/NetworkProxyWin.cpp @@ -0,0 +1,195 @@ +// Only compile on windows. +#if defined(_WIN32) || defined(_WIN64) + +#include "MantidKernel/NetworkProxy.h" +// std +#include +// windows +#include +#include + +namespace Mantid +{ + namespace Kernel + { + + bool get_proxy_configuration_win(const std::string & target_url, std::string &proxy_str, std::string & err_msg) + { + HINTERNET hSession = NULL; + std::wstring proxy; + std::wstring wtarget_url; + if (target_url.find("http://") == std::string::npos) + { + wtarget_url = L"http://"; + } + wtarget_url += std::wstring(target_url.begin(),target_url.end()); + bool fail = false; + std::stringstream info; + WINHTTP_CURRENT_USER_IE_PROXY_CONFIG ie_proxy; + WINHTTP_AUTOPROXY_OPTIONS proxy_options; + WINHTTP_PROXY_INFO proxy_info; + ZeroMemory( &proxy_options, sizeof(proxy_options)); + ZeroMemory( &ie_proxy, sizeof(ie_proxy)); + ZeroMemory( &proxy_info, sizeof(proxy_info)); + + // the loop is just to allow us to go out of this session whenever we want + while(true) + { + // Use WinHttpOpen to obtain a session handle. + hSession = WinHttpOpen( L"ScriptRepository FindingProxy/1.0", + WINHTTP_ACCESS_TYPE_DEFAULT_PROXY, + WINHTTP_NO_PROXY_NAME, + WINHTTP_NO_PROXY_BYPASS, 0 ); + if (!hSession) + { + fail = true; + info << "Failed to create the session (Error Code: " << GetLastError() << ")."; + break; + } + // get the configuration of the web browser + if (!WinHttpGetIEProxyConfigForCurrentUser(&ie_proxy)) + { + fail = true; + info << "Could not find the proxy settings (Error code :" << GetLastError(); + break; + } + + if (ie_proxy.lpszProxy) + { + // the proxy was already given, + // it is not necessary to query the system for the auto proxy + proxy = ie_proxy.lpszProxy; + break; + } + + if (ie_proxy.fAutoDetect) + { + // if auto detect, than setup the proxy to auto detect + proxy_options.dwFlags |= WINHTTP_AUTOPROXY_AUTO_DETECT; + proxy_options.dwAutoDetectFlags = WINHTTP_AUTO_DETECT_TYPE_DNS_A; + } + + if (ie_proxy.lpszAutoConfigUrl) + { + // configure to auto proxy + proxy_options.dwFlags |= WINHTTP_AUTOPROXY_CONFIG_URL; + proxy_options.lpszAutoConfigUrl = ie_proxy.lpszAutoConfigUrl; + } + + if (!WinHttpGetProxyForUrl(hSession, wtarget_url.c_str(), &proxy_options, &proxy_info)) + { + info << "Could not find the proxy for this url (Error code :" << GetLastError() <<")."; + fail = true; + break; + } + + //std::cout << "get proxy for url passed" << std::endl; + if (proxy_info.dwAccessType == WINHTTP_ACCESS_TYPE_NO_PROXY) + { + // no proxy (return an empty proxy) + break; + } + + if (proxy_info.lpszProxy) + { + //proxy found. Get it. + proxy = proxy_info.lpszProxy; + break; + } + break; // loop finished + } + + // free memory of all possibly allocated objects + // ie_proxy + if (ie_proxy.lpszAutoConfigUrl) + GlobalFree(ie_proxy.lpszAutoConfigUrl); + if (ie_proxy.lpszProxy) + GlobalFree(ie_proxy.lpszProxy); + if (ie_proxy.lpszProxyBypass) + GlobalFree(ie_proxy.lpszProxyBypass); + // proxy_info + if (proxy_info.lpszProxyBypass) + GlobalFree(proxy_info.lpszProxyBypass); + if (proxy_info.lpszProxy) + GlobalFree(proxy_info.lpszProxy); + + // hSession + if( hSession ) WinHttpCloseHandle( hSession ); + + if (fail) + { + err_msg = info.str(); + } + proxy_str = std::string(proxy.begin(),proxy.end()); + return !fail; + } + + //---------------------------------------------------------------------------------------------- + /** Constructor + */ + NetworkProxy::NetworkProxy() : + m_logger("network_proxy_logger_win") + { + } + + //---------------------------------------------------------------------------------------------- + /** Destructor + */ + NetworkProxy::~NetworkProxy() + { + } + + /** + * Get the http proxy information + * @param targetURLString + * @return Proxy information + */ + ProxyInfo NetworkProxy::getHttpProxy(const std::string& targetURLString) + { + + ProxyInfo proxyInfo; // No proxy + std::string errmsg, proxy_option; + m_logger.debug() << "Attempt to get the windows proxy configuration for this connection" << std::endl; + if(get_proxy_configuration_win(targetURLString, proxy_option,errmsg)) + { + std::string proxyServer; + int proxyPort; + if (!proxy_option.empty()) + { + size_t pos = proxy_option.rfind(':'); + if (pos != std::string::npos) + { + if (pos == 4 || pos == 5) // means it found http(s): + { + proxyServer = proxy_option; + proxyPort = 8080; // default port for proxy + } + else + { + proxyServer = std::string(proxy_option.begin(),proxy_option.begin()+pos); + std::stringstream port_str; + port_str << std::string(proxy_option.begin()+pos+1,proxy_option.end()); + port_str >> proxyPort; + } + } + else + { + proxyServer = proxy_option; + proxyPort = 8080; + } + } + proxyInfo = ProxyInfo(proxyServer, proxyPort, true); + } + else + { + m_logger.information() << "ScriptRepository failed to find the proxy information. It will attempt without proxy. " + << errmsg << std::endl; + } + + return proxyInfo; + } + + } // namespace Kernel +} // namespace Mantid + +#endif diff --git a/Code/Mantid/Framework/Kernel/src/ProgressBase.cpp b/Code/Mantid/Framework/Kernel/src/ProgressBase.cpp index afc3b4d5c080..b0da3a397808 100644 --- a/Code/Mantid/Framework/Kernel/src/ProgressBase.cpp +++ b/Code/Mantid/Framework/Kernel/src/ProgressBase.cpp @@ -174,6 +174,8 @@ namespace Kernel m_start = start; m_end = end; m_i = 0; + m_last_reported = 0; + m_timeElapsed->reset(); setNumSteps(nsteps); } diff --git a/Code/Mantid/Framework/Kernel/src/Property.cpp b/Code/Mantid/Framework/Kernel/src/Property.cpp index 7adf842043f2..34f364543b08 100644 --- a/Code/Mantid/Framework/Kernel/src/Property.cpp +++ b/Code/Mantid/Framework/Kernel/src/Property.cpp @@ -4,6 +4,7 @@ #include "MantidKernel/Exception.h" #include "MantidKernel/IPropertySettings.h" #include "MantidKernel/PropertyHistory.h" +#include "MantidKernel/TimeSeriesProperty.h" #include #include @@ -312,6 +313,50 @@ namespace DataObjects namespace Kernel { + +/** + * @param lhs Thing on the left + * @param rhs Thing on the right + * @return true if they are equal + */ +bool operator==( const Property & lhs, const Property & rhs ) +{ + if (lhs.name() != rhs.name()) + return false; + if (lhs.type() != rhs.type()) + return false; + + // check for TimeSeriesProperty specializations + auto lhs_tsp_float = dynamic_cast *>(&lhs); + if (lhs_tsp_float) + return lhs_tsp_float->operator==(rhs); + + auto lhs_tsp_double = dynamic_cast *>(&lhs); + if (lhs_tsp_double) + return lhs_tsp_double->operator==(rhs); + + auto lhs_tsp_string = dynamic_cast *>(&lhs); + if (lhs_tsp_string) + return lhs_tsp_string->operator==(rhs); + + auto lhs_tsp_bool = dynamic_cast *>(&lhs); + if (lhs_tsp_bool) + return lhs_tsp_bool->operator==(rhs); + + // use fallthrough behavior + return (lhs.value() == rhs.value()); +} + +/** + * @param lhs Thing on the left + * @param rhs Thing on the right + * @return true if they are not equal + */ +bool operator!=( const Property & lhs, const Property & rhs ) +{ + return (!(lhs == rhs)); +} + /** * Get the unmangled name of the given typestring for some common types that we use. Note that * this is just a lookup and NOT an unmangling algorithm diff --git a/Code/Mantid/Framework/Kernel/src/ProxyInfo.cpp b/Code/Mantid/Framework/Kernel/src/ProxyInfo.cpp new file mode 100644 index 000000000000..6d6866e0d697 --- /dev/null +++ b/Code/Mantid/Framework/Kernel/src/ProxyInfo.cpp @@ -0,0 +1,112 @@ +#include "MantidKernel/ProxyInfo.h" +#include +#include + +namespace Mantid +{ + namespace Kernel + { + + //---------------------------------------------------------------------------------------------- + /** Destructor + */ + ProxyInfo::~ProxyInfo() + { + } + +//---------------------------------------------------------------------------------------------- + /** Constructor + */ + ProxyInfo::ProxyInfo() : + m_host(""), m_port(0), m_isHttpProxy(false), m_isEmptyProxy(true) + { + } + + /** + * Proxy information constructor + * @param host : host url + * @param port : port number + * @param isHttpProxy : is this a http proxy + */ + ProxyInfo::ProxyInfo(const std::string& host, const int port, const bool isHttpProxy) : + m_host(host), m_port(port), m_isHttpProxy(isHttpProxy), m_isEmptyProxy(false) + { + if(host.empty() || port == 0) + { + m_isEmptyProxy = true; + } + } + + /** + * Host url + * @return host url or throws if an unset proxy. + */ + std::string ProxyInfo::host() const + { + if (m_isEmptyProxy) + { + throw std::logic_error("Calling host on an undefined proxy"); + } + return m_host; + } + + /** + * Port Number + * @return Port number or throws if an unset proxy. + */ + int ProxyInfo::port() const + { + if (m_isEmptyProxy) + { + throw std::logic_error("Calling port on an undefined proxy"); + } + return m_port; + } + + /** + * Is this a http proxy + * @return True if a http proxy or throws if an unset proxy. + */ + bool ProxyInfo::isHttpProxy() const + { + return m_isHttpProxy; + } + + /** + * + * @return True if an empty proxy. + */ + bool ProxyInfo::emptyProxy() const + { + return m_isEmptyProxy; + } + + /** + * Copy constructor + * @param other : to copy from + */ + ProxyInfo::ProxyInfo(const ProxyInfo& other) : + m_host(other.m_host), m_port(other.m_port), m_isHttpProxy(other.m_isHttpProxy), m_isEmptyProxy(other.m_isEmptyProxy) + { + + } + + /** + * Assignment operator + * @param other : to assign from. + * @return + */ + ProxyInfo& ProxyInfo::operator=(const ProxyInfo& other) + { + if (&other != this) + { + m_host = other.m_host; + m_isEmptyProxy = other.m_isEmptyProxy; + m_isHttpProxy = other.m_isHttpProxy; + m_port = other.m_port; + } + return *this; + } + + } // namespace Kernel +} // namespace Mantid diff --git a/Code/Mantid/Framework/Kernel/src/ThreadPool.cpp b/Code/Mantid/Framework/Kernel/src/ThreadPool.cpp index 814b19b51cd3..5eeb26f264ed 100644 --- a/Code/Mantid/Framework/Kernel/src/ThreadPool.cpp +++ b/Code/Mantid/Framework/Kernel/src/ThreadPool.cpp @@ -1,10 +1,10 @@ //---------------------------------------------------------------------- // Includes //---------------------------------------------------------------------- -#include "MantidKernel/MultiThreaded.h" #include "MantidKernel/ThreadPool.h" #include "MantidKernel/ThreadPoolRunnable.h" #include "MantidKernel/Task.h" +#include "MantidKernel/ConfigService.h" #include #include #include @@ -12,6 +12,7 @@ #include #include #include +#include namespace Mantid { @@ -38,8 +39,8 @@ namespace Kernel if (numThreads == 0) { - //Uses OpenMP to find how many cores there are. - m_numThreads = PARALLEL_GET_MAX_THREADS; + //Uses Poco to find how many cores there are. + m_numThreads = getNumPhysicalCores(); } else m_numThreads = numThreads; @@ -60,16 +61,19 @@ namespace Kernel //-------------------------------------------------------------------------------- /** Return the number of physical cores available on the system. - * NOTE: Uses OpenMP getMaxThreads to find the number. - * @return how many cores are present. 1 if no OpenMP is installed. + * NOTE: Uses Poco::Environment::processorCount() to find the number. + * @return how many cores are present. */ size_t ThreadPool::getNumPhysicalCores() { - return PARALLEL_GET_MAX_THREADS; + int maxCores(0); + int retVal = Kernel::ConfigService::Instance().getValue("MultiThreaded.MaxCores", maxCores); + if(retVal > 0 && maxCores > 0) + return maxCores; + else + return Poco::Environment::processorCount(); } - - //-------------------------------------------------------------------------------- /** Start the threads and begin looking for tasks. * diff --git a/Code/Mantid/Framework/Kernel/src/ThreadSafeLogStream.cpp b/Code/Mantid/Framework/Kernel/src/ThreadSafeLogStream.cpp index e4680cb57916..5b8961e54fd6 100644 --- a/Code/Mantid/Framework/Kernel/src/ThreadSafeLogStream.cpp +++ b/Code/Mantid/Framework/Kernel/src/ThreadSafeLogStream.cpp @@ -48,10 +48,8 @@ int ThreadSafeLogStreamBuf::writeToDevice(char c) } else { - PARALLEL_CRITICAL(logstream) - { - m_messages[Poco::Thread::currentTid()] += c; - } + Poco::FastMutex::ScopedLock lock(m_mutex); + m_messages[Poco::Thread::currentTid()] += c; } return static_cast(c); } diff --git a/Code/Mantid/Framework/Kernel/src/TimeSeriesProperty.cpp b/Code/Mantid/Framework/Kernel/src/TimeSeriesProperty.cpp index fd5486eac227..355b450bccbd 100644 --- a/Code/Mantid/Framework/Kernel/src/TimeSeriesProperty.cpp +++ b/Code/Mantid/Framework/Kernel/src/TimeSeriesProperty.cpp @@ -145,6 +145,20 @@ namespace Mantid return true; } + /** + * Deep comparison. + * @param right The other property to compare to. + * @return true if the are equal. + */ + template + bool TimeSeriesProperty::operator==( const Property & right ) const + { + auto rhs_tsp = dynamic_cast *>(&right); + if (!rhs_tsp) + return false; + return this->operator==(*rhs_tsp); + } + /** * Deep comparison (not equal). * @param right The other property to compare to. @@ -156,7 +170,18 @@ namespace Mantid return !(*this == right); } - /* + /** + * Deep comparison (not equal). + * @param right The other property to compare to. + * @return true if the are not equal. + */ + template + bool TimeSeriesProperty::operator!=( const Property & right ) const + { + return !(*this == right); + } + + /** * Set name of the property */ template diff --git a/Code/Mantid/Framework/Kernel/src/V3D.cpp b/Code/Mantid/Framework/Kernel/src/V3D.cpp index 8e06fb397002..1e6025349131 100644 --- a/Code/Mantid/Framework/Kernel/src/V3D.cpp +++ b/Code/Mantid/Framework/Kernel/src/V3D.cpp @@ -482,9 +482,8 @@ V3D::cross_prod(const V3D& v) const double V3D::distance(const V3D& v) const { - V3D dif(*this); - dif-=v; - return dif.norm(); + const double dx(x-v.x), dy(y-v.y), dz(z-v.z); + return sqrt(dx*dx +dy*dy + dz*dz); } /** Calculates the zenith angle (theta) of this vector with respect to another @@ -556,15 +555,10 @@ V3D::rotate(const Kernel::Matrix& A) @param A :: Rotation matrix (needs to be >3x3) */ { - Matrix Pv(3,1); - Pv[0][0]=x; - Pv[1][0]=y; - Pv[2][0]=z; - Matrix Po=A*Pv; - x=Po[0][0]; - y=Po[1][0]; - z=Po[2][0]; - return; + double xold(x), yold(y), zold(z); + x = A[0][0]*xold + A[0][1]*yold + A[0][2]*zold; + y = A[1][0]*xold + A[1][1]*yold + A[1][2]*zold; + z = A[2][0]*xold + A[2][1]*yold + A[2][2]*zold; } /** diff --git a/Code/Mantid/Framework/Kernel/test/ConfigServiceTest.h b/Code/Mantid/Framework/Kernel/test/ConfigServiceTest.h index 5af09a06f008..1f2a1202346e 100644 --- a/Code/Mantid/Framework/Kernel/test/ConfigServiceTest.h +++ b/Code/Mantid/Framework/Kernel/test/ConfigServiceTest.h @@ -187,6 +187,43 @@ class ConfigServiceTest : public CxxTest::TestSuite TS_ASSERT_LESS_THAN(0, ConfigService::Instance().getCurrentDir().length()); //check that the string is not empty // TS_ASSERT_LESS_THAN(0, ConfigService::Instance().getHomeDir().length()); //check that the string is not empty TS_ASSERT_LESS_THAN(0, ConfigService::Instance().getTempDir().length()); //check that the string is not empty + + std::string appdataDir = ConfigService::Instance().getAppDataDir(); + TS_ASSERT_LESS_THAN(0, appdataDir.length()); +#ifdef _WIN32 + std::string::size_type index = appdataDir.find("\\AppData\\Roaming\\mantidproject\\mantid"); + TSM_ASSERT_LESS_THAN("Could not find correct path in getAppDataDir()",index,appdataDir.size()); +#else + std::string::size_type index = appdataDir.find("/.mantid"); + TSM_ASSERT_LESS_THAN("Could not find correct path in getAppDataDir()",index,appdataDir.size()); +#endif + + } + + void TestInstrumentDirectory() + { + + auto directories = ConfigService::Instance().getInstrumentDirectories(); + TS_ASSERT_LESS_THAN(1,directories.size()); + //the first entry should be the AppDataDir + instrument + TSM_ASSERT_LESS_THAN("Could not find the appData directory in getInstrumentDirectories()[0]",directories[0].find(ConfigService::Instance().getAppDataDir()),directories[0].size()); + TSM_ASSERT_LESS_THAN("Could not find the 'instrument' directory in getInstrumentDirectories()[0]",directories[0].find("instrument"),directories[0].size()); + + if (directories.size() == 3) + { + // The middle entry should be /etc/mantid/instrument + TSM_ASSERT_LESS_THAN("Could not find /etc/mantid/instrument path in getInstrumentDirectories()[1]",directories[1].find("etc/mantid/instrument"),directories[1].size()); + } + //Check that the last directory matches that returned by getInstrumentDirectory + TS_ASSERT_EQUALS(directories[directories.size()-1],ConfigService::Instance().getInstrumentDirectory()); + + //check all of the directory entries actually exist + for (auto it = directories.begin(); it != directories.end(); ++it) + { + Poco::File directory(*it); + TSM_ASSERT(*it + " does not exist", directory.exists()); + } + } void TestCustomProperty() diff --git a/Code/Mantid/Framework/Kernel/test/ProxyInfoTest.h b/Code/Mantid/Framework/Kernel/test/ProxyInfoTest.h new file mode 100644 index 000000000000..6e7b235ce2cc --- /dev/null +++ b/Code/Mantid/Framework/Kernel/test/ProxyInfoTest.h @@ -0,0 +1,113 @@ +#ifndef MANTID_SCRIPTREPOSITORY_PROXYINFOTEST_H_ +#define MANTID_SCRIPTREPOSITORY_PROXYINFOTEST_H_ + +#include + +#include "MantidKernel/ProxyInfo.h" + +using Mantid::Kernel::ProxyInfo; + +class ProxyInfoTest: 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 ProxyInfoTest *createSuite() + { + return new ProxyInfoTest(); + } + static void destroySuite(ProxyInfoTest *suite) + { + delete suite; + } + + void test_construction_no_proxy() + { + ProxyInfo proxyInfo; + TSM_ASSERT("Is not a valid proxy object", proxyInfo.emptyProxy()); + TS_ASSERT_THROWS(proxyInfo.host(), std::logic_error&); + TS_ASSERT_THROWS(proxyInfo.port(), std::logic_error&); + TSM_ASSERT("Cannot be a http proxy if not a proxy at all.", !proxyInfo.isHttpProxy()); + } + + void test_empty_host_is_empy_proxy() + { + const std::string url = ""; + const int port = 1; + const bool isHttpProxy = true; + ProxyInfo proxyInfo(url, port, isHttpProxy); + TSM_ASSERT("This is a NOT valid proxy object", proxyInfo.emptyProxy()); + } + + void test_empty_port_is_empy_proxy() + { + const std::string url = "some_url"; + const int port = 0; + const bool isHttpProxy = true; + ProxyInfo proxyInfo(url, port, isHttpProxy); + TSM_ASSERT("This is a NOT valid proxy object", proxyInfo.emptyProxy()); + } + + void test_construction_proxy() + { + const std::string url = "some_url"; + const int port = 1; + const bool isHttpProxy = true; + ProxyInfo proxyInfo(url, port, isHttpProxy); + TSM_ASSERT("This is a valid proxy object", !proxyInfo.emptyProxy()); + TS_ASSERT_EQUALS(url, proxyInfo.host()); + TS_ASSERT_EQUALS(port, proxyInfo.port()); + TS_ASSERT_EQUALS(isHttpProxy, proxyInfo.isHttpProxy()); + } + + void test_is_http_proxy() + { + const std::string url = "some_url"; + const int port = 1; + const bool isHttpProxy = false; + ProxyInfo proxyInfo(url, port, isHttpProxy); + TS_ASSERT_EQUALS(isHttpProxy, proxyInfo.isHttpProxy()); + } + + void test_copy_live_proxy() + { + const std::string url = "some_url"; + const int port = 1; + const bool isHttpProxy = true; + ProxyInfo a(url, port, isHttpProxy); + ProxyInfo b = a; + + TS_ASSERT_EQUALS(a.host(), b.host()); + TS_ASSERT_EQUALS(a.port(), b.port()); + TS_ASSERT_EQUALS(a.isHttpProxy(), b.isHttpProxy()); + } + + void test_assign_from_live_proxy() + { + ProxyInfo a("a", 1, false); + ProxyInfo b("b", 2, true); + + a = b; + TS_ASSERT_EQUALS(a.host(), b.host()); + TS_ASSERT_EQUALS(a.port(), b.port()); + TS_ASSERT_EQUALS(a.isHttpProxy(), b.isHttpProxy()); + } + + void test_copy_dead_proxy() + { + ProxyInfo a; + ProxyInfo b = a; // Should not throw + TS_ASSERT(b.emptyProxy()) + } + + void test_assign_from_dead_proxy() + { + ProxyInfo a; + ProxyInfo b("b", 1, true); + b = a; // Should not throw + TS_ASSERT(b.emptyProxy()) + } + +}; + +#endif /* MANTID_SCRIPTREPOSITORY_PROXYINFOTEST_H_ */ diff --git a/Code/Mantid/Framework/Kernel/test/V3DTest.h b/Code/Mantid/Framework/Kernel/test/V3DTest.h index 98f6367c1948..e5d7fb2112c9 100644 --- a/Code/Mantid/Framework/Kernel/test/V3DTest.h +++ b/Code/Mantid/Framework/Kernel/test/V3DTest.h @@ -8,6 +8,7 @@ #include #include "MantidKernel/V3D.h" +#include "MantidKernel/Matrix.h" #include "MantidTestHelpers/NexusTestHelper.h" using Mantid::Kernel::V3D; @@ -300,6 +301,63 @@ class V3DTest: public CxxTest::TestSuite TS_ASSERT_DELTA( a.angle(d), M_PI, 0.0001); } + void testRotate() + { + V3D direc(1,1,1); + const double theta = 45.0*M_PI/180.0; + const double invRt2(1.0/sqrt(2.0)); + + // rotate around X + Mantid::Kernel::Matrix rx(3,3); + rx[0][0] = 1.0; + rx[1][1] = cos(theta); + rx[1][2] = -sin(theta); + rx[2][2] = cos(theta); + rx[2][1] = sin(theta); + direc.rotate(rx); + + TS_ASSERT_DELTA(direc.X(), 1.0, 1e-08); + TS_ASSERT_DELTA(direc.Y(), 0.0, 1e-08); + TS_ASSERT_DELTA(direc.Z(), 2.0*invRt2, 1e-08); + + // rotate around Y + direc = V3D(1,1,1); + Mantid::Kernel::Matrix ry(3,3); + ry[0][0] = cos(theta); + ry[0][2] = sin(theta); + ry[1][1] = 1.0; + ry[2][0] = -sin(theta); + ry[2][2] = cos(theta); + direc.rotate(ry); + + TS_ASSERT_DELTA(direc.X(), 2.0*invRt2, 1e-08); + TS_ASSERT_DELTA(direc.Y(), 1.0, 1e-08); + TS_ASSERT_DELTA(direc.Z(), 0.0, 1e-08); + + // rotate around Z + direc = V3D(1,1,1); + Mantid::Kernel::Matrix rz(3,3); + rz[0][0] = cos(theta); + rz[0][1] = -sin(theta); + rz[1][0] = sin(theta); + rz[1][1] = cos(theta); + rz[2][2] = 1.0; + direc.rotate(rz); + + TS_ASSERT_DELTA(direc.X(), 0.0, 1e-08); + TS_ASSERT_DELTA(direc.Y(), 2.0*invRt2, 1e-08); + TS_ASSERT_DELTA(direc.Z(), 1.0, 1e-08); + + // General rotation + Mantid::Kernel::Matrix Rt = rz*ry*rx; + direc = V3D(1,1,1); + direc.rotate(Rt); + + TS_ASSERT_DELTA(direc.X(), invRt2*(1+invRt2), 1e-08); + TS_ASSERT_DELTA(direc.Y(), invRt2*(1+invRt2), 1e-08); + TS_ASSERT_DELTA(direc.Z(), 1.0-invRt2, 1e-08); + } + void testSpherical() { double r = 3, theta = 45.0, phi = 45.0; @@ -539,4 +597,45 @@ class V3DTest: public CxxTest::TestSuite }; +//--------------------------------------------------------------------------- +// Performance tests +//--------------------------------------------------------------------------- + +class V3DTestPerformance : 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 V3DTestPerformance *createSuite() { return new V3DTestPerformance(); } + static void destroySuite( V3DTestPerformance *suite ) { delete suite; } + + V3DTestPerformance() + { + const double theta = 45.0*M_PI/180.0; + + // rotate around X + m_rotx = Mantid::Kernel::Matrix(3,3); + m_rotx[0][0] = 1.0; + m_rotx[1][1] = cos(theta); + m_rotx[1][2] = -sin(theta); + m_rotx[2][2] = cos(theta); + m_rotx[2][1] = sin(theta); + } + + void testRotate() + { + V3D direction(1.0,1.0,1.0); + for(size_t i = 0; i < 100000; ++i) + { + direction = V3D(1.0,1.0,1.0); + direction.rotate(m_rotx); + } + // Do something so the compiler doesn't optimise the loop away + TS_ASSERT_DELTA(direction.Y(), 0.0, 1e-08); + } + +private: + Mantid::Kernel::Matrix m_rotx; +}; + #endif diff --git a/Code/Mantid/Framework/LiveData/inc/MantidLiveData/FakeISISHistoDAE.h b/Code/Mantid/Framework/LiveData/inc/MantidLiveData/FakeISISHistoDAE.h index ae67b4c51c15..04a4eccb5711 100644 --- a/Code/Mantid/Framework/LiveData/inc/MantidLiveData/FakeISISHistoDAE.h +++ b/Code/Mantid/Framework/LiveData/inc/MantidLiveData/FakeISISHistoDAE.h @@ -22,6 +22,10 @@ namespace LiveData Simulates ISIS histogram DAE. It runs continuously until canceled and listens to port 6789 for ISIS DAE commands. + Data is generated starting at 10000 microseconds Time of flight, and each bin requested covers 100 microseconds. + The algorithm silently defines three additional spectra with numbers NSpectra+1, NSpectra+2 and NSpectra+3 in a + different time regime (they have different binning to the rest of the spectra). + Copyright © 2008-9 ISIS Rutherford Appleton Laboratory & NScD Oak Ridge National Laboratory This file is part of Mantid. diff --git a/Code/Mantid/Framework/LiveData/inc/MantidLiveData/ISISHistoDataListener.h b/Code/Mantid/Framework/LiveData/inc/MantidLiveData/ISISHistoDataListener.h index d71ebb94836b..d031d9f5b719 100644 --- a/Code/Mantid/Framework/LiveData/inc/MantidLiveData/ISISHistoDataListener.h +++ b/Code/Mantid/Framework/LiveData/inc/MantidLiveData/ISISHistoDataListener.h @@ -64,18 +64,21 @@ namespace Mantid ILiveListener::RunStatus runStatus(); int runNumber() const; - void setSpectra(const std::vector& specList); - private: + void setSpectra(const std::vector& specList); + void setPeriods(const std::vector& periodList); int getInt(const std::string& par) const; std::string getString(const std::string& par) const; void getFloatArray(const std::string& par, std::vector& arr, const size_t dim); void getIntArray(const std::string& par, std::vector& arr, const size_t dim); void getData(int period, int index, int count, boost::shared_ptr workspace, size_t workspaceIndex); void calculateIndicesForReading(std::vector& index, std::vector& count); - void loadSpectraMap(boost::shared_ptr localWorkspace); + void loadSpectraMap(); void runLoadInstrument(boost::shared_ptr localWorkspace, const std::string& iName); + void loadTimeRegimes(); + int getTimeRegimeToLoad() const; + bool isPeriodIgnored(int period) const; static double dblSqrt(double in); /// is initialized @@ -90,17 +93,35 @@ namespace Mantid /// number of periods int m_numberOfPeriods; - /// number of spectra - int m_numberOfSpectra; + /// number of spectra for each time regime + std::vector m_numberOfSpectra; - /// number of bins - int m_numberOfBins; + /// total number of spectra + int m_totalNumberOfSpectra; + + /// number of bins for each time regime + std::vector m_numberOfBins; /// list of spectra to read or empty to read all std::vector m_specList; - /// Store the bin boundaries - boost::shared_ptr m_bins; + /// list of periods to read or empty to read all + std::vector m_periodList; + + /// Store the bin boundaries for each time regime + std::vector> m_bins; + + /// Detector IDs + std::vector m_detIDs; + + /// Spectra IDs + std::vector m_specIDs; + + /// Monitor spectra + std::vector m_monitorSpectra; + + /// Time regime to load + int m_timeRegime; /// reporter function called when the IDC reading routines raise an error static void IDCReporter(int status, int code, const char* message); diff --git a/Code/Mantid/Framework/LiveData/inc/MantidLiveData/StartLiveData.h b/Code/Mantid/Framework/LiveData/inc/MantidLiveData/StartLiveData.h index 7707b5b8dce5..df22e45f02ae 100644 --- a/Code/Mantid/Framework/LiveData/inc/MantidLiveData/StartLiveData.h +++ b/Code/Mantid/Framework/LiveData/inc/MantidLiveData/StartLiveData.h @@ -58,11 +58,10 @@ namespace LiveData private: void init(); void exec(); - + void afterPropertySet(const std::string&); }; - } // namespace LiveData } // namespace Mantid diff --git a/Code/Mantid/Framework/LiveData/src/FakeISISHistoDAE.cpp b/Code/Mantid/Framework/LiveData/src/FakeISISHistoDAE.cpp index 3fd3bdee27cf..75f1a5d5b546 100644 --- a/Code/Mantid/Framework/LiveData/src/FakeISISHistoDAE.cpp +++ b/Code/Mantid/Framework/LiveData/src/FakeISISHistoDAE.cpp @@ -58,6 +58,8 @@ class TestServerConnection: public Poco::Net::TCPServerConnection int m_nPeriods; int m_nSpectra; int m_nBins; + int m_nMonitors; + int m_nMonitorBins; public: /** * Constructor. Defines the simulated dataset dimensions. @@ -70,7 +72,9 @@ class TestServerConnection: public Poco::Net::TCPServerConnection Poco::Net::TCPServerConnection(soc), m_nPeriods(nper), m_nSpectra(nspec), - m_nBins(nbins) + m_nBins(nbins), + m_nMonitors(3), + m_nMonitorBins(nbins * 2) { char buffer[1024]; socket().receiveBytes(&buffer,1024); @@ -132,17 +136,17 @@ class TestServerConnection: public Poco::Net::TCPServerConnection { int period = 0; int istart = spec; - const int ns1 = m_nSpectra + 1; - const int nb1 = m_nBins + 1; + const int ns1 = m_nSpectra + m_nMonitors + 1; if ( m_nPeriods > 1 ) { period = spec / ns1; istart = spec - period * ns1; - if ( period >= m_nPeriods || istart + nos > ns1 ) - { - sendOK(); - } } + if ( period >= m_nPeriods || istart + nos > ns1 ) + { + sendOK(); + } + const int nb1 = (istart <= m_nSpectra? m_nBins : m_nMonitorBins) + 1; const int ndata = nos * nb1; std::vector data( ndata ); for(int i = 0; i < nos; ++i) @@ -228,13 +232,25 @@ class TestServerConnection: public Poco::Net::TCPServerConnection { sendInt( m_nSpectra ); } + else if ( command == "NSP2" ) + { + sendInt( m_nMonitors ); + } else if ( command == "NTC1" ) { sendInt( m_nBins ); } + else if ( command == "NTC2" ) + { + sendInt( m_nMonitorBins ); + } else if ( command == "NDET" ) { - sendInt( m_nSpectra ); + sendInt( m_nSpectra + m_nMonitors ); + } + else if ( command == "NMON" ) + { + sendInt( m_nMonitors ); } else if ( command == "RTCB1" ) { @@ -247,6 +263,17 @@ class TestServerConnection: public Poco::Net::TCPServerConnection }; sendFloatArray( bins ); } + else if ( command == "RTCB2" || (command.size() > 5 && command.substr(0,5) == "RTCB_") ) + { + std::vector bins( m_nMonitorBins + 1 ); + const float dx = 10.0f; + float x = 10000.0f; + for(auto b = bins.begin(); b != bins.end(); ++b, x += dx) + { + *b = x; + }; + sendFloatArray( bins ); + } else if ( command == "RRPB" ) { std::vector rrpb( 32 ); @@ -255,8 +282,8 @@ class TestServerConnection: public Poco::Net::TCPServerConnection } else if ( command == "UDET" ) { - std::vector udet( m_nSpectra ); - for(int i = 0; i < m_nSpectra; ++i) + std::vector udet( m_nSpectra + m_nMonitors ); + for(int i = 0; i < static_cast(udet.size()); ++i) { udet[i] = (int)( 1000 + i + 1 ); } @@ -264,13 +291,22 @@ class TestServerConnection: public Poco::Net::TCPServerConnection } else if ( command == "SPEC" ) { - std::vector spec( m_nSpectra ); - for(int i = 0; i < m_nSpectra; ++i) + std::vector spec( m_nSpectra + m_nMonitors ); + for(int i = 0; i < static_cast(spec.size()); ++i) { spec[i] = (int)( i + 1 ); } sendIntArray( spec ); } + else if ( command == "MDET" ) + { + std::vector mdet( m_nMonitors ); + for(int i = 0; i < m_nMonitors; ++i) + { + mdet[i] = (int)( m_nSpectra + i + 1 ); + } + sendIntArray( mdet ); + } else { sendOK(); diff --git a/Code/Mantid/Framework/LiveData/src/ISISHistoDataListener.cpp b/Code/Mantid/Framework/LiveData/src/ISISHistoDataListener.cpp index 98c20ed936cf..5f91c3e4cc53 100644 --- a/Code/Mantid/Framework/LiveData/src/ISISHistoDataListener.cpp +++ b/Code/Mantid/Framework/LiveData/src/ISISHistoDataListener.cpp @@ -9,6 +9,8 @@ #include "MantidKernel/ConfigService.h" #include "MantidKernel/Exception.h" #include "MantidKernel/UnitFactory.h" +#include "MantidKernel/ArrayProperty.h" +#include "MantidKernel/ArrayBoundedValidator.h" #include "MantidKernel/WarningSuppressions.h" #include "MantidGeometry/Instrument.h" @@ -19,8 +21,10 @@ #include "LoadDAE/idc.h" #include +#include #include +#include using namespace Mantid::API; using namespace Mantid::Geometry; @@ -39,8 +43,15 @@ namespace LiveData } /// Constructor - ISISHistoDataListener::ISISHistoDataListener() : ILiveListener(), isInitilized(false), m_daeHandle( NULL ) + ISISHistoDataListener::ISISHistoDataListener() : ILiveListener(), isInitilized(false), m_daeHandle( NULL ), m_timeRegime(-1) { + declareProperty(new Kernel::ArrayProperty("SpectraList"), + "An optional list of spectra to load. If blank, all available spectra will be loaded."); + + auto validator = boost::make_shared>(); + validator->setLower( 1 ); + declareProperty(new Kernel::ArrayProperty("PeriodList",validator), + "An optional list of periods to load. If blank, all available periods will be loaded."); } /// Destructor @@ -69,6 +80,7 @@ namespace LiveData */ bool ISISHistoDataListener::connect(const Poco::Net::SocketAddress& address) { + m_daeName = address.toString(); // remove the port part auto i = m_daeName.find(':'); @@ -87,12 +99,25 @@ namespace LiveData } m_numberOfPeriods = getInt("NPER"); - m_numberOfSpectra = getInt("NSP1"); - m_numberOfBins = getInt("NTC1"); + g_log.information() << "Number of periods " << m_numberOfPeriods << std::endl; + + // Set the spectra list to load + std::vector spectra = getProperty("SpectraList"); + if ( !spectra.empty() ) + { + setSpectra( spectra ); + } + + // Set the period list to load + std::vector periodList = getProperty("PeriodList"); + if ( !periodList.empty() ) + { + setPeriods( periodList ); + } -// std::cerr << "number of periods " << m_numberOfPeriods << std::endl; -// std::cerr << "number of spectra " << m_numberOfSpectra << std::endl; -// std::cerr << "number of bins " << m_numberOfBins << std::endl; + loadSpectraMap(); + + loadTimeRegimes(); return true; } @@ -129,6 +154,14 @@ namespace LiveData */ boost::shared_ptr ISISHistoDataListener::extractData() { + + if ( m_timeRegime < 0 ) + { + m_timeRegime = getTimeRegimeToLoad(); + g_log.debug() << "Loading spectra for time regime " << m_timeRegime + 1 << std::endl; + } + + if ( !m_daeHandle ) { g_log.error("DAE is not connected"); @@ -140,48 +173,48 @@ namespace LiveData // check that the dimensions haven't change since last time int numberOfPeriods = getInt("NPER"); - int numberOfSpectra = getInt("NSP1"); - int numberOfBins = getInt("NTC1"); - if ( numberOfPeriods != m_numberOfPeriods || numberOfSpectra != m_numberOfSpectra || - numberOfBins != m_numberOfBins) + if ( numberOfPeriods != m_numberOfPeriods ) { g_log.error("Data dimensions changed"); throw Kernel::Exception::FileError("Data dimensions changed", m_daeName); } + loadTimeRegimes(); + // buffer to read loat values in std::vector floatBuffer; - // read in the bin boundaries - getFloatArray( "RTCB1", floatBuffer, numberOfBins + 1); - // copy them into a MantidVec - m_bins.reset(new MantidVec(floatBuffer.begin(), floatBuffer.end())); - // read in the proton charge getFloatArray( "RRPB", floatBuffer, 32); const double protonCharge = floatBuffer[8]; // find out the number of histograms in the output workspace - const size_t numberOfHistograms = m_specList.empty() ? m_numberOfSpectra : m_specList.size(); + const size_t numberOfHistograms = m_specList.empty() ? m_numberOfSpectra[m_timeRegime] : m_specList.size(); // Create the 2D workspace for the output - auto localWorkspace = WorkspaceFactory::Instance().create( "Workspace2D", numberOfHistograms, numberOfBins + 1, numberOfBins ); + auto localWorkspace = WorkspaceFactory::Instance().create( + "Workspace2D", numberOfHistograms, m_numberOfBins[m_timeRegime] + 1, m_numberOfBins[m_timeRegime] + ); // Set the unit on the workspace to TOF localWorkspace->getAxis(0)->unit() = Kernel::UnitFactory::Instance().create("TOF"); localWorkspace->setYUnit("Counts"); - loadSpectraMap(localWorkspace); + localWorkspace->updateSpectraUsing(SpectrumDetectorMapping(m_specIDs, m_detIDs)); // cut the spectra numbers into chunks std::vector index, count; calculateIndicesForReading(index, count); + + int firstPeriod = m_periodList.empty() ? 0: m_periodList.front() - 1; // create a workspace group in case the data are multiperiod auto workspaceGroup = API::WorkspaceGroup_sptr( new API::WorkspaceGroup ); // loop over periods and spectra and fill in the output workspace for(int period = 0; period < m_numberOfPeriods; ++period) { - if ( period > 0 ) + if ( isPeriodIgnored( period ) ) continue; + + if ( period > firstPeriod ) { // create a new matrix workspace similar to the previous, copy over the instrument info localWorkspace = WorkspaceFactory::Instance().create( localWorkspace ); @@ -194,7 +227,7 @@ namespace LiveData workspaceIndex += count[i]; } - if (period == 0) + if (period == firstPeriod) { // Only run the Child Algorithms once runLoadInstrument( localWorkspace, getString("NAME") ); @@ -209,7 +242,7 @@ namespace LiveData } } - if ( m_numberOfPeriods > 1 ) + if ( m_numberOfPeriods > 1 && (m_periodList.empty() || m_periodList.size() > 1) ) { return workspaceGroup; } @@ -262,6 +295,22 @@ namespace LiveData } } + /** Sets a list of periods to be extracted. Default is reading all available periods. + * @param periodList :: A vector with period numbers. + */ + void ISISHistoDataListener::setPeriods(const std::vector& periodList) + { + // after listener has created its first workspace the period numbers cannot be changed + if ( !isInitilized ) + { + m_periodList = periodList; + if ( *std::max_element( m_periodList.begin(), m_periodList.end() ) > m_numberOfPeriods ) + { + throw std::invalid_argument( "Invalid period(s) specified. Maximum " + boost::lexical_cast(m_numberOfPeriods) ); + } + } + } + /** * Read an array of floats from the DAE * @param par :: Array name @@ -303,8 +352,10 @@ namespace LiveData */ void ISISHistoDataListener::calculateIndicesForReading(std::vector& index, std::vector& count) { + const int numberOfBins = m_numberOfBins[m_timeRegime]; + const int numberOfSpectra = m_numberOfSpectra[m_timeRegime]; // max number of spectra that could be read in in one go - int maxNumberOfSpectra = 1024 * 1024 / ( m_numberOfBins * (int)sizeof(int) ); + int maxNumberOfSpectra = 1024 * 1024 / ( numberOfBins * (int)sizeof(int) ); if ( maxNumberOfSpectra == 0 ) { maxNumberOfSpectra = 1; @@ -314,7 +365,7 @@ namespace LiveData { // make sure the chunk sizes < maxNumberOfSpectra int spec = 1; - int n = m_numberOfSpectra; + int n = numberOfSpectra; while( n > 0 ) { if ( n < maxNumberOfSpectra ) @@ -342,14 +393,16 @@ namespace LiveData specid_t next = m_specList[i]; if ( next - m_specList[i-1] > 1 || static_cast(i - i0) >= maxNumberOfSpectra ) { + int n = static_cast( i - i0 ); index.push_back( spec ); - count.push_back( static_cast( i - i0 ) ); + count.push_back( n ); i0 = i; spec = next; } } + int n = static_cast( m_specList.size() - i0 ); index.push_back( spec ); - count.push_back( static_cast( m_specList.size() - i0 ) ); + count.push_back( n ); } } @@ -364,14 +417,15 @@ namespace LiveData */ void ISISHistoDataListener::getData(int period, int index, int count, API::MatrixWorkspace_sptr workspace, size_t workspaceIndex) { - const size_t bufferSize = count * (m_numberOfBins + 1) * sizeof(int); + const int numberOfBins = m_numberOfBins[m_timeRegime]; + const size_t bufferSize = count * (numberOfBins + 1) * sizeof(int); std::vector dataBuffer( bufferSize ); // Read in spectra from DAE int ndims = 2, dims[2]; dims[0] = count; - dims[1] = m_numberOfBins + 1; + dims[1] = numberOfBins + 1; - int spectrumIndex = index + period * (m_numberOfSpectra + 1); + int spectrumIndex = index + period * (m_totalNumberOfSpectra + 1); if (IDCgetdat(m_daeHandle, spectrumIndex, count, dataBuffer.data(), dims, &ndims) != 0) { g_log.error("Unable to read DATA from DAE " + m_daeName); @@ -381,29 +435,25 @@ namespace LiveData for(size_t i = 0; i < static_cast(count); ++i) { size_t wi = workspaceIndex + i; - workspace->setX(wi, m_bins); + workspace->setX(wi, m_bins[m_timeRegime]); MantidVec& y = workspace->dataY( wi ); MantidVec& e = workspace->dataE( wi ); workspace->getSpectrum(wi)->setSpectrumNo(index + static_cast(i)); - size_t shift = i * (m_numberOfBins + 1) + 1; + size_t shift = i * (numberOfBins + 1) + 1; y.assign( dataBuffer.begin() + shift, dataBuffer.begin() + shift + y.size() ); std::transform( y.begin(), y.end(), e.begin(), dblSqrt ); } } /** Populate spectra-detector map - @param localWorkspace :: The workspace + * */ - void ISISHistoDataListener::loadSpectraMap(MatrixWorkspace_sptr localWorkspace) + void ISISHistoDataListener::loadSpectraMap() { // Read in the number of detectors int ndet = getInt( "NDET" ); - - std::vector udet; - std::vector spec; - getIntArray( "UDET", udet, ndet); - getIntArray( "SPEC", spec, ndet); - localWorkspace->updateSpectraUsing(SpectrumDetectorMapping(spec, udet)); + getIntArray( "UDET", m_detIDs, ndet); + getIntArray( "SPEC", m_specIDs, ndet); } /** Run the Child Algorithm LoadInstrument (or LoadInstrumentFromRaw). @@ -438,11 +488,165 @@ namespace LiveData } } + /** + * Determine the number of time regimes. + * Load time regime for each spectrum, bin boundaries and number of spectra for each regime. + */ + void ISISHistoDataListener::loadTimeRegimes() + { + // Expecting loadSpectraMap() to be called first. + if ( m_specIDs.empty() || m_detIDs.empty() ) + { + throw std::logic_error("Spectra-detector mapping must be loaded first."); + } + + // prefix for DAE command to get the number of time channels (bins) + const std::string ntcPrefix = "NTC"; + // prefix for DAE command to get the time channel boundaries + const std::string rtcbPrefix = "RTCB"; + // prefix for DAE command to get the number of spectra + const std::string nspPrefix = "NSP"; + + // At the moment we cannot get the number of time regimes from the dae. + // It will be possible in the future when Freddie adds a parameter for it. + // For now we assume that two regimes are possible. The first must always be present. + // If there is nonzero number of time channels for the second one then we have two regimes. + for(size_t tr = 0; tr < 2; ++tr) + { + const std::string regime = boost::lexical_cast( tr + 1 ); + // get number of bins in this regime + int nbins = getInt( ntcPrefix + regime ); + if ( nbins == 0 ) + { + if ( tr == 0 ) + { + throw std::runtime_error("Didn't find any time bins for time regime 1."); + } + break; + } + // get number of spectra in this time regime + int nspec = getInt( nspPrefix + regime ); + + // if it's first call of this method populate the member variables + if ( m_bins.size() == tr ) + { + m_numberOfBins.push_back( nbins ); + m_numberOfSpectra.push_back( nspec ); + // buffer to read float values in + std::vector floatBuffer; + + if ( tr == 0 ) + { + // read in the bin boundaries + getFloatArray( rtcbPrefix + regime, floatBuffer, nbins + 1); + } + else + { + // In principle bin boundaries for all regimes should be loaded + // the same way as for tr == 0 but because of a bug in the dae software + // it only works for regime 1. What follows is a workaround. + + // number of monitors + int nmon = getInt( "NMON" ); + // indices of monitors in m_detIDs and m_specIDs ( +1 ) + std::vector monitorIndices; + getIntArray("MDET",monitorIndices,nmon); + + // we make an assumtion that regime 2 is used for monitors only + if ( monitorIndices.empty() ) + { + throw std::runtime_error("Time regime 2 is expected to be used for monitors but none are found."); + } + + m_monitorSpectra.resize( nmon ); + for(size_t i = 0; i < m_monitorSpectra.size(); ++i) + { + m_monitorSpectra[i] = m_specIDs[monitorIndices[i] - 1]; + } + + for(auto mon = m_monitorSpectra.begin(); mon != m_monitorSpectra.end(); ++mon) + { + g_log.information() << "Monitor spectrum " << *mon << std::endl; + } + + const std::string detRTCB = rtcbPrefix + "_" + boost::lexical_cast( m_monitorSpectra.front() ); + // read in the bin boundaries + getFloatArray( detRTCB, floatBuffer, nbins + 1); + } + + // copy them into a MantidVec + m_bins.push_back(boost::make_shared(floatBuffer.begin(), floatBuffer.end())); + } + else + { + // check that dimensions haven't changed + if ( nspec != m_numberOfSpectra[tr] || nbins != m_numberOfBins[tr]) + { + g_log.error("Data dimensions changed"); + throw Kernel::Exception::FileError("Data dimensions changed", m_daeName); + } + } + } + g_log.information() << "Number of time regimes " << m_bins.size() << std::endl; + assert( m_numberOfBins.size() == m_numberOfSpectra.size() ); + for(size_t i = 0; i < m_numberOfBins.size(); ++i) + { + g_log.information() << "Number of bins in time regime " << i + 1 << " is " << m_numberOfBins[i] << std::endl; + g_log.information() << "Number of spectra in time regime " << i + 1 << " is " << m_numberOfSpectra[i] << std::endl; + } + + // find the total number of spectra in all regimes + m_totalNumberOfSpectra = std::accumulate(m_numberOfSpectra.begin(),m_numberOfSpectra.end(),0); + } + + /** + * Get the time regime for which the data should be loaded. + * If spectrum list isn't specified (all data) return regime 1. + * If spectrum list is given return the common regime for all + * spectra in the list. If regimes are mixed throw invalid_argument. + * @return :: 0 (regime 1) or 1 (regime 2). + */ + int ISISHistoDataListener::getTimeRegimeToLoad() const + { + if ( ! m_specList.empty() ) + { + if ( m_monitorSpectra.empty() ) return 0; + int regime = -1; + for( auto specIt = m_specList.begin(); specIt != m_specList.end(); ++specIt ) + { + bool isMonitor = std::find(m_monitorSpectra.begin(),m_monitorSpectra.end(), *specIt) != m_monitorSpectra.end(); + if ( !isMonitor && *specIt > m_totalNumberOfSpectra ) throw std::invalid_argument("Invalid spectra index is found: " + boost::lexical_cast(*specIt)); + int specRegime = isMonitor? 1 : 0; + if ( regime < 0 ) + { + regime = specRegime; + } + else if ( specRegime != regime ) + { + throw std::invalid_argument("Cannot mix spectra in different time regimes."); + } + } + return regime; + } + return 0; + } + /// Personal wrapper for sqrt to allow msvs to compile double ISISHistoDataListener::dblSqrt(double in) { return sqrt( in ); } + /** + * Check if a data period should be ignored. + * @param period :: Period to check. + * @return :: True to ignore the period. + */ + bool ISISHistoDataListener::isPeriodIgnored(int period) const + { + if ( m_periodList.empty() ) return false; + return std::find( m_periodList.begin(), m_periodList.end(), period + 1 ) == m_periodList.end(); + } + } // namespace LiveData } // namespace Mantid diff --git a/Code/Mantid/Framework/LiveData/src/ISISLiveEventDataListener.cpp b/Code/Mantid/Framework/LiveData/src/ISISLiveEventDataListener.cpp index b7ff3a96e20f..e8b1c5d5f159 100644 --- a/Code/Mantid/Framework/LiveData/src/ISISLiveEventDataListener.cpp +++ b/Code/Mantid/Framework/LiveData/src/ISISLiveEventDataListener.cpp @@ -39,7 +39,11 @@ DECLARE_LISTENER(ISISLiveEventDataListener) */ ISISLiveEventDataListener::ISISLiveEventDataListener():API::ILiveListener(), m_isConnected(false), - m_stopThread(false) + m_stopThread(false), + m_runNumber(0), + m_daeHandle(), + m_numberOfPeriods(0), + m_numberOfSpectra(0) { m_warnings["period"] = "Period number is outside the range. Changed to 0."; } diff --git a/Code/Mantid/Framework/LiveData/src/LiveDataAlgorithm.cpp b/Code/Mantid/Framework/LiveData/src/LiveDataAlgorithm.cpp index ad37de38a93e..f51ff65dfa77 100644 --- a/Code/Mantid/Framework/LiveData/src/LiveDataAlgorithm.cpp +++ b/Code/Mantid/Framework/LiveData/src/LiveDataAlgorithm.cpp @@ -3,6 +3,7 @@ #include "MantidKernel/DateAndTime.h" #include "MantidKernel/ListValidator.h" #include "MantidKernel/FacilityInfo.h" +#include "MantidKernel/ArrayProperty.h" #include "MantidAPI/LiveListenerFactory.h" #include "MantidAPI/AlgorithmManager.h" #include "boost/tokenizer.hpp" @@ -165,7 +166,7 @@ namespace LiveData // Not stored? Need to create it std::string inst = this->getPropertyValue("Instrument"); - m_listener = LiveListenerFactory::Instance().create(inst, true); + m_listener = LiveListenerFactory::Instance().create(inst, true, this); // Start at the given date/time m_listener->start( this->getStartTime() ); diff --git a/Code/Mantid/Framework/LiveData/src/LoadDAE/idc.cpp b/Code/Mantid/Framework/LiveData/src/LoadDAE/idc.cpp index adb61df6be63..b6b8f1b05205 100644 --- a/Code/Mantid/Framework/LiveData/src/LoadDAE/idc.cpp +++ b/Code/Mantid/Framework/LiveData/src/LoadDAE/idc.cpp @@ -106,6 +106,7 @@ static int getdat(idc_handle_t fh, int ifsn, int nos, int** value, int dims_arra if (do_alloc) { stat = isisds_recv_command_alloc(fh->s, &command, (void**)value, &ret_type, dims_array, ndims); + free(command); } else { @@ -157,6 +158,7 @@ static int IDCgetpar(idc_handle_t fh, const char* name, void** value, ISISDSData if (do_alloc) { stat = isisds_recv_command_alloc(fh->s, &command, value, &ret_type, dims_array, ndims); + free(command); } else { diff --git a/Code/Mantid/Framework/LiveData/src/LoadDAE/isisds_command.cpp b/Code/Mantid/Framework/LiveData/src/LoadDAE/isisds_command.cpp index 99a3f6288342..0fd2402a6c91 100644 --- a/Code/Mantid/Framework/LiveData/src/LoadDAE/isisds_command.cpp +++ b/Code/Mantid/Framework/LiveData/src/LoadDAE/isisds_command.cpp @@ -167,6 +167,7 @@ SOCKET isisds_send_open(const char* host, ISISDSAccessMode access_type, uint16_t op.ver_major = ISISDS_MAJOR_VER; op.ver_minor = ISISDS_MINOR_VER; op.pid = 0; + op.pad[0] = 0; op.access_type = access_type; strncpy(op.user, "faa", sizeof(op.user)); strncpy(op.host, "localhost", sizeof(op.host)); @@ -176,9 +177,11 @@ SOCKET isisds_send_open(const char* host, ISISDSAccessMode access_type, uint16_t closesocket(s); return INVALID_SOCKET; } + comm = NULL; if (isisds_recv_command_alloc(s, &comm, (void**)&comm_data, &data_type, dims_array, &ndims) <= 0) { closesocket(s); + free(comm); return INVALID_SOCKET; } if (comm_data != NULL) @@ -255,7 +258,9 @@ int isisds_send_command(SOCKET s, const char* command, const void* data, ISISDSD } comm.len = sizeof(comm) + len_data; comm.type = type; - strncpy(comm.command, command, sizeof(comm.command)); + // fixing coverity warning: comm.command is filled with 0's by memset(&comm, 0, sizeof(comm)); above + // if strncpy reaches the limit the last character in comm.command is still '\0' + strncpy(comm.command, command, sizeof(comm.command)-1); clear_replies(s); n = send(s, (char*)&comm, sizeof(comm), 0); if ( (n == sizeof(comm)) && (data != NULL) && (len_data > 0) ) diff --git a/Code/Mantid/Framework/LiveData/src/StartLiveData.cpp b/Code/Mantid/Framework/LiveData/src/StartLiveData.cpp index cb4b79ba3d7c..56ffacde6e2a 100644 --- a/Code/Mantid/Framework/LiveData/src/StartLiveData.cpp +++ b/Code/Mantid/Framework/LiveData/src/StartLiveData.cpp @@ -5,6 +5,7 @@ #include "MantidAPI/AlgorithmManager.h" #include "MantidAPI/AlgorithmProxy.h" #include "MantidAPI/AlgorithmProperty.h" +#include "MantidAPI/LiveListenerFactory.h" #include @@ -19,7 +20,11 @@ namespace LiveData // Register the algorithm into the AlgorithmFactory DECLARE_ALGORITHM(StartLiveData) - +namespace +{ + /// name for a group of properties that get copied from the listener + const char* listenerPropertyGroup = "ListenerProperties"; +} //---------------------------------------------------------------------------------------------- /** Constructor @@ -142,7 +147,6 @@ namespace LiveData Workspace_sptr accumWS = loadAlg->getProperty("AccumulationWorkspace"); this->setProperty("AccumulationWorkspace", accumWS); - double UpdateEvery = this->getProperty("UpdateEvery"); if (UpdateEvery > 0) { @@ -172,6 +176,39 @@ namespace LiveData } + /** + * After Instrument property is set copy any properties that the instrument's + * listener may have to this algorithm. + */ + void StartLiveData::afterPropertySet(const std::string& propName) + { + if ( propName == "Instrument" ) + { + // remove old listener's properties + auto properties = getProperties(); + for(auto prop = properties.begin(); prop != properties.end(); ++prop) + { + if ( (**prop).getGroup() == listenerPropertyGroup ) + { + removeProperty( (**prop).name() ); + } + } + // add new listener's properties + auto listener = LiveListenerFactory::Instance().create( getPropertyValue(propName), false ); + auto propertyManagerListener = boost::dynamic_pointer_cast( listener ); + if ( propertyManagerListener ) + { + auto properties = propertyManagerListener->getProperties(); + for(auto prop = properties.begin(); prop != properties.end(); ++prop) + { + propertyManagerListener->removeProperty( (**prop).name(), false ); + declareProperty( *prop ); + (**prop).setGroup( listenerPropertyGroup ); + } + } + } + } + } // namespace LiveData diff --git a/Code/Mantid/Framework/LiveData/test/ISISHistoDataListenerTest.h b/Code/Mantid/Framework/LiveData/test/ISISHistoDataListenerTest.h index b03e42ae5441..ade476de5954 100644 --- a/Code/Mantid/Framework/LiveData/test/ISISHistoDataListenerTest.h +++ b/Code/Mantid/Framework/LiveData/test/ISISHistoDataListenerTest.h @@ -9,6 +9,7 @@ #include "MantidAPI/WorkspaceFactory.h" #include "MantidAPI/AnalysisDataService.h" #include "MantidAPI/WorkspaceGroup.h" +#include "MantidKernel/ArrayProperty.h" #include "MantidTestHelpers/FacilityHelper.h" #include @@ -38,7 +39,6 @@ class ISISHistoDataListenerTest : public CxxTest::TestSuite { // cannot make it work for linux #ifdef _WIN32 - //system("pause"); FacilityHelper::ScopedFacilities loadTESTFacility("IDFs_for_UNIT_TESTING/UnitTestFacilities.xml", "TEST"); FakeISISHistoDAE dae; @@ -46,15 +46,18 @@ class ISISHistoDataListenerTest : public CxxTest::TestSuite dae.setProperty("NPeriods",1); auto res = dae.executeAsync(); - auto listener = Mantid::API::LiveListenerFactory::Instance().create("TESTHISTOLISTENER",true); + Kernel::PropertyManager props; + props.declareProperty(new Kernel::ArrayProperty("SpectraList","")); + int s[] = {1,2,3,10,11,95,96,97,98,99,100}; + std::vector specs; + specs.assign( s, s + 11 ); + props.setProperty( "SpectraList", specs ); + + auto listener = Mantid::API::LiveListenerFactory::Instance().create("TESTHISTOLISTENER",true,&props); TS_ASSERT( listener ); TSM_ASSERT("Listener has failed to connect", listener->isConnected() ); if (!listener->isConnected()) return; - int s[] = {1,2,3,10,11,95,96,97,98,99,100}; - std::vector specs; - specs.assign( s, s + 11 ); - listener->setSpectra( specs ); auto outWS = listener->extractData(); auto ws = boost::dynamic_pointer_cast( outWS ); //TS_ASSERT( ws ); @@ -124,9 +127,9 @@ class ISISHistoDataListenerTest : public CxxTest::TestSuite } + void test_Receiving_multiperiod_data() { - #ifdef _WIN32 FacilityHelper::ScopedFacilities loadTESTFacility("IDFs_for_UNIT_TESTING/UnitTestFacilities.xml", "TEST"); @@ -239,6 +242,169 @@ class ISISHistoDataListenerTest : public CxxTest::TestSuite TS_ASSERT( true ); #endif } + + void test_Receiving_selected_periods() + { +#ifdef _WIN32 + FacilityHelper::ScopedFacilities loadTESTFacility("IDFs_for_UNIT_TESTING/UnitTestFacilities.xml", "TEST"); + + FakeISISHistoDAE dae; + dae.initialize(); + dae.setProperty("NSpectra",30); + dae.setProperty("NPeriods",4); + auto res = dae.executeAsync(); + + Kernel::PropertyManager props; + props.declareProperty(new Kernel::ArrayProperty("PeriodList")); + std::vector periods(2); + periods[0] = 2; + periods[1] = 3; + props.setProperty( "PeriodList", periods ); + + auto listener = Mantid::API::LiveListenerFactory::Instance().create("TESTHISTOLISTENER",true,&props); + TS_ASSERT( listener ); + TSM_ASSERT("Listener has failed to connect", listener->isConnected() ); + if (!listener->isConnected()) return; + + auto outWS = listener->extractData(); + auto group = boost::dynamic_pointer_cast( outWS ); + TS_ASSERT( group ); + TS_ASSERT_EQUALS( group->size(), 2 ); + + auto ws = boost::dynamic_pointer_cast( group->getItem(0) ); + TS_ASSERT( ws ); + auto y = ws->readY( 2 ); + TS_ASSERT_EQUALS( y[0], 1003 ); + TS_ASSERT_EQUALS( y[5], 1003 ); + TS_ASSERT_EQUALS( y[29], 1003 ); + + ws = boost::dynamic_pointer_cast( group->getItem(1) ); + TS_ASSERT( ws ); + y = ws->readY( 2 ); + TS_ASSERT_EQUALS( y[0], 2003 ); + TS_ASSERT_EQUALS( y[5], 2003 ); + TS_ASSERT_EQUALS( y[29], 2003 ); + + dae.cancel(); + res.wait(); +#else + TS_ASSERT( true ); +#endif + } + + void test_Receiving_selected_monitors() + { +#ifdef _WIN32 + FacilityHelper::ScopedFacilities loadTESTFacility("IDFs_for_UNIT_TESTING/UnitTestFacilities.xml", "TEST"); + + FakeISISHistoDAE dae; + dae.initialize(); + dae.setProperty("NSpectra",10); + dae.setProperty("NPeriods",4); + dae.setProperty("NBins",20); + auto res = dae.executeAsync(); + + Kernel::PropertyManager props; + props.declareProperty(new Kernel::ArrayProperty("SpectraList")); + props.declareProperty(new Kernel::ArrayProperty("PeriodList")); + props.setProperty( "PeriodList", "1,3" ); + // FakeISISHistoDAE has 3 monitors with spectra numbers NSpectra+1, NSpectra+2, NSpectra+2 + props.setProperty( "SpectraList", "11-13" ); + + auto listener = Mantid::API::LiveListenerFactory::Instance().create("TESTHISTOLISTENER",true,&props); + TS_ASSERT( listener ); + TSM_ASSERT("Listener has failed to connect", listener->isConnected() ); + if (!listener->isConnected()) return; + + auto outWS = listener->extractData(); + auto group = boost::dynamic_pointer_cast( outWS ); + TS_ASSERT( group ); + TS_ASSERT_EQUALS( group->size(), 2 ); + + auto ws = boost::dynamic_pointer_cast( group->getItem(0) ); + TS_ASSERT( ws ); + auto y = ws->readY( 2 ); + // monitors in FakeISISHistoDAE have twice the number of bins of normal spectra + TS_ASSERT_EQUALS( y.size(), 40 ); + TS_ASSERT_EQUALS( y[0], 13 ); + TS_ASSERT_EQUALS( y[5], 13 ); + TS_ASSERT_EQUALS( y[29], 13 ); + + ws = boost::dynamic_pointer_cast( group->getItem(1) ); + TS_ASSERT( ws ); + y = ws->readY( 2 ); + TS_ASSERT_EQUALS( y.size(), 40 ); + TS_ASSERT_EQUALS( y[0], 2013 ); + TS_ASSERT_EQUALS( y[5], 2013 ); + TS_ASSERT_EQUALS( y[29], 2013 ); + + dae.cancel(); + res.wait(); +#else + TS_ASSERT( true ); +#endif + } + + void test_invalid_spectra_numbers() + { +#ifdef _WIN32 + FacilityHelper::ScopedFacilities loadTESTFacility("IDFs_for_UNIT_TESTING/UnitTestFacilities.xml", "TEST"); + + FakeISISHistoDAE dae; + dae.initialize(); + dae.setProperty("NSpectra",10); + dae.setProperty("NPeriods",4); + dae.setProperty("NBins",20); + auto res = dae.executeAsync(); + + Kernel::PropertyManager props; + props.declareProperty(new Kernel::ArrayProperty("SpectraList")); + props.declareProperty(new Kernel::ArrayProperty("PeriodList")); + props.setProperty( "PeriodList", "1,3" ); + // FakeISISHistoDAE has 3 monitors with spectra numbers NSpectra+1, NSpectra+2, NSpectra+2 + props.setProperty( "SpectraList", "14-17" ); + + auto listener = Mantid::API::LiveListenerFactory::Instance().create("TESTHISTOLISTENER",true,&props); + TS_ASSERT( listener ); + TSM_ASSERT("Listener has failed to connect", listener->isConnected() ); + if (!listener->isConnected()) return; + + TS_ASSERT_THROWS( auto outWS = listener->extractData(), std::invalid_argument ); + + dae.cancel(); + res.wait(); +#else + TS_ASSERT( true ); +#endif + } + + + void test_no_period() + { +#ifdef _WIN32 + FacilityHelper::ScopedFacilities loadTESTFacility("IDFs_for_UNIT_TESTING/UnitTestFacilities.xml", "TEST"); + + FakeISISHistoDAE dae; + dae.initialize(); + dae.setProperty("NPeriods",4); + auto res = dae.executeAsync(); + + Kernel::PropertyManager props; + props.declareProperty(new Kernel::ArrayProperty("PeriodList")); + std::vector periods(2); + periods[0] = 2; + periods[1] = 5; // this period doesn't exist in dae + props.setProperty( "PeriodList", periods ); + + TS_ASSERT_THROWS( auto listener = Mantid::API::LiveListenerFactory::Instance().create("TESTHISTOLISTENER",true,&props), std::invalid_argument ); + + dae.cancel(); + res.wait(); +#else + TS_ASSERT( true ); +#endif + } + }; diff --git a/Code/Mantid/Framework/MDAlgorithms/CMakeLists.txt b/Code/Mantid/Framework/MDAlgorithms/CMakeLists.txt index d4952e2ba98c..ab0039013900 100644 --- a/Code/Mantid/Framework/MDAlgorithms/CMakeLists.txt +++ b/Code/Mantid/Framework/MDAlgorithms/CMakeLists.txt @@ -15,28 +15,30 @@ set ( SRC_FILES src/ConvertToDiffractionMDWorkspace.cpp src/ConvertToDiffractionMDWorkspace2.cpp src/ConvertToMD.cpp - src/ConvertToMDParent.cpp src/ConvertToMDMinMaxGlobal.cpp - src/ConvertToMDMinMaxLocal.cpp + src/ConvertToMDMinMaxLocal.cpp + src/ConvertToMDParent.cpp src/CreateMDHistoWorkspace.cpp src/CreateMDWorkspace.cpp src/DivideMD.cpp src/EqualToMD.cpp + src/EvaluateMDFunction.cpp src/ExponentialMD.cpp src/FakeMDEventData.cpp src/FindPeaksMD.cpp src/GreaterThanMD.cpp src/IDynamicRebinning.cpp + src/IntegrateFlux.cpp src/IntegratePeaksMD.cpp src/IntegratePeaksMD2.cpp src/InvalidParameter.cpp src/InvalidParameterParser.cpp src/LessThanMD.cpp + src/LoadILLAscii.cpp + src/LoadILLAsciiHelper.cpp src/LoadMD.cpp src/LoadSQW.cpp src/LogarithmMD.cpp - src/LoadILLAscii.cpp - src/LoadILLAsciiHelper.cpp src/MaskMD.cpp src/MergeMD.cpp src/MergeMDFiles.cpp @@ -53,15 +55,16 @@ set ( SRC_FILES src/Quantification/ForegroundModelFactory.cpp src/Quantification/MDResolutionConvolution.cpp src/Quantification/MDResolutionConvolutionFactory.cpp + src/Quantification/Models/MullerAnsatz.cpp src/Quantification/Models/QCoordinate.cpp src/Quantification/Models/Strontium122.cpp - src/Quantification/Models/MullerAnsatz.cpp src/Quantification/Resolution/ModeratorChopperResolution.cpp src/Quantification/Resolution/TobyFitBMatrix.cpp src/Quantification/Resolution/TobyFitResolutionModel.cpp src/Quantification/Resolution/TobyFitYVector.cpp src/Quantification/ResolutionConvolvedCrossSection.cpp src/Quantification/SimulateResolutionConvolvedModel.cpp + src/MDNormSXD.cpp src/SaveMD.cpp src/SaveZODS.cpp src/SetMDUsingMask.cpp @@ -93,30 +96,32 @@ set ( INC_FILES inc/MantidMDAlgorithms/ConvertToDiffractionMDWorkspace.h inc/MantidMDAlgorithms/ConvertToDiffractionMDWorkspace2.h inc/MantidMDAlgorithms/ConvertToMD.h - inc/MantidMDAlgorithms/ConvertToMDParent.h inc/MantidMDAlgorithms/ConvertToMDMinMaxGlobal.h - inc/MantidMDAlgorithms/ConvertToMDMinMaxLocal.h + inc/MantidMDAlgorithms/ConvertToMDMinMaxLocal.h + inc/MantidMDAlgorithms/ConvertToMDParent.h inc/MantidMDAlgorithms/CreateMDHistoWorkspace.h inc/MantidMDAlgorithms/CreateMDWorkspace.h inc/MantidMDAlgorithms/DivideMD.h inc/MantidMDAlgorithms/DllConfig.h inc/MantidMDAlgorithms/EqualToMD.h + inc/MantidMDAlgorithms/EvaluateMDFunction.h inc/MantidMDAlgorithms/ExponentialMD.h inc/MantidMDAlgorithms/FakeMDEventData.h inc/MantidMDAlgorithms/FindPeaksMD.h + inc/MantidMDAlgorithms/GSLFunctions.h inc/MantidMDAlgorithms/GreaterThanMD.h - inc/MantidMDAlgorithms/GSLFunctions.h inc/MantidMDAlgorithms/IDynamicRebinning.h + inc/MantidMDAlgorithms/IntegrateFlux.h inc/MantidMDAlgorithms/IntegratePeaksMD.h inc/MantidMDAlgorithms/IntegratePeaksMD2.h inc/MantidMDAlgorithms/InvalidParameter.h inc/MantidMDAlgorithms/InvalidParameterParser.h inc/MantidMDAlgorithms/LessThanMD.h + inc/MantidMDAlgorithms/LoadILLAscii.h + inc/MantidMDAlgorithms/LoadILLAsciiHelper.h inc/MantidMDAlgorithms/LoadMD.h inc/MantidMDAlgorithms/LoadSQW.h inc/MantidMDAlgorithms/LogarithmMD.h - inc/MantidMDAlgorithms/LoadILLAscii.h - inc/MantidMDAlgorithms/LoadILLAsciiHelper.h inc/MantidMDAlgorithms/MaskMD.h inc/MantidMDAlgorithms/MergeMD.h inc/MantidMDAlgorithms/MergeMDFiles.h @@ -133,15 +138,16 @@ set ( INC_FILES inc/MantidMDAlgorithms/Quantification/ForegroundModelFactory.h inc/MantidMDAlgorithms/Quantification/MDResolutionConvolution.h inc/MantidMDAlgorithms/Quantification/MDResolutionConvolutionFactory.h + inc/MantidMDAlgorithms/Quantification/Models/MullerAnsatz.h inc/MantidMDAlgorithms/Quantification/Models/QCoordinate.h inc/MantidMDAlgorithms/Quantification/Models/Strontium122.h - inc/MantidMDAlgorithms/Quantification/Models/MullerAnsatz.h inc/MantidMDAlgorithms/Quantification/Resolution/ModeratorChopperResolution.h inc/MantidMDAlgorithms/Quantification/Resolution/TobyFitBMatrix.h inc/MantidMDAlgorithms/Quantification/Resolution/TobyFitResolutionModel.h inc/MantidMDAlgorithms/Quantification/Resolution/TobyFitYVector.h inc/MantidMDAlgorithms/Quantification/ResolutionConvolvedCrossSection.h inc/MantidMDAlgorithms/Quantification/SimulateResolutionConvolvedModel.h + inc/MantidMDAlgorithms/MDNormSXD.h inc/MantidMDAlgorithms/SaveMD.h inc/MantidMDAlgorithms/SaveZODS.h inc/MantidMDAlgorithms/SetMDUsingMask.h @@ -165,8 +171,8 @@ set ( TEST_FILES AndMDTest.h BooleanBinaryOperationMDTest.h CachedExperimentInfoTest.h - CentroidPeaksMDTest.h CentroidPeaksMD2Test.h + CentroidPeaksMDTest.h CloneMDWorkspaceTest.h CompareMDWorkspacesTest.h ConvertEventsToMDTest.h @@ -175,21 +181,23 @@ set ( TEST_FILES ConvertToDiffractionMDWorkspaceTest.h ConvertToMDComponentsTest.h ConvertToMDMinMaxGlobalTest.h - ConvertToMDMinMaxLocalTest.h + ConvertToMDMinMaxLocalTest.h ConvertToMDTest.h ConvertToQ3DdETest.h CreateMDHistoWorkspaceTest.h CreateMDWorkspaceTest.h DivideMDTest.h EqualToMDTest.h + EvaluateMDFunctionTest.h ExponentialMDTest.h FakeMDEventDataTest.h FindPeaksMDTest.h FitResolutionConvolvedModelTest.h ForegroundModelTest.h GreaterThanMDTest.h - IntegratePeaksMDTest.h + IntegrateFluxTest.h IntegratePeaksMD2Test.h + IntegratePeaksMDTest.h InvalidParameterParserTest.h InvalidParameterTest.h LessThanMDTest.h @@ -202,14 +210,15 @@ set ( TEST_FILES MergeMDTest.h MinusMDTest.h ModeratorChopperResolutionTest.h + MullerAnsatzTest.h MultiplyMDTest.h - MullerAnsatzTest.h NotMDTest.h OrMDTest.h PlusMDTest.h PowerMDTest.h PreprocessDetectorsToMDTest.h ResolutionConvolvedCrossSectionTest.h + MDNormSXDTest.h SaveMDTest.h SaveZODSTest.h SetMDUsingMaskTest.h diff --git a/Code/Mantid/Framework/MDAlgorithms/inc/MantidMDAlgorithms/EvaluateMDFunction.h b/Code/Mantid/Framework/MDAlgorithms/inc/MantidMDAlgorithms/EvaluateMDFunction.h new file mode 100644 index 000000000000..ed2ee59597c9 --- /dev/null +++ b/Code/Mantid/Framework/MDAlgorithms/inc/MantidMDAlgorithms/EvaluateMDFunction.h @@ -0,0 +1,56 @@ +#ifndef MANTID_MDALGORITHMS_EVALUATEMDFUNCTION_H_ +#define MANTID_MDALGORITHMS_EVALUATEMDFUNCTION_H_ + +#include "MantidKernel/System.h" +#include "MantidAPI/Algorithm.h" + +namespace Mantid +{ +namespace MDAlgorithms +{ + + /** EvaluateMDFunction : TODO: DESCRIPTION + + Copyright © 2014 ISIS Rutherford Appleton Laboratory & NScD Oak Ridge National Laboratory + + This file is part of Mantid. + + Mantid is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + Mantid is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + + File change history is stored at: + Code Documentation is available at: + */ + class DLLExport EvaluateMDFunction : public API::Algorithm + { + public: + EvaluateMDFunction(); + virtual ~EvaluateMDFunction(); + + virtual const std::string name() const {return "EvaluateMDFunction";} + virtual int version() const; + virtual const std::string category() const; + virtual const std::string summary() const; + + private: + void init(); + void exec(); + + + }; + + +} // namespace MDAlgorithms +} // namespace Mantid + +#endif /* MANTID_MDALGORITHMS_EVALUATEMDFUNCTION_H_ */ diff --git a/Code/Mantid/Framework/MDAlgorithms/inc/MantidMDAlgorithms/IntegrateFlux.h b/Code/Mantid/Framework/MDAlgorithms/inc/MantidMDAlgorithms/IntegrateFlux.h new file mode 100644 index 000000000000..0b652515c80f --- /dev/null +++ b/Code/Mantid/Framework/MDAlgorithms/inc/MantidMDAlgorithms/IntegrateFlux.h @@ -0,0 +1,65 @@ +#ifndef MANTID_MDALGORITHMS_INTEGRATEFLUX_H_ +#define MANTID_MDALGORITHMS_INTEGRATEFLUX_H_ + +#include "MantidKernel/System.h" +#include "MantidAPI/Algorithm.h" + +namespace Mantid +{ + +namespace DataObjects +{ + class EventWorkspace; +} + +namespace MDAlgorithms +{ + + /** Algorithm IntegrateFlux. + + Calculates indefinite integral of the spectra in the input workspace sampled at a regular grid. + The input workspace is expected to be an event workspace with weighted-no-time events. + + Copyright © 2014 ISIS Rutherford Appleton Laboratory & NScD Oak Ridge National Laboratory + + This file is part of Mantid. + + Mantid is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + Mantid is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + + File change history is stored at: + Code Documentation is available at: + */ + class DLLExport IntegrateFlux : public API::Algorithm + { + public: + + virtual const std::string name() const; + virtual int version() const; + virtual const std::string category() const; + virtual const std::string summary() const; + + private: + void init(); + void exec(); + + boost::shared_ptr createOutputWorkspace( const DataObjects::EventWorkspace& eventWS, size_t nX ) const; + void integrateSpectra( const DataObjects::EventWorkspace& eventWS, API::MatrixWorkspace &integrWS ); + + }; + + +} // namespace MDAlgorithms +} // namespace Mantid + +#endif /* MANTID_MDALGORITHMS_INTEGRATEFLUX_H_ */ \ No newline at end of file diff --git a/Code/Mantid/Framework/MDAlgorithms/inc/MantidMDAlgorithms/IntegratePeaksMD2.h b/Code/Mantid/Framework/MDAlgorithms/inc/MantidMDAlgorithms/IntegratePeaksMD2.h index b8c77ee874e9..31ecc80fa710 100644 --- a/Code/Mantid/Framework/MDAlgorithms/inc/MantidMDAlgorithms/IntegratePeaksMD2.h +++ b/Code/Mantid/Framework/MDAlgorithms/inc/MantidMDAlgorithms/IntegratePeaksMD2.h @@ -48,6 +48,7 @@ namespace MDAlgorithms /// Calculate if this Q is on a detector bool detectorQ(Mantid::Kernel::V3D QLabFrame, double PeakRadius); + void runMaskDetectors(Mantid::DataObjects::PeaksWorkspace_sptr peakWS, std::string property, std::string values); /// Instrument reference Geometry::Instrument_const_sptr inst; diff --git a/Code/Mantid/Framework/MDAlgorithms/inc/MantidMDAlgorithms/MDNormSXD.h b/Code/Mantid/Framework/MDAlgorithms/inc/MantidMDAlgorithms/MDNormSXD.h new file mode 100644 index 000000000000..1c791f73ff31 --- /dev/null +++ b/Code/Mantid/Framework/MDAlgorithms/inc/MantidMDAlgorithms/MDNormSXD.h @@ -0,0 +1,84 @@ +#ifndef MANTID_MDALGORITHMS_MDNORMSXD_H_ +#define MANTID_MDALGORITHMS_MDNORMSXD_H_ + +#include "MantidKernel/System.h" +#include "MantidAPI/Algorithm.h" +#include "MantidMDAlgorithms/SlicingAlgorithm.h" +namespace Mantid +{ +namespace DataObjects +{ + class EventWorkspace; +} +namespace MDAlgorithms +{ + + /** MDNormSXD : Generate MD normalization for single crystal diffraction + + Copyright © 2014 ISIS Rutherford Appleton Laboratory & NScD Oak Ridge National Laboratory + + This file is part of Mantid. + + Mantid is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + Mantid is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + + File change history is stored at: + Code Documentation is available at: + */ + class DLLExport MDNormSXD :public SlicingAlgorithm + { + public: + MDNormSXD(); + virtual ~MDNormSXD(); + + virtual const std::string name() const; + virtual int version() const; + virtual const std::string category() const; + virtual const std::string summary() const; + + private: + void init(); + void exec(); + + /// function to calculate intersections of teh trajectory with MDBoxes + std::vector calculateIntersections(Mantid::Geometry::IDetector_const_sptr detector); + /// Integrate flux spectra + void integrateFlux( const DataObjects::EventWorkspace& flux, API::MatrixWorkspace &integrFlux ); + /// Use interpolation to calculate integrals + void calcIntegralsForIntersections( const std::vector &xValues, const API::MatrixWorkspace &integrFlux, size_t sp, std::vector &yValues ) const; + + /// number of MD dimensions + size_t m_nDims; + /// Normalization workspace + Mantid::MDEvents::MDHistoWorkspace_sptr m_normWS; + /// Input workspace + Mantid::API::IMDEventWorkspace_sptr m_inputWS; + ///limits for h,k,l dimensions + coord_t hMin,hMax,kMin,kMax,lMin,lMax; + ///flag for integrated h,k,l dimensions + bool hIntegrated,kIntegrated,lIntegrated; + ///(2*PiRUBW)^-1 + Mantid::Kernel::DblMatrix transf; + /// limits for momentum + double KincidentMin,KincidentMax; + ///index of h,k,l dimensions in the output workspaces + size_t hIndex,kIndex,lIndex; + /// cached x values along dimensions h,k,l + std::vector m_hX, m_kX, m_lX; + }; + + +} // namespace MDAlgorithms +} // namespace Mantid + +#endif /* MANTID_MDALGORITHMS_MDNORMSXD_H_ */ 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 6b92cd6ccdfc..d33e03f2f177 100644 --- a/Code/Mantid/Framework/MDAlgorithms/inc/MantidMDAlgorithms/Quantification/Resolution/TobyFitResolutionModel.h +++ b/Code/Mantid/Framework/MDAlgorithms/inc/MantidMDAlgorithms/Quantification/Resolution/TobyFitResolutionModel.h @@ -134,8 +134,6 @@ namespace Mantid /// Storage for currently in use random number generators mutable std::vector m_randomNumbers; - /// The value to mark an attribute as active - int m_activeAttrValue; /// Check for convergence after loop min number of steps int m_mcLoopMin; /// Maximum number of Monte Carlo evaluations diff --git a/Code/Mantid/Framework/MDAlgorithms/inc/MantidMDAlgorithms/Quantification/ResolutionConvolvedCrossSection.h b/Code/Mantid/Framework/MDAlgorithms/inc/MantidMDAlgorithms/Quantification/ResolutionConvolvedCrossSection.h index 3bd7ab8553fb..5d17fbb93af7 100644 --- a/Code/Mantid/Framework/MDAlgorithms/inc/MantidMDAlgorithms/Quantification/ResolutionConvolvedCrossSection.h +++ b/Code/Mantid/Framework/MDAlgorithms/inc/MantidMDAlgorithms/Quantification/ResolutionConvolvedCrossSection.h @@ -82,7 +82,12 @@ namespace Mantid void setAttribute(const std::string& name, const API::IFunction::Attribute & value); /// Set a pointer to the concrete convolution object void setupResolutionFunction(const std::string & name, const std::string & fgModelName); + /// Mutex-locked version to store the function value + void storeCalculatedWithMutex(const size_t index, const double signal, + API::FunctionValues& functionValues) const; + /// Mutex to protect storing the function values + mutable Poco::FastMutex m_valuesMutex; /// Flag that marks if this is a simulation store each event bool m_simulation; /// The meat of the calculation for each MD point diff --git a/Code/Mantid/Framework/MDAlgorithms/src/BinMD.cpp b/Code/Mantid/Framework/MDAlgorithms/src/BinMD.cpp index 48425eb9dbab..23ca5d91b3c8 100644 --- a/Code/Mantid/Framework/MDAlgorithms/src/BinMD.cpp +++ b/Code/Mantid/Framework/MDAlgorithms/src/BinMD.cpp @@ -270,7 +270,7 @@ namespace MDAlgorithms // How many bins (in that dimension) per chunk. // Try to split it so each core will get 2 tasks: - int chunkNumBins = int(m_binDimensions[chunkDimension]->getNBins() / (Mantid::Kernel::ThreadPool::getNumPhysicalCores() * 2)); + int chunkNumBins = int(m_binDimensions[chunkDimension]->getNBins() / (PARALLEL_GET_MAX_THREADS*2)); if (chunkNumBins < 1) chunkNumBins = 1; // Do we actually do it in parallel? diff --git a/Code/Mantid/Framework/MDAlgorithms/src/CentroidPeaksMD2.cpp b/Code/Mantid/Framework/MDAlgorithms/src/CentroidPeaksMD2.cpp index 13d7cef67254..42ea06afd59c 100644 --- a/Code/Mantid/Framework/MDAlgorithms/src/CentroidPeaksMD2.cpp +++ b/Code/Mantid/Framework/MDAlgorithms/src/CentroidPeaksMD2.cpp @@ -133,20 +133,28 @@ namespace MDAlgorithms V3D vecCentroid(centroid[0], centroid[1], centroid[2]); // Save it back in the peak object, in the dimension specified. - if (CoordinatesToUse == 1) //"Q (lab frame)" - { - p.setQLabFrame( vecCentroid, detectorDistance); - p.findDetector(); - } - else if (CoordinatesToUse == 2) //"Q (sample frame)" - { - p.setQSampleFrame( vecCentroid, detectorDistance); - p.findDetector(); - } - else if (CoordinatesToUse == 3) //"HKL" - { - p.setHKL( vecCentroid ); - } + try + { + if (CoordinatesToUse == 1) //"Q (lab frame)" + { + p.setQLabFrame( vecCentroid, detectorDistance); + p.findDetector(); + } + else if (CoordinatesToUse == 2) //"Q (sample frame)" + { + p.setQSampleFrame( vecCentroid, detectorDistance); + p.findDetector(); + } + else if (CoordinatesToUse == 3) //"HKL" + { + p.setHKL( vecCentroid ); + } + } + catch (std::exception & e) + { + g_log.warning() << "Error setting Q or HKL" << std::endl; + g_log.warning() << e.what() << std::endl; + } g_log.information() << "Peak " << i << " at " << pos << ": signal " diff --git a/Code/Mantid/Framework/MDAlgorithms/src/ConvertToMDParent.cpp b/Code/Mantid/Framework/MDAlgorithms/src/ConvertToMDParent.cpp index a8a64f5f1f36..c91bfedbcd0c 100644 --- a/Code/Mantid/Framework/MDAlgorithms/src/ConvertToMDParent.cpp +++ b/Code/Mantid/Framework/MDAlgorithms/src/ConvertToMDParent.cpp @@ -188,6 +188,30 @@ namespace Mantid if(oldInstrName==currentWSInstrumentName) { + // a direct mode instrument can be unchanged but incident energy can be different. + // It is cheap operation so we should always replace incident energy on the target workspace + bool hasEi= InWS2D->run().hasProperty("Ei"); + bool hasEfix= InWS2D->run().hasProperty("eFixed"); + if (hasEi||hasEfix) + { + + double Ei; + if (hasEi) Ei=InWS2D->run().getPropertyValueAsType("Ei"); + if (hasEfix) Ei=InWS2D->run().getPropertyValueAsType("eFixed"); + + TargTableWS->logs()->addProperty("Ei",Ei,true); + } + else + { + Emode = Kernel::DeltaEMode().fromString(dEModeRequested); + if(Emode==Kernel::DeltaEMode::Direct) + throw(std::invalid_argument("Input neutron's energy has to be present at the workspace as Ei or eFixed number log in Direct inelastic mode")); + //if(Emode==Kernel::DeltaEMode::Indirect && !hasEfix) + // throw(std::invalid_argument("Input neutron's energy has to be present at the workspace as eFixed number log in Indirect inelastic mode")); + + } + + if(!updateMasks) return TargTableWS; //Target workspace with preprocessed detectors exists and seems is correct one. // We still need to update masked detectors information diff --git a/Code/Mantid/Framework/MDAlgorithms/src/EvaluateMDFunction.cpp b/Code/Mantid/Framework/MDAlgorithms/src/EvaluateMDFunction.cpp new file mode 100644 index 000000000000..b4e1a6cc8203 --- /dev/null +++ b/Code/Mantid/Framework/MDAlgorithms/src/EvaluateMDFunction.cpp @@ -0,0 +1,98 @@ +#include "MantidMDAlgorithms/EvaluateMDFunction.h" +#include "MantidAPI/FunctionProperty.h" +#include "MantidAPI/IMDHistoWorkspace.h" +#include "MantidAPI/AlgorithmManager.h" +#include "MantidAPI/IMDIterator.h" +#include "MantidAPI/FunctionDomainMD.h" +#include "MantidAPI/FunctionValues.h" + +namespace Mantid +{ +namespace MDAlgorithms +{ + + using Mantid::Kernel::Direction; + using Mantid::API::WorkspaceProperty; + + // Register the algorithm into the AlgorithmFactory + DECLARE_ALGORITHM(EvaluateMDFunction) + + + + //---------------------------------------------------------------------------------------------- + /** Constructor + */ + EvaluateMDFunction::EvaluateMDFunction() + { + } + + //---------------------------------------------------------------------------------------------- + /** Destructor + */ + EvaluateMDFunction::~EvaluateMDFunction() + { + } + + + //---------------------------------------------------------------------------------------------- + + + /// Algorithm's version for identification. @see Algorithm::version + int EvaluateMDFunction::version() const { return 1;}; + + /// Algorithm's category for identification. @see Algorithm::category + const std::string EvaluateMDFunction::category() const { return "MDAlgorithms";} + + /// 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. + */ + void EvaluateMDFunction::init() + { + declareProperty(new WorkspaceProperty("InputWorkspace","",Direction::Input), "An input workspace that provides dimensions for the output."); + declareProperty(new API::FunctionProperty("Function"),"Parameters defining the fitting function and its initial values"); + declareProperty(new WorkspaceProperty("OutputWorkspace","",Direction::Output), "An output workspace."); + } + + //---------------------------------------------------------------------------------------------- + /** Execute the algorithm. + */ + void EvaluateMDFunction::exec() + { + API::IMDHistoWorkspace_sptr input = getProperty("InputWorkspace"); + + auto cloner = API::AlgorithmManager::Instance().create("CloneMDWorkspace"); + cloner->initialize(); + cloner->setChild(true); + cloner->setProperty("InputWorkspace", input); + cloner->setPropertyValue("OutputWorkspace", "_"); + cloner->execute(); + + API::IMDWorkspace_sptr clone = cloner->getProperty("OutputWorkspace"); + API::IMDHistoWorkspace_sptr output = boost::dynamic_pointer_cast(clone); + + if ( !output ) + throw std::runtime_error("Cannot create output workspace"); + + API::IFunction_sptr function = getProperty("Function"); + function->setWorkspace( output ); + + API::FunctionDomainMD domain( output ); + API::FunctionValues values( domain ); + + function->function( domain, values ); + + double *data = values.getPointerToCalculated(0); + size_t length = values.size(); + double *outputData = output->getSignalArray(); + std::copy( data, data + length, outputData ); + + setProperty("OutputWorkspace",output); + } + + + +} // namespace MDAlgorithms +} // namespace Mantid diff --git a/Code/Mantid/Framework/MDAlgorithms/src/IntegrateFlux.cpp b/Code/Mantid/Framework/MDAlgorithms/src/IntegrateFlux.cpp new file mode 100644 index 000000000000..65f7469307f3 --- /dev/null +++ b/Code/Mantid/Framework/MDAlgorithms/src/IntegrateFlux.cpp @@ -0,0 +1,164 @@ +#include "MantidMDAlgorithms/IntegrateFlux.h" +#include "MantidDataObjects/EventWorkspace.h" +#include "MantidAPI/MatrixWorkspace.h" +#include "MantidAPI/WorkspaceFactory.h" +#include "MantidKernel/BoundedValidator.h" + +#include + +namespace Mantid +{ +namespace MDAlgorithms +{ + + using Mantid::Kernel::Direction; + using Mantid::API::WorkspaceProperty; + + // Register the algorithm into the AlgorithmFactory + DECLARE_ALGORITHM(IntegrateFlux) + +namespace{ + + /// Void deleter for shared pointers +class NoEventWorkspaceDeleting +{ +public: + /// deleting operator. Does nothing + void operator()(const DataObjects::EventWorkspace*){} +}; + +} + + //---------------------------------------------------------------------------------------------- + + /// Algorithms name for identification. @see Algorithm::name + const std::string IntegrateFlux::name() const { return "IntegrateFlux"; } + + /// Algorithm's version for identification. @see Algorithm::version + int IntegrateFlux::version() const { return 1;}; + + /// Algorithm's category for identification. @see Algorithm::category + 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. + */ + void IntegrateFlux::init() + { + declareProperty(new WorkspaceProperty("InputWorkspace","",Direction::Input), "An input workspace."); + auto validator = boost::make_shared>(); + validator->setLower(2); + declareProperty("NPoints", 1000, validator, "Number of points per output spectrum."); + declareProperty(new WorkspaceProperty("OutputWorkspace","",Direction::Output), "An output workspace."); + } + + //---------------------------------------------------------------------------------------------- + /** Execute the algorithm. + */ + void IntegrateFlux::exec() + { + DataObjects::EventWorkspace_sptr inputWS = getProperty("InputWorkspace"); + size_t nX = static_cast( (int)getProperty("NPoints") ); + + auto outputWS = createOutputWorkspace( *inputWS, nX ); + + integrateSpectra( *inputWS, *outputWS ); + + setProperty("OutputWorkspace",outputWS); + } + + /** + * Create an empty output workspace with required dimensions and defined x-values + * @param eventWS :: The input event workspace. + * @param nX :: Suggested size of the output spectra. It can change in the actual output. + */ + boost::shared_ptr IntegrateFlux::createOutputWorkspace( const DataObjects::EventWorkspace& eventWS, size_t nX ) const + { + size_t nSpec = eventWS.getNumberHistograms(); + + if ( nSpec == 0 ) + { + throw std::runtime_error("Input workspace has no data."); + } + + // make sure the output spectrum size isn't too large + auto nEvents = eventWS.getEventList(0).getNumberEvents(); + if ( nX > nEvents ) + { + nX = nEvents; + } + + // and not 0 or 1 as they are to be used for interpolation + if ( nX < 2 ) + { + throw std::runtime_error("Failed to create output." + "Output spectra should have at least two points."); + } + + // crate empty output workspace + API::MatrixWorkspace_sptr ws = API::WorkspaceFactory::Instance().create( + boost::shared_ptr(&eventWS,NoEventWorkspaceDeleting()), + nSpec, nX, nX ); + + // claculate the integration points and save them in the x-vactors of integrFlux + double xMin = eventWS.getEventXMin(); + double xMax = eventWS.getEventXMax(); + double dx = ( xMax - xMin ) / static_cast( nX - 1 ); + auto &X = ws->dataX(0); + auto ix = X.begin(); + // x-values are equally spaced between the min and max tof in the first flux spectrum + for(double x = xMin; ix != X.end(); ++ix, x += dx) + { + *ix = x; + } + + // share the xs for all spectra + auto xRef = ws->refX(0); + for(size_t sp = 1; sp < nSpec; ++sp) + { + ws->setX(sp,xRef); + } + + return ws; + } + + /** + * Integrate spectra in eventWS at x-values in integrWS and save the results in y-vectors of integrWS. + * @param eventWS :: A workspace to integrate. The events have to be weighted-no-time. + * @param integrWS :: A workspace to store the results. + */ + void IntegrateFlux::integrateSpectra( const DataObjects::EventWorkspace& eventWS, API::MatrixWorkspace &integrWS ) + { + size_t nSpec = eventWS.getNumberHistograms(); + assert( nSpec == integrWS.getNumberHistograms() ); + + auto &X = integrWS.readX(0); + // loop overr the spectra and integrate + for(size_t sp = 0; sp < nSpec; ++sp) + { + std::vector el = eventWS.getEventList(sp).getWeightedEventsNoTime(); + auto &outY = integrWS.dataY(sp); + double sum = 0; + auto x = X.begin() + 1; + size_t i = 1; + // the integral is a running sum of the event weights in the spectrum + for(auto evnt = el.begin(); evnt != el.end(); ++evnt) + { + double tof = evnt->tof(); + while( x != X.end() && *x < tof ) + { + outY[i] = sum; + ++x; ++i; + } + if ( x == X.end() ) break; + sum += evnt->weight(); + outY[i] = sum; + } + } + } + +} // namespace MDAlgorithms +} // namespace Mantid \ No newline at end of file diff --git a/Code/Mantid/Framework/MDAlgorithms/src/IntegratePeaksMD2.cpp b/Code/Mantid/Framework/MDAlgorithms/src/IntegratePeaksMD2.cpp index 4a283db06d9e..8337881274a2 100644 --- a/Code/Mantid/Framework/MDAlgorithms/src/IntegratePeaksMD2.cpp +++ b/Code/Mantid/Framework/MDAlgorithms/src/IntegratePeaksMD2.cpp @@ -136,7 +136,19 @@ namespace MDAlgorithms Mantid::DataObjects::PeaksWorkspace_sptr peakWS = getProperty("OutputWorkspace"); if (peakWS != inPeakWS) peakWS = inPeakWS->clone(); + // This only fails in the unit tests which say that MaskBTP is not registered + try + { + runMaskDetectors(peakWS,"Tube","edges"); + runMaskDetectors(peakWS,"Pixel","edges"); + } catch (...) + { + g_log.error("Can't execute MaskBTP algorithm for this instrument to set edge for IntegrateIfOnEdge option"); + } + + // Get the instrument and its detectors + inst = peakWS->getInstrument(); int CoordinatesToUse = ws->getSpecialCoordinateSystem(); /// Radius to use around peaks @@ -242,8 +254,6 @@ namespace MDAlgorithms else if (CoordinatesToUse == 3) //"HKL" pos = p.getHKL(); - // Get the instrument and its detectors - inst = peakWS->getInstrument(); // Do not integrate if sphere is off edge of detector if (BackgroundOuterRadius > PeakRadius) { @@ -579,45 +589,49 @@ namespace MDAlgorithms } /** Calculate if this Q is on a detector + * Define edges for each instrument by masking. For CORELLI, tubes 1 and 16, and pixels 0 and 255. + * Get Q in the lab frame for every peak, call it C + * For every point on the edge, the trajectory in reciprocal space is a straight line, going through O=V3D(0,0,0). + * Calculate a point at a fixed momentum, say k=1. Q in the lab frame E=V3D(-k*sin(tt)*cos(ph),-k*sin(tt)*sin(ph),k-k*cos(ph)). + * Normalize E to 1: E=E*(1./E.norm()) + * The distance from C to OE is given by dv=C-E*(C.scalar_prod(E)) + * If dv.norm(nAngles); - // check 64 points in theta and phi at outer radius - for (int i = 0; i < nAngles; ++i) - { - double theta = (2 * M_PI) / dAngles * i; - for (int j = 0; j < nAngles; ++j) - { - double phi = (2 * M_PI) / dAngles * j; - // Calculate an edge position at this point on the sphere surface. Spherical coordinates to cartesian. - V3D edge = V3D( - QLabFrame.X() + r * std::cos(theta) * std::sin(phi), - QLabFrame.Y() + r * std::sin(theta) * std::sin(phi), - QLabFrame.Z() + r * std::cos(phi)); - // Create the peak using the Q in the lab frame with all its info: - try - { - Peak p(inst, edge); - in = (in && p.findDetector()); - if (!in) - { - return in; - } - } - catch (...) - { - return false; - } - } - } - return in; + std::vector detectorIDs = inst->getDetectorIDs(); + + for (auto detID = detectorIDs.begin(); detID != detectorIDs.end(); ++detID) + { + Mantid::Geometry::IDetector_const_sptr det = inst->getDetector(*detID); + if( det->isMonitor() ) continue; //skip monitor + if( !det->isMasked() ) continue;// edge is masked so don't check if not masked + double tt1=det->getTwoTheta(V3D(0,0,0),V3D(0,0,1)); //two theta + double ph1=det->getPhi(); //phi + V3D E1=V3D(-std::sin(tt1)*std::cos(ph1),-std::sin(tt1)*std::sin(ph1),1.-std::cos(tt1)); //end of trajectory + E1=E1*(1./E1.norm()); //normalize + V3D distv=QLabFrame-E1*(QLabFrame.scalar_prod(E1)); //distance to the trajectory as a vector + if(distv.norm()setProperty("Workspace", peakWS); + alg->setProperty(property,values); + if (!alg->execute()) + throw std::runtime_error("MaskDetectors Child Algorithm has not executed successfully"); } + void IntegratePeaksMD2::checkOverlap(int i, Mantid::DataObjects::PeaksWorkspace_sptr peakWS, int CoordinatesToUse, double radius) { diff --git a/Code/Mantid/Framework/MDAlgorithms/src/LoadMD.cpp b/Code/Mantid/Framework/MDAlgorithms/src/LoadMD.cpp index e9057798c501..e9736c335496 100644 --- a/Code/Mantid/Framework/MDAlgorithms/src/LoadMD.cpp +++ b/Code/Mantid/Framework/MDAlgorithms/src/LoadMD.cpp @@ -21,9 +21,9 @@ #include #if defined(__GLIBCXX__) && __GLIBCXX__ >= 20100121 // libstdc++-4.4.3 - typedef std::unique_ptr< Mantid::API::IBoxControllerIO> file_holder_type; +typedef std::unique_ptr< Mantid::API::IBoxControllerIO> file_holder_type; #else - typedef std::auto_ptr< Mantid::API::IBoxControllerIO> file_holder_type; +typedef std::auto_ptr< Mantid::API::IBoxControllerIO> file_holder_type; #endif using namespace Mantid::Kernel; @@ -56,10 +56,10 @@ namespace Mantid /** - * Return the confidence with with this algorithm can load the file - * @param descriptor A descriptor for the file - * @returns An integer specifying the confidence level. 0 indicates it will not be used - */ + * Return the confidence with which this algorithm can load the file + * @param descriptor A descriptor for the file + * @returns An integer specifying the confidence level. 0 indicates it will not be used + */ int LoadMD::confidence(Kernel::NexusDescriptor & descriptor) const { int confidence(0); @@ -91,7 +91,7 @@ namespace Mantid "Load Box structure and other metadata without events. The loaded workspace will be empty and not file-backed."); declareProperty(new Kernel::PropertyWithValue("BoxStructureOnly", false), - "Load partial information aboug the boxes and events. Redundant property currently equivalent to MetadataOnly"); + "Load partial information about the boxes and events. Redundant property currently equivalent to MetadataOnly"); declareProperty(new PropertyWithValue("FileBackEnd", false), "Set to true to load the data only on demand."); @@ -123,19 +123,19 @@ namespace Mantid m_BoxStructureAndMethadata = true; } - // Nexus constructor/desctructors throw, so can not be used with scoped pointers directrly + // Nexus constructor/destructor throw, so can not be used with scoped pointers directly //(do they lock file because of this and this code is useless?) std::string for_access; if (fileBacked) { - for_access="for Read/Write access"; - m_file.reset(new ::NeXus::File(m_filename, NXACC_RDWR)); + for_access="for Read/Write access"; + m_file.reset(new ::NeXus::File(m_filename, NXACC_RDWR)); } else { - for_access="for Read access"; - m_file.reset(new ::NeXus::File(m_filename, NXACC_READ)); + for_access="for Read access"; + m_file.reset(new ::NeXus::File(m_filename, NXACC_READ)); } if(!m_file) @@ -196,13 +196,13 @@ namespace Mantid } /** - * Load a slab of double data into a bare array. - * Checks that the size is correct. - * @param name - * @param data bare pointer to doublel array - * @param ws - * @param dataType - */ + * Load a slab of double data into a bare array. + * Checks that the size is correct. + * @param name + * @param data bare pointer to double array + * @param ws + * @param dataType + */ void LoadMD::loadSlab(std::string name, void * data, MDHistoWorkspace_sptr ws, NeXus::NXnumtype dataType) { m_file->openData(name); @@ -212,7 +212,13 @@ namespace Mantid throw std::runtime_error("Inconsistency between the number of points in '" + name + "' and the number of bins defined by the dimensions."); std::vector start(1,0); std::vector size(1, static_cast(ws->getNPoints())); - m_file->getSlab(data, start, size); + try + { + m_file->getSlab(data, start, size); + }catch(...) + { + std::cout<<" start: "<closeData(); } @@ -304,36 +310,37 @@ namespace Mantid // ----------------------------------------- Box Structure ------------------------------ + prog->report("Reading box structure from HDD."); MDBoxFlatTree FlatBoxTree; - int nDims = static_cast(nd); // should be safe + int nDims = static_cast(nd); // should be safe FlatBoxTree.loadBoxStructure(m_filename,nDims,MDE::getTypeName()); BoxController_sptr bc = ws->getBoxController(); bc->fromXMLString(FlatBoxTree.getBCXMLdescr()); + prog->report("Restoring box structure and connectivity"); std::vector boxTree; - // uint64_t totalNumEvents = FlatBoxTree.restoreBoxTree(boxTree,bc,fileBackEnd,bMetadataOnly); - FlatBoxTree.restoreBoxTree(boxTree,bc,fileBackEnd,m_BoxStructureAndMethadata); + FlatBoxTree.restoreBoxTree(boxTree,bc,fileBackEnd,m_BoxStructureAndMethadata); size_t numBoxes = boxTree.size(); - // ---------------------------------------- DEAL WITH BOXES ------------------------------------ + // ---------------------------------------- DEAL WITH BOXES ------------------------------------ if (fileBackEnd) { // TODO:: call to the file format factory - auto loader = boost::shared_ptr(new MDEvents::BoxControllerNeXusIO(bc.get())); - loader->setDataType(sizeof(coord_t),MDE::getTypeName()); - bc->setFileBacked(loader,m_filename); - // boxes have been already made file-backed when restoring the boxTree; - // How much memory for the cache? + auto loader = boost::shared_ptr(new MDEvents::BoxControllerNeXusIO(bc.get())); + loader->setDataType(sizeof(coord_t),MDE::getTypeName()); + bc->setFileBacked(loader,m_filename); + // boxes have been already made file-backed when restoring the boxTree; + // How much memory for the cache? { - // TODO: Clean up, only a write buffer now + // TODO: Clean up, only a write buffer now double mb = getProperty("Memory"); - - // Defaults have changed, defauld disk buffer size should be 10 data chunks TODO: find optimal, 100 may be better. + + // Defaults have changed, default disk buffer size should be 10 data chunks TODO: find optimal, 100 may be better. if (mb <= 0) mb = double(10*loader->getDataChunk()* sizeof(MDE))/double(1024*1024); // Express the cache memory in units of number of events. uint64_t cacheMemory = static_cast((mb * 1024. * 1024.) / sizeof(MDE))+1; - + // Set these values in the diskMRU bc->getFileIO()->setWriteBufferSize(cacheMemory); @@ -343,7 +350,7 @@ namespace Mantid else if (!m_BoxStructureAndMethadata) { // ---------------------------------------- READ IN THE BOXES ------------------------------------ - // TODO:: call to the file format factory + // TODO:: call to the file format factory auto loader = file_holder_type(new MDEvents::BoxControllerNeXusIO(bc.get())); loader->setDataType(sizeof(coord_t),MDE::getTypeName()); @@ -359,12 +366,15 @@ namespace Mantid if(!box)continue; if(BoxEventIndex[2*i+1]>0) // Load in memory NOT using the file as the back-end, - boxTree[i]->loadAndAddFrom(loader.get(),BoxEventIndex[2*i],static_cast(BoxEventIndex[2*i+1])); + { + boxTree[i]->reserveMemoryForLoad(BoxEventIndex[2*i+1]); + boxTree[i]->loadAndAddFrom(loader.get(),BoxEventIndex[2*i],static_cast(BoxEventIndex[2*i+1])); + } } loader->closeFile(); } - else // box structure and methadata only + else // box structure and metadata only { } g_log.debug() << tim << " to create all the boxes and fill them with events." << std::endl; @@ -385,64 +395,64 @@ namespace Mantid delete prog; } - /** - * Load all of the affine matricies from the file, create the - * appropriate coordinate transform and set those on the workspace. - * @param ws : workspace to set the coordinate transforms on - */ - void LoadMD::loadAffineMatricies(IMDWorkspace_sptr ws) - { - std::map entries; - m_file->getEntries(entries); - - if (entries.find("transform_to_orig") != entries.end()) - { - CoordTransform *transform = this->loadAffineMatrix("transform_to_orig"); - ws->setTransformToOriginal(transform); - } - if (entries.find("transform_from_orig") != entries.end()) - { - CoordTransform *transform = this->loadAffineMatrix("transform_from_orig"); - ws->setTransformFromOriginal(transform); - } - } - - /** - * Do that actual loading and manipulating of the read data to create - * the affine matrix and then the appropriate transformation. This is - * currently limited to CoordTransformAffine transforms. - * @param entry_name : the entry point in the NeXus file to read - * @return the coordinate transform object - */ - CoordTransform *LoadMD::loadAffineMatrix(std::string entry_name) - { - m_file->openData(entry_name); - std::vector vec; - m_file->getData(vec); - std::string type; - int inD(0); - int outD(0); - m_file->getAttr("type", type); - m_file->getAttr("rows", outD); - m_file->getAttr("columns", inD); - m_file->closeData(); - // Adjust dimensions - inD--; - outD--; - Matrix mat(vec); - CoordTransform *transform = NULL; - if ("CoordTransformAffine" == type) + /** + * Load all of the affine matrices from the file, create the + * appropriate coordinate transform and set those on the workspace. + * @param ws : workspace to set the coordinate transforms on + */ + void LoadMD::loadAffineMatricies(IMDWorkspace_sptr ws) { - CoordTransformAffine *affine = new CoordTransformAffine(inD, outD); - affine->setMatrix(mat); - transform = affine; + std::map entries; + m_file->getEntries(entries); + + if (entries.find("transform_to_orig") != entries.end()) + { + CoordTransform *transform = this->loadAffineMatrix("transform_to_orig"); + ws->setTransformToOriginal(transform); + } + if (entries.find("transform_from_orig") != entries.end()) + { + CoordTransform *transform = this->loadAffineMatrix("transform_from_orig"); + ws->setTransformFromOriginal(transform); + } } - else + + /** + * Do that actual loading and manipulating of the read data to create + * the affine matrix and then the appropriate transformation. This is + * currently limited to CoordTransformAffine transforms. + * @param entry_name : the entry point in the NeXus file to read + * @return the coordinate transform object + */ + CoordTransform *LoadMD::loadAffineMatrix(std::string entry_name) { - g_log.information("Do not know how to process coordinate transform " + type); + m_file->openData(entry_name); + std::vector vec; + m_file->getData(vec); + std::string type; + int inD(0); + int outD(0); + m_file->getAttr("type", type); + m_file->getAttr("rows", outD); + m_file->getAttr("columns", inD); + m_file->closeData(); + // Adjust dimensions + inD--; + outD--; + Matrix mat(vec); + CoordTransform *transform = NULL; + if ("CoordTransformAffine" == type) + { + CoordTransformAffine *affine = new CoordTransformAffine(inD, outD); + affine->setMatrix(mat); + transform = affine; + } + else + { + g_log.information("Do not know how to process coordinate transform " + type); + } + return transform; } - return transform; - } } // namespace Mantid } // namespace MDEvents diff --git a/Code/Mantid/Framework/MDAlgorithms/src/LoadSQW.cpp b/Code/Mantid/Framework/MDAlgorithms/src/LoadSQW.cpp index 508b3982d05b..22882a3b6ece 100644 --- a/Code/Mantid/Framework/MDAlgorithms/src/LoadSQW.cpp +++ b/Code/Mantid/Framework/MDAlgorithms/src/LoadSQW.cpp @@ -34,11 +34,11 @@ namespace Mantid { //------------------------------------------------------------------------------------------------ /** Helper function allowing to typecast sequence of bytes into proper expected type. - * The input buffer is interpreted as the template type - * - * @param Buf -- the vector of characters, representing data to cast - * @param ind -- the starting position of first byte of data within the data buffer - * @returns the data type produced by type-casing proper sequence of bytes + * The input buffer is interpreted as the template type + * + * @param Buf -- the vector of characters, representing data to cast + * @param ind -- the starting position of first byte of data within the data buffer + * @returns the data type produced by type-casing proper sequence of bytes */ template T interpretAs(std::vector &Buf, size_t ind=0) { @@ -50,14 +50,14 @@ namespace Mantid /// Constructor LoadSQW::LoadSQW() - : m_prog(new Mantid::API::Progress(this, 0.05, 0.95, 100)) + : m_prog(new Mantid::API::Progress(this, 0.05, 0.95, 100)) { } /** - * Return the confidence with with this algorithm can load the file - * @param descriptor A descriptor for the file - * @returns An integer specifying the confidence level. 0 indicates it will not be used - */ + * Return the confidence with this algorithm can load the file + * @param descriptor A descriptor for the file + * @returns An integer specifying the confidence level. 0 indicates it will not be used + */ int LoadSQW::confidence(Kernel::FileDescriptor & descriptor) const { @@ -66,11 +66,11 @@ namespace Mantid if(extn.compare(".sqw") != 0) return 0; - if(descriptor.isAscii()) - { - return 10; // Low so that others may try - } - return 80; // probably it is sqw indeed + if(descriptor.isAscii()) + { + return 10; // Low so that others may try + } + return 80; // probably it is sqw indeed } @@ -83,7 +83,7 @@ namespace Mantid /// Provide wiki documentation. - /// Initalize the algorithm + /// Initialize the algorithm void LoadSQW::init() { std::vector fileExtensions(1); @@ -96,8 +96,8 @@ namespace Mantid std::vector fileExtensions2(1); fileExtensions2[0]=".nxs"; declareProperty(new API::FileProperty("OutputFilename","", API::FileProperty::OptionalSave, fileExtensions2), - "If the input SQW file is too large to fit in memory, specify an output NXS file.\n" - "The MDEventWorkspace will be create with this file as its back-end."); + "If the input SQW file is too large to fit in memory, specify an output NXS file.\n" + "The MDEventWorkspace will be create with this file as its back-end."); } /// Execute the algorithm @@ -114,13 +114,8 @@ namespace Mantid // Add dimensions onto workspace. std::vector DimVector; + readDNDDimensions(DimVector,false); - this->m_nBins.resize(4); - for(size_t i=0;i<4;i++) - { - m_nBins[i] = DimVector[i].getNumBins(); - if(m_nBins[i]<1)m_nBins[i]=1; - } readSQWDimensions(DimVector); addDimsToWs(pWs,DimVector); // Set some reasonable values for the box controller @@ -129,31 +124,24 @@ namespace Mantid { bc->setSplitInto(i,m_nBins[i]); } - bc->setSplitThreshold(3000); + bc->setMaxDepth(1); // Initialize the workspace. pWs->initialize(); // Add oriented lattice. addLattice(pWs); - // Save the empty WS and turn it into a file-backed MDEventWorkspace (on option) - m_outputFile = getPropertyValue("OutputFilename"); - // set file backed; - if(!m_outputFile.empty()) - { - auto Saver = boost::shared_ptr(new MDEvents::BoxControllerNeXusIO(bc.get())); - bc->setFileBacked(Saver,m_outputFile); - pWs->getBox()->setFileBacked(); - bc->getFileIO()->setWriteBufferSize(1000000); - } // Start with a MDGridBox. pWs->splitBox(); - + // readBoxSizes(); + // Save the empty WS and turn it into a file-backed MDEventWorkspace (on option) + m_outputFile = getPropertyValue("OutputFilename"); if (!m_outputFile.empty()) { + // set file backed; MemoryStats stat; if ((m_nDataPoints * sizeof(MDEvent<4>) * 2 / 1024) < stat.availMem()) g_log.notice() << "You have enough memory available to load the " << m_nDataPoints << " points into memory; this would be faster than using a file back-end." << std::endl; @@ -161,9 +149,18 @@ namespace Mantid IAlgorithm_sptr saver = this->createChildAlgorithm("SaveMD" ,0.01, 0.05, true); saver->setProperty("InputWorkspace", ws); saver->setPropertyValue("Filename", m_outputFile); - saver->setProperty("MakeFileBacked", true); + // should think about it. + saver->setProperty("UpdateFileBackEnd", false); + saver->setProperty("MakeFileBacked", false); saver->executeAsChildAlg(); m_prog->resetNumSteps(100, 0.05, 0.75); + + // set file backed boxes + auto Saver = boost::shared_ptr(new MDEvents::BoxControllerNeXusIO(bc.get())); + bc->setFileBacked(Saver,m_outputFile); + pWs->getBox()->setFileBacked(); + bc->getFileIO()->setWriteBufferSize(1000000); + } else { @@ -174,12 +171,12 @@ namespace Mantid if(bc->isFileBacked()) { - std::cout << "File backed? " << bc->isFileBacked() << ". Cache " << bc->getFileIO()->getMemoryStr() << std::endl; + std::cout << "File backed? " << bc->isFileBacked() << ". Cache " << bc->getFileIO()->getMemoryStr() << std::endl; } else { - bool ff(false); - std::cout << "File backed? " << ff << ". Cache 0" << std::endl; + bool ff(false); + std::cout << "File backed? " << ff << ". Cache 0" << std::endl; } //Persist the workspace. @@ -245,7 +242,7 @@ namespace Mantid BoxController_sptr bc = ws->getBoxController(); DiskBuffer * dbuf(NULL); if(bc->isFileBacked()) - dbuf = bc->getFileIO(); + dbuf = bc->getFileIO(); for (int blockNum=0; blockNum < numBlocks; blockNum++) { @@ -273,25 +270,25 @@ namespace Mantid size_t current_pix = size_t(i*pixel_width); coord_t centers[4] = { - interpretAs(Buffer,current_pix), - interpretAs(Buffer,current_pix + column_size), - interpretAs(Buffer,current_pix + column_size_2), - interpretAs(Buffer,current_pix + column_size_3) + interpretAs(Buffer,current_pix), + interpretAs(Buffer,current_pix + column_size), + interpretAs(Buffer,current_pix + column_size_2), + interpretAs(Buffer,current_pix + column_size_3) }; float error = interpretAs(Buffer,current_pix + column_size_8); ws->addEvent(MDEvent<4>( - interpretAs(Buffer,current_pix + column_size_7), // Signal - error*error, // Error sq - static_cast(interpretAs(Buffer,current_pix + column_size_6)), // run Index - static_cast(interpretAs(Buffer,current_pix + column_size_4)), // Detector Id - centers)); + interpretAs(Buffer,current_pix + column_size_7), // Signal + error*error, // Error sq + static_cast(interpretAs(Buffer,current_pix + column_size_6)), // run Index + static_cast(interpretAs(Buffer,current_pix + column_size_4)), // Detector Id + centers)); } -// MemoryStats stat; -// size_t bytesAvail = stat.availMem() * 1024; -// // Estimate how many extra bytes will (temporarily) be used when splitting events -// size_t bytesNeededToSplit = eventsAdded * sizeof(MDEvent<4>) / 2; + // MemoryStats stat; + // size_t bytesAvail = stat.availMem() * 1024; + // // Estimate how many extra bytes will (temporarily) be used when splitting events + // size_t bytesNeededToSplit = eventsAdded * sizeof(MDEvent<4>) / 2; // Split: // 1. When < 1 GB of memory is free @@ -300,8 +297,8 @@ namespace Mantid // 4. At the last block being added -// if ((bytesAvail < 1000000000) || (bytesAvail < bytesNeededToSplit) || -// bc->shouldSplitBoxes(eventsAdded*2, lastNumBoxes) || (blockNum == numBlocks-1) ) + // if ((bytesAvail < 1000000000) || (bytesAvail < bytesNeededToSplit) || + // bc->shouldSplitBoxes(eventsAdded*2, lastNumBoxes) || (blockNum == numBlocks-1) ) if (eventsAdded > 19000000 ) @@ -316,45 +313,57 @@ namespace Mantid tp.joinAll(); // Flush the cache - this will save things out to disk - dbuf->flushCache(); + if(dbuf)dbuf->flushCache(); // Flush memory Mantid::API::MemoryManager::Instance().releaseFreeMemory(); eventsAdded = 0; } -// -// if (false) -// { -// std::vector,4>*> boxes; -// ws->getBox()->getBoxes(boxes, 100, true); -// size_t modified = 0; -// size_t inmem = 0; -// size_t ondisk = 0; -// size_t events = 0; -// for (size_t i=0; i,4>* box = dynamic_cast,4>*>(boxes[i]); -// if (box) -// { -// //box->save(); -// if (box->dataAdded() || box->dataModified()) -// modified++; -// if (box->getInMemory()) -// inmem++; -// if (box->getOnDisk()) -// ondisk++; -// events += box->getEventVectorSize(); -// } -// } -// g_log.information() << modified << " of " << boxes.size() << " MDBoxes have data added or modified." << std::endl; -// g_log.information() << inmem << " MDBoxes are in memory." << std::endl; -// //g_log.information() << ondisk << " MDBoxes are on disk." << std::endl; -// g_log.information() << double(events)/1e6 << " million events in memory." << std::endl; -// } + // This will be correct optimized code after all. + // + // if (false) + // { + // std::vector,4>*> boxes; + // ws->getBox()->getBoxes(boxes, 100, true); + // size_t modified = 0; + // size_t inmem = 0; + // size_t ondisk = 0; + // size_t events = 0; + // for (size_t i=0; i,4>* box = dynamic_cast,4>*>(boxes[i]); + // if (box) + // { + // //box->save(); + // if (box->dataAdded() || box->dataModified()) + // modified++; + // if (box->getInMemory()) + // inmem++; + // if (box->getOnDisk()) + // ondisk++; + // events += box->getEventVectorSize(); + // } + // } + // g_log.information() << modified << " of " << boxes.size() << " MDBoxes have data added or modified." << std::endl; + // g_log.information() << inmem << " MDBoxes are in memory." << std::endl; + // //g_log.information() << ondisk << " MDBoxes are on disk." << std::endl; + // g_log.information() << double(events)/1e6 << " million events in memory." << std::endl; + // } // Report progress once per block. m_prog->report(); } + Kernel::ThreadScheduler * ts = new ThreadSchedulerFIFO(); + ThreadPool tp(ts); + ws->splitAllIfNeeded(ts); + tp.joinAll(); + + // Flush the cache - this will save things out to disk + if(dbuf)dbuf->flushCache(); + // Flush memory + Mantid::API::MemoryManager::Instance().releaseFreeMemory(); + + } /** @@ -373,7 +382,7 @@ namespace Mantid double aa = static_cast(interpretAs(buf,12)); double bb = static_cast(interpretAs(buf,16)); double cc = static_cast(interpretAs(buf,20)); - + ExperimentInfo_sptr info(new ExperimentInfo()); // set up the goniometer. All mdEvents (pixels) in Horace sqw file are in lab frame, // Q units so general goniometer should provide unit rotation matrix @@ -389,7 +398,7 @@ namespace Mantid std::vector dimID(4,"qx"); std::vector dimUnit(4,"A^-1"); dimID[1]="qy";dimID[2]="qz";dimID[3]="en"; - dimUnit[3]="mEv"; + dimUnit[3]="meV"; DimVector.resize(4); for(size_t i=0;i<4;i++) { @@ -415,8 +424,8 @@ namespace Mantid // interpret shifts size_t i0 = 4*(3+3) ; //for(size_t i=0;im_nDims;i++){ - //double val = (double)*((float*)(&buf[i0+i*4])); - //dscrptn.pDimDescription(i)->data_shift = val; + //double val = (double)*((float*)(&buf[i0+i*4])); + //dscrptn.pDimDescription(i)->data_shift = val; //} //TODO: how to use it in our framework? -> it is B^-1 matrix possibly re-scaled @@ -477,17 +486,17 @@ namespace Mantid unsigned int npax = interpretAs(buf); unsigned int niax = 4-npax; - /* + /* [npax, count, ok, mess] = fread_catch(fid,1,'int32'); if ~all(ok); return; end; niax=4-npax; if niax~=0 - [data.iax, count, ok, mess] = fread_catch(fid,[1,niax],'int32'); if ~all(ok); return; end; - [data.iint, count, ok, mess] = fread_catch(fid,[2,niax],'float32'); if ~all(ok); return; end; + [data.iax, count, ok, mess] = fread_catch(fid,[1,niax],'int32'); if ~all(ok); return; end; + [data.iint, count, ok, mess] = fread_catch(fid,[2,niax],'float32'); if ~all(ok); return; end; else - data.iax=zeros(1,0); % create empty index of integration array in standard form + data.iax=zeros(1,0); % create empty index of integration array in standard form data.iint=zeros(2,0); - end - */ + end + */ // axis counter ic = 0;; std::vector iax; @@ -513,22 +522,22 @@ namespace Mantid /* if npax~=0 - [data.pax, count, ok, mess] = fread_catch(fid,[1,npax],'int32'); if ~all(ok); return; end; - psize=zeros(1,npax); % will contain number of bins along each dimension of plot axes - for i=1:npax - [np,count,ok,mess] = fread_catch(fid,1,'int32'); if ~all(ok); return; end; - [data.p{i},count,ok,mess] = fread_catch(fid,np,'float32'); if ~all(ok); return; end; - psize(i)=np-1; - end - [data.dax, count, ok, mess] = fread_catch(fid,[1,npax],'int32'); if ~all(ok); return; end; - if length(psize)==1 - psize=[psize,1]; % make size of a column vector - end + [data.pax, count, ok, mess] = fread_catch(fid,[1,npax],'int32'); if ~all(ok); return; end; + psize=zeros(1,npax); % will contain number of bins along each dimension of plot axes + for i=1:npax + [np,count,ok,mess] = fread_catch(fid,1,'int32'); if ~all(ok); return; end; + [data.p{i},count,ok,mess] = fread_catch(fid,np,'float32'); if ~all(ok); return; end; + psize(i)=np-1; + end + [data.dax, count, ok, mess] = fread_catch(fid,[1,npax],'int32'); if ~all(ok); return; end; + if length(psize)==1 + psize=[psize,1]; % make size of a column vector + end else - data.pax=zeros(1,0); % create empty index of plot axes - data.p=cell(1,0); - data.dax=zeros(1,0); % create empty index of plot axes - psize=[1,1]; % to hold a scalar + data.pax=zeros(1,0); % create empty index of plot axes + data.p=cell(1,0); + data.dax=zeros(1,0); % create empty index of plot axes + psize=[1,1]; % to hold a scalar end */ std::vector pax,dax; @@ -561,13 +570,13 @@ namespace Mantid //[data.dax, count, ok, mess] = fread_catch(fid,[1,npax],'int32'); if ~all(ok); return; end; this->m_fileStream.read(&buf[0],4*npax); for(unsigned int i=0;i(buf,4*i)-1; + dax[i]=interpretAs(buf,4*i)-1; } if(arrangeByMDImage) { - //Place dimensions to output vector in the correct dimensions order; + //Place dimensions to output vector in the correct dimensions order; size_t ic=0; DimVectorOut.resize(4); for(size_t i=0;im_nBins.resize(4); + for(size_t i=0;i<4;i++) + { + m_nBins[i] = DimVectorOut[i].getNumBins(); + if(m_nBins[i]<1)m_nBins[i]=1; + } + } /// add range of dimensions to the workspace; void LoadSQW::addDimsToWs(Mantid::MDEvents::MDEventWorkspace,4>* ws,std::vector &DimVector) { + //Add dimensions to the workspace by invoking the dimension builders. for(size_t i=0;i<4;i++) { - ws->addDimension(DimVector[i].create()); + ws->addDimension(DimVector[i].create()); } - //Add dimensions to the workspace by invoking the dimension builders. - // ws->addDimension(qx.create()); - // ws->addDimension(qy.create()); - // ws->addDimension(qz.create()); - // ws->addDimension(en.create()); - } - + /// Add a dimension after reading info from file. void LoadSQW::readSQWDimensions(std::vector &DimVectorOut) { @@ -622,16 +634,12 @@ namespace Mantid { float min = interpretAs(buf,4*i*2); float max = interpretAs(buf,4*(i*2+1))*(1+FLT_EPSILON); - DimVectorOut[i].setNumBins(10); + DimVectorOut[i].setNumBins(m_nBins[i]); DimVectorOut[i].setMax(max); DimVectorOut[i].setMin(min); } -// std::cout << qx.create()->getNBins() << " bins in x\n"; -// std::cout << qy.create()->getNBins() << " bins in y\n"; -// std::cout << qz.create()->getNBins() << " bins in z\n"; -// std::cout << en.create()->getNBins() << " bins in en\n"; } @@ -640,8 +648,8 @@ namespace Mantid Region: Functions in the following region are candidates for refactoring. Copied from MD_FileHoraceReader ==================================================================================*/ - /** Function provides seam on to access auxillary functions ported from MD_FileHoraceReader. - + /** Function provides seam on to access axillary functions ported from MD_FileHoraceReader. + */ void LoadSQW::parseMetadata(const std::string &fileName) { @@ -649,7 +657,7 @@ namespace Mantid m_fileStream.open(fileName.c_str(), std::ios::binary); if(!m_fileStream.is_open()) - throw(Kernel::Exception::FileError("Can not open inout sqw file",fileName)); + throw(Kernel::Exception::FileError("Can not open input sqw file",fileName)); std::vector data_buffer; m_fileStream.seekg(m_dataPositions.if_sqw_start); @@ -677,273 +685,273 @@ namespace Mantid void LoadSQW::readBoxSizes() { - - m_boxSizes.resize(m_dataPositions.mdImageSize); - m_fileStream.seekg(m_dataPositions.n_cell_pix_start, std::ios::beg); - m_fileStream.read((char *)(&m_boxSizes[0]),m_dataPositions.mdImageSize*sizeof(uint64_t)); - + + m_boxSizes.resize(m_dataPositions.mdImageSize); + m_fileStream.seekg(m_dataPositions.n_cell_pix_start, std::ios::beg); + m_fileStream.read((char *)(&m_boxSizes[0]),m_dataPositions.mdImageSize*sizeof(uint64_t)); + } -namespace LoadSQWHelper -{ + namespace LoadSQWHelper + { - // auxiliary functions - /**Block 1: Main_header: Parse SQW main data header - *@param dataStream -- the open file hanlder responsible for IO operations - **/ - void dataPositions::parse_sqw_main_header(std::ifstream &dataStream) - { // we do not need this header at the moment -> just need to calculated its length; + // auxiliary functions + /**Block 1: Main_header: Parse SQW main data header + *@param dataStream -- the open file handler responsible for IO operations + **/ + void dataPositions::parse_sqw_main_header(std::ifstream &dataStream) + { // we do not need this header at the moment -> just need to calculated its length; - std::vector data_buffer(4 * 3); - dataStream.read(&data_buffer[0], 4); + std::vector data_buffer(4 * 3); + dataStream.read(&data_buffer[0], 4); - unsigned int file_name_length = *((uint32_t*) (&data_buffer[0])); - //skip main header file name - dataStream.seekg(file_name_length, std::ios_base::cur); + unsigned int file_name_length = *((uint32_t*) (&data_buffer[0])); + //skip main header file name + dataStream.seekg(file_name_length, std::ios_base::cur); - dataStream.read(&data_buffer[0], 4); - unsigned int file_path_length = *((uint32_t*) (&data_buffer[0])); + dataStream.read(&data_buffer[0], 4); + unsigned int file_path_length = *((uint32_t*) (&data_buffer[0])); - //skip main header file path - dataStream.seekg(file_path_length, std::ios_base::cur); + //skip main header file path + dataStream.seekg(file_path_length, std::ios_base::cur); - dataStream.read(&data_buffer[0], 4); - unsigned int file_title = *((uint32_t*) (&data_buffer[0])); + dataStream.read(&data_buffer[0], 4); + unsigned int file_title = *((uint32_t*) (&data_buffer[0])); - //skip ws titile - dataStream.seekg(file_title, std::ios_base::cur); + //skip ws title + dataStream.seekg(file_title, std::ios_base::cur); - // indentify number of file headers, contributed into the dataset - dataStream.read(&data_buffer[0], 4); - unsigned int nFiles = *((uint32_t*) (&data_buffer[0])); + // identify number of file headers, contributed into the dataset + dataStream.read(&data_buffer[0], 4); + unsigned int nFiles = *((uint32_t*) (&data_buffer[0])); - /// allocate space for the component headers positions; - this->component_headers_starts.assign(nFiles, 0); + /// allocate space for the component headers positions; + this->component_headers_starts.assign(nFiles, 0); - std::streamoff last_location = dataStream.tellg(); - if(last_location<0)throw("IO error for input file at start of component headers; Can not seek to last location"); - if (nFiles > 0) - { - this->component_headers_starts[0] = last_location; + std::streamoff last_location = dataStream.tellg(); + if(last_location<0)throw("IO error for input file at start of component headers; Can not seek to last location"); + if (nFiles > 0) + { + this->component_headers_starts[0] = last_location; + } } - } - /**Block 2: Header: Parse header of single SPE file - *@param dataStream -- the open file hanlder responsible for IO operations - *@param start_location -- initial file position of the header within the binary file - * - *@returns: the file location of the first byte behind this header - */ - std::streamoff dataPositions::parse_component_header(std::ifstream &dataStream,std::streamoff start_location) - { // we do not need this header at the moment -> just calculating its length; or may be we do soon? - std::vector data_buffer(8); + /**Block 2: Header: Parse header of single SPE file + *@param dataStream -- the open file handler responsible for IO operations + *@param start_location -- initial file position of the header within the binary file + * + *@returns: the file location of the first byte behind this header + */ + std::streamoff dataPositions::parse_component_header(std::ifstream &dataStream,std::streamoff start_location) + { // we do not need this header at the moment -> just calculating its length; or may be we do soon? + std::vector data_buffer(8); - std::streamoff shift = start_location-dataStream.tellg(); - // move to specified location, which should be usually 0; - dataStream.seekg(shift,std::ios_base::cur); + std::streamoff shift = start_location-dataStream.tellg(); + // move to specified location, which should be usually 0; + dataStream.seekg(shift,std::ios_base::cur); - dataStream.read(&data_buffer[0],4); + dataStream.read(&data_buffer[0],4); - unsigned int file_name_length= *((uint32_t*)(&data_buffer[0])); - //skip component header file name - dataStream.seekg(file_name_length,std::ios_base::cur); + unsigned int file_name_length= *((uint32_t*)(&data_buffer[0])); + //skip component header file name + dataStream.seekg(file_name_length,std::ios_base::cur); - dataStream.read(&data_buffer[0],4); - unsigned int file_path_length= *((uint32_t*)(&data_buffer[0])); + dataStream.read(&data_buffer[0],4); + unsigned int file_path_length= *((uint32_t*)(&data_buffer[0])); - //skip component header file path - dataStream.seekg(file_path_length,std::ios_base::cur); + //skip component header file path + dataStream.seekg(file_path_length,std::ios_base::cur); - // move to by specifified nuber of bytes, see Matlab header above; - dataStream.seekg(4*(7+3*4),std::ios_base::cur); + // move to by specified number of bytes, see Matlab header above; + dataStream.seekg(4*(7+3*4),std::ios_base::cur); - // read number of energy bins; - dataStream.read(&data_buffer[0],4); - unsigned int nEn_bins = *((uint32_t*)(&data_buffer[0])); - // skip energy values; - dataStream.seekg(4*(nEn_bins),std::ios_base::cur); + // read number of energy bins; + dataStream.read(&data_buffer[0],4); + unsigned int nEn_bins = *((uint32_t*)(&data_buffer[0])); + // skip energy values; + dataStream.seekg(4*(nEn_bins),std::ios_base::cur); - // skip offsets and conversions; - dataStream.seekg(4*(4+4*4+4),std::ios_base::cur); + // skip offsets and conversions; + dataStream.seekg(4*(4+4*4+4),std::ios_base::cur); - // get labels matix size; - dataStream.read(&data_buffer[0],8); + // get labels matrix size; + dataStream.read(&data_buffer[0],8); - unsigned int nRows = *((uint32_t*)(&data_buffer[0])); - unsigned int nCols = *((uint32_t*)(&data_buffer[4])); + unsigned int nRows = *((uint32_t*)(&data_buffer[0])); + unsigned int nCols = *((uint32_t*)(&data_buffer[4])); - // skip labels - dataStream.seekg(nRows*nCols,std::ios_base::cur); + // skip labels + dataStream.seekg(nRows*nCols,std::ios_base::cur); - std::streamoff end_location = dataStream.tellg(); - return end_location; + std::streamoff end_location = dataStream.tellg(); + return end_location; - } - /**Block 3: Detpar: parse positions of the contributed detectors. These detectors have to be the same for all contributing spe files - *@param dataStream -- the open file hanlder responsible for IO operations - *@param start_location -- initial file position of the detectors data within the binary file - * - *@returns: the file location of the first byte behind this header */ - std::streamoff dataPositions::parse_sqw_detpar(std::ifstream &dataStream,std::streamoff start_location) - { // - std::vector data_buffer(8); - - std::streamoff shift = start_location-dataStream.tellg(); - // move to specified location, which should be usually 0; - dataStream.seekg(shift,std::ios_base::cur); - - - dataStream.read(&data_buffer[0],4); - unsigned int file_name_length= *((uint32_t*)(&data_buffer[0])); - //skip component header file name - dataStream.seekg(file_name_length,std::ios_base::cur); - - dataStream.read(&data_buffer[0],4); - unsigned int file_path_length= *((uint32_t*)(&data_buffer[0])); - //skip component header file path - dataStream.seekg(file_path_length,std::ios_base::cur); - - dataStream.read(&data_buffer[0],4); - unsigned int num_detectors = *((uint32_t*)(&data_buffer[0])); - //skip detector information - dataStream.seekg(num_detectors*6*4,std::ios_base::cur); - - std::streamoff end_location = dataStream.tellg(); - return end_location; + } + /**Block 3: Detpar: parse positions of the contributed detectors. These detectors have to be the same for all contributing spe files + *@param dataStream -- the open file handler responsible for IO operations + *@param start_location -- initial file position of the detectors data within the binary file + * + *@returns: the file location of the first byte behind this header */ + std::streamoff dataPositions::parse_sqw_detpar(std::ifstream &dataStream,std::streamoff start_location) + { // + std::vector data_buffer(8); + + std::streamoff shift = start_location-dataStream.tellg(); + // move to specified location, which should be usually 0; + dataStream.seekg(shift,std::ios_base::cur); + + + dataStream.read(&data_buffer[0],4); + unsigned int file_name_length= *((uint32_t*)(&data_buffer[0])); + //skip component header file name + dataStream.seekg(file_name_length,std::ios_base::cur); + + dataStream.read(&data_buffer[0],4); + unsigned int file_path_length= *((uint32_t*)(&data_buffer[0])); + //skip component header file path + dataStream.seekg(file_path_length,std::ios_base::cur); + + dataStream.read(&data_buffer[0],4); + unsigned int num_detectors = *((uint32_t*)(&data_buffer[0])); + //skip detector information + dataStream.seekg(num_detectors*6*4,std::ios_base::cur); + + std::streamoff end_location = dataStream.tellg(); + return end_location; - } - /**Block 4: Data: parse positions of the data fields - *@param dataStream -- the open file hanlder responsible for IO operations - *@param data_start -- Initial position of the data block4 within the data file - @param nBins -- the vector of bin sizes for MD image - @param nDataPoints -- number of pixels (MD events) contributing to the image - */ - void dataPositions::parse_data_locations(std::ifstream &dataStream,std::streamoff data_start, - std::vector &nBins,uint64_t &nDataPoints) - { - std::vector data_buffer(12); + } + /**Block 4: Data: parse positions of the data fields + *@param dataStream -- the open file handler responsible for IO operations + *@param data_start -- Initial position of the data block4 within the data file + @param nBins -- the vector of bin sizes for MD image + @param nDataPoints -- number of pixels (MD events) contributing to the image + */ + void dataPositions::parse_data_locations(std::ifstream &dataStream,std::streamoff data_start, + std::vector &nBins,uint64_t &nDataPoints) + { + std::vector data_buffer(12); - std::streamoff shift = data_start-dataStream.tellg(); - // move to specified location, which should be usually 0; - dataStream.seekg(shift,std::ios_base::cur); + std::streamoff shift = data_start-dataStream.tellg(); + // move to specified location, which should be usually 0; + dataStream.seekg(shift,std::ios_base::cur); - dataStream.read(&data_buffer[0],4); + dataStream.read(&data_buffer[0],4); - unsigned int file_name_length= *((uint32_t*)(&data_buffer[0])); - //skip dummy file name - dataStream.seekg(file_name_length,std::ios_base::cur); + unsigned int file_name_length= *((uint32_t*)(&data_buffer[0])); + //skip dummy file name + dataStream.seekg(file_name_length,std::ios_base::cur); - dataStream.read(&data_buffer[0],4); - unsigned int file_path_length= *((uint32_t*)(&data_buffer[0])); + dataStream.read(&data_buffer[0],4); + unsigned int file_path_length= *((uint32_t*)(&data_buffer[0])); - //skip dummy file path - dataStream.seekg(file_path_length,std::ios_base::cur); + //skip dummy file path + dataStream.seekg(file_path_length,std::ios_base::cur); - dataStream.read(&data_buffer[0],4); - unsigned int data_title_length = *((uint32_t*)(&data_buffer[0])); + dataStream.read(&data_buffer[0],4); + unsigned int data_title_length = *((uint32_t*)(&data_buffer[0])); - //skip data title - dataStream.seekg(data_title_length,std::ios_base::cur); + //skip data title + dataStream.seekg(data_title_length,std::ios_base::cur); - this->geom_start = dataStream.tellg(); + this->geom_start = dataStream.tellg(); - dataStream.seekg(4*(3+3+4+16+4),std::ios_base::cur); + dataStream.seekg(4*(3+3+4+16+4),std::ios_base::cur); - // get label information and skip labels; - dataStream.read(&data_buffer[0],8); + // get label information and skip labels; + dataStream.read(&data_buffer[0],8); - unsigned int n_labels = *((uint32_t*)(&data_buffer[0])); - unsigned int labels_length = *((uint32_t*)(&data_buffer[4])); - dataStream.seekg(n_labels*labels_length,std::ios_base::cur); + unsigned int n_labels = *((uint32_t*)(&data_buffer[0])); + unsigned int labels_length = *((uint32_t*)(&data_buffer[4])); + dataStream.seekg(n_labels*labels_length,std::ios_base::cur); - this->npax_start = dataStream.tellg(); + this->npax_start = dataStream.tellg(); - dataStream.read(&data_buffer[0],4); + dataStream.read(&data_buffer[0],4); - unsigned int npax = *((uint32_t*)(&data_buffer[0])); - unsigned int niax = 4-npax; - if(niax!=0) - { - dataStream.seekg(3*niax*4,std::ios_base::cur); - } - if(npax!=0) - { - nBins.resize(npax); + unsigned int npax = *((uint32_t*)(&data_buffer[0])); + unsigned int niax = 4-npax; + if(niax!=0) + { + dataStream.seekg(3*niax*4,std::ios_base::cur); + } + if(npax!=0) + { + nBins.resize(npax); - // skip projection axis - dataStream.seekg(npax*4,std::ios_base::cur); + // skip projection axis + dataStream.seekg(npax*4,std::ios_base::cur); - mdImageSize = 1; - for(unsigned int i=0;is_start = dataStream.tellg(); + // and skip to errors + dataStream.seekg(mdImageSize*4,std::ios_base::cur); - } - // signal start: - this->s_start = dataStream.tellg(); - // and skip to errors - dataStream.seekg(mdImageSize*4,std::ios_base::cur); + // error start: + this->err_start= dataStream.tellg(); + dataStream.seekg(mdImageSize*4,std::ios_base::cur); - // error start: - this->err_start= dataStream.tellg(); - dataStream.seekg(mdImageSize*4,std::ios_base::cur); + // dnd data file. we do not support this? + if(dataStream.eof()) + { + nDataPoints = 0; + return; + //throw(std::invalid_argument("DND Horace datasets are not supported by Mantid")); + } - // dnd data file. we do not suppor this? - if(dataStream.eof()) - { - nDataPoints = 0; - return; - //throw(std::invalid_argument("DND Horace datasets are not supported by Mantid")); - } + this->n_cell_pix_start=dataStream.tellg(); + // skip to the end of pixels; + dataStream.seekg(mdImageSize*8,std::ios_base::cur); - this->n_cell_pix_start=dataStream.tellg(); - // skip to the end of pixels; - dataStream.seekg(mdImageSize*8,std::ios_base::cur); + if(dataStream.eof()){ + nDataPoints = 0; + return; + //throw(std::invalid_argument("DND b+ Horace datasets are not supported by Mantid")); + } + this->min_max_start = dataStream.tellg(); + // skip min-max start + //[data.urange,count,ok,mess] = fread_catch(fid,[2,4],'float32'); if ~all(ok); return; end; + dataStream.seekg(8*4,std::ios_base::cur); + + if(dataStream.eof()){ + nDataPoints = 0; + return; + //throw(std::invalid_argument("SQW a- Horace datasets are not supported by Mantid")); + } + // skip redundant field and read nPix (number of data points) + dataStream.read(&data_buffer[0],12); - if(dataStream.eof()){ - nDataPoints = 0; - return; - //throw(std::invalid_argument("DND b+ Horace datasets are not supported by Mantid")); - } - this->min_max_start = dataStream.tellg(); - // skip min-max start - //[data.urange,count,ok,mess] = fread_catch(fid,[2,4],'float32'); if ~all(ok); return; end; - dataStream.seekg(8*4,std::ios_base::cur); - - if(dataStream.eof()){ - nDataPoints = 0; - return; - //throw(std::invalid_argument("SQW a- Horace datasets are not supported by Mantid")); + nDataPoints =(size_t)( *((uint64_t*)(&data_buffer[4]))); + this->pix_start = dataStream.tellg(); } - // skip redundant field and read nPix (number of data points) - dataStream.read(&data_buffer[0],12); - nDataPoints =(size_t)( *((uint64_t*)(&data_buffer[4]))); - this->pix_start = dataStream.tellg(); - } - - /*================================================================================== - EndRegion: - ==================================================================================*/ + /*================================================================================== + EndRegion: + ==================================================================================*/ } // endNamespace LoadSQWHelper -} + } } diff --git a/Code/Mantid/Framework/MDAlgorithms/src/MDNormSXD.cpp b/Code/Mantid/Framework/MDAlgorithms/src/MDNormSXD.cpp new file mode 100644 index 000000000000..49fa22981141 --- /dev/null +++ b/Code/Mantid/Framework/MDAlgorithms/src/MDNormSXD.cpp @@ -0,0 +1,725 @@ +#include "MantidMDAlgorithms/MDNormSXD.h" +#include "MantidMDEvents/MDEventWorkspace.h" +#include "MantidMDEvents/MDHistoWorkspace.h" +#include "MantidAPI/WorkspaceValidators.h" +#include "MantidKernel/TimeSeriesProperty.h" +#include "MantidDataObjects/EventWorkspace.h" + +namespace Mantid +{ +namespace MDAlgorithms +{ + + using Mantid::Kernel::Direction; + using Mantid::API::WorkspaceProperty; + using namespace Mantid::MDEvents; + using namespace Mantid::API; + using namespace Mantid::Kernel; + + namespace{ + + ///function to compare two intersections (h,k,l,Momentum) by Momentum + bool compareMomentum(const Mantid::Kernel::VMD &v1, const Mantid::Kernel::VMD &v2) + { + return (v1[3]("InputWorkspace","",Direction::Input), "An input MDWorkspace."); + + std::string dimChars = getDimensionChars(); + // --------------- Axis-aligned properties --------------------------------------- + for (size_t i=0; i(propName,"",Direction::Input), + "Binning parameters for the " + Strings::toString(i) + "th dimension.\n" + "Enter it as a comma-separated list of values with the format: 'name,minimum,maximum,number_of_bins'. Leave blank for NONE."); + } + + auto fluxValidator = boost::make_shared(); + fluxValidator->add("Momentum"); + fluxValidator->add(); + fluxValidator->add(); + auto solidAngleValidator = fluxValidator->clone(); + fluxValidator->add(); + + declareProperty(new WorkspaceProperty<>("FluxWorkspace","",Direction::Input,fluxValidator), "An input workspace containing integrated momentum dependent flux."); + declareProperty(new WorkspaceProperty<>("SolidAngleWorkspace","",Direction::Input,solidAngleValidator), "An input workspace containing momentum integrated vanadium (a measure of the solid angle)."); + + declareProperty(new WorkspaceProperty("OutputWorkspace","",Direction::Output), "A name for the output data MDHistoWorkspace."); + declareProperty(new WorkspaceProperty("OutputNormalizationWorkspace","",Direction::Output), "A name for the output normalization MDHistoWorkspace."); + } + + //---------------------------------------------------------------------------------------------- + /** Execute the algorithm. + */ + void MDNormSXD::exec() + { + bool skipProcessing=false; + m_inputWS=getProperty("InputWorkspace"); + WorkspaceHistory hist=m_inputWS->getHistory(); + std::string dEMode(""); + if (hist.lastAlgorithm()->name()=="ConvertToMD") + { + dEMode=hist.lastAlgorithm()->getPropertyValue("dEAnalysisMode"); + } + else if (((hist.lastAlgorithm()->name()=="Load")||(hist.lastAlgorithm()->name()=="LoadMD"))&&(hist.getAlgorithmHistory(hist.size()-2)->name()=="ConvertToMD")) + { + //get dEAnalysisMode + PropertyHistories histvec=hist.getAlgorithmHistory(hist.size()-2)->getProperties(); + for(auto it=histvec.begin();it!=histvec.end();++it) + { + if((*it)->name()=="dEAnalysisMode") + { + dEMode=(*it)->value(); + } + } + } + else + { + throw std::runtime_error("The last algorithm in the history of the input workspace is not ConvertToMD"); + } + if (dEMode!="Elastic") + { + throw std::runtime_error("This is not elastic scattering data"); + } + hMin=m_inputWS->getDimension(0)->getMinimum(); + kMin=m_inputWS->getDimension(1)->getMinimum(); + lMin=m_inputWS->getDimension(2)->getMinimum(); + hMax=m_inputWS->getDimension(0)->getMaximum(); + kMax=m_inputWS->getDimension(1)->getMaximum(); + lMax=m_inputWS->getDimension(2)->getMaximum(); + + //initialize some variables + hIntegrated=true; + kIntegrated=true; + lIntegrated=true; + hIndex=-1; + kIndex=-1; + lIndex=-1; + + //check for other dimensions if we could measure anything in the original data + std::vector otherValues; + for(size_t i=3;igetNumDims();i++) + { + float dimMin=static_cast(m_inputWS->getDimension(i)->getMinimum()); + float dimMax=static_cast(m_inputWS->getDimension(i)->getMaximum()); + Kernel::TimeSeriesProperty *run_property = dynamic_cast *>(m_inputWS->getExperimentInfo(0)->run().getProperty(m_inputWS->getDimension(i)->getName())); + if (run_property!=NULL) + { + coord_t value=static_cast(run_property->firstValue()); + otherValues.push_back(value); + //in the original MD data no time was spent measuring between dimMin and dimMax + if ((valuedimMax)) + { + skipProcessing=true; + } + } + delete run_property; + } + + // Run BinMD + Workspace_sptr outputWS = getProperty("OutputWorkspace"); + auto props=getProperties(); + IAlgorithm_sptr bin = createChildAlgorithm("BinMD",0.0,0.3); + bin->setPropertyValue("AxisAligned","1"); + for(auto it=props.begin();it!=props.end();++it) + { + if(((*it)->name()!="FluxWorkspace")&&((*it)->name()!="SolidAngleWorkspace")&&((*it)->name()!="OutputNormalizationWorkspace")) + bin->setPropertyValue((*it)->name(),(*it)->value()); + } + bin->executeAsChildAlg(); + outputWS=bin->getProperty("OutputWorkspace"); + this->setProperty("OutputWorkspace", outputWS); + + //copy the MDHisto workspace, and change signals and errors to 0. + m_normWS=MDHistoWorkspace_sptr(new MDHistoWorkspace(*(boost::dynamic_pointer_cast(outputWS)))); + m_normWS->setTo(0.,0.,0.); + + //get indices of the original dimensions in the output workspace, and if not found, the corresponding dimension is integrated + Mantid::Kernel::Matrix mat=m_normWS->getTransformFromOriginal(0)->makeAffineMatrix(); + + for (size_t row=0; rowgetDimension(row)->getMinimum()) hMin=m_normWS->getDimension(row)->getMinimum(); + if(hMax>m_normWS->getDimension(row)->getMaximum()) hMax=m_normWS->getDimension(row)->getMaximum(); + if((hMin>m_normWS->getDimension(row)->getMaximum())||(hMaxgetDimension(row)->getMinimum())) + { + skipProcessing=true; + } + } + if(mat[row][1]==1.) + { + kIntegrated=false; + kIndex=row; + if(kMingetDimension(row)->getMinimum()) kMin=m_normWS->getDimension(row)->getMinimum(); + if(kMax>m_normWS->getDimension(row)->getMaximum()) kMax=m_normWS->getDimension(row)->getMaximum(); + if((kMin>m_normWS->getDimension(row)->getMaximum())||(kMaxgetDimension(row)->getMinimum())) + { + skipProcessing=true; + } + } + if(mat[row][2]==1.) + { + lIntegrated=false; + lIndex=row; + if(lMingetDimension(row)->getMinimum()) lMin=m_normWS->getDimension(row)->getMinimum(); + if(lMax>m_normWS->getDimension(row)->getMaximum()) lMax=m_normWS->getDimension(row)->getMaximum(); + if((lMin>m_normWS->getDimension(row)->getMaximum())||(lMaxgetDimension(row)->getMinimum())) + { + skipProcessing=true; + } + + for(size_t col=3;colm_normWS->getDimension(row)->getMaximum())||(valgetDimension(row)->getMinimum())) + { + skipProcessing=true; + } + } + } + } + } + + auto &hDim = *m_normWS->getDimension(hIndex); + m_hX.resize( hDim.getNBins() ); + for(size_t i = 0; i < m_hX.size(); ++i) + { + m_hX[i] = hDim.getX(i); + } + + auto &kDim = *m_normWS->getDimension(kIndex); + m_kX.resize( kDim.getNBins() ); + for(size_t i = 0; i < m_kX.size(); ++i) + { + m_kX[i] = kDim.getX(i); + } + + auto &lDim = *m_normWS->getDimension(lIndex); + m_lX.resize( lDim.getNBins() ); + for(size_t i = 0; i < m_lX.size(); ++i) + { + m_lX[i] = lDim.getX(i); + } + + Mantid::API::MatrixWorkspace_const_sptr integrFlux = getProperty("FluxWorkspace"); + integrFlux->getXMinMax(KincidentMin,KincidentMax); + Mantid::API::MatrixWorkspace_const_sptr sA=getProperty("SolidAngleWorkspace"); + + if (skipProcessing) + { + g_log.warning("Binning limits are outside the limits of the MDWorkspace\n"); + } + else + { + double PC=m_normWS->getExperimentInfo(0)->run().getProtonCharge(); + Kernel::PropertyWithValue< std::vector > *prop=dynamic_cast< Mantid::Kernel::PropertyWithValue >*>(m_normWS->getExperimentInfo(0)->getLog("RUBW_MATRIX")); + if (prop==NULL) + { + throw std::runtime_error("No RUBW_MATRIX"); + } + else + { + Mantid::Kernel::DblMatrix RUBW((*prop)()); //includes the 2*pi factor but not goniometer for now :) + transf=m_normWS->getExperimentInfo(0)->run().getGoniometerMatrix()*RUBW; + transf.Invert(); + } + //FIXME: the detector positions are from the IDF. Need to account for calibration + std::vector detIDS=m_normWS->getExperimentInfo(0)->getInstrument()->getDetectorIDs(true); + + Mantid::API::Progress *prog=new Mantid::API::Progress(this,0.3,1,static_cast(detIDS.size())); + const detid2index_map d2m = integrFlux->getDetectorIDToWorkspaceIndexMap(); + const detid2index_map d2mSA = sA->getDetectorIDToWorkspaceIndexMap(); + auto instrument = m_normWS->getExperimentInfo(0)->getInstrument(); + + PARALLEL_FOR1(m_normWS) + for(int i=0;i(detIDS.size());i++) + { + PARALLEL_START_INTERUPT_REGION + Mantid::Geometry::IDetector_const_sptr detector=instrument->getDetector(detIDS[i]); + if(!detector->isMonitor()&&!detector->isMasked()) + { + //get intersections + std::vector intersections=calculateIntersections(detector); + + if(!intersections.empty()) + { + //calculate indices + //add to the correct signal at that particular index + //NOTE: if parallel it has to be atomic/critical + + //get flux spectrum number + size_t sp=d2m.find(detIDS[i])->second; + // get the solid angle + double solid=sA->readY(d2mSA.find(detIDS[i])->second)[0]*PC; + + const size_t sizeOfMVD = intersections.front().size(); + // pre-allocate for efficiency + std::vector pos( sizeOfMVD + otherValues.size() ); + + auto intersectionsBegin = intersections.begin(); + + // calculate integrals for the intersection + + // momentum values at intersections + std::vector xValues( intersections.size() ); + // buffer for the integrals + std::vector yValues( intersections.size() ); + { + // copy momenta to xValues + auto x = xValues.begin(); + for (auto it = intersectionsBegin; it != intersections.end(); ++it, ++x) + { + *x = (*it)[3]; + } + } + // calculate integrals at momenta from xValues by interpolating between points in spectrum sp + // of workspace integrFlux. The result is stored in yValues + calcIntegralsForIntersections( xValues, *integrFlux, sp, yValues ); + + for (auto it = intersectionsBegin + 1; it != intersections.end(); ++it) + { + //Mantid::Kernel::VMD deltav=(*it)-(*(it-1));//difference between consecutive intersections + // the full vector isn't used so compute only what is necessary + const double xStart = (*(it-1))[3]; + const double xEnd = (*it)[3]; + const double delta = xEnd - xStart; + const double eps=1e-7;//do not integrate if momemntum difference is smaller than eps, assume contribution is 0 + + if (delta > eps) + { + //Mantid::Kernel::VMD avev=((*it)+(*(it-1)))*0.5;//average between two intersection (to get position) + //std::vector pos=avev.toVector(); + //pos.insert(pos.end()-1,otherValues.begin(),otherValues.end()); + // a bit longer and less readable but faster version of the above + std::transform( it->getBareArray(), it->getBareArray() + sizeOfMVD, (it-1)->getBareArray(), pos.begin(), std::plus() ); + std::transform( pos.begin(), pos.begin() + sizeOfMVD, pos.begin(), std::bind2nd( std::multiplies(), 0.5 ) ); + std::copy( otherValues.begin(), otherValues.end(), pos.begin() + sizeOfMVD ); + + std::vector posNew = mat*pos; + size_t linIndex=m_normWS->getLinearIndexAtCoord(posNew.data()); + + if(linIndex!=size_t(-1)) + { + // index of the current intersection + size_t k = static_cast( std::distance( intersectionsBegin, it ) ); + // signal = integral between two consecutive intersections + double signal = yValues[k] - yValues[k - 1]; + signal*=solid; + + PARALLEL_CRITICAL(updateMD) + { + signal+=m_normWS->getSignalAt(linIndex); + m_normWS->setSignalAt(linIndex,signal); + } + } + } + } + + } + } + prog->report(); + PARALLEL_END_INTERUPT_REGION + } + PARALLEL_CHECK_INTERUPT_REGION + delete prog; + } + + this->setProperty("OutputNormalizationWorkspace",m_normWS); + + } + + + std::vector MDNormSXD::calculateIntersections(Mantid::Geometry::IDetector_const_sptr detector) + { + std::vector intersections; + double th=detector->getTwoTheta(V3D(0,0,0),V3D(0,0,1)); + double phi=detector->getPhi(); + V3D q(-sin(th)*cos(phi),-sin(th)*sin(phi),1.-cos(th)); + q=transf*q; + double hStart=q.X()*KincidentMin,hEnd=q.X()*KincidentMax; + double kStart=q.Y()*KincidentMin,kEnd=q.Y()*KincidentMax; + double lStart=q.Z()*KincidentMin,lEnd=q.Z()*KincidentMax; + + double eps=1e-7; + + auto hNBins = m_hX.size(); + auto kNBins = m_kX.size(); + auto lNBins = m_lX.size(); + intersections.reserve( hNBins + kNBins + lNBins + 8 ); + + //calculate intersections with planes perpendicular to h + if (fabs(hStart-hEnd)>eps) + { + double fmom=(KincidentMax-KincidentMin)/(hEnd-hStart); + double fk=(kEnd-kStart)/(hEnd-hStart); + double fl=(lEnd-lStart)/(hEnd-hStart); + if(!hIntegrated) + { + for(size_t i=0;i=hMin)&&(hi<=hMax)&&((hStart-hi)*(hEnd-hi)<0)) + { + // if hi is between hStart and hEnd, then ki and li will be between kStart, kEnd and lStart, lEnd and momi will be between KincidentMin and KnincidemtmMax + double ki=fk*(hi-hStart)+kStart; + double li=fl*(hi-hStart)+lStart; + if ((ki>=kMin)&&(ki<=kMax)&&(li>=lMin)&&(li<=lMax)) + { + double momi=fmom*(hi-hStart)+KincidentMin; + Mantid::Kernel::VMD v(hi,ki,li,momi); + intersections.push_back(v); + } + } + } + } + + double momhMin=fmom*(hMin-hStart)+KincidentMin; + if ((momhMin>KincidentMin)&&(momhMin=kMin)&&(khmin<=kMax)&&(lhmin>=lMin)&&(lhmin<=lMax)) + { + Mantid::Kernel::VMD v(hMin,khmin,lhmin,momhMin); + intersections.push_back(v); + } + } + double momhMax=fmom*(hMax-hStart)+KincidentMin; + if ((momhMax>KincidentMin)&&(momhMax=kMin)&&(khmax<=kMax)&&(lhmax>=lMin)&&(lhmax<=lMax)) + { + Mantid::Kernel::VMD v(hMax,khmax,lhmax,momhMax); + intersections.push_back(v); + } + } + } + + //calculate intersections with planes perpendicular to k + if (fabs(kStart-kEnd)>eps) + { + double fmom=(KincidentMax-KincidentMin)/(kEnd-kStart); + double fh=(hEnd-hStart)/(kEnd-kStart); + double fl=(lEnd-lStart)/(kEnd-kStart); + if(!kIntegrated) + { + for(size_t i=0;i=kMin)&&(ki<=kMax)&&((kStart-ki)*(kEnd-ki)<0)) + { + // if ki is between kStart and kEnd, then hi and li will be between hStart, hEnd and lStart, lEnd + double hi=fh*(ki-kStart)+hStart; + double li=fl*(ki-kStart)+lStart; + if ((hi>=hMin)&&(hi<=hMax)&&(li>=lMin)&&(li<=lMax)) + { + double momi=fmom*(ki-kStart)+KincidentMin; + Mantid::Kernel::VMD v(hi,ki,li,momi); + intersections.push_back(v); + } + } + } + } + + double momkMin=fmom*(kMin-kStart)+KincidentMin; + if ((momkMin>KincidentMin)&&(momkMin=hMin)&&(hkmin<=hMax)&&(lkmin>=lMin)&&(lkmin<=lMax)) + { + Mantid::Kernel::VMD v(hkmin,kMin,lkmin,momkMin); + intersections.push_back(v); + } + } + double momkMax=fmom*(kMax-kStart)+KincidentMin; + if ((momkMax>KincidentMin)&&(momkMax=hMin)&&(hkmax<=hMax)&&(lkmax>=lMin)&&(lkmax<=lMax)) + { + Mantid::Kernel::VMD v(hkmax,kMax,lkmax,momkMax); + intersections.push_back(v); + } + } + } + + //calculate intersections with planes perpendicular to l + if (fabs(lStart-lEnd)>eps) + { + double fmom=(KincidentMax-KincidentMin)/(lEnd-lStart); + double fh=(hEnd-hStart)/(lEnd-lStart); + double fk=(kEnd-kStart)/(lEnd-lStart); + if(!lIntegrated) + { + for(size_t i=0;i=lMin)&&(li<=lMax)&&((lStart-li)*(lEnd-li)<0)) + { + // if li is between lStart and lEnd, then hi and ki will be between hStart, hEnd and kStart, kEnd + double hi=fh*(li-lStart)+hStart; + double ki=fk*(li-lStart)+kStart; + if ((hi>=hMin)&&(hi<=hMax)&&(ki>=kMin)&&(ki<=kMax)) + { + double momi=fmom*(li-lStart)+KincidentMin; + Mantid::Kernel::VMD v(hi,ki,li,momi); + intersections.push_back(v); + } + } + } + } + + double momlMin=fmom*(lMin-lStart)+KincidentMin; + if ((momlMin>KincidentMin)&&(momlMin=hMin)&&(hlmin<=hMax)&&(klmin>=kMin)&&(klmin<=kMax)) + { + Mantid::Kernel::VMD v(hlmin,klmin,lMin,momlMin); + intersections.push_back(v); + } + } + double momlMax=fmom*(lMax-lStart)+KincidentMin; + if ((momlMax>KincidentMin)&&(momlMax=hMin)&&(hlmax<=hMax)&&(klmax>=kMin)&&(klmax<=kMax)) + { + Mantid::Kernel::VMD v(hlmax,klmax,lMax,momlMax); + intersections.push_back(v); + } + } + } + + //add endpoints + if ((hStart>=hMin)&&(hStart<=hMax)&&(kStart>=kMin)&&(kStart<=kMax)&&(lStart>=lMin)&&(lStart<=lMax)) + { + Mantid::Kernel::VMD v(hStart,kStart,lStart,KincidentMin); + intersections.push_back(v); + } + if ((hEnd>=hMin)&&(hEnd<=hMax)&&(kEnd>=kMin)&&(kEnd<=kMax)&&(lEnd>=lMin)&&(lEnd<=lMax)) + { + Mantid::Kernel::VMD v(hEnd,kEnd,lEnd,KincidentMax); + intersections.push_back(v); + } + + //sort intersections by momentum + typedef std::vector::iterator IterType; + std::stable_sort(intersections.begin(),intersections.end(),compareMomentum); + + return intersections; + } + + /** + * Integrate spectra in flux at x-values in integrFlux and save the results in y-vectors of integrFlux. + * @param flux :: A workspace to integrate. + * @param integrFlux :: A workspace to store the results. + */ + void MDNormSXD::integrateFlux( const DataObjects::EventWorkspace& flux, API::MatrixWorkspace &integrFlux ) + { + size_t nSpec = flux.getNumberHistograms(); + assert( nSpec == integrFlux.getNumberHistograms() ); + + // claculate the integration points and save them in the x-vactors of integrFlux + double xMin = flux.getEventXMin(); + double xMax = flux.getEventXMax(); + double dx = ( xMax - xMin ) / static_cast( integrFlux.blocksize() - 1 ); + auto &X = integrFlux.dataX(0); + auto ix = X.begin(); + // x-values are equally spaced between the min and max tof in the first flux spectrum + for(double x = xMin; ix != X.end(); ++ix, x += dx) + { + *ix = x; + } + + // loop overr the spectra and integrate + for(size_t sp = 0; sp < nSpec; ++sp) + { + if ( sp > 0 ) + { + integrFlux.setX(sp,X); + } + std::vector el = flux.getEventList(sp).getWeightedEventsNoTime(); + auto &outY = integrFlux.dataY(sp); + double sum = 0; + auto x = X.begin() + 1; + size_t i = 1; + // the integral is a running sum of the event weights in the spectrum + for(auto evnt = el.begin(); evnt != el.end(); ++evnt) + { + double tof = evnt->tof(); + while( x != X.end() && *x < tof ) + { + ++x; ++i; + } + if ( x == X.end() ) break; + sum += evnt->weight(); + outY[i] = sum; + } + } + } + + /** + * LInearly interpolate between the points in integrFlux at xValues and save the results in yValues. + * @param xValues :: X-values at which to interpolate + * @param integrFlux :: A workspace with the spectra to interpolate + * @param sp :: A workspace index for a spectrum in integrFlux to interpolate. + * @param yValues :: A vector to save the results. + */ + void MDNormSXD::calcIntegralsForIntersections( const std::vector &xValues, const API::MatrixWorkspace &integrFlux, size_t sp, std::vector &yValues ) const + { + assert( xValues.size() == yValues.size() ); + + // the x-data from the workspace + auto &xData = integrFlux.readX(sp); + const double xStart = xData.front(); + const double xEnd = xData.back(); + + // the values in integrFlux are expected to be integrals of a non-negative function + // ie they must make a non-decreasing function + auto &yData = integrFlux.readY(sp); + size_t spSize = yData.size(); + + const double yMin = 0.0; + const double yMax = yData.back(); + + size_t nData = xValues.size(); + // all integrals below xStart must be 0 + if (xValues[nData-1] < xStart) + { + std::fill( yValues.begin(), yValues.end(), yMin ); + return; + } + + // all integrals above xEnd must be equal tp yMax + if ( xValues[0] > xEnd ) + { + std::fill( yValues.begin(), yValues.end(), yMax ); + return; + } + + size_t i = 0; + // integrals below xStart must be 0 + while(i < nData - 1 && xValues[i] < xStart) + { + yValues[i] = yMin; + i++; + } + size_t j = 0; + for(;i= spSize - 1) + { + yValues[i] = yMax; + } + else + { + double xi = xValues[i]; + while(j < spSize - 1 && xi > xData[j]) j++; + // if x falls onto an interpolation point return the corresponding y + if (xi == xData[j]) + { + yValues[i] = yData[j]; + } + else if (j == spSize - 1) + { + // if we get above xEnd it's yMax + yValues[i] = yMax; + } + else if (j > 0) + { + // interpolate between the consecutive points + double x0 = xData[j-1]; + double x1 = xData[j]; + double y0 = yData[j-1]; + double y1 = yData[j]; + yValues[i] = y0 + (y1 - y0)*(xi - x0)/(x1 - x0); + } + else // j == 0 + { + yValues[i] = yMin; + } + } + } + + } + +} // namespace MDAlgorithms +} // namespace Mantid diff --git a/Code/Mantid/Framework/MDAlgorithms/src/MergeMDFiles.cpp b/Code/Mantid/Framework/MDAlgorithms/src/MergeMDFiles.cpp index ef5ec50e7f47..2798ea8d4b2d 100644 --- a/Code/Mantid/Framework/MDAlgorithms/src/MergeMDFiles.cpp +++ b/Code/Mantid/Framework/MDAlgorithms/src/MergeMDFiles.cpp @@ -159,17 +159,24 @@ namespace MDAlgorithms TargetBox->clear(); uint64_t nBoxEvents(0); + std::vector numFileEvents(m_EventLoader.size()); + for (size_t iw=0; iwm_EventLoader.size(); iw++) { size_t ID = TargetBox->getID(); + numFileEvents[iw] = static_cast(m_fileComponentsStructure[iw].getEventIndex()[2*ID+1]); + nBoxEvents += numFileEvents[iw]; + } - uint64_t fileLocation = m_fileComponentsStructure[iw].getEventIndex()[2*ID+0]; - size_t numFileEvents = static_cast(m_fileComponentsStructure[iw].getEventIndex()[2*ID+1]); - if(numFileEvents==0)continue; - //TODO: it is possible to avoid the reallocation of the memory at each load - TargetBox->loadAndAddFrom(m_EventLoader[iw],fileLocation,numFileEvents); + // At this point memory required is known, so it is reserved all in one go + TargetBox->reserveMemoryForLoad(nBoxEvents); - nBoxEvents += numFileEvents; + for (size_t iw=0; iwm_EventLoader.size(); iw++) + { + size_t ID = TargetBox->getID(); + uint64_t fileLocation = m_fileComponentsStructure[iw].getEventIndex()[2*ID+0]; + if(numFileEvents[iw]==0) continue; + TargetBox->loadAndAddFrom(m_EventLoader[iw],fileLocation,numFileEvents[iw]); } return nBoxEvents; @@ -316,7 +323,8 @@ namespace MDAlgorithms { g_log.notice() << "Starting SaveMD to update the file back-end." << std::endl; // create or open WS group and put there additional information about WS and its dimensions - boost::scoped_ptr< ::NeXus::File> file(MDBoxFlatTree::createOrOpenMDWSgroup(outputFile,m_nDims,m_MDEventType,false)); + bool old_data_there; + boost::scoped_ptr< ::NeXus::File> file(MDBoxFlatTree::createOrOpenMDWSgroup(outputFile,m_nDims,m_MDEventType,false,old_data_there)); this->progress(0.94, "Saving ws history and dimensions"); MDBoxFlatTree::saveWSGenericInfo(file.get(),m_OutIWS); // Save each ExperimentInfo to a spot in the file diff --git a/Code/Mantid/Framework/MDAlgorithms/src/Quantification/ForegroundModel.cpp b/Code/Mantid/Framework/MDAlgorithms/src/Quantification/ForegroundModel.cpp index bf1406abab52..fa4cee8cbcfc 100644 --- a/Code/Mantid/Framework/MDAlgorithms/src/Quantification/ForegroundModel.cpp +++ b/Code/Mantid/Framework/MDAlgorithms/src/Quantification/ForegroundModel.cpp @@ -161,7 +161,7 @@ namespace Mantid /** * Returns the form factor for the given \f$Q^2\f$ value - * @param qsqr :: \f$Q^2\f$ in \f$\AA^{-2}\f$ + * @param qsqr :: \f$Q^2\f$ in \f$\mbox{\AA}^{-2}\f$ * @returns The form factor for the given factor or 1.0 if turned off */ double ForegroundModel::formFactor(const double qsqr) const diff --git a/Code/Mantid/Framework/MDAlgorithms/src/Quantification/ResolutionConvolvedCrossSection.cpp b/Code/Mantid/Framework/MDAlgorithms/src/Quantification/ResolutionConvolvedCrossSection.cpp index 3b6398de3c94..663059f5c07d 100644 --- a/Code/Mantid/Framework/MDAlgorithms/src/Quantification/ResolutionConvolvedCrossSection.cpp +++ b/Code/Mantid/Framework/MDAlgorithms/src/Quantification/ResolutionConvolvedCrossSection.cpp @@ -16,14 +16,14 @@ /// Parallel region start macro. Different to generic one as that is specific to algorithms /// Assumes boolean exceptionThrow has been declared -#define OMP_START_INTERRUPT \ +#define BEGIN_PARALLEL_REGION \ if (!exceptionThrown && !this->cancellationRequestReceived()) \ { \ try \ { /// Parallel region end macro. Different to generic one as that is specific to algorithms -#define OMP_END_INTERRUPT \ +#define END_PARALLEL_REGION \ } \ catch(std::exception &ex) \ { \ @@ -40,7 +40,7 @@ } /// Check for exceptions in parallel region -#define OMP_INTERRUPT_CHECK \ +#define CHECK_PARALLEL_EXCEPTIONS \ if (exceptionThrown) \ { \ g_log.debug("Exception thrown in parallel region"); \ @@ -130,7 +130,7 @@ namespace Mantid } } - bool exceptionThrown = false; + bool exceptionThrown = false; // required for *_PARALLEL_* macros PARALLEL_FOR_NO_WSP_CHECK() for(int i = 0; i < nthreads; ++i) { @@ -140,21 +140,18 @@ namespace Mantid size_t boxIndex(0); do { - OMP_START_INTERRUPT + BEGIN_PARALLEL_REGION // Not standard macros. See top of file for reason - const double avgSignal = functionMD(*boxIterator); - const size_t resultIndex = resultsOffset + boxIndex; - PARALLEL_CRITICAL(ResolutionConvolvedCrossSection_function) - { - values.setCalculated(resultIndex, avgSignal); - } + storeCalculatedWithMutex(resultsOffset + boxIndex, + functionMD(*boxIterator), + values); ++boxIndex; - OMP_END_INTERRUPT + END_PARALLEL_REGION // Not standard macros. See top of file for reason } while(boxIterator->next()); } - OMP_INTERRUPT_CHECK + CHECK_PARALLEL_EXCEPTIONS // Not standard macros. See top of file for reason for(auto it = iterators.begin(); it != iterators.end(); ++it) { @@ -337,5 +334,18 @@ namespace Mantid } } + /** + * @param index Index value into functionValues array + * @param signal Calculated signal value + * @param functionValues [InOut] Final calculated values + */ + void + ResolutionConvolvedCrossSection::storeCalculatedWithMutex(const size_t index, const double signal, + API::FunctionValues& functionValues) const + { + Poco::FastMutex::ScopedLock lock(m_valuesMutex); + functionValues.setCalculated(index, signal); + } + } } diff --git a/Code/Mantid/Framework/MDAlgorithms/src/SaveMD.cpp b/Code/Mantid/Framework/MDAlgorithms/src/SaveMD.cpp index 606baa9cca6c..0c50915c0a00 100644 --- a/Code/Mantid/Framework/MDAlgorithms/src/SaveMD.cpp +++ b/Code/Mantid/Framework/MDAlgorithms/src/SaveMD.cpp @@ -111,18 +111,19 @@ namespace MDAlgorithms if(update) // workspace has its own file and ignores any changes to the algorithm parameters { if(!ws->isFileBacked()) - throw std::runtime_error(" attemtp to update non-file backed workspace"); + throw std::runtime_error(" attempt to update non-file backed workspace"); filename = bc->getFileIO()->getFileName(); } //----------------------------------------------------------------------------------------------------- - // create or open WS group and put there additional information about WS and its dimesnions + // create or open WS group and put there additional information about WS and its dimensions int nDims = static_cast(nd); - auto file = file_holder_type(MDBoxFlatTree::createOrOpenMDWSgroup(filename,nDims,MDE::getTypeName(),false)); + bool data_exist; + auto file = file_holder_type(MDBoxFlatTree::createOrOpenMDWSgroup(filename,nDims,MDE::getTypeName(),false,data_exist)); // Save each NEW ExperimentInfo to a spot in the file MDBoxFlatTree::saveExperimentInfos(file.get(),ws); - if(!update) + if(!update || !data_exist ) { MDBoxFlatTree::saveWSGenericInfo(file.get(),ws); } @@ -131,7 +132,7 @@ namespace MDAlgorithms MDBoxFlatTree BoxFlatStruct; //----------------------------------------------------------------------------------------------------- - if(update) // the workspace is already file backed; We not usually use this mode but want to leave it for compartibility + if(update) // the workspace is already file backed; { // remove all boxes from the DiskBuffer. DB will calculate boxes positions on HDD. bc->getFileIO()->flushCache(); diff --git a/Code/Mantid/Framework/MDAlgorithms/test/ConvertToMDComponentsTest.h b/Code/Mantid/Framework/MDAlgorithms/test/ConvertToMDComponentsTest.h index 6c1ca26e4114..958d745759d7 100644 --- a/Code/Mantid/Framework/MDAlgorithms/test/ConvertToMDComponentsTest.h +++ b/Code/Mantid/Framework/MDAlgorithms/test/ConvertToMDComponentsTest.h @@ -124,6 +124,11 @@ class ConvertToMDComponentsTest : public CxxTest::TestSuite TS_ASSERT_EQUALS(9,TableWS6->rowCount()); TS_ASSERT_EQUALS(4,TableWS5->rowCount()); + // Trow on running the test again if the workspace does not have energy attached. + ws2DNew->mutableRun().removeProperty("Ei"); + TSM_ASSERT_THROWS("WS has to have input energy for indirect methods despite the table workspace is already calculated",pAlg->preprocessDetectorsPositions(ws2DNew),std::invalid_argument); + + } void testUpdateMasksSkipped() diff --git a/Code/Mantid/Framework/MDAlgorithms/test/ConvertToMDMinMaxLocalTest.h b/Code/Mantid/Framework/MDAlgorithms/test/ConvertToMDMinMaxLocalTest.h index 5ca43c8ba0ae..3f555afd1bde 100644 --- a/Code/Mantid/Framework/MDAlgorithms/test/ConvertToMDMinMaxLocalTest.h +++ b/Code/Mantid/Framework/MDAlgorithms/test/ConvertToMDMinMaxLocalTest.h @@ -137,6 +137,7 @@ class ConvertToMDMinMaxLocalTest : public CxxTest::TestSuite Mantid::API::FrameworkManager::Instance(); ConvertToMDMinMaxLocal alg; Mantid::API::MatrixWorkspace_sptr ws=MakeWorkspace(-2.5,0.05,true,0,5); + WorkspaceCreationHelper::storeWS(WSName,ws); TS_ASSERT_THROWS_NOTHING( alg.initialize() ) diff --git a/Code/Mantid/Framework/MDAlgorithms/test/EvaluateMDFunctionTest.h b/Code/Mantid/Framework/MDAlgorithms/test/EvaluateMDFunctionTest.h new file mode 100644 index 000000000000..f1fe2cbbc9cd --- /dev/null +++ b/Code/Mantid/Framework/MDAlgorithms/test/EvaluateMDFunctionTest.h @@ -0,0 +1,97 @@ +#ifndef MANTID_MDALGORITHMS_EVALUATEMDFUNCTIONTEST_H_ +#define MANTID_MDALGORITHMS_EVALUATEMDFUNCTIONTEST_H_ + +#include + +#include "MantidMDAlgorithms/EvaluateMDFunction.h" +#include "MantidMDAlgorithms/CreateMDHistoWorkspace.h" + +using Mantid::MDAlgorithms::EvaluateMDFunction; +using Mantid::MDAlgorithms::CreateMDHistoWorkspace; +using namespace Mantid::API; + +class EvaluateMDFunctionTest : 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 EvaluateMDFunctionTest *createSuite() { return new EvaluateMDFunctionTest(); } + static void destroySuite( EvaluateMDFunctionTest *suite ) { delete suite; } + + + void test_Init() + { + EvaluateMDFunction alg; + TS_ASSERT_THROWS_NOTHING( alg.initialize() ) + TS_ASSERT( alg.isInitialized() ) + } + + void test_exec() + { + // Name of the output workspace. + std::string outWSName("EvaluateMDFunctionTest_OutputWS"); + + const size_t nx = 3, ny = 4; + IMDHistoWorkspace_sptr inputWorkspace = createInputWorkspace(nx,ny); + TS_ASSERT( inputWorkspace ); + std::string funcStr = "name=UserFunctionMD,Formula=x+y"; + + EvaluateMDFunction alg; + TS_ASSERT_THROWS_NOTHING( alg.initialize() ) + TS_ASSERT( alg.isInitialized() ) + TS_ASSERT_THROWS_NOTHING( alg.setProperty("InputWorkspace", inputWorkspace) ); + TS_ASSERT_THROWS_NOTHING( alg.setPropertyValue("Function", funcStr) ); + TS_ASSERT_THROWS_NOTHING( alg.setPropertyValue("OutputWorkspace", outWSName) ); + TS_ASSERT_THROWS_NOTHING( alg.execute(); ); + TS_ASSERT( alg.isExecuted() ); + + IMDHistoWorkspace_sptr ws; + TS_ASSERT_THROWS_NOTHING( ws = AnalysisDataService::Instance().retrieveWS(outWSName) ); + TS_ASSERT(ws); + if (!ws) return; + + for(size_t i = 0; i < nx; ++i) + for(size_t j = 0; j < ny; ++j) + { + size_t linearIndex = ws->getLinearIndex(i,j); + auto v = ws->getCenter(linearIndex); + auto x = v[0]; + auto y = v[1]; + auto f = ws->getSignalAt(linearIndex); + TS_ASSERT_DELTA( f, x + y, 1e-15 ); + } + + // Remove workspace from the data service. + AnalysisDataService::Instance().remove(outWSName); + } + + IMDHistoWorkspace_sptr createInputWorkspace(size_t nx, size_t ny) + { + + std::vector values( nx * ny, 1.0 ); + std::vector dims(2); + dims[0] = static_cast(nx); + dims[1] = static_cast(ny); + + CreateMDHistoWorkspace alg; + alg.initialize(); + alg.setProperty("SignalInput", values); + alg.setProperty("ErrorInput", values); + alg.setProperty("Dimensionality", 2); + alg.setProperty("NumberOfBins", dims); + alg.setPropertyValue("Extents", "-1,1,-1,1"); + alg.setPropertyValue("Names", "A,B"); + alg.setPropertyValue("Units", "U,U"); + alg.setPropertyValue("OutputWorkspace", "out"); + alg.execute(); + TS_ASSERT( alg.isExecuted() ); + + IMDHistoWorkspace_sptr ws = AnalysisDataService::Instance().retrieveWS("out"); + AnalysisDataService::Instance().remove("out"); + return ws; + } + +}; + + +#endif /* MANTID_MDALGORITHMS_EVALUATEMDFUNCTIONTEST_H_ */ diff --git a/Code/Mantid/Framework/MDAlgorithms/test/IntegrateFluxTest.h b/Code/Mantid/Framework/MDAlgorithms/test/IntegrateFluxTest.h new file mode 100644 index 000000000000..ec5e88feb910 --- /dev/null +++ b/Code/Mantid/Framework/MDAlgorithms/test/IntegrateFluxTest.h @@ -0,0 +1,204 @@ +#ifndef MANTID_MDALGORITHMS_INTEGRATEFLUXTEST_H_ +#define MANTID_MDALGORITHMS_INTEGRATEFLUXTEST_H_ + +#include + +#include "MantidMDAlgorithms/IntegrateFlux.h" +#include "MantidAPI/AlgorithmManager.h" + +using Mantid::MDAlgorithms::IntegrateFlux; +using namespace Mantid::API; + +class IntegrateFluxTest : 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 IntegrateFluxTest *createSuite() { return new IntegrateFluxTest(); } + static void destroySuite( IntegrateFluxTest *suite ) + { + delete suite; + } + + + void test_Init() + { + IntegrateFlux alg; + TS_ASSERT_THROWS_NOTHING( alg.initialize() ) + TS_ASSERT( alg.isInitialized() ) + } + + void test_exec() + { + // Name of the input workspace. + std::string inWSName("IntegrateFluxTest_InputWS"); + // Name of the output workspace. + std::string outWSName("IntegrateFluxTest_OutputWS"); + + // Create an input workspace + createInputWorkspace(inWSName); + + IntegrateFlux alg; + TS_ASSERT_THROWS_NOTHING( alg.initialize() ) + TS_ASSERT( alg.isInitialized() ) + TS_ASSERT_THROWS_NOTHING( alg.setPropertyValue("InputWorkspace", inWSName) ); + TS_ASSERT_THROWS_NOTHING( alg.setPropertyValue("OutputWorkspace", outWSName) ); + TS_ASSERT_THROWS_NOTHING( alg.execute(); ); + TS_ASSERT( alg.isExecuted() ); + + // Retrieve the workspace from data service. TODO: Change to your desired type + MatrixWorkspace_sptr ws; + TS_ASSERT_THROWS_NOTHING( ws = AnalysisDataService::Instance().retrieveWS(outWSName) ); + TS_ASSERT(ws); + if (!ws) return; + + auto inWS = AnalysisDataService::Instance().retrieveWS( inWSName ); + + TS_ASSERT( ws->getAxis(0)->unit() == inWS->getAxis(0)->unit() ); + TS_ASSERT_EQUALS( ws->getNumberHistograms(), 4 ); + + auto &x = ws->readX(0); + auto &y = ws->readY(0); + + TS_ASSERT_EQUALS( x.size(), 98 ); + TS_ASSERT_EQUALS( x.size(), y.size() ); + + for(size_t i = 10; i < x.size(); ++i) + { + double t = x[i]; + TS_ASSERT_DELTA( t*(t+1.0) / y[i], 1.0, 0.1 ); + } + + // Remove workspace from the data service. + AnalysisDataService::Instance().clear(); + } + + void test_two_interpolation_point() + { + // Name of the input workspace. + std::string inWSName("IntegrateFluxTest_InputWS"); + // Name of the output workspace. + std::string outWSName("IntegrateFluxTest_OutputWS"); + + // Create an input workspace + createInputWorkspace(inWSName); + + IntegrateFlux alg; + alg.initialize(); + alg.setPropertyValue("InputWorkspace", inWSName); + alg.setPropertyValue("OutputWorkspace", outWSName); + alg.setProperty("NPoints", 2); + alg.execute(); + TS_ASSERT( alg.isExecuted() ); + + // Retrieve the workspace from data service. TODO: Change to your desired type + MatrixWorkspace_sptr ws; + TS_ASSERT_THROWS_NOTHING( ws = AnalysisDataService::Instance().retrieveWS(outWSName) ); + TS_ASSERT(ws); + if (!ws) return; + + TS_ASSERT_EQUALS( ws->getNumberHistograms(), 4 ); + + auto &x = ws->readX(0); + auto &y = ws->readY(0); + + TS_ASSERT_EQUALS( x.size(), y.size() ); + TS_ASSERT_EQUALS( x.size(), 2 ); + + double t = x[1]; + TS_ASSERT_DELTA( t*(t+1.0) / y[1], 1.0, 0.1 ); + + // Remove workspace from the data service. + AnalysisDataService::Instance().clear(); + } + + void test_one_interpolation_point() + { + // Name of the input workspace. + std::string inWSName("IntegrateFluxTest_InputWS"); + // Name of the output workspace. + std::string outWSName("IntegrateFluxTest_OutputWS"); + + // Create an input workspace + createInputWorkspace(inWSName); + + IntegrateFlux alg; + alg.initialize(); + alg.setPropertyValue("InputWorkspace", inWSName); + alg.setPropertyValue("OutputWorkspace", outWSName); + TS_ASSERT_THROWS( alg.setProperty("NPoints", 1), std::invalid_argument ); + + // Remove workspace from the data service. + AnalysisDataService::Instance().clear(); + } + + void test_bad_input_workspace() + { + // Name of the input workspace. + std::string inWSName("IntegrateFluxTest_InputWS"); + // Name of the output workspace. + std::string outWSName("IntegrateFluxTest_OutputWS"); + + // Create an input workspace + createBadInputWorkspace(inWSName); + + IntegrateFlux alg; + alg.initialize(); + alg.setRethrows(true); + alg.setPropertyValue("InputWorkspace", inWSName); + alg.setPropertyValue("OutputWorkspace", outWSName); + TS_ASSERT_THROWS( alg.execute(), std::runtime_error ); + + // Remove workspace from the data service. + AnalysisDataService::Instance().clear(); + } + +private: + + void createInputWorkspace(const std::string& wsName) + { + auto alg = Mantid::API::AlgorithmManager::Instance().create("CreateSampleWorkspace"); + alg->initialize(); + alg->setPropertyValue("WorkspaceType","Event"); + alg->setPropertyValue("Function","User Defined"); + alg->setPropertyValue("UserDefinedFunction","name=LinearBackground,A0=1,A1=2"); + alg->setProperty("NumEvents",10000); + alg->setProperty("NumBanks",1); + alg->setProperty("BankPixelWidth",2); + alg->setProperty("XMin",0.0); + alg->setProperty("XMax",100.0); + alg->setPropertyValue("XUnit","Momentum"); + alg->setProperty("BinWidth",1.0); + alg->setProperty("OutputWorkspace",wsName); + alg->execute(); + + alg = Mantid::API::AlgorithmManager::Instance().create("CompressEvents"); + alg->initialize(); + alg->setPropertyValue("InputWorkspace",wsName); + alg->setPropertyValue("OutputWorkspace",wsName); + alg->setProperty("Tolerance",1.0); + alg->execute(); + } + + void createBadInputWorkspace(const std::string& wsName) + { + auto alg = Mantid::API::AlgorithmManager::Instance().create("CreateSampleWorkspace"); + alg->initialize(); + alg->setPropertyValue("WorkspaceType","Event"); + alg->setPropertyValue("Function","User Defined"); + alg->setPropertyValue("UserDefinedFunction","name=LinearBackground,A0=1,A1=2"); + alg->setProperty("NumEvents",10000); + alg->setProperty("NumBanks",1); + alg->setProperty("BankPixelWidth",2); + alg->setProperty("XMin",0.0); + alg->setProperty("XMax",100.0); + alg->setPropertyValue("XUnit","Momentum"); + alg->setProperty("BinWidth",1.0); + alg->setProperty("OutputWorkspace",wsName); + alg->execute(); + + } +}; + + +#endif /* MANTID_MDALGORITHMS_INTEGRATEFLUXTEST_H_ */ \ No newline at end of file diff --git a/Code/Mantid/Framework/MDAlgorithms/test/LoadSQWTest.h b/Code/Mantid/Framework/MDAlgorithms/test/LoadSQWTest.h index e40d4e7aef49..1642548fccfb 100644 --- a/Code/Mantid/Framework/MDAlgorithms/test/LoadSQWTest.h +++ b/Code/Mantid/Framework/MDAlgorithms/test/LoadSQWTest.h @@ -89,6 +89,7 @@ class ExposedLoadSQW : public LoadSQW void readSQWDimensions(MDEventWorkspace4* ws) { std::vector DimVector; + LoadSQW::readDNDDimensions(DimVector,false); LoadSQW::readSQWDimensions(DimVector); this->addDimsToWs(ws,DimVector); } @@ -145,7 +146,7 @@ class LoadSQWTest : public CxxTest::TestSuite TS_ASSERT_EQUALS("A^-1", a->getUnits().ascii()); TS_ASSERT_EQUALS("A^-1", b->getUnits().ascii()); TS_ASSERT_EQUALS("A^-1", c->getUnits().ascii()); - TS_ASSERT_EQUALS("mEv", d->getUnits().ascii()); + TS_ASSERT_EQUALS("meV", d->getUnits().ascii()); //Check Nbins TS_ASSERT_EQUALS(3, a->getNBins()); @@ -322,7 +323,7 @@ class LoadSQWTest : public CxxTest::TestSuite }; //===================================================================================== -// Perfomance Tests +// Performance Tests //===================================================================================== class LoadSQWTestPerformance : public CxxTest::TestSuite { diff --git a/Code/Mantid/Framework/MDAlgorithms/test/MDNormSXDTest.h b/Code/Mantid/Framework/MDAlgorithms/test/MDNormSXDTest.h new file mode 100644 index 000000000000..3e4082bb571b --- /dev/null +++ b/Code/Mantid/Framework/MDAlgorithms/test/MDNormSXDTest.h @@ -0,0 +1,119 @@ +#ifndef MANTID_MDALGORITHMS_MDNORMSXDTEST_H_ +#define MANTID_MDALGORITHMS_MDNORMSXDTEST_H_ + +#include + +#include "MantidMDAlgorithms/MDNormSXD.h" +#include "MantidMDAlgorithms/CreateMDWorkspace.h" +#include "MantidAPI/IMDHistoWorkspace.h" +#include "MantidAPI/WorkspaceFactory.h" +#include "MantidTestHelpers/WorkspaceCreationHelper.h" + +using Mantid::MDAlgorithms::MDNormSXD; +using namespace Mantid::API; + +class MDNormSXDTest : 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 MDNormSXDTest *createSuite() { return new MDNormSXDTest(); } + static void destroySuite( MDNormSXDTest *suite ) { delete suite; } + + + void test_Init() + { + MDNormSXD alg; + TS_ASSERT_THROWS_NOTHING( alg.initialize() ) + TS_ASSERT( alg.isInitialized() ) + } + + void test_properties() + { + std::string mdWsName = "__temp_InputMDWorkspaceName"; + createMDWorkspace(mdWsName); + std::string fluxGoodWsName = "__temp_InputGoodFluxWorkspaceName"; + createGoodFluxWorkspace(fluxGoodWsName); + std::string fluxBadWsName = "__temp_InputBadFluxWorkspaceName"; + createBadFluxWorkspace(fluxBadWsName); + std::string saWsName = "__temp_InputSAWorkspaceName"; + createBadFluxWorkspace(saWsName); + + MDNormSXD alg; + TS_ASSERT_THROWS_NOTHING( alg.initialize() ) + TS_ASSERT( alg.isInitialized() ) + TS_ASSERT_THROWS_NOTHING( alg.setPropertyValue("InputWorkspace", mdWsName) ); + TS_ASSERT_THROWS_NOTHING( alg.setProperty("FluxWorkspace", fluxGoodWsName) ); + TS_ASSERT_THROWS( alg.setProperty("FluxWorkspace", fluxBadWsName), std::invalid_argument ); + TS_ASSERT_THROWS_NOTHING( alg.setProperty("SolidAngleWorkspace", saWsName) ); + TS_ASSERT_THROWS_NOTHING( alg.setPropertyValue("OutputWorkspace", "OutWSName") ); + TS_ASSERT_THROWS_NOTHING( alg.setPropertyValue("OutputNormalizationWorkspace", "OutNormWSName") ); + + AnalysisDataService::Instance().clear(); + } + +private: + + void createMDWorkspace(const std::string& wsName) + { + const int ndims = 2; + std::string bins = "2,2"; + std::string extents = "0,1,0,1"; + std::vector names(ndims); + names[0] = "A"; names[1] = "B"; + std::vector units(ndims); + units[0] = "a"; units[1] = "b"; + + Mantid::MDAlgorithms::CreateMDWorkspace alg; + alg.initialize(); + TS_ASSERT_THROWS_NOTHING( alg.setProperty("Dimensions", ndims) ); + TS_ASSERT_THROWS_NOTHING( alg.setPropertyValue("Extents", extents) ); + TS_ASSERT_THROWS_NOTHING( alg.setProperty("Names", names) ); + TS_ASSERT_THROWS_NOTHING( alg.setProperty("Units", units) ); + TS_ASSERT_THROWS_NOTHING( alg.setPropertyValue("OutputWorkspace", wsName) ); + alg.execute(); + + } + + void createGoodFluxWorkspace(const std::string& wsName) + { + auto flux = WorkspaceCreationHelper::create2DWorkspaceWithFullInstrument( 2, 10 ); + auto &x = flux->dataX(0); + auto &y1 = flux->dataY(1); + + for(size_t i = 0; i < y1.size(); ++i) + { + y1[i] = 2 * x[i]; + } + flux->setX(1,x); + flux->getAxis(0)->setUnit("Momentum"); + + AnalysisDataService::Instance().addOrReplace( wsName, flux ); + } + + void createBadFluxWorkspace(const std::string& wsName) + { + auto flux = WorkspaceCreationHelper::create2DWorkspaceWithFullInstrument( 2, 10 ); + auto &x = flux->dataX(0); + auto &y1 = flux->dataY(1); + + for(size_t i = 0; i < y1.size(); ++i) + { + y1[i] = -2 * x[i]; + } + flux->setX(1,x); + flux->getAxis(0)->setUnit("Momentum"); + + AnalysisDataService::Instance().addOrReplace( wsName, flux ); + } + + void createSolidAngleWorkspace(const std::string& wsName) + { + auto sa = WorkspaceCreationHelper::create2DWorkspaceWithFullInstrument( 2, 10 ); + AnalysisDataService::Instance().addOrReplace( wsName, sa ); + } + +}; + + +#endif /* MANTID_MDALGORITHMS_MDNORMSXDTEST_H_ */ diff --git a/Code/Mantid/Framework/MDEvents/inc/MantidMDEvents/FitMD.h b/Code/Mantid/Framework/MDEvents/inc/MantidMDEvents/FitMD.h index 95a0ffc00ec1..fd9de1a6ede8 100644 --- a/Code/Mantid/Framework/MDEvents/inc/MantidMDEvents/FitMD.h +++ b/Code/Mantid/Framework/MDEvents/inc/MantidMDEvents/FitMD.h @@ -14,6 +14,8 @@ namespace Mantid class FunctionDomain; class FunctionDomainMD; class IMDWorkspace; + class IMDEventWorkspace; + class IMDHistoWorkspace; } namespace MDEvents @@ -82,6 +84,17 @@ namespace Mantid protected: /// Set all parameters void setParameters()const; + /// Create event output workspace + boost::shared_ptr createEventOutputWorkspace(const std::string& baseName, + const API::IMDEventWorkspace &inputWorkspace, + const API::FunctionValues &values, + const std::string& outputWorkspacePropertyName); + /// Create histo output workspace + boost::shared_ptr createHistoOutputWorkspace(const std::string& baseName, + API::IFunction_sptr function, + boost::shared_ptr inputWorkspace, + const std::string& outputWorkspacePropertyName); + /// Store workspace property name std::string m_workspacePropertyName; /// Store maxSize property name diff --git a/Code/Mantid/Framework/MDEvents/inc/MantidMDEvents/MDBox.h b/Code/Mantid/Framework/MDEvents/inc/MantidMDEvents/MDBox.h index 347e37008629..ea9bdc625d29 100644 --- a/Code/Mantid/Framework/MDEvents/inc/MantidMDEvents/MDBox.h +++ b/Code/Mantid/Framework/MDEvents/inc/MantidMDEvents/MDBox.h @@ -68,6 +68,7 @@ namespace MDEvents //----------------------------------------------------------------------------------------------- virtual void saveAt(API::IBoxControllerIO *const /* */, uint64_t /*position*/)const; virtual void loadAndAddFrom(API::IBoxControllerIO *const /* */, uint64_t /*position*/, size_t /* Size */); + virtual void reserveMemoryForLoad(uint64_t /* Size */); /**drop events data from memory but keep averages (and file-backed info) */ void clearDataFromMemory(); /** */ diff --git a/Code/Mantid/Framework/MDEvents/inc/MantidMDEvents/MDBoxFlatTree.h b/Code/Mantid/Framework/MDEvents/inc/MantidMDEvents/MDBoxFlatTree.h index 43cfb1d0c19b..48c2f5dfe615 100644 --- a/Code/Mantid/Framework/MDEvents/inc/MantidMDEvents/MDBoxFlatTree.h +++ b/Code/Mantid/Framework/MDEvents/inc/MantidMDEvents/MDBoxFlatTree.h @@ -66,7 +66,7 @@ namespace MDEvents uint64_t restoreBoxTree(std::vector&Boxes ,API::BoxController_sptr &bc, bool FileBackEnd,bool NoFileInfo=false); /*** this function tries to set file positions of the boxes to - make data physiclly located close to each otger to be as close as possible on the HDD */ + make data physically located close to each other to be as close as possible on the HDD */ void setBoxesFilePositions(bool setFileBacked); /**Save flat box structure into a file, defined by the file name*/ @@ -112,7 +112,7 @@ namespace MDEvents /// shared pointer to multiple experiment info stored within the workspace boost::shared_ptr m_mEI; public: - static ::NeXus::File * createOrOpenMDWSgroup(const std::string &fileName,int &nDims, const std::string &WSEventType, bool readOnly); + static ::NeXus::File * createOrOpenMDWSgroup(const std::string &fileName,int &nDims, const std::string &WSEventType, bool readOnly,bool &exist); // save each experiment info into its own NeXus group within an existing opened group static void saveExperimentInfos(::NeXus::File * const file, API::IMDEventWorkspace_const_sptr ws); // load experiment infos, previously saved through the the saveExperimentInfo function diff --git a/Code/Mantid/Framework/MDEvents/inc/MantidMDEvents/MDGridBox.h b/Code/Mantid/Framework/MDEvents/inc/MantidMDEvents/MDGridBox.h index 0058be49fdf2..4d5f63be210c 100644 --- a/Code/Mantid/Framework/MDEvents/inc/MantidMDEvents/MDGridBox.h +++ b/Code/Mantid/Framework/MDEvents/inc/MantidMDEvents/MDGridBox.h @@ -67,6 +67,8 @@ namespace MDEvents /**Load the box data of specified size from the disk location provided using the class, respoinsible for the file IO. */ virtual void loadAndAddFrom(API::IBoxControllerIO *const /* */, uint64_t /*position*/, size_t /* Size */) {/*Not directly loadable */} + virtual void reserveMemoryForLoad(uint64_t /* Size */) + {/*Not directly loadable */} //------------------------------------------------------------------------------------------------------- /** Uses the cached value of points stored in the grid box diff --git a/Code/Mantid/Framework/MDEvents/src/BoxControllerNeXusIO.cpp b/Code/Mantid/Framework/MDEvents/src/BoxControllerNeXusIO.cpp index 926195ac2f2c..6757d18ea860 100644 --- a/Code/Mantid/Framework/MDEvents/src/BoxControllerNeXusIO.cpp +++ b/Code/Mantid/Framework/MDEvents/src/BoxControllerNeXusIO.cpp @@ -55,7 +55,7 @@ namespace MDEvents } /** The optional method to set up the event type and the size of the event coordinate * As save/load operations use void data type, these function allow set up/get the type name provided for the IO operations - * and the size of the data type in bytes (e.g. the class dependant physical meaning of the blockSize and blockPosition used + * and the size of the data type in bytes (e.g. the class dependent physical meaning of the blockSize and blockPosition used * by save/load operations * @param blockSize -- size (in bytes) of the blockPosition and blockSize used in save/load operations. 4 and 8 are supported only e.g. float and double @@ -86,7 +86,7 @@ namespace MDEvents } /** As save/load operations use void data type, these function allow set up/get the type name provided for the IO operations - * and the size of the data type in bytes (e.g. the class dependant physical meaning of the blockSize and blockPosition used + * and the size of the data type in bytes (e.g. the class dependent physical meaning of the blockSize and blockPosition used * by save/load operations *@return CoordSize -- size (in bytes) of the blockPosition and blockSize used in save/load operations *@return typeName -- the name of the event used in the operations. The name itself defines the size and the format of the event @@ -100,7 +100,7 @@ namespace MDEvents /**Open the file to use in IO operations with events * - *@param fileName -- the name of the file to open. Search for file perfomed within the Mantid search path. + *@param fileName -- the name of the file to open. Search for file performed within the Mantid search path. *@param mode -- opening mode (read or read/write) * * @@ -133,7 +133,10 @@ namespace MDEvents throw Kernel::Exception::FileError("Can not open file to read ",m_fileName); } int nDims = static_cast(this->m_bc->getNDims()); - m_File = MDBoxFlatTree::createOrOpenMDWSgroup(m_fileName,nDims, m_EventsTypesSupported[m_EventType],m_ReadOnly); + + bool group_exists; + m_File = MDBoxFlatTree::createOrOpenMDWSgroup(m_fileName,nDims, m_EventsTypesSupported[m_EventType],m_ReadOnly,group_exists); + // we are in MD workspace Class group now std::map groupEntries; m_File->getEntries(groupEntries); @@ -144,7 +147,7 @@ namespace MDEvents // we are in MDEvent group now (either created or opened) - // read if exist and create if not the group, which is responsible for saving DiskBuffer infornation; + // read if exist and create if not the group, which is responsible for saving DiskBuffer information; getDiskBufferFileData(); if(m_ReadOnly) diff --git a/Code/Mantid/Framework/MDEvents/src/FitMD.cpp b/Code/Mantid/Framework/MDEvents/src/FitMD.cpp index d4ec3719ebe6..0673b924ffe1 100644 --- a/Code/Mantid/Framework/MDEvents/src/FitMD.cpp +++ b/Code/Mantid/Framework/MDEvents/src/FitMD.cpp @@ -10,6 +10,9 @@ #include "MantidAPI/IFunctionMD.h" #include "MantidAPI/MemoryManager.h" #include "MantidAPI/WorkspaceProperty.h" +#include "MantidAPI/AlgorithmFactory.h" +#include "MantidAPI/Algorithm.h" + #include "MantidGeometry/MDGeometry/MDHistoDimensionBuilder.h" #include "MantidMDEvents/MDEventFactory.h" @@ -121,9 +124,13 @@ namespace Mantid while(iter) { values->setFitData(i,iter->getNormalizedSignal()); - double err = iter->getNormalizedError(); - if (err <= 0.0) err = 1.0; - values->setFitWeight(i,1/err); + // there is a problem with errors in md workspaces. Until it is solved + // set all weights to 1.0 + // code commented out after the next line is the normal way of setting weights + values->setFitWeight(i,1.0); + //double err = iter->getNormalizedError(); + //if (err <= 0.0) err = 1.0; + //values->setFitWeight(i,1/err); iter = dmd->getNextIterator(); ++i; }; @@ -139,7 +146,7 @@ namespace Mantid * @param outputWorkspacePropertyName :: The property name */ boost::shared_ptr FitMD::createOutputWorkspace(const std::string& baseName, - API::IFunction_sptr, + API::IFunction_sptr function, boost::shared_ptr domain, boost::shared_ptr values, const std::string& outputWorkspacePropertyName) @@ -154,12 +161,35 @@ namespace Mantid return boost::shared_ptr(); } API::IMDWorkspace_const_sptr domainWS = functionMD->getWorkspace(); - auto inputWS = boost::dynamic_pointer_cast(domainWS); - if(!inputWS) + + auto inputEventWS = boost::dynamic_pointer_cast(domainWS); + if( inputEventWS ) { - return boost::shared_ptr(); + return createEventOutputWorkspace( baseName, *inputEventWS, *values, outputWorkspacePropertyName ); + } + + auto inputHistoWS = boost::dynamic_pointer_cast(domainWS); + if( inputHistoWS ) + { + return createHistoOutputWorkspace( baseName, function, inputHistoWS, outputWorkspacePropertyName ); } - auto outputWS = MDEventFactory::CreateMDWorkspace(inputWS->getNumDims(), "MDEvent"); + + return boost::shared_ptr(); + } + + /** + * Create an output event workspace filled with data simulated with the fitting function. + * @param baseName :: The base name for the workspace + * @param inputWorkspace :: The input workspace. + * @param values :: The calculated values + * @param outputWorkspacePropertyName :: The property name + */ + boost::shared_ptr FitMD::createEventOutputWorkspace(const std::string& baseName, + const API::IMDEventWorkspace &inputWorkspace, + const API::FunctionValues &values, + const std::string& outputWorkspacePropertyName) + { + auto outputWS = MDEventFactory::CreateMDWorkspace(inputWorkspace.getNumDims(), "MDEvent"); // Add events // TODO: Generalize to ND (the current framework is a bit limiting) auto mdWS = boost::dynamic_pointer_cast,4> >(outputWS); @@ -171,7 +201,7 @@ namespace Mantid // Bins extents and meta data for(size_t i = 0;i < 4; ++i) { - boost::shared_ptr inputDim = inputWS->getDimension(i); + boost::shared_ptr inputDim = inputWorkspace.getDimension(i); Geometry::MDHistoDimensionBuilder builder; builder.setName(inputDim->getName()); builder.setId(inputDim->getDimensionId()); @@ -184,7 +214,7 @@ namespace Mantid } // Run information - outputWS->copyExperimentInfos(*inputWS); + outputWS->copyExperimentInfos(inputWorkspace); // Set sensible defaults for splitting behaviour BoxController_sptr bc = outputWS->getBoxController(); bc->setSplitInto(3); @@ -192,13 +222,13 @@ namespace Mantid outputWS->initialize(); outputWS->splitBox(); - auto inputIter = inputWS->createIterator(); + auto inputIter = inputWorkspace.createIterator(); size_t resultValueIndex(0); const float errorSq = 0.0; do { const size_t numEvents = inputIter->getNumEvents(); - const float signal = static_cast(values->getCalculated(resultValueIndex)); + const float signal = static_cast(values.getCalculated(resultValueIndex)); for(size_t i = 0; i < numEvents; ++i) { coord_t centers[4] = { inputIter->getInnerPosition(i,0), inputIter->getInnerPosition(i,1), @@ -235,6 +265,44 @@ namespace Mantid return outputWS; } + /** + * Create an output histo workspace filled with data simulated with the fitting function. + * @param baseName :: The base name for the workspace + * @param function :: The function used for the calculation + * @param inputWorkspace :: The input workspace + * @param outputWorkspacePropertyName :: The property name + */ + boost::shared_ptr FitMD::createHistoOutputWorkspace(const std::string& baseName, + API::IFunction_sptr function, + API::IMDHistoWorkspace_const_sptr inputWorkspace, + const std::string& outputWorkspacePropertyName) + { + // have to cast const away to be able to pass the workspace to the algorithm + API::IMDHistoWorkspace_sptr nonConstInputWS = boost::const_pointer_cast( inputWorkspace ); + // evaluate the function on the input workspace + auto alg = API::AlgorithmFactory::Instance().create("EvaluateMDFunction",-1); + alg->setChild( true ); + alg->setRethrows( true ); + alg->initialize(); + alg->setProperty( "Function", function ); + alg->setProperty( "InputWorkspace", nonConstInputWS ); + alg->setProperty( "OutputWorkspace", "__FitMD_createHistoOutputWorkspace_outputWorkspace" ); + alg->execute(); + + // get the result + API::IMDHistoWorkspace_sptr outputWorkspace = alg->getProperty( "OutputWorkspace" ); + // Store it + if ( !outputWorkspacePropertyName.empty() ) + { + declareProperty(new API::WorkspaceProperty(outputWorkspacePropertyName,"",Direction::Output), + "Name of the output Workspace holding resulting simulated spectrum"); + m_manager->setPropertyValue(outputWorkspacePropertyName,baseName+"Workspace"); + m_manager->setProperty(outputWorkspacePropertyName,outputWorkspace); + } + + return outputWorkspace; + } + /** * Set all parameters */ diff --git a/Code/Mantid/Framework/MDEvents/src/IntegrateEllipsoids.cpp b/Code/Mantid/Framework/MDEvents/src/IntegrateEllipsoids.cpp index 0f74019a6af9..4c4e3722f72f 100644 --- a/Code/Mantid/Framework/MDEvents/src/IntegrateEllipsoids.cpp +++ b/Code/Mantid/Framework/MDEvents/src/IntegrateEllipsoids.cpp @@ -83,8 +83,7 @@ namespace MDEvents auto ws_valid = boost::make_shared(); ws_valid->add(); - // the validator which checks if the workspace has axis and time-of-flight units - ws_valid->add("TOF"); + // the validator which checks if the workspace has axis declareProperty(new WorkspaceProperty( "InputWorkspace", "", Direction::Input,ws_valid), "An input EventWorkspace with time-of-flight units along X-axis and defined instrument with defined sample"); @@ -122,11 +121,6 @@ namespace MDEvents // get the input workspace EventWorkspace_sptr wksp = getProperty("InputWorkspace"); - // this only works for unweighted events - if (wksp->getEventType() != API::TOF) - { - throw std::runtime_error("IntegrateEllipsoids only works for raw events"); - } // error out if there are not events if (wksp->getNumberEvents() <= 0) { @@ -226,7 +220,9 @@ namespace MDEvents for (std::size_t i = 0; i < numSpectra; ++i) { // get a reference to the event list - const EventList& events = wksp->getEventList(i); + EventList& events = wksp->getEventList(i); + + events.switchTo(WEIGHTED_NOTIME); // check to see if the event list is empty if (events.empty()) @@ -243,7 +239,7 @@ namespace MDEvents // loop over the events double signal(1.); // ignorable garbage double errorSq(1.); // ignorable garbage - const std::vector& raw_events = events.getEvents(); + const std::vector& raw_events = events.getWeightedEventsNoTime(); event_qs.clear(); for (auto event = raw_events.begin(); event != raw_events.end(); ++event) { diff --git a/Code/Mantid/Framework/MDEvents/src/MDBox.cpp b/Code/Mantid/Framework/MDEvents/src/MDBox.cpp index 7ff3e63add7f..ece7dfc1309f 100644 --- a/Code/Mantid/Framework/MDEvents/src/MDBox.cpp +++ b/Code/Mantid/Framework/MDEvents/src/MDBox.cpp @@ -437,30 +437,30 @@ namespace MDEvents TMDE( void MDBox)::calculateCentroid(coord_t * centroid) const { - for (size_t d=0; dm_signal == 0) return; + // Signal was calculated before (when adding) + // Keep 0.0 if the signal is null. This avoids dividing by 0.0 + if (this->m_signal == 0) return; - typename std::vector::const_iterator it_end = data.end(); - for(typename std::vector::const_iterator it = data.begin(); it != it_end; ++it) - { - const MDE & Evnt = *it; - double signal = Evnt.getSignal(); - for (size_t d=0; d(signal); - } - } + typename std::vector::const_iterator it_end = data.end(); + for(typename std::vector::const_iterator it = data.begin(); it != it_end; ++it) + { + const MDE & Evnt = *it; + double signal = Evnt.getSignal(); + for (size_t d=0; d(signal); + } + } - // Normalize by the total signal - for (size_t d=0; dm_signal); - } + // Normalize by the total signal + for (size_t d=0; dm_signal); + } } @@ -644,9 +644,9 @@ namespace MDEvents if (out[0] < radius && std::fabs(out[1]) < 0.5*length) { // add event to appropriate y channel - size_t xchannel; - if (out[1] < 0) xchannel = static_cast(out[1] / deltaQ - 0.5) + static_cast(numSteps / 2)-1; - else xchannel = static_cast(out[1] / deltaQ + 0.5) + static_cast(numSteps / 2)-1; + size_t xchannel; + if (out[1] < 0) xchannel = static_cast(out[1] / deltaQ - 0.5) + static_cast(numSteps / 2)-1; + else xchannel = static_cast(out[1] / deltaQ + 0.5) + static_cast(numSteps / 2)-1; if (xchannel < numSteps ) signal_fit[xchannel] += static_cast(it->getSignal()); signal += static_cast(it->getSignal()); @@ -850,8 +850,8 @@ namespace MDEvents /**Make this box file-backed * @param fileLocation -- the starting position of this box data are/should be located in the direct access file - * @param fileSize -- the size this box data occupy in the file (in the units of the numbner of eventss) - * @param markSaved -- set to true if the data indeed are physically there and one can indedd read then from there + * @param fileSize -- the size this box data occupy in the file (in the units of the number of events) + * @param markSaved -- set to true if the data indeed are physically there and one can indeed read then from there */ TMDE( void MDBox)::setFileBacked(const uint64_t fileLocation,const size_t fileSize, const bool markSaved) @@ -869,7 +869,7 @@ namespace MDEvents this->setFileBacked(UNDEF_UINT64,this->getDataInMemorySize(),false); } - /**Save the box dataat specific disk position using the class, responsible for the file IO. + /**Save the box data to specific disk position using the class, responsible for the file IO. * *@param FileSaver -- the pointer to the class, responsible for File IO operations *@param position -- the position of the data within the class. @@ -900,9 +900,20 @@ namespace MDEvents FileSaver->saveBlock(TabledData,position); } + + /** + * Reserve all the memory required for loading in one step. + * + * @param size -- number of events to reserve for + */ + TMDE( + void MDBox)::reserveMemoryForLoad(uint64_t size) + { + this->data.reserve(size); + } + /**Load the box data of specified size from the disk location provided using the class, respoinsible for the file IO and append them to exisiting events - * Clear events vector first if overwriting the exisitng events is necessary. The efficiency would be higher if jentle cleaning occurs (the size of event data vector - is nullified but memory still allocated) + * Clear events vector first if overwriting the exisitng events is necessary. * * @param FileSaver -- the pointer to the class, responsible for file IO * @param filePosition -- the place in the direct access file, where necessary data are located @@ -923,9 +934,6 @@ namespace MDEvents std::vector TableData; FileSaver->loadBlock(TableData,filePosition,nEvents); - // convert loaded events to data; - size_t nCurrentEvents = data.size(); - this->data.reserve(nCurrentEvents+nEvents); // convert data to events appending new events to existing MDE::dataToEvents(TableData,data,false); diff --git a/Code/Mantid/Framework/MDEvents/src/MDBoxFlatTree.cpp b/Code/Mantid/Framework/MDEvents/src/MDBoxFlatTree.cpp index a00a1685be10..a6e47a5a9603 100644 --- a/Code/Mantid/Framework/MDEvents/src/MDBoxFlatTree.cpp +++ b/Code/Mantid/Framework/MDEvents/src/MDBoxFlatTree.cpp @@ -70,7 +70,7 @@ namespace Mantid // currently ID is the number of the box, but it may change in a future. TODO: uint64_t size_t id = Box->getID(); size_t numChildren = Box->getNumChildren(); - if (numChildren > 0) // MDGridBox have childred + if (numChildren > 0) // MDGridBox have children { // DEBUG: //// Make sure that all children are ordered. TODO: This might not be needed if the IDs are rigorously done @@ -124,7 +124,7 @@ namespace Mantid } ic++; } - // file postion have to be calculated afresh + // file position have to be calculated afresh if(!filePositionDefined) { uint64_t boxPosition(0); @@ -140,13 +140,13 @@ namespace Mantid } /*** this function tries to set file positions of the boxes to - make data physiclly located close to each otger to be as close as possible on the HDD + make data physically located close to each other to be as close as possible on the HDD @param setFileBacked -- initiate the boxes to be fileBacked. The boxes assumed not to be saved before. */ void MDBoxFlatTree::setBoxesFilePositions(bool setFileBacked) { // this will preserve file-backed workspace and information in it as we are not loading old box data and not? - // this would be right for binary axcess but questionable for Nexus --TODO: needs testing + // this would be right for binary access but questionable for Nexus --TODO: needs testing // Done in INIT--> need check if ID and index in the tree are always the same. //Kernel::ISaveable::sortObjByFilePos(m_Boxes); // calculate the box positions in the resulting file and save it on place @@ -172,8 +172,8 @@ namespace Mantid void MDBoxFlatTree::saveBoxStructure(const std::string &fileName) { m_FileName = fileName; - - auto hFile = file_holder_type(createOrOpenMDWSgroup(fileName,m_nDim,m_Boxes[0]->getEventType(),false)); + bool old_group; + auto hFile = file_holder_type(createOrOpenMDWSgroup(fileName,m_nDim,m_Boxes[0]->getEventType(),false,old_group)); //Save box structure; this->saveBoxStructure(hFile.get()); @@ -194,7 +194,7 @@ namespace Mantid bool create(false); - if(groupEntries.find("box_structure")==groupEntries.end()) //dimesnions dataset exist + if(groupEntries.find("box_structure")==groupEntries.end()) //dimensions dataset exist create = true; // Start the box data group @@ -241,7 +241,7 @@ namespace Mantid } else { - // Update the extendible data sets + // Update the expendable data sets hFile->writeUpdatedData("box_type", m_BoxType); hFile->writeUpdatedData("depth", m_Depth); hFile->writeUpdatedData("inverse_volume", m_InverseVolume); @@ -261,8 +261,8 @@ namespace Mantid @param fileName :: The name of the file with the box information @param nDim :: number of dimensions the boxes have. If this number is <=0 on input, method loads existing number of box dimensions from the file, if it is a number, method verifies if - if the number of dimensions provided equal to this number in the file. (leftower from the time when it was templated method) - @param EventType :: "MDEvent" or "MDLeanEvent" -- describe the type of events the workspace contans, similarly to nDim, used to check the data integrity + if the number of dimensions provided equal to this number in the file. (leftover from the time when it was templated method) + @param EventType :: "MDEvent" or "MDLeanEvent" -- describe the type of events the workspace contains, similarly to nDim, used to check the data integrity @param onlyEventInfo :: load only box controller information and the events locations -- do not restore boxes themselves @param restoreExperimentInfo :: load also experiment information */ @@ -272,9 +272,13 @@ namespace Mantid m_FileName = fileName; m_nDim = nDim; m_eventType = EventType; - + + bool old_group; // open the file and the MD workspace group. - auto hFile = file_holder_type(createOrOpenMDWSgroup(fileName,nDim,m_eventType,true)); + auto hFile = file_holder_type(createOrOpenMDWSgroup(fileName,nDim,m_eventType,true,old_group)); + if(!old_group) + throw Kernel::Exception::FileError("MD workspace box structure data are not present in the file",fileName); + m_nDim = nDim; @@ -473,10 +477,10 @@ namespace Mantid } /** Method recovers the interconnected box structure from the plain tree into box tree, recovering both boxes and their connectivity - * does the opposite to the initFlatStructure operation (the class contants remains unchanged) + * does the opposite to the initFlatStructure operation (the class contents remains unchanged) @param Boxes :: the return vector of pointers to interconnected boxes. All previous pointers found in the vector will be overwritten (beware of memory loss) @param bc :: shard pointer to the box controller, which each box uses - @param FileBackEnd :: if one should make the data file backed, namely restore/calculate the data, nesessary to obtain events file positions + @param FileBackEnd :: if one should make the data file backed, namely restore/calculate the data, necessary to obtain events file positions @param BoxStructureOnly :: restore box tree only ignoring information about the box events @@ -589,14 +593,16 @@ namespace Mantid *@param nDims -- number of workspace dimensions; *@param WSEventType -- the string describing event type *@param readOnly -- true if the file is opened for read-only access + *@param alreadyExists -- return true, if opened existing group or false if new group has been created. *@return NeXus pointer to properly opened NeXus data file and group. * *@throws if group or its component do not exist and the file is opened read-only or if the existing file parameters are not equal to the input parameters. */ - ::NeXus::File * MDBoxFlatTree::createOrOpenMDWSgroup(const std::string &fileName,int &nDims, const std::string &WSEventType, bool readOnly) + ::NeXus::File * MDBoxFlatTree::createOrOpenMDWSgroup(const std::string &fileName,int &nDims, const std::string &WSEventType, bool readOnly,bool &alreadyExists) { + alreadyExists = false; Poco::File oldFile(fileName); bool fileExists = oldFile.exists(); if (!fileExists && readOnly) @@ -626,6 +632,7 @@ namespace Mantid { // Open and check ws group -------------------------------------------------------------------------------->>> hFile->openGroup("MDEventWorkspace", "NXentry"); + alreadyExists = true; std::string eventType; if(hFile->hasAttr("event_type")) @@ -683,6 +690,7 @@ namespace Mantid try { + alreadyExists = false; hFile->makeGroup("MDEventWorkspace", "NXentry", true); hFile->putAttr("event_type",WSEventType); @@ -698,7 +706,7 @@ namespace Mantid } - /**Save workpace generig info like dimension structure, history, titile dimensions etc.*/ + /**Save workspace generic info like dimension structure, history, title dimensions etc.*/ void MDBoxFlatTree::saveWSGenericInfo(::NeXus::File *const file,API::IMDWorkspace_const_sptr ws) { @@ -723,7 +731,7 @@ namespace Mantid } /** - * Save the affine matricies to both directional conversions to the + * Save the affine matrices to both directional conversions to the * data. * @param file : pointer to the NeXus file * @param ws : workspace to get matrix from diff --git a/Code/Mantid/Framework/MDEvents/src/MDGridBox.cpp b/Code/Mantid/Framework/MDEvents/src/MDGridBox.cpp index be571ac4dec3..92b4191455bf 100644 --- a/Code/Mantid/Framework/MDEvents/src/MDGridBox.cpp +++ b/Code/Mantid/Framework/MDEvents/src/MDGridBox.cpp @@ -1715,11 +1715,15 @@ GCC_DIAG_ON(array-bounds) { throw(Kernel::Exception::NotImplementedError("Recursive file backed is not yet implemented (unclear how to set file location etc)")); } - /** Make the box file-backed without knowing its position on the HDD. Not implemented for gridboxes*/ + /** Make the box file-backed without knowing its position on the HDD. Works recursively through all children*/ TMDE( void MDGridBox)::setFileBacked() { - this->setFileBacked(UNDEF_UINT64,0,false); + for(size_t i=0;inumBoxes;i++) + { + m_Children[i]->setFileBacked(); + } + } /**Recursively clear the file-backed information stored in mdBoxes from the boxes if such information exists * diff --git a/Code/Mantid/Framework/MDEvents/test/FitMDTest.h b/Code/Mantid/Framework/MDEvents/test/FitMDTest.h index 5f15aeae0d79..300fdf2bd4be 100644 --- a/Code/Mantid/Framework/MDEvents/test/FitMDTest.h +++ b/Code/Mantid/Framework/MDEvents/test/FitMDTest.h @@ -9,6 +9,7 @@ #include "MantidAPI/FrameworkManager.h" #include "MantidAPI/IMDIterator.h" #include "MantidAPI/ITableWorkspace.h" +#include "MantidAPI/IMDHistoWorkspace.h" #include "MantidMDEvents/UserFunctionMD.h" #include @@ -212,10 +213,74 @@ class FitMDTest : public CxxTest::TestSuite TS_ASSERT_EQUALS(params->Double(2,2), 0.0); API::AnalysisDataService::Instance().clear(); - //--------------------------------------------------// } + void test_output_histo_workspace() + { + auto inputWS = createHistoWorkspace(3,4, "name=UserFunctionMD,Formula=10 + y + (2 + 0.1*y) * x"); + + auto fit = API::AlgorithmManager::Instance().create("Fit"); + fit->initialize(); + + fit->setProperty("Function","name=UserFunctionMD,Formula=h + y + (s + 0.1*y) * x, h = 0, s = 0"); + fit->setProperty("InputWorkspace",inputWS); + fit->setPropertyValue("Output","out"); + fit->execute(); + + IMDHistoWorkspace_sptr outputWS = AnalysisDataService::Instance().retrieveWS( "out_Workspace" ); + TS_ASSERT( outputWS ); + if ( !outputWS ) return; + + TS_ASSERT_EQUALS( inputWS->getNPoints(), outputWS->getNPoints() ); + + uint64_t n = outputWS->getNPoints(); + coord_t invVolume = inputWS->getInverseVolume(); + for( uint64_t i = 0; i < n; ++i ) + { + TS_ASSERT_DELTA( outputWS->signalAt(i) / inputWS->signalAt(i) / invVolume, 1.0, 0.1 ); + } + + AnalysisDataService::Instance().clear(); + } + + // ---------------------------------------------------------- // + IMDHistoWorkspace_sptr createHistoWorkspace(size_t nx, size_t ny, const std::string& function) + { + + std::vector values( nx * ny, 1.0 ); + std::vector dims(2); + dims[0] = static_cast(nx); + dims[1] = static_cast(ny); + + auto alg = AlgorithmManager::Instance().create("CreateMDHistoWorkspace"); + alg->initialize(); + alg->setProperty("SignalInput", values); + alg->setProperty("ErrorInput", values); + alg->setProperty("Dimensionality", 2); + alg->setProperty("NumberOfBins", dims); + alg->setPropertyValue("Extents", "-1,1,-1,1"); + alg->setPropertyValue("Names", "A,B"); + alg->setPropertyValue("Units", "U,U"); + alg->setPropertyValue("OutputWorkspace", "out"); + alg->execute(); + TS_ASSERT( alg->isExecuted() ); + + IMDHistoWorkspace_sptr ws = AnalysisDataService::Instance().retrieveWS("out"); + + alg = AlgorithmManager::Instance().create("EvaluateMDFunction"); + alg->initialize(); + alg->setProperty("InputWorkspace", ws); + alg->setPropertyValue("Function",function); + alg->setPropertyValue("OutputWorkspace", "out"); + alg->execute(); + + ws = AnalysisDataService::Instance().retrieveWS("out"); + + AnalysisDataService::Instance().remove("out"); + return ws; + } + }; diff --git a/Code/Mantid/Framework/MDEvents/test/MDBoxBaseTest.h b/Code/Mantid/Framework/MDEvents/test/MDBoxBaseTest.h index 14c4a60f1ac7..44733b33da4b 100644 --- a/Code/Mantid/Framework/MDEvents/test/MDBoxBaseTest.h +++ b/Code/Mantid/Framework/MDEvents/test/MDBoxBaseTest.h @@ -49,6 +49,7 @@ class MDBoxBaseTester : public MDBoxBase void setFileBacked(){}; void saveAt(API::IBoxControllerIO *const /* */, uint64_t /*position*/)const{/*Not saveable */}; void loadAndAddFrom(API::IBoxControllerIO *const /* */, uint64_t /*position*/, size_t /* Size */){}; + void reserveMemoryForLoad(uint64_t /* Size */){}; // regardless of what is actually instantiated, base tester would call itself gridbox bool isBox()const{return false;} diff --git a/Code/Mantid/Framework/MDEvents/test/MDBoxTest.h b/Code/Mantid/Framework/MDEvents/test/MDBoxTest.h index 1cf9119bce53..136448053eaa 100644 --- a/Code/Mantid/Framework/MDEvents/test/MDBoxTest.h +++ b/Code/Mantid/Framework/MDEvents/test/MDBoxTest.h @@ -629,6 +629,15 @@ static void destroySuite(MDBoxTest * suite) { delete suite; } TS_ASSERT_THROWS_NOTHING(box.unmask()); TSM_ASSERT("Should have been masked.", !box.getIsMasked()); } + + void test_reserve() + { + BoxController_sptr sc( new BoxController(2)); + MDBox,2> b(sc.get()); + + b.reserveMemoryForLoad(3); + TS_ASSERT_EQUALS( b.getEvents().capacity(), 3); + } }; diff --git a/Code/Mantid/Framework/Nexus/inc/MantidNexus/NexusFileIO.h b/Code/Mantid/Framework/Nexus/inc/MantidNexus/NexusFileIO.h index 1b4de0b238bf..3e60d7c15af5 100644 --- a/Code/Mantid/Framework/Nexus/inc/MantidNexus/NexusFileIO.h +++ b/Code/Mantid/Framework/Nexus/inc/MantidNexus/NexusFileIO.h @@ -13,6 +13,8 @@ #include #include +#include +#include namespace Mantid { @@ -51,7 +53,11 @@ namespace Mantid */ class DLLExport NexusFileIO { + public: + // Helper typedef + typedef boost::optional optional_size_t; + /// Default constructor NexusFileIO(); @@ -59,14 +65,16 @@ namespace Mantid NexusFileIO( API::Progress* prog ); /// Destructor - ~NexusFileIO() {} + ~NexusFileIO(); /// open the nexus file for writing - void openNexusWrite(const std::string& fileName); + void openNexusWrite(const std::string& fileName, optional_size_t entryNumber = optional_size_t()); /// write the header ifon for the Mantid workspace format int writeNexusProcessedHeader( const std::string& title, const std::string& wsName="") const; /// close the nexus file void closeNexusFile(); + /// Close the group. + void closeGroup(); /// Write a lgos section int writeNexusSampleLogs( const Mantid::API::Run& runProperties) const; /// write the workspace data @@ -101,12 +109,15 @@ namespace Mantid /// write bin masking information bool writeNexusBinMasking(API::MatrixWorkspace_const_sptr ws) const; + /// Reset the pointer to the progress object. + void resetProgress(Mantid::API::Progress* prog); + /// Nexus file handle NXhandle fileID; private: /// C++ API file handle - ::NeXus::File *m_filehandle; + boost::shared_ptr< ::NeXus::File> m_filehandle; /// Nexus compression method int m_nexuscompression; /// Allow an externally supplied progress object to be used @@ -432,6 +443,9 @@ namespace Mantid NXclosedata(fileID); } + /// Helper typedef for a shared pointer of a NexusFileIO. + typedef boost::shared_ptr NexusFileIO_sptr; + } // namespace NeXus } // namespace Mantid diff --git a/Code/Mantid/Framework/Nexus/src/NexusFileIO.cpp b/Code/Mantid/Framework/Nexus/src/NexusFileIO.cpp index 243856606020..de3afdaf607f 100644 --- a/Code/Mantid/Framework/Nexus/src/NexusFileIO.cpp +++ b/Code/Mantid/Framework/Nexus/src/NexusFileIO.cpp @@ -30,1158 +30,1249 @@ #include "MantidAPI/AlgorithmHistory.h" #include -#include +#include #include namespace Mantid { -namespace NeXus -{ -using namespace Kernel; -using namespace API; -using namespace DataObjects; - - namespace - { - /// static logger - Logger g_log("NexusFileIO"); - } - - /// Empty default constructor - NexusFileIO::NexusFileIO() : - m_filehandle(0), - m_nexuscompression(NX_COMP_LZW), - m_progress(0) + namespace NeXus { - } + using namespace Kernel; + using namespace API; + using namespace DataObjects; - /// Constructor that supplies a progress object - NexusFileIO::NexusFileIO( Progress *prog ) : - m_filehandle(0), - m_nexuscompression(NX_COMP_LZW), - m_progress(prog) - { - } - - - // - // Write out the data in a worksvn space in Nexus "Processed" format. - // This *Proposed* standard comprises the fields: - // - // - // {Extended title for entry} - // - // - // NXprocessed - // - // ? - // {Any relevant sample information necessary to define the data.} - // - // - // {Processed values} - // {Values of the first dimension's axis} - // {Values of the second dimension's axis} - // - // ? - // {Any relevant information about the steps used to process the data.} - // - // - - void NexusFileIO::openNexusWrite(const std::string& fileName ) - { - // open named file and entry - file may exist - // @throw Exception::FileError if cannot open Nexus file for writing - // - NXaccess mode(NXACC_CREATE5); - std::string className="NXentry"; - std::string mantidEntryName; - m_filename=fileName; - // - // If file to write exists, then open as is else see if the extension is xml, if so open as xml - // format otherwise as compressed hdf5 - // - if(Poco::File(m_filename).exists()) - mode = NXACC_RDWR; + namespace + { + /// static logger + Logger g_log("NexusFileIO"); + } - else + /// Empty default constructor + NexusFileIO::NexusFileIO() : + m_nexuscompression(NX_COMP_LZW), m_progress(0) { - if( fileName.find(".xml") < fileName.size() || fileName.find(".XML") < fileName.size() ) - { - mode = NXACC_CREATEXML; - m_nexuscompression = NX_COMP_NONE; - } - mantidEntryName="mantid_workspace_1"; } - // open the file and copy the handle into the NeXus::File object - NXstatus status=NXopen(fileName.c_str(), mode, &fileID); - if(status==NX_ERROR) + /// Constructor that supplies a progress object + NexusFileIO::NexusFileIO(Progress *prog) : + m_nexuscompression(NX_COMP_LZW), m_progress(prog) { - g_log.error("Unable to open file " + fileName); - throw Exception::FileError("Unable to open File:" , fileName); } - m_filehandle = new ::NeXus::File(fileID, true); - // - // for existing files, search for any current mantid_workspace_ entries and set the - // new name to be n+1 so that we do not over-write by default. This may need changing. - // - if(mode==NXACC_RDWR) + void NexusFileIO::resetProgress(Progress *prog) { - int count=findMantidWSEntries(); - std::stringstream suffix; - suffix << (count+1); - mantidEntryName="mantid_workspace_"+suffix.str(); + m_progress = prog; } + // - // make and open the new mantid_workspace_ group - // file remains open until explict close - // - m_filehandle->makeGroup(mantidEntryName,className); - m_filehandle->openGroup(mantidEntryName,className); - } + // Write out the data in a worksvn space in Nexus "Processed" format. + // This *Proposed* standard comprises the fields: + // + // + // {Extended title for entry} + // + // + // NXprocessed + // + // ? + // {Any relevant sample information necessary to define the data.} + // + // + // {Processed values} + // {Values of the first dimension's axis} + // {Values of the second dimension's axis} + // + // ? + // {Any relevant information about the steps used to process the data.} + // + // + + void NexusFileIO::openNexusWrite(const std::string& fileName, NexusFileIO::optional_size_t entryNumber) + { + // open named file and entry - file may exist + // @throw Exception::FileError if cannot open Nexus file for writing + // + NXaccess mode(NXACC_CREATE5); + std::string mantidEntryName; + m_filename = fileName; + // + // If file to write exists, then open as is else see if the extension is xml, if so open as xml + // format otherwise as compressed hdf5 + // + if (Poco::File(m_filename).exists()) + mode = NXACC_RDWR; + else + { + if (fileName.find(".xml") < fileName.size() || fileName.find(".XML") < fileName.size()) + { + mode = NXACC_CREATEXML; + m_nexuscompression = NX_COMP_NONE; + } + mantidEntryName = "mantid_workspace_1"; + } - //----------------------------------------------------------------------------------------------- - void NexusFileIO::closeNexusFile() - { - m_filehandle->closeGroup(); - delete m_filehandle; - } - - //----------------------------------------------------------------------------------------------- - /** Write Nexus mantid workspace header fields for the NXentry/IXmantid/NXprocessed field. - The URLs are not correct as they do not exist presently, but follow the format for other - Nexus specs. - @param title :: title field. - @param wsName :: workspace name. - */ - int NexusFileIO::writeNexusProcessedHeader( const std::string& title, const std::string& wsName) const - { + /*Only create the file handle if needed.*/ + if (!m_filehandle) + { + // open the file and copy the handle into the NeXus::File object + NXstatus status = NXopen(fileName.c_str(), mode, &fileID); + if (status == NX_ERROR) + { + g_log.error("Unable to open file " + fileName); + throw Exception::FileError("Unable to open File:", fileName); + } + ::NeXus::File* file = new ::NeXus::File(fileID, true); + m_filehandle = boost::shared_ptr< ::NeXus::File>(file); + } - std::string className="Mantid Processed Workspace"; - std::vector attributes,avalues; - if( ! writeNxValue("title", title, NX_CHAR, attributes, avalues) ) - return(3); - //name for workspace if this is a multi workspace nexus file - if(!wsName.empty()) - { - if( ! writeNxValue("workspace_name", wsName, NX_CHAR, attributes, avalues) ) - return(3); + // + // for existing files, search for any current mantid_workspace_ entries and set the + // new name to be n+1 so that we do not over-write by default. This may need changing. + // + if (mode == NXACC_RDWR) + { + size_t count = 0; + if( entryNumber.is_initialized() ) + { + // Use the entry number provided. + count = entryNumber.get(); + } + else + { + // Have to figure it our ourselves. Requires opening the exisitng file to get the information via a search. + count = findMantidWSEntries(); + } + + std::stringstream suffix; + suffix << (count + 1); + mantidEntryName = "mantid_workspace_" + suffix.str(); + } + // + // make and open the new mantid_workspace_ group + // file remains open until explicit close + // + const std::string className = "NXentry"; + + m_filehandle->makeGroup(mantidEntryName, className); + m_filehandle->openGroup(mantidEntryName, className); } - attributes.push_back("URL"); - avalues.push_back("http://www.nexusformat.org/instruments/xml/NXprocessed.xml"); - attributes.push_back("Version"); - avalues.push_back("1.0"); - // this may not be the "correct" long term path, but it is valid at present - if( ! writeNxValue( "definition", className, NX_CHAR, attributes, avalues) ) - return(3); - avalues.clear(); - avalues.push_back("http://www.isis.rl.ac.uk/xml/IXmantid.xml"); - avalues.push_back("1.0"); - if( ! writeNxValue( "definition_local", className, NX_CHAR, attributes, avalues) ) - return(3); - return(0); - } - - - //----------------------------------------------------------------------------------------------- - // - // write an NXdata entry with Float array values - // - void NexusFileIO::writeNxFloatArray(const std::string& name, const std::vector& values, const std::vector& attributes, - const std::vector& avalues) const - { - m_filehandle->writeData(name, values); - m_filehandle->openData(name); - for(size_t it=0; itputAttr(attributes[it], avalues[it]); - m_filehandle->closeData(); - } - - - //----------------------------------------------------------------------------------------------- - // - // write an NXdata entry with String array values - // - bool NexusFileIO::writeNxStringArray(const std::string& name, const std::vector& values, const std::vector& attributes, - const std::vector& avalues) const - { - int dimensions[2]; - size_t maxlen=0; - dimensions[0]=static_cast(values.size()); - for(size_t i=0;imaxlen) maxlen=values[i].size(); - dimensions[1]=static_cast(maxlen); - NXstatus status=NXmakedata(fileID, name.c_str(), NX_CHAR, 2, dimensions); - if(status==NX_ERROR) return(false); - NXopendata(fileID, name.c_str()); - for(size_t it=0; it(const_cast(avalues[it].c_str())), static_cast(avalues[it].size()+1), NX_CHAR); - char* strs=new char[values.size()*maxlen]; - for(size_t i=0;icloseGroup(); } - NXputdata(fileID, (void*)strs); - NXclosedata(fileID); - delete[] strs; - return(true); - } - // - // Write an NXnote entry with data giving parameter pair values for algorithm history and environment - // Use NX_CHAR instead of NX_BINARY for the parameter values to make more simple. - // - bool NexusFileIO::writeNxNote(const std::string& noteName, const std::string& author, const std::string& date, - const std::string& description, const std::string& pairValues) const - { - m_filehandle->makeGroup(noteName, "NXnote", true); - std::vector attributes,avalues; - if(date!="") + //----------------------------------------------------------------------------------------------- + void NexusFileIO::closeNexusFile() { - attributes.push_back("date"); - avalues.push_back(date); + if (m_filehandle) + { + m_filehandle.reset(); + } } - if( ! writeNxValue( "author", author, NX_CHAR, attributes, avalues) ) - return(false); - attributes.clear(); - avalues.clear(); - - if( ! writeNxValue( "description", description, NX_CHAR, attributes, avalues) ) - return(false); - if( ! writeNxValue( "data", pairValues, NX_CHAR, attributes, avalues) ) - return(false); - m_filehandle->closeGroup(); - return(true); - } + //----------------------------------------------------------------------------------------------- + /** Write Nexus mantid workspace header fields for the NXentry/IXmantid/NXprocessed field. + The URLs are not correct as they do not exist presently, but follow the format for other + Nexus specs. + @param title :: title field. + @param wsName :: workspace name. + */ + int NexusFileIO::writeNexusProcessedHeader(const std::string& title, const std::string& wsName) const + { + std::string className = "Mantid Processed Workspace"; + std::vector attributes, avalues; + if (!writeNxValue("title", title, NX_CHAR, attributes, avalues)) + return (3); + //name for workspace if this is a multi workspace nexus file + if (!wsName.empty()) + { + if (!writeNxValue("workspace_name", wsName, NX_CHAR, attributes, avalues)) + return (3); + } - //------------------------------------------------------------------------------------- - /** Write out a MatrixWorkspace's data as a 2D matrix. - * Use writeNexusProcessedDataEvent if writing an EventWorkspace. - */ - int NexusFileIO::writeNexusProcessedData2D( const API::MatrixWorkspace_const_sptr& localworkspace, - const bool& uniformSpectra, const std::vector& spec, - const char * group_name, bool write2Ddata) const - { - NXstatus status; - - //write data entry - status=NXmakegroup(fileID,group_name,"NXdata"); - if(status==NX_ERROR) - return(2); - NXopengroup(fileID,group_name,"NXdata"); - // write workspace data - const size_t nHist=localworkspace->getNumberHistograms(); - if(nHist<1) - return(2); - const size_t nSpectBins=localworkspace->readY(0).size(); - const size_t nSpect=spec.size(); - int dims_array[2] = { static_cast(nSpect),static_cast(nSpectBins) }; - - - // Set the axis labels and values - Mantid::API::Axis *xAxis=localworkspace->getAxis(0); - Mantid::API::Axis *sAxis=localworkspace->getAxis(1); - std::string xLabel,sLabel; - if ( xAxis->isSpectra() ) xLabel = "spectraNumber"; - else - { - if ( xAxis->unit() ) xLabel = xAxis->unit()->unitID(); - else xLabel = "unknown"; + attributes.push_back("URL"); + avalues.push_back("http://www.nexusformat.org/instruments/xml/NXprocessed.xml"); + attributes.push_back("Version"); + avalues.push_back("1.0"); + // this may not be the "correct" long term path, but it is valid at present + if (!writeNxValue("definition", className, NX_CHAR, attributes, avalues)) + return (3); + avalues.clear(); + avalues.push_back("http://www.isis.rl.ac.uk/xml/IXmantid.xml"); + avalues.push_back("1.0"); + if (!writeNxValue("definition_local", className, NX_CHAR, attributes, avalues)) + return (3); + return (0); } - if ( sAxis->isSpectra() ) sLabel = "spectraNumber"; - else + + //----------------------------------------------------------------------------------------------- + // + // write an NXdata entry with Float array values + // + void NexusFileIO::writeNxFloatArray(const std::string& name, const std::vector& values, + const std::vector& attributes, const std::vector& avalues) const { - if ( sAxis->unit() ) sLabel = sAxis->unit()->unitID(); - else sLabel = "unknown"; + m_filehandle->writeData(name, values); + m_filehandle->openData(name); + for (size_t it = 0; it < attributes.size(); ++it) + m_filehandle->putAttr(attributes[it], avalues[it]); + m_filehandle->closeData(); } - // Get the values on the vertical axis - std::vector axis2; - if (nSpect < nHist) - for (size_t i=0;ilength();i++) - axis2.push_back((*sAxis)(i)); - - int start[2]={0,0}; - int asize[2]={1,dims_array[1]}; - - // -------------- Actually write the 2D data ---------------------------- - if (write2Ddata) + //----------------------------------------------------------------------------------------------- + // + // write an NXdata entry with String array values + // + bool NexusFileIO::writeNxStringArray(const std::string& name, const std::vector& values, + const std::vector& attributes, const std::vector& avalues) const { - std::string name="values"; - NXcompmakedata(fileID, name.c_str(), NX_FLOAT64, 2, dims_array,m_nexuscompression,asize); + int dimensions[2]; + size_t maxlen = 0; + dimensions[0] = static_cast(values.size()); + for (size_t i = 0; i < values.size(); i++) + if (values[i].size() > maxlen) + maxlen = values[i].size(); + dimensions[1] = static_cast(maxlen); + NXstatus status = NXmakedata(fileID, name.c_str(), NX_CHAR, 2, dimensions); + if (status == NX_ERROR) + return (false); NXopendata(fileID, name.c_str()); - for(size_t i=0;i(const_cast(avalues[it].c_str())), + static_cast(avalues[it].size() + 1), NX_CHAR); + char* strs = new char[values.size() * maxlen]; + for (size_t i = 0; i < values.size(); i++) { - int s = spec[i]; - NXputslab(fileID, reinterpret_cast(const_cast(&(localworkspace->readY(s)[0]))),start,asize); - start[0]++; + strncpy(&strs[i * maxlen], values[i].c_str(), maxlen); } - if(m_progress != 0) m_progress->reportIncrement(1, "Writing data"); - int signal=1; - NXputattr (fileID, "signal", &signal, 1, NX_INT32); - // More properties - const std::string axesNames="axis2,axis1"; - NXputattr (fileID, "axes", reinterpret_cast(const_cast(axesNames.c_str())), static_cast(axesNames.size()), NX_CHAR); - std::string yUnits=localworkspace->YUnit(); - std::string yUnitLabel=localworkspace->YUnitLabel(); - NXputattr (fileID, "units", reinterpret_cast(const_cast(yUnits.c_str())), static_cast(yUnits.size()), NX_CHAR); - NXputattr (fileID, "unit_label", reinterpret_cast(const_cast(yUnitLabel.c_str())), static_cast(yUnitLabel.size()), NX_CHAR); + NXputdata(fileID, (void*) strs); NXclosedata(fileID); + delete[] strs; + return (true); + } + // + // Write an NXnote entry with data giving parameter pair values for algorithm history and environment + // Use NX_CHAR instead of NX_BINARY for the parameter values to make more simple. + // + bool NexusFileIO::writeNxNote(const std::string& noteName, const std::string& author, + const std::string& date, const std::string& description, const std::string& pairValues) const + { + m_filehandle->makeGroup(noteName, "NXnote", true); - // error - name="errors"; - NXcompmakedata(fileID, name.c_str(), NX_FLOAT64, 2, dims_array,m_nexuscompression,asize); - NXopendata(fileID, name.c_str()); - start[0]=0; - for(size_t i=0;i attributes, avalues; + if (date != "") + { + attributes.push_back("date"); + avalues.push_back(date); + } + if (!writeNxValue("author", author, NX_CHAR, attributes, avalues)) + return (false); + attributes.clear(); + avalues.clear(); + + if (!writeNxValue("description", description, NX_CHAR, attributes, avalues)) + return (false); + if (!writeNxValue("data", pairValues, NX_CHAR, attributes, avalues)) + return (false); + + m_filehandle->closeGroup(); + return (true); + } + + //------------------------------------------------------------------------------------- + /** Write out a MatrixWorkspace's data as a 2D matrix. + * Use writeNexusProcessedDataEvent if writing an EventWorkspace. + */ + int NexusFileIO::writeNexusProcessedData2D(const API::MatrixWorkspace_const_sptr& localworkspace, + const bool& uniformSpectra, const std::vector& spec, const char * group_name, + bool write2Ddata) const + { + NXstatus status; + + //write data entry + status = NXmakegroup(fileID, group_name, "NXdata"); + if (status == NX_ERROR) + return (2); + NXopengroup(fileID, group_name, "NXdata"); + // write workspace data + const size_t nHist = localworkspace->getNumberHistograms(); + if (nHist < 1) + return (2); + const size_t nSpectBins = localworkspace->readY(0).size(); + const size_t nSpect = spec.size(); + int dims_array[2] = + { static_cast(nSpect), static_cast(nSpectBins) }; + + // Set the axis labels and values + Mantid::API::Axis *xAxis = localworkspace->getAxis(0); + Mantid::API::Axis *sAxis = localworkspace->getAxis(1); + std::string xLabel, sLabel; + if (xAxis->isSpectra()) + xLabel = "spectraNumber"; + else { - int s = spec[i]; - NXputslab(fileID, reinterpret_cast(const_cast(&(localworkspace->readE(s)[0]))),start,asize); - start[0]++; + if (xAxis->unit()) + xLabel = xAxis->unit()->unitID(); + else + xLabel = "unknown"; } - if(m_progress != 0) m_progress->reportIncrement(1, "Writing data"); + if (sAxis->isSpectra()) + sLabel = "spectraNumber"; + else + { + if (sAxis->unit()) + sLabel = sAxis->unit()->unitID(); + else + sLabel = "unknown"; + } + // Get the values on the vertical axis + std::vector axis2; + if (nSpect < nHist) + for (size_t i = 0; i < nSpect; i++) + axis2.push_back((*sAxis)(spec[i])); + else + for (size_t i = 0; i < sAxis->length(); i++) + axis2.push_back((*sAxis)(i)); - // Fractional area for RebinnedOutput - if (localworkspace->id() == "RebinnedOutput") + int start[2] = + { 0, 0 }; + int asize[2] = + { 1, dims_array[1] }; + + // -------------- Actually write the 2D data ---------------------------- + if (write2Ddata) { - RebinnedOutput_const_sptr rebin_workspace = boost::dynamic_pointer_cast(localworkspace); - name="frac_area"; - NXcompmakedata(fileID, name.c_str(), NX_FLOAT64, 2, - dims_array,m_nexuscompression,asize); + std::string name = "values"; + NXcompmakedata(fileID, name.c_str(), NX_FLOAT64, 2, dims_array, m_nexuscompression, asize); NXopendata(fileID, name.c_str()); - start[0]=0; - for(size_t i=0;i(const_cast(&(rebin_workspace->readF(s)[0]))), - start, asize); + NXputslab(fileID, reinterpret_cast(const_cast(&(localworkspace->readY(s)[0]))), + start, asize); start[0]++; } - if(m_progress != 0) m_progress->reportIncrement(1, "Writing data"); - } - - NXclosedata(fileID); - } - - // write X data, as single array or all values if "ragged" - if(uniformSpectra) - { - dims_array[0]=static_cast(localworkspace->readX(0).size()); - NXmakedata(fileID, "axis1", NX_FLOAT64, 1, dims_array); - NXopendata(fileID, "axis1"); - NXputdata(fileID, reinterpret_cast(const_cast(&(localworkspace->readX(0)[0])))); - } - else - { - dims_array[0]=static_cast(nSpect); - dims_array[1]=static_cast(localworkspace->readX(0).size()); - NXmakedata(fileID, "axis1", NX_FLOAT64, 2, dims_array); - NXopendata(fileID, "axis1"); - start[0]=0; asize[1]=dims_array[1]; - for(size_t i=0;i(const_cast(&(localworkspace->readX(i)[0]))),start,asize); - start[0]++; - } - } - std::string dist=(localworkspace->isDistribution()) ? "1" : "0"; - NXputattr(fileID, "distribution", reinterpret_cast(const_cast(dist.c_str())), 2, NX_CHAR); - NXputattr (fileID, "units", reinterpret_cast(const_cast(xLabel.c_str())), static_cast(xLabel.size()), NX_CHAR); + if (m_progress != 0) + m_progress->reportIncrement(1, "Writing data"); + int signal = 1; + NXputattr(fileID, "signal", &signal, 1, NX_INT32); + // More properties + const std::string axesNames = "axis2,axis1"; + NXputattr(fileID, "axes", reinterpret_cast(const_cast(axesNames.c_str())), + static_cast(axesNames.size()), NX_CHAR); + std::string yUnits = localworkspace->YUnit(); + std::string yUnitLabel = localworkspace->YUnitLabel(); + NXputattr(fileID, "units", reinterpret_cast(const_cast(yUnits.c_str())), + static_cast(yUnits.size()), NX_CHAR); + NXputattr(fileID, "unit_label", reinterpret_cast(const_cast(yUnitLabel.c_str())), + static_cast(yUnitLabel.size()), NX_CHAR); + NXclosedata(fileID); - auto label = boost::dynamic_pointer_cast(xAxis->unit()); - if(label) - { - NXputattr (fileID, "caption", reinterpret_cast(const_cast(label->caption().c_str())), static_cast(label->caption().size()), NX_CHAR); - auto unitLbl = label->label(); - NXputattr (fileID, "label", reinterpret_cast(const_cast(unitLbl.ascii().c_str())), static_cast(unitLbl.ascii().size()), NX_CHAR); - } + // error + name = "errors"; + NXcompmakedata(fileID, name.c_str(), NX_FLOAT64, 2, dims_array, m_nexuscompression, asize); + NXopendata(fileID, name.c_str()); + start[0] = 0; + for (size_t i = 0; i < nSpect; i++) + { + int s = spec[i]; + NXputslab(fileID, reinterpret_cast(const_cast(&(localworkspace->readE(s)[0]))), + start, asize); + start[0]++; + } + if (m_progress != 0) + m_progress->reportIncrement(1, "Writing data"); - NXclosedata(fileID); + // Fractional area for RebinnedOutput + if (localworkspace->id() == "RebinnedOutput") + { + RebinnedOutput_const_sptr rebin_workspace = boost::dynamic_pointer_cast( + localworkspace); + name = "frac_area"; + NXcompmakedata(fileID, name.c_str(), NX_FLOAT64, 2, dims_array, m_nexuscompression, asize); + NXopendata(fileID, name.c_str()); + start[0] = 0; + for (size_t i = 0; i < nSpect; i++) + { + int s = spec[i]; + NXputslab(fileID, + reinterpret_cast(const_cast(&(rebin_workspace->readF(s)[0]))), start, + asize); + start[0]++; + } + if (m_progress != 0) + m_progress->reportIncrement(1, "Writing data"); + } - if ( ! sAxis->isText() ) - { - // write axis2, maybe just spectra number - dims_array[0]=static_cast(axis2.size()); - NXmakedata(fileID, "axis2", NX_FLOAT64, 1, dims_array); - NXopendata(fileID, "axis2"); - NXputdata(fileID, (void*)&(axis2[0])); - NXputattr (fileID, "units", reinterpret_cast(const_cast(sLabel.c_str())), static_cast(sLabel.size()), NX_CHAR); + NXclosedata(fileID); + } - auto label = boost::dynamic_pointer_cast(sAxis->unit()); - if(label) + // write X data, as single array or all values if "ragged" + if (uniformSpectra) { - NXputattr (fileID, "caption", reinterpret_cast(const_cast(label->caption().c_str())), static_cast(label->caption().size()), NX_CHAR); - auto unitLbl = label->label(); - NXputattr (fileID, "label", reinterpret_cast(const_cast(unitLbl.ascii().c_str())), static_cast(unitLbl.ascii().size()), NX_CHAR); + dims_array[0] = static_cast(localworkspace->readX(0).size()); + NXmakedata(fileID, "axis1", NX_FLOAT64, 1, dims_array); + NXopendata(fileID, "axis1"); + NXputdata(fileID, reinterpret_cast(const_cast(&(localworkspace->readX(0)[0])))); } - - NXclosedata(fileID); - } - else - { - std::string textAxis; - for ( size_t i = 0; i < sAxis->length(); i ++ ) + else { - std::string label = sAxis->label(i); - textAxis += label + "\n"; + dims_array[0] = static_cast(nSpect); + dims_array[1] = static_cast(localworkspace->readX(0).size()); + NXmakedata(fileID, "axis1", NX_FLOAT64, 2, dims_array); + NXopendata(fileID, "axis1"); + start[0] = 0; + asize[1] = dims_array[1]; + for (size_t i = 0; i < nSpect; i++) + { + NXputslab(fileID, reinterpret_cast(const_cast(&(localworkspace->readX(i)[0]))), + start, asize); + start[0]++; + } } - dims_array[0] = static_cast(textAxis.size()); - NXmakedata(fileID, "axis2", NX_CHAR, 2, dims_array); - NXopendata(fileID, "axis2"); - NXputdata(fileID, reinterpret_cast(const_cast(textAxis.c_str()))); - NXputattr (fileID, "units", reinterpret_cast(const_cast("TextAxis")), 8, NX_CHAR); - - auto label = boost::dynamic_pointer_cast(sAxis->unit()); - if(label) + std::string dist = (localworkspace->isDistribution()) ? "1" : "0"; + NXputattr(fileID, "distribution", reinterpret_cast(const_cast(dist.c_str())), 2, + NX_CHAR); + NXputattr(fileID, "units", reinterpret_cast(const_cast(xLabel.c_str())), + static_cast(xLabel.size()), NX_CHAR); + + auto label = boost::dynamic_pointer_cast(xAxis->unit()); + if (label) { - NXputattr (fileID, "caption", reinterpret_cast(const_cast(label->caption().c_str())), static_cast(label->caption().size()), NX_CHAR); + NXputattr(fileID, "caption", + reinterpret_cast(const_cast(label->caption().c_str())), + static_cast(label->caption().size()), NX_CHAR); auto unitLbl = label->label(); - NXputattr (fileID, "label", reinterpret_cast(const_cast(unitLbl.ascii().c_str())), static_cast(unitLbl.ascii().size()), NX_CHAR); + NXputattr(fileID, "label", reinterpret_cast(const_cast(unitLbl.ascii().c_str())), + static_cast(unitLbl.ascii().size()), NX_CHAR); } NXclosedata(fileID); - } - writeNexusBinMasking(localworkspace); + if (!sAxis->isText()) + { + // write axis2, maybe just spectra number + dims_array[0] = static_cast(axis2.size()); + NXmakedata(fileID, "axis2", NX_FLOAT64, 1, dims_array); + NXopendata(fileID, "axis2"); + NXputdata(fileID, (void*) &(axis2[0])); + NXputattr(fileID, "units", reinterpret_cast(const_cast(sLabel.c_str())), + static_cast(sLabel.size()), NX_CHAR); + + auto label = boost::dynamic_pointer_cast(sAxis->unit()); + if (label) + { + NXputattr(fileID, "caption", + reinterpret_cast(const_cast(label->caption().c_str())), + static_cast(label->caption().size()), NX_CHAR); + auto unitLbl = label->label(); + NXputattr(fileID, "label", reinterpret_cast(const_cast(unitLbl.ascii().c_str())), + static_cast(unitLbl.ascii().size()), NX_CHAR); + } - status=NXclosegroup(fileID); - return((status==NX_ERROR)?3:0); - } + NXclosedata(fileID); + } + else + { + std::string textAxis; + for (size_t i = 0; i < sAxis->length(); i++) + { + std::string label = sAxis->label(i); + textAxis += label + "\n"; + } + dims_array[0] = static_cast(textAxis.size()); + NXmakedata(fileID, "axis2", NX_CHAR, 2, dims_array); + NXopendata(fileID, "axis2"); + NXputdata(fileID, reinterpret_cast(const_cast(textAxis.c_str()))); + NXputattr(fileID, "units", reinterpret_cast(const_cast("TextAxis")), 8, NX_CHAR); + + auto label = boost::dynamic_pointer_cast(sAxis->unit()); + if (label) + { + NXputattr(fileID, "caption", + reinterpret_cast(const_cast(label->caption().c_str())), + static_cast(label->caption().size()), NX_CHAR); + auto unitLbl = label->label(); + NXputattr(fileID, "label", reinterpret_cast(const_cast(unitLbl.ascii().c_str())), + static_cast(unitLbl.ascii().size()), NX_CHAR); + } + NXclosedata(fileID); + } - //------------------------------------------------------------------------------------- - /** Write out a table Workspace's - */ - int NexusFileIO::writeNexusTableWorkspace( const API::ITableWorkspace_const_sptr& itableworkspace, - const char * group_name) const - { - NXstatus status = 0; + writeNexusBinMasking(localworkspace); - boost::shared_ptr tableworkspace = - boost::dynamic_pointer_cast(itableworkspace); - boost::shared_ptr peakworkspace = - boost::dynamic_pointer_cast(itableworkspace); + status = NXclosegroup(fileID); + return ((status == NX_ERROR) ? 3 : 0); + } - if ( !tableworkspace && !peakworkspace ) - return((status==NX_ERROR)?3:0); + //------------------------------------------------------------------------------------- + /** Write out a table Workspace's + */ + int NexusFileIO::writeNexusTableWorkspace(const API::ITableWorkspace_const_sptr& itableworkspace, + const char * group_name) const + { + NXstatus status = 0; - //write data entry - status=NXmakegroup(fileID,group_name,"NXdata"); - if(status==NX_ERROR) - return(2); - NXopengroup(fileID,group_name,"NXdata"); + boost::shared_ptr tableworkspace = boost::dynamic_pointer_cast< + const TableWorkspace>(itableworkspace); + boost::shared_ptr peakworkspace = boost::dynamic_pointer_cast< + const PeaksWorkspace>(itableworkspace); - int nRows = static_cast(itableworkspace->rowCount()); + if (!tableworkspace && !peakworkspace) + return ((status == NX_ERROR) ? 3 : 0); - int dims_array[1] = { nRows }; + //write data entry + status = NXmakegroup(fileID, group_name, "NXdata"); + if (status == NX_ERROR) + return (2); + NXopengroup(fileID, group_name, "NXdata"); - for (size_t i = 0; i < itableworkspace->columnCount(); i++) - { - Column_const_sptr col = itableworkspace->getColumn(i); + int nRows = static_cast(itableworkspace->rowCount()); - std::string str = "column_" + boost::lexical_cast(i+1); + int dims_array[1] = + { nRows }; - if ( col->isType() ) - { - double * toNexus = new double[nRows]; - for (int ii = 0; ii < nRows; ii++) - toNexus[ii] = col->cell(ii); - NXwritedata(str.c_str(), NX_FLOAT64, 1, dims_array, (void *)(toNexus), false); - delete[] toNexus; + for (size_t i = 0; i < itableworkspace->columnCount(); i++) + { + Column_const_sptr col = itableworkspace->getColumn(i); - // attributes - NXopendata(fileID, str.c_str()); - std::string units = "Not known"; - std::string interpret_as = "A double"; - NXputattr(fileID, "units", reinterpret_cast(const_cast(units.c_str())), static_cast(units.size()), NX_CHAR); - NXputattr(fileID, "interpret_as", reinterpret_cast(const_cast(interpret_as.c_str())), - static_cast(interpret_as.size()), NX_CHAR); - NXclosedata(fileID); - } - else if ( col->isType() ) - { - int * toNexus = new int[nRows]; - for (int ii = 0; ii < nRows; ii++) - toNexus[ii] = col->cell(ii); - NXwritedata(str.c_str(), NX_INT32, 1, dims_array, (void *)(toNexus), false); - delete[] toNexus; + std::string str = "column_" + boost::lexical_cast(i + 1); - // attributes - NXopendata(fileID, str.c_str()); - std::string units = "Not known"; - std::string interpret_as = "An integer"; - NXputattr(fileID, "units", reinterpret_cast(const_cast(units.c_str())), static_cast(units.size()), NX_CHAR); - NXputattr(fileID, "interpret_as", reinterpret_cast(const_cast(interpret_as.c_str())), - static_cast(interpret_as.size()), NX_CHAR); - NXclosedata(fileID); - } - else if ( col->isType() ) - { - // determine max string size - size_t maxStr = 0; - for (int ii = 0; ii < nRows; ii++) + if (col->isType()) { - if ( col->cell(ii).size() > maxStr) - maxStr = col->cell(ii).size(); + double * toNexus = new double[nRows]; + for (int ii = 0; ii < nRows; ii++) + toNexus[ii] = col->cell(ii); + NXwritedata(str.c_str(), NX_FLOAT64, 1, dims_array, (void *) (toNexus), false); + delete[] toNexus; + + // attributes + NXopendata(fileID, str.c_str()); + std::string units = "Not known"; + std::string interpret_as = "A double"; + NXputattr(fileID, "units", reinterpret_cast(const_cast(units.c_str())), + static_cast(units.size()), NX_CHAR); + NXputattr(fileID, "interpret_as", + reinterpret_cast(const_cast(interpret_as.c_str())), + static_cast(interpret_as.size()), NX_CHAR); + NXclosedata(fileID); } - int dims_array[2] = { nRows, static_cast(maxStr) }; - int asize[2]={1,dims_array[1]}; - - NXcompmakedata(fileID, str.c_str(), NX_CHAR, 2, dims_array,false,asize); - NXopendata(fileID, str.c_str()); - char* toNexus = new char[maxStr*nRows]; - for(int ii = 0; ii < nRows; ii++) + else if (col->isType()) { - std::string rowStr = col->cell(ii); - for (size_t ic = 0; ic < rowStr.size(); ic++) - toNexus[ii*maxStr+ic] = rowStr[ic]; - for (size_t ic = rowStr.size(); ic < static_cast(maxStr); ic++) - toNexus[ii*maxStr+ic] = ' '; + int * toNexus = new int[nRows]; + for (int ii = 0; ii < nRows; ii++) + toNexus[ii] = col->cell(ii); + NXwritedata(str.c_str(), NX_INT32, 1, dims_array, (void *) (toNexus), false); + delete[] toNexus; + + // attributes + NXopendata(fileID, str.c_str()); + std::string units = "Not known"; + std::string interpret_as = "An integer"; + NXputattr(fileID, "units", reinterpret_cast(const_cast(units.c_str())), + static_cast(units.size()), NX_CHAR); + NXputattr(fileID, "interpret_as", + reinterpret_cast(const_cast(interpret_as.c_str())), + static_cast(interpret_as.size()), NX_CHAR); + NXclosedata(fileID); } - - NXputdata(fileID, (void *)(toNexus)); - delete[] toNexus; + else if (col->isType()) + { + // determine max string size + size_t maxStr = 0; + for (int ii = 0; ii < nRows; ii++) + { + if (col->cell(ii).size() > maxStr) + maxStr = col->cell(ii).size(); + } + int dims_array[2] = + { nRows, static_cast(maxStr) }; + int asize[2] = + { 1, dims_array[1] }; + + NXcompmakedata(fileID, str.c_str(), NX_CHAR, 2, dims_array, false, asize); + NXopendata(fileID, str.c_str()); + char* toNexus = new char[maxStr * nRows]; + for (int ii = 0; ii < nRows; ii++) + { + std::string rowStr = col->cell(ii); + for (size_t ic = 0; ic < rowStr.size(); ic++) + toNexus[ii * maxStr + ic] = rowStr[ic]; + for (size_t ic = rowStr.size(); ic < static_cast(maxStr); ic++) + toNexus[ii * maxStr + ic] = ' '; + } - // attributes - std::string units = "N/A"; - std::string interpret_as = "A string"; - NXputattr(fileID, "units", reinterpret_cast(const_cast(units.c_str())), static_cast(units.size()), NX_CHAR); - NXputattr(fileID, "interpret_as", reinterpret_cast(const_cast(interpret_as.c_str())), - static_cast(interpret_as.size()), NX_CHAR); + NXputdata(fileID, (void *) (toNexus)); + delete[] toNexus; - NXclosedata(fileID); - } - #define IF_VECTOR_COLUMN(Type, NexusType) \ + // attributes + std::string units = "N/A"; + std::string interpret_as = "A string"; + NXputattr(fileID, "units", reinterpret_cast(const_cast(units.c_str())), + static_cast(units.size()), NX_CHAR); + NXputattr(fileID, "interpret_as", + reinterpret_cast(const_cast(interpret_as.c_str())), + static_cast(interpret_as.size()), NX_CHAR); + + NXclosedata(fileID); + } +#define IF_VECTOR_COLUMN(Type, NexusType) \ else if ( col->isType< std::vector >() ) \ { \ auto vecCol = boost::dynamic_pointer_cast< const VectorColumn >(col); \ writeNexusVectorColumn(vecCol, str, NexusType, #Type); \ } - IF_VECTOR_COLUMN(int,NX_INT32) - IF_VECTOR_COLUMN(double,NX_FLOAT64) - - // write out title - NXopendata(fileID, str.c_str()); - NXputattr(fileID, "name", reinterpret_cast(const_cast(col->name().c_str())), static_cast(col->name().size()), NX_CHAR); - NXclosedata(fileID); - } + IF_VECTOR_COLUMN(int,NX_INT32) IF_VECTOR_COLUMN(double, NX_FLOAT64) - status=NXclosegroup(fileID); - return((status==NX_ERROR)?3:0); - } - - - //------------------------------------------------------------------------------------- - /** Write out a combined chunk of event data - * - * @param ws :: an EventWorkspace - * @param indices :: array of event list indexes - * @param tofs :: array of TOFs - * @param weights :: array of event weights - * @param errorSquareds :: array of event squared errors - * @param pulsetimes :: array of pulsetimes - * @param compress :: if true, compress the entry - */ - int NexusFileIO::writeNexusProcessedDataEventCombined( const DataObjects::EventWorkspace_const_sptr& ws, - std::vector & indices, - double * tofs, float * weights, float * errorSquareds, int64_t * pulsetimes, - bool compress) const - { - NXopengroup(fileID,"event_workspace","NXdata"); + // write out title + NXopendata(fileID, str.c_str()); + NXputattr(fileID, "name", reinterpret_cast(const_cast(col->name().c_str())), + static_cast(col->name().size()), NX_CHAR); + NXclosedata(fileID); + } - // The array of indices for each event list # - int dims_array[1] = { static_cast(indices.size()) }; - if (indices.size() > 0) - { - if (compress) - NXcompmakedata(fileID, "indices", NX_INT64, 1, dims_array, m_nexuscompression, dims_array); - else - NXmakedata(fileID, "indices", NX_INT64, 1, dims_array); - NXopendata(fileID, "indices"); - NXputdata(fileID, (void*)(indices.data()) ); - std::string yUnits=ws->YUnit(); - std::string yUnitLabel=ws->YUnitLabel(); - NXputattr (fileID, "units", reinterpret_cast(const_cast(yUnits.c_str())), static_cast(yUnits.size()), NX_CHAR); - NXputattr (fileID, "unit_label", reinterpret_cast(const_cast(yUnitLabel.c_str())), static_cast(yUnitLabel.size()), NX_CHAR); - NXclosedata(fileID); + status = NXclosegroup(fileID); + return ((status == NX_ERROR) ? 3 : 0); } - // Write out each field - dims_array[0] = static_cast(indices.back()); // TODO big truncation error! This is the # of events - if (tofs) - NXwritedata("tof", NX_FLOAT64, 1, dims_array, (void *)(tofs), compress); - if (pulsetimes) - NXwritedata("pulsetime", NX_INT64, 1, dims_array, (void *)(pulsetimes), compress); - if (weights) - NXwritedata("weight", NX_FLOAT32, 1, dims_array, (void *)(weights), compress); - if (errorSquareds) - NXwritedata("error_squared", NX_FLOAT32, 1, dims_array, (void *)(errorSquareds), compress); - - - // Close up the overall group - NXstatus status=NXclosegroup(fileID); - return((status==NX_ERROR)?3:0); - } - - - - - //------------------------------------------------------------------------------------- - /** Write out all of the event lists in the given workspace - * @param ws :: an EventWorkspace */ - int NexusFileIO::writeNexusProcessedDataEvent( const DataObjects::EventWorkspace_const_sptr& ws) - { - //write data entry - NXstatus status=NXmakegroup(fileID,"event_workspace","NXdata"); - if(status==NX_ERROR) return(2); - NXopengroup(fileID,"event_workspace","NXdata"); - - for (size_t wi=0; wi < ws->getNumberHistograms(); wi++) + //------------------------------------------------------------------------------------- + /** Write out a combined chunk of event data + * + * @param ws :: an EventWorkspace + * @param indices :: array of event list indexes + * @param tofs :: array of TOFs + * @param weights :: array of event weights + * @param errorSquareds :: array of event squared errors + * @param pulsetimes :: array of pulsetimes + * @param compress :: if true, compress the entry + */ + int NexusFileIO::writeNexusProcessedDataEventCombined( + const DataObjects::EventWorkspace_const_sptr& ws, std::vector & indices, double * tofs, + float * weights, float * errorSquareds, int64_t * pulsetimes, bool compress) const { - std::ostringstream group_name; - group_name << "event_list_" << wi; - this->writeEventList( ws->getEventList(wi), group_name.str()); - } + NXopengroup(fileID, "event_workspace", "NXdata"); - // Close up the overall group - status=NXclosegroup(fileID); - return((status==NX_ERROR)?3:0); - } + // The array of indices for each event list # + int dims_array[1] = + { static_cast(indices.size()) }; + if (indices.size() > 0) + { + if (compress) + NXcompmakedata(fileID, "indices", NX_INT64, 1, dims_array, m_nexuscompression, dims_array); + else + NXmakedata(fileID, "indices", NX_INT64, 1, dims_array); + NXopendata(fileID, "indices"); + NXputdata(fileID, (void*) (indices.data())); + std::string yUnits = ws->YUnit(); + std::string yUnitLabel = ws->YUnitLabel(); + NXputattr(fileID, "units", reinterpret_cast(const_cast(yUnits.c_str())), + static_cast(yUnits.size()), NX_CHAR); + NXputattr(fileID, "unit_label", reinterpret_cast(const_cast(yUnitLabel.c_str())), + static_cast(yUnitLabel.size()), NX_CHAR); + NXclosedata(fileID); + } - //------------------------------------------------------------------------------------- - /** Write out an array to the open file. */ - void NexusFileIO::NXwritedata( const char * name, int datatype, int rank, int * dims_array, void * data, bool compress) const - { - if (compress) - { - // We'll use the same slab/buffer size as the size of the array - NXcompmakedata(fileID, name, datatype, rank, dims_array, m_nexuscompression, dims_array); - } - else - { - // Write uncompressed. - NXmakedata(fileID, name, datatype, rank, dims_array); + // Write out each field + dims_array[0] = static_cast(indices.back()); // TODO big truncation error! This is the # of events + if (tofs) + NXwritedata("tof", NX_FLOAT64, 1, dims_array, (void *) (tofs), compress); + if (pulsetimes) + NXwritedata("pulsetime", NX_INT64, 1, dims_array, (void *) (pulsetimes), compress); + if (weights) + NXwritedata("weight", NX_FLOAT32, 1, dims_array, (void *) (weights), compress); + if (errorSquareds) + NXwritedata("error_squared", NX_FLOAT32, 1, dims_array, (void *) (errorSquareds), compress); + + // Close up the overall group + NXstatus status = NXclosegroup(fileID); + return ((status == NX_ERROR) ? 3 : 0); } - NXopendata(fileID, name); - NXputdata(fileID, data ); - NXclosedata(fileID); - } - - //------------------------------------------------------------------------------------- - /** Write out the event list data, no matter what the underlying event type is - * @param events :: vector of TofEvent or WeightedEvent, etc. - * @param writeTOF :: if true, write the TOF values - * @param writePulsetime :: if true, write the pulse time values - * @param writeWeight :: if true, write the event weights - * @param writeError :: if true, write the errors - */ - template - void NexusFileIO::writeEventListData( std::vector events, bool writeTOF, bool writePulsetime, bool writeWeight, bool writeError) const - { - // Do nothing if there are no events. - if (events.empty()) - return; - - size_t num = events.size(); - double * tofs = new double[num]; - double * weights = new double[num]; - double * errorSquareds = new double[num]; - int64_t * pulsetimes = new int64_t[num]; - - typename std::vector::const_iterator it; - typename std::vector::const_iterator it_end = events.end(); - size_t i = 0; - - // Fill the C-arrays with the fields from all the events, as requested. - for (it = events.begin(); it != it_end; it++) + //------------------------------------------------------------------------------------- + /** Write out all of the event lists in the given workspace + * @param ws :: an EventWorkspace */ + int NexusFileIO::writeNexusProcessedDataEvent(const DataObjects::EventWorkspace_const_sptr& ws) { - if (writeTOF) tofs[i] = it->tof(); - if (writePulsetime) pulsetimes[i] = it->pulseTime().totalNanoseconds(); - if (writeWeight) weights[i] = it->weight(); - if (writeError) errorSquareds[i] = it->errorSquared(); - i++; - } + //write data entry + NXstatus status = NXmakegroup(fileID, "event_workspace", "NXdata"); + if (status == NX_ERROR) + return (2); + NXopengroup(fileID, "event_workspace", "NXdata"); - // Write out all the required arrays. - int dims_array[1] = { static_cast(num) }; - // In this mode, compressing makes things extremely slow! Not to be used for managed event workspaces. - bool compress = true; //(num > 100); - if (writeTOF) - NXwritedata("tof", NX_FLOAT64, 1, dims_array, (void *)(tofs), compress); - if (writePulsetime) - NXwritedata("pulsetime", NX_INT64, 1, dims_array, (void *)(pulsetimes), compress); - if (writeWeight) - NXwritedata("weight", NX_FLOAT32, 1, dims_array, (void *)(weights), compress); - if (writeError) - NXwritedata("error_squared", NX_FLOAT32, 1, dims_array, (void *)(errorSquareds), compress); - - // Free mem. - delete [] tofs; - delete [] weights; - delete [] errorSquareds; - delete [] pulsetimes; - } - - - //------------------------------------------------------------------------------------- - /** Write out an event list into an already-opened group - * @param el :: reference to the EventList to write. - * @param group_name :: group_name to create. - * */ - int NexusFileIO::writeEventList( const DataObjects::EventList & el, std::string group_name) const - { - //write data entry - NXstatus status=NXmakegroup(fileID, group_name.c_str(), "NXdata"); - if(status==NX_ERROR) return(2); - NXopengroup(fileID, group_name.c_str(), "NXdata"); + for (size_t wi = 0; wi < ws->getNumberHistograms(); wi++) + { + std::ostringstream group_name; + group_name << "event_list_" << wi; + this->writeEventList(ws->getEventList(wi), group_name.str()); + } - // Copy the detector IDs to an array. - const std::set& dets = el.getDetectorIDs(); + // Close up the overall group + status = NXclosegroup(fileID); + return ((status == NX_ERROR) ? 3 : 0); + } - // Write out the detector IDs - if (!dets.empty()) + //------------------------------------------------------------------------------------- + /** Write out an array to the open file. */ + void NexusFileIO::NXwritedata(const char * name, int datatype, int rank, int * dims_array, + void * data, bool compress) const { - std::vector detectorIDs(dets.begin(),dets.end()); - int dims_array[1]; - NXwritedata("detector_IDs", NX_INT64, 1, dims_array, (void*)(detectorIDs.data()), false ); + if (compress) + { + // We'll use the same slab/buffer size as the size of the array + NXcompmakedata(fileID, name, datatype, rank, dims_array, m_nexuscompression, dims_array); + } + else + { + // Write uncompressed. + NXmakedata(fileID, name, datatype, rank, dims_array); + } + + NXopendata(fileID, name); + NXputdata(fileID, data); + NXclosedata(fileID); } - std::string eventType("UNKNOWN"); - size_t num = el.getNumberEvents(); - switch (el.getEventType()) + //------------------------------------------------------------------------------------- + /** Write out the event list data, no matter what the underlying event type is + * @param events :: vector of TofEvent or WeightedEvent, etc. + * @param writeTOF :: if true, write the TOF values + * @param writePulsetime :: if true, write the pulse time values + * @param writeWeight :: if true, write the event weights + * @param writeError :: if true, write the errors + */ + template + void NexusFileIO::writeEventListData(std::vector events, bool writeTOF, bool writePulsetime, + bool writeWeight, bool writeError) const { - case TOF: - eventType = "TOF"; - writeEventListData( el.getEvents(), true, true, false, false ); - break; - case WEIGHTED: - eventType = "WEIGHTED"; - writeEventListData( el.getWeightedEvents(), true, true, true, true ); - break; - case WEIGHTED_NOTIME: - eventType = "WEIGHTED_NOTIME"; - writeEventListData( el.getWeightedEventsNoTime(), true, false, true, true ); - break; + // Do nothing if there are no events. + if (events.empty()) + return; + + size_t num = events.size(); + double * tofs = new double[num]; + double * weights = new double[num]; + double * errorSquareds = new double[num]; + int64_t * pulsetimes = new int64_t[num]; + + typename std::vector::const_iterator it; + typename std::vector::const_iterator it_end = events.end(); + size_t i = 0; + + // Fill the C-arrays with the fields from all the events, as requested. + for (it = events.begin(); it != it_end; it++) + { + if (writeTOF) + tofs[i] = it->tof(); + if (writePulsetime) + pulsetimes[i] = it->pulseTime().totalNanoseconds(); + if (writeWeight) + weights[i] = it->weight(); + if (writeError) + errorSquareds[i] = it->errorSquared(); + i++; + } + + // Write out all the required arrays. + int dims_array[1] = + { static_cast(num) }; + // In this mode, compressing makes things extremely slow! Not to be used for managed event workspaces. + bool compress = true; //(num > 100); + if (writeTOF) + NXwritedata("tof", NX_FLOAT64, 1, dims_array, (void *) (tofs), compress); + if (writePulsetime) + NXwritedata("pulsetime", NX_INT64, 1, dims_array, (void *) (pulsetimes), compress); + if (writeWeight) + NXwritedata("weight", NX_FLOAT32, 1, dims_array, (void *) (weights), compress); + if (writeError) + NXwritedata("error_squared", NX_FLOAT32, 1, dims_array, (void *) (errorSquareds), compress); + + // Free mem. + delete[] tofs; + delete[] weights; + delete[] errorSquareds; + delete[] pulsetimes; } - // --- Save the type of sorting ----- - std::string sortType; - switch (el.getSortType()) + //------------------------------------------------------------------------------------- + /** Write out an event list into an already-opened group + * @param el :: reference to the EventList to write. + * @param group_name :: group_name to create. + * */ + int NexusFileIO::writeEventList(const DataObjects::EventList & el, std::string group_name) const { - case TOF_SORT: - sortType = "TOF_SORT"; - break; - case PULSETIME_SORT: - sortType = "PULSETIME_SORT"; - break; - case UNSORTED: - default: - sortType = "UNSORTED"; - break; - } - NXputattr (fileID, "sort_type", reinterpret_cast(const_cast(sortType.c_str())), static_cast(sortType.size()), NX_CHAR); + //write data entry + NXstatus status = NXmakegroup(fileID, group_name.c_str(), "NXdata"); + if (status == NX_ERROR) + return (2); + NXopengroup(fileID, group_name.c_str(), "NXdata"); - // Save an attribute with the type of each event. - NXputattr (fileID, "event_type", reinterpret_cast(const_cast(eventType.c_str())), static_cast(eventType.size()), NX_CHAR); - // Save an attribute with the number of events - NXputattr (fileID, "num_events", (void*)(&num), 1, NX_INT64); + // Copy the detector IDs to an array. + const std::set& dets = el.getDetectorIDs(); - // Close it up! - status=NXclosegroup(fileID); - return((status==NX_ERROR)?3:0); - } + // Write out the detector IDs + if (!dets.empty()) + { + std::vector detectorIDs(dets.begin(), dets.end()); + int dims_array[1]; + NXwritedata("detector_IDs", NX_INT64, 1, dims_array, (void*) (detectorIDs.data()), false); + } + std::string eventType("UNKNOWN"); + size_t num = el.getNumberEvents(); + switch (el.getEventType()) + { + case TOF: + eventType = "TOF"; + writeEventListData(el.getEvents(), true, true, false, false); + break; + case WEIGHTED: + eventType = "WEIGHTED"; + writeEventListData(el.getWeightedEvents(), true, true, true, true); + break; + case WEIGHTED_NOTIME: + eventType = "WEIGHTED_NOTIME"; + writeEventListData(el.getWeightedEventsNoTime(), true, false, true, true); + break; + } + // --- Save the type of sorting ----- + std::string sortType; + switch (el.getSortType()) + { + case TOF_SORT: + sortType = "TOF_SORT"; + break; + case PULSETIME_SORT: + sortType = "PULSETIME_SORT"; + break; + case UNSORTED: + default: + sortType = "UNSORTED"; + break; + } + NXputattr(fileID, "sort_type", reinterpret_cast(const_cast(sortType.c_str())), + static_cast(sortType.size()), NX_CHAR); + + // Save an attribute with the type of each event. + NXputattr(fileID, "event_type", reinterpret_cast(const_cast(eventType.c_str())), + static_cast(eventType.size()), NX_CHAR); + // Save an attribute with the number of events + NXputattr(fileID, "num_events", (void*) (&num), 1, NX_INT64); + + // Close it up! + status = NXclosegroup(fileID); + return ((status == NX_ERROR) ? 3 : 0); + } - //------------------------------------------------------------------------------------- - /** Read the size of the data section in a mantid_workspace_entry and also get the names of axes - * - */ + //------------------------------------------------------------------------------------- + /** Read the size of the data section in a mantid_workspace_entry and also get the names of axes + * + */ - int NexusFileIO::getWorkspaceSize( int& numberOfSpectra, int& numberOfChannels, int& numberOfXpoints , - bool& uniformBounds, std::string& axesUnits, std::string& yUnits ) const - { - NXstatus status; - //open workspace group - status=NXopengroup(fileID,"workspace","NXdata"); - if(status==NX_ERROR) - return(1); - // open "values" data which is identified by attribute "signal", if it exists - std::string entry; - if(checkEntryAtLevelByAttribute("signal", entry)) - status=NXopendata(fileID, entry.c_str()); - else - { - status=NXclosegroup(fileID); - return(2); - } - if(status==NX_ERROR) + int NexusFileIO::getWorkspaceSize(int& numberOfSpectra, int& numberOfChannels, int& numberOfXpoints, + bool& uniformBounds, std::string& axesUnits, std::string& yUnits) const { - status=NXclosegroup(fileID); - return(2); - } - // read workspace data size - int rank,dim[2],type; - status=NXgetinfo(fileID, &rank, dim, &type); - if(status==NX_ERROR) - return(3); - numberOfSpectra=dim[0]; - numberOfChannels=dim[1]; - // get axes attribute - char sbuf[NX_MAXNAMELEN]; - int len=NX_MAXNAMELEN; - type=NX_CHAR; - - if(checkAttributeName("units")) - { - status=NXgetattr(fileID,const_cast("units"),(void *)sbuf,&len,&type); - if(status!=NX_ERROR) - yUnits=sbuf; + NXstatus status; + //open workspace group + status = NXopengroup(fileID, "workspace", "NXdata"); + if (status == NX_ERROR) + return (1); + // open "values" data which is identified by attribute "signal", if it exists + std::string entry; + if (checkEntryAtLevelByAttribute("signal", entry)) + status = NXopendata(fileID, entry.c_str()); + else + { + status = NXclosegroup(fileID); + return (2); + } + if (status == NX_ERROR) + { + status = NXclosegroup(fileID); + return (2); + } + // read workspace data size + int rank, dim[2], type; + status = NXgetinfo(fileID, &rank, dim, &type); + if (status == NX_ERROR) + return (3); + numberOfSpectra = dim[0]; + numberOfChannels = dim[1]; + // get axes attribute + char sbuf[NX_MAXNAMELEN]; + int len = NX_MAXNAMELEN; + type = NX_CHAR; + + if (checkAttributeName("units")) + { + status = NXgetattr(fileID, const_cast("units"), (void *) sbuf, &len, &type); + if (status != NX_ERROR) + yUnits = sbuf; + NXclosedata(fileID); + } + // + // read axis1 size + status = NXopendata(fileID, "axis1"); + if (status == NX_ERROR) + return (4); + len = NX_MAXNAMELEN; + type = NX_CHAR; + NXgetattr(fileID, const_cast("units"), (void *) sbuf, &len, &type); + axesUnits = std::string(sbuf, len); + NXgetinfo(fileID, &rank, dim, &type); + // non-uniform X has 2D axis1 data + if (rank == 1) + { + numberOfXpoints = dim[0]; + uniformBounds = true; + } + else + { + numberOfXpoints = dim[1]; + uniformBounds = false; + } NXclosedata(fileID); + NXopendata(fileID, "axis2"); + len = NX_MAXNAMELEN; + type = NX_CHAR; + NXgetattr(fileID, const_cast("units"), (void *) sbuf, &len, &type); + axesUnits += std::string(":") + std::string(sbuf, len); + NXclosedata(fileID); + NXclosegroup(fileID); + return (0); } - // - // read axis1 size - status=NXopendata(fileID,"axis1"); - if(status==NX_ERROR) - return(4); - len=NX_MAXNAMELEN; - type=NX_CHAR; - NXgetattr(fileID,const_cast("units"),(void *)sbuf,&len,&type); - axesUnits = std::string(sbuf,len); - NXgetinfo(fileID, &rank, dim, &type); - // non-uniform X has 2D axis1 data - if(rank==1) - { - numberOfXpoints=dim[0]; - uniformBounds=true; - } - else - { - numberOfXpoints=dim[1]; - uniformBounds=false; - } - NXclosedata(fileID); - NXopendata(fileID,"axis2"); - len=NX_MAXNAMELEN; - type=NX_CHAR; - NXgetattr(fileID,const_cast("units"),(void *)sbuf,&len,&type); - axesUnits += std::string(":") + std::string(sbuf,len); - NXclosedata(fileID); - NXclosegroup(fileID); - return(0); - } - - bool NexusFileIO::checkAttributeName(const std::string& target) const - { - // see if the given attribute name is in the current level - // return true if it is. - const std::vector< ::NeXus::AttrInfo> infos = m_filehandle->getAttrInfos(); - for (auto it = infos.begin(); it != infos.end(); ++it) - { - if (target.compare(it->name)==0) - return true; - } - - return false; - } - int NexusFileIO::getXValues(MantidVec& xValues, const int& spectra) const - { - // - // find the X values for spectra. If uniform, the spectra number is ignored. - // - int rank,dim[2],type; - - //open workspace group - NXstatus status=NXopengroup(fileID,"workspace","NXdata"); - if(status==NX_ERROR) - return(1); - // read axis1 size - status=NXopendata(fileID,"axis1"); - if(status==NX_ERROR) - return(2); - NXgetinfo(fileID, &rank, dim, &type); - if(rank==1) - { - NXgetdata(fileID,&xValues[0]); - } - else + bool NexusFileIO::checkAttributeName(const std::string& target) const { - int start[2]={spectra,0}; - int size[2]={1,dim[1]}; - NXgetslab(fileID,&xValues[0],start,size); + // see if the given attribute name is in the current level + // return true if it is. + const std::vector< ::NeXus::AttrInfo> infos = m_filehandle->getAttrInfos(); + for (auto it = infos.begin(); it != infos.end(); ++it) + { + if (target.compare(it->name) == 0) + return true; + } + + return false; } - NXclosedata(fileID); - NXclosegroup(fileID); - return(0); - } - int NexusFileIO::getSpectra(MantidVec& values, MantidVec& errors, const int& spectra) const - { - // - // read the values and errors for spectra - // - int rank,dim[2],type; - - //open workspace group - NXstatus status=NXopengroup(fileID,"workspace","NXdata"); - if(status==NX_ERROR) - return(1); - std::string entry; - if(checkEntryAtLevelByAttribute("signal", entry)) - status=NXopendata(fileID, entry.c_str()); - else + int NexusFileIO::getXValues(MantidVec& xValues, const int& spectra) const { - status=NXclosegroup(fileID); - return(2); + // + // find the X values for spectra. If uniform, the spectra number is ignored. + // + int rank, dim[2], type; + + //open workspace group + NXstatus status = NXopengroup(fileID, "workspace", "NXdata"); + if (status == NX_ERROR) + return (1); + // read axis1 size + status = NXopendata(fileID, "axis1"); + if (status == NX_ERROR) + return (2); + NXgetinfo(fileID, &rank, dim, &type); + if (rank == 1) + { + NXgetdata(fileID, &xValues[0]); + } + else + { + int start[2] = + { spectra, 0 }; + int size[2] = + { 1, dim[1] }; + NXgetslab(fileID, &xValues[0], start, size); + } + NXclosedata(fileID); + NXclosegroup(fileID); + return (0); } - if(status==NX_ERROR) + + int NexusFileIO::getSpectra(MantidVec& values, MantidVec& errors, const int& spectra) const { + // + // read the values and errors for spectra + // + int rank, dim[2], type; + + //open workspace group + NXstatus status = NXopengroup(fileID, "workspace", "NXdata"); + if (status == NX_ERROR) + return (1); + std::string entry; + if (checkEntryAtLevelByAttribute("signal", entry)) + status = NXopendata(fileID, entry.c_str()); + else + { + status = NXclosegroup(fileID); + return (2); + } + if (status == NX_ERROR) + { + NXclosegroup(fileID); + return (2); + } + NXgetinfo(fileID, &rank, dim, &type); + // get buffer and block size + int start[2] = + { spectra - 1, 0 }; + int size[2] = + { 1, dim[1] }; + NXgetslab(fileID, &values[0], start, size); + NXclosedata(fileID); + + // read errors + status = NXopendata(fileID, "errors"); + if (status == NX_ERROR) + return (2); + NXgetinfo(fileID, &rank, dim, &type); + // set block size; + size[1] = dim[1]; + NXgetslab(fileID, &errors[0], start, size); + NXclosedata(fileID); + NXclosegroup(fileID); - return(2); + + return (0); } - NXgetinfo(fileID, &rank, dim, &type); - // get buffer and block size - int start[2]={spectra-1,0}; - int size[2]={1,dim[1]}; - NXgetslab(fileID,&values[0],start,size); - NXclosedata(fileID); - - // read errors - status=NXopendata(fileID,"errors"); - if(status==NX_ERROR) - return(2); - NXgetinfo(fileID, &rank, dim, &type); - // set block size; - size[1]=dim[1]; - NXgetslab(fileID,&errors[0],start,size); - NXclosedata(fileID); - - NXclosegroup(fileID); - - return(0); - } - - int NexusFileIO::findMantidWSEntries() const - { - // search exiting file for entries of form mantid_workspace_ and return count - int count=0; - std::map entries = m_filehandle->getEntries(); - for (auto it = entries.begin(); it != entries.end(); ++it) + + int NexusFileIO::findMantidWSEntries() const { - if (it->second == "NXentry") + // search exiting file for entries of form mantid_workspace_ and return count + int count = 0; + std::map entries = m_filehandle->getEntries(); + for (auto it = entries.begin(); it != entries.end(); ++it) { - if (it->first.find("mantid_workspace_")==0) - count++; + if (it->second == "NXentry") + { + if (it->first.find("mantid_workspace_") == 0) + count++; + } } - } - return count; - } + return count; + } - bool NexusFileIO::checkEntryAtLevel(const std::string& item) const - { - // Search the currently open level for name "item" - std::map entries = m_filehandle->getEntries(); - for (auto it = entries.begin(); it != entries.end(); ++it) + bool NexusFileIO::checkEntryAtLevel(const std::string& item) const { - if (it->first== item) + // Search the currently open level for name "item" + std::map entries = m_filehandle->getEntries(); + for (auto it = entries.begin(); it != entries.end(); ++it) + { + if (it->first == item) return true; - } - - return(false); - } + } + return (false); + } - bool NexusFileIO::checkEntryAtLevelByAttribute(const std::string& attribute, std::string& entry) const - { - // Search the currently open level for a section with "attribute" and return entry name - std::map entries = m_filehandle->getEntries(); - for (auto it = entries.begin(); it != entries.end(); ++it) + bool NexusFileIO::checkEntryAtLevelByAttribute(const std::string& attribute, + std::string& entry) const { - if (it->second == "SDS") + // Search the currently open level for a section with "attribute" and return entry name + std::map entries = m_filehandle->getEntries(); + for (auto it = entries.begin(); it != entries.end(); ++it) { - m_filehandle->openData(it->first); - bool result = checkAttributeName(attribute); - m_filehandle->closeData(); - if (result) + if (it->second == "SDS") { - entry = it->first; - return true; + m_filehandle->openData(it->first); + bool result = checkAttributeName(attribute); + m_filehandle->closeData(); + if (result) + { + entry = it->first; + return true; + } } } - } - return(false); - - } + return (false); + } - /** - * Write bin masking information - * @param ws :: The workspace - * @return true for OK, false for error - */ - bool NexusFileIO::writeNexusBinMasking(API::MatrixWorkspace_const_sptr ws) const - { - std::vector< int > spectra; - std::vector< std::size_t > bins; - std::vector< double > weights; - int spectra_count = 0; - int offset = 0; - for(std::size_t i=0;igetNumberHistograms(); ++i) + /** + * Write bin masking information + * @param ws :: The workspace + * @return true for OK, false for error + */ + bool NexusFileIO::writeNexusBinMasking(API::MatrixWorkspace_const_sptr ws) const { - if (ws->hasMaskedBins(i)) + std::vector spectra; + std::vector bins; + std::vector weights; + int spectra_count = 0; + int offset = 0; + for (std::size_t i = 0; i < ws->getNumberHistograms(); ++i) { - const API::MatrixWorkspace::MaskList& mList = ws->maskedBins(i); - spectra.push_back(spectra_count); - spectra.push_back(offset); - API::MatrixWorkspace::MaskList::const_iterator it = mList.begin(); - for(;it != mList.end(); ++it) + if (ws->hasMaskedBins(i)) { - bins.push_back(it->first); - weights.push_back(it->second); + const API::MatrixWorkspace::MaskList& mList = ws->maskedBins(i); + spectra.push_back(spectra_count); + spectra.push_back(offset); + API::MatrixWorkspace::MaskList::const_iterator it = mList.begin(); + for (; it != mList.end(); ++it) + { + bins.push_back(it->first); + weights.push_back(it->second); + } + ++spectra_count; + offset += static_cast(mList.size()); } - ++spectra_count; - offset += static_cast(mList.size()); } + + if (spectra_count == 0) + return false; + + NXstatus status; + + // save spectra offsets as a 2d array of ints + int dimensions[2]; + dimensions[0] = spectra_count; + dimensions[1] = 2; + status = NXmakedata(fileID, "masked_spectra", NX_INT32, 2, dimensions); + if (status == NX_ERROR) + return false; + NXopendata(fileID, "masked_spectra"); + const std::string description = "spectra index,offset in masked_bins and mask_weights"; + NXputattr(fileID, "description", reinterpret_cast(const_cast(description.c_str())), + static_cast(description.size() + 1), NX_CHAR); + NXputdata(fileID, (void*) &spectra[0]); + NXclosedata(fileID); + + // save masked bin indices + dimensions[0] = static_cast(bins.size()); + status = NXmakedata(fileID, "masked_bins", NX_INT32, 1, dimensions); + if (status == NX_ERROR) + return false; + NXopendata(fileID, "masked_bins"); + NXputdata(fileID, (void*) &bins[0]); + NXclosedata(fileID); + + // save masked bin weights + dimensions[0] = static_cast(bins.size()); + status = NXmakedata(fileID, "mask_weights", NX_FLOAT64, 1, dimensions); + if (status == NX_ERROR) + return false; + NXopendata(fileID, "mask_weights"); + NXputdata(fileID, (void*) &weights[0]); + NXclosedata(fileID); + + return true; } - if (spectra_count == 0) return false; - - NXstatus status; - - // save spectra offsets as a 2d array of ints - int dimensions[2]; - dimensions[0]=spectra_count; - dimensions[1]=2; - status=NXmakedata(fileID, "masked_spectra", NX_INT32, 2, dimensions); - if(status==NX_ERROR) return false; - NXopendata(fileID, "masked_spectra"); - const std::string description = "spectra index,offset in masked_bins and mask_weights"; - NXputattr(fileID, "description", reinterpret_cast(const_cast(description.c_str())), static_cast(description.size()+1), NX_CHAR); - NXputdata(fileID, (void*)&spectra[0]); - NXclosedata(fileID); - - // save masked bin indices - dimensions[0]=static_cast(bins.size()); - status=NXmakedata(fileID, "masked_bins", NX_INT32, 1, dimensions); - if(status==NX_ERROR) return false; - NXopendata(fileID, "masked_bins"); - NXputdata(fileID, (void*)&bins[0]); - NXclosedata(fileID); - - // save masked bin weights - dimensions[0]=static_cast(bins.size()); - status=NXmakedata(fileID, "mask_weights", NX_FLOAT64, 1, dimensions); - if(status==NX_ERROR) return false; - NXopendata(fileID, "mask_weights"); - NXputdata(fileID, (void*)&weights[0]); - NXclosedata(fileID); - - return true; - } - - - template<> - std::string NexusFileIO::logValueType()const{return "double";} - - template<> - std::string NexusFileIO::logValueType()const{return "int";} - - template<> - std::string NexusFileIO::logValueType()const{return "bool";} - - - /** Get all the Nexus entry types for a file - * - * Try to open named Nexus file and return all entries plus the definition found for each. - * If definition not found, try and return "analysis" field (Muon V1 files) - * Closes file on exit. - * - * @param fileName :: file to open - * @param entryName :: vector that gets filled with strings with entry names - * @param definition :: vector that gets filled with the "definition" or "analysis" string. - * @return count of entries if OK, -1 failed to open file. - */ - int getNexusEntryTypes(const std::string& fileName, std::vector& entryName, - std::vector& definition ) - { - // - // - NXhandle fileH; - NXaccess mode= NXACC_READ; - NXstatus stat=NXopen(fileName.c_str(), mode, &fileH); - if(stat==NX_ERROR) return(-1); - // - entryName.clear(); - definition.clear(); - char *nxname,*nxclass; - int nxdatatype; - nxname= new char[NX_MAXNAMELEN]; - nxclass = new char[NX_MAXNAMELEN]; - int rank,dims[2],type; - // - // Loop through all entries looking for the definition section in each (or analysis for MuonV1) - // - std::vector entryList; - while( ( stat=NXgetnextentry(fileH,nxname,nxclass,&nxdatatype) ) == NX_OK ) + template<> + std::string NexusFileIO::logValueType() const + { + return "double"; + } + + template<> + std::string NexusFileIO::logValueType() const + { + return "int"; + } + + template<> + std::string NexusFileIO::logValueType() const { - std::string nxc(nxclass); - if(nxc.compare("NXentry")==0) - entryList.push_back(nxname); + return "bool"; } - // for each entry found, look for "analysis" or "definition" text data fields and return value plus entry name - for(size_t i=0;i& entryName, + std::vector& definition) { // - stat=NXopengroup(fileH,entryList[i].c_str(),"NXentry"); - // loop through field names in this entry - while( ( stat=NXgetnextentry(fileH,nxname,nxclass,&nxdatatype) ) == NX_OK ) + // + NXhandle fileH; + NXaccess mode = NXACC_READ; + NXstatus stat = NXopen(fileName.c_str(), mode, &fileH); + if (stat == NX_ERROR) + return (-1); + // + entryName.clear(); + definition.clear(); + char *nxname, *nxclass; + int nxdatatype; + nxname = new char[NX_MAXNAMELEN]; + nxclass = new char[NX_MAXNAMELEN]; + int rank, dims[2], type; + // + // Loop through all entries looking for the definition section in each (or analysis for MuonV1) + // + std::vector entryList; + while ((stat = NXgetnextentry(fileH, nxname, nxclass, &nxdatatype)) == NX_OK) { - std::string nxc(nxclass),nxn(nxname); - // if a data field - if(nxc.compare("SDS")==0) - // if one of the two names we are looking for - if(nxn.compare("definition")==0 || nxn.compare("analysis")==0) - { - NXopendata(fileH,nxname); - stat=NXgetinfo(fileH,&rank,dims,&type); - if(stat==NX_ERROR) - continue; - char* value=new char[dims[0]+1]; - stat=NXgetdata(fileH,value); - if(stat==NX_ERROR) - continue; - value[dims[0]]='\0'; - // return e.g entryName "analysis"/definition "muonTD" - definition.push_back(value); - entryName.push_back(entryList[i]); - delete[] value; - NXclosegroup(fileH); // close data group, then entry - stat=NXclosegroup(fileH); - break; - } + std::string nxc(nxclass); + if (nxc.compare("NXentry") == 0) + entryList.push_back(nxname); + } + // for each entry found, look for "analysis" or "definition" text data fields and return value plus entry name + for (size_t i = 0; i < entryList.size(); i++) + { + // + stat = NXopengroup(fileH, entryList[i].c_str(), "NXentry"); + // loop through field names in this entry + while ((stat = NXgetnextentry(fileH, nxname, nxclass, &nxdatatype)) == NX_OK) + { + std::string nxc(nxclass), nxn(nxname); + // if a data field + if (nxc.compare("SDS") == 0) + // if one of the two names we are looking for + if (nxn.compare("definition") == 0 || nxn.compare("analysis") == 0) + { + NXopendata(fileH, nxname); + stat = NXgetinfo(fileH, &rank, dims, &type); + if (stat == NX_ERROR) + continue; + char* value = new char[dims[0] + 1]; + stat = NXgetdata(fileH, value); + if (stat == NX_ERROR) + continue; + value[dims[0]] = '\0'; + // return e.g entryName "analysis"/definition "muonTD" + definition.push_back(value); + entryName.push_back(entryList[i]); + delete[] value; + NXclosegroup(fileH); // close data group, then entry + stat = NXclosegroup(fileH); + break; + } + } } + stat = NXclose(&fileH); + delete[] nxname; + delete[] nxclass; + return (static_cast(entryName.size())); } - stat=NXclose(&fileH); - delete[] nxname; - delete[] nxclass; - return(static_cast(entryName.size())); - } + /** + Destructor + */ + NexusFileIO::~NexusFileIO() + { + // Close the nexus file if not already closed. + //this->closeNexusFile(); + } -} // namespace NeXus + } // namespace NeXus } // namespace Mantid diff --git a/Code/Mantid/Framework/Properties/Mantid.properties.template b/Code/Mantid/Framework/Properties/Mantid.properties.template index 53da75d63ccc..745bb42bb970 100644 --- a/Code/Mantid/Framework/Properties/Mantid.properties.template +++ b/Code/Mantid/Framework/Properties/Mantid.properties.template @@ -16,7 +16,7 @@ default.facility = ISIS default.instrument = # Set of PyQt interfaces to add to the Interfaces menu, separated by a space. Interfaces are seperated from their respective categories by a "/". -mantidqt.python_interfaces = Direct/DGS_Reduction.py SANS/ORNL_SANS.py Reflectometry/REFL_Reduction.py Reflectometry/REFL_SF_Calculator.py Reflectometry/REFM_Reduction.py Utility/TofConverter.py Reflectometry/ISIS_Reflectometry.py Diffraction/Powder_Diffraction_Reduction.py +mantidqt.python_interfaces = Direct/DGS_Reduction.py SANS/ORNL_SANS.py Reflectometry/REFL_Reduction.py Reflectometry/REFL_SF_Calculator.py Reflectometry/REFM_Reduction.py Utility/TofConverter.py Reflectometry/ISIS_Reflectometry.py Diffraction/Powder_Diffraction_Reduction.py Utility/FilterEvents.py mantidqt.python_interfaces_directory = @MANTID_ROOT@/scripts # Where to find mantid plugin libraries @@ -37,9 +37,6 @@ python.plugins.directories = @PYTHONPLUGIN_DIRS@ # Where to load instrument definition files from instrumentDefinition.directory = @MANTID_ROOT@/instrument -# Where to load parameter definition files from -parameterDefinition.directory = @MANTID_ROOT@/instrument - # Where to load Grouping files (that are shipped with Mantid) from groupingFiles.directory = @MANTID_ROOT@/instrument/Grouping diff --git a/Code/Mantid/Framework/PythonInterface/inc/MantidPythonInterface/kernel/TypedValidatorExporter.h b/Code/Mantid/Framework/PythonInterface/inc/MantidPythonInterface/kernel/TypedValidatorExporter.h index 59455a8b7e74..2b2a435262d4 100644 --- a/Code/Mantid/Framework/PythonInterface/inc/MantidPythonInterface/kernel/TypedValidatorExporter.h +++ b/Code/Mantid/Framework/PythonInterface/inc/MantidPythonInterface/kernel/TypedValidatorExporter.h @@ -1,5 +1,5 @@ #ifndef MANTID_PYTHONINTERFACE_TYPEDVALIDATOREXPORTER_H_ -#define MANTID_PYTHONINTERFACE_TYPEDVALIDATOREXPORTER_ +#define MANTID_PYTHONINTERFACE_TYPEDVALIDATOREXPORTER_H_ /* Copyright © 2012 ISIS Rutherford Appleton Laboratory & NScD Oak Ridge National Laboratory diff --git a/Code/Mantid/Framework/PythonInterface/mantid/geometry/CMakeLists.txt b/Code/Mantid/Framework/PythonInterface/mantid/geometry/CMakeLists.txt index 3994ff02495c..7c79f4f4afa8 100644 --- a/Code/Mantid/Framework/PythonInterface/mantid/geometry/CMakeLists.txt +++ b/Code/Mantid/Framework/PythonInterface/mantid/geometry/CMakeLists.txt @@ -24,6 +24,12 @@ set ( EXPORT_FILES src/Exports/ReferenceFrame.cpp src/Exports/Goniometer.cpp src/Exports/Object.cpp + src/Exports/PointGroup.cpp + src/Exports/PointGroupFactory.cpp + src/Exports/SpaceGroup.cpp + src/Exports/SpaceGroupFactory.cpp + src/Exports/SymmetryOperation.cpp + src/Exports/SymmetryOperationFactory.cpp ) set ( SRC_FILES diff --git a/Code/Mantid/Framework/PythonInterface/mantid/geometry/src/Exports/PointGroup.cpp b/Code/Mantid/Framework/PythonInterface/mantid/geometry/src/Exports/PointGroup.cpp new file mode 100644 index 000000000000..545f5bbd9847 --- /dev/null +++ b/Code/Mantid/Framework/PythonInterface/mantid/geometry/src/Exports/PointGroup.cpp @@ -0,0 +1,66 @@ + +#include "MantidGeometry/Crystal/PointGroup.h" +#include "MantidPythonInterface/kernel/Converters/PyObjectToV3D.h" + +#include +#include +#include +#include +#include + +using Mantid::Geometry::PointGroup; + +using namespace boost::python; + +namespace // +{ + using namespace Mantid::PythonInterface; + + bool isEquivalent(PointGroup & self, const object& hkl1, const object& hkl2) + { + return self.isEquivalent(Converters::PyObjectToV3D(hkl1)(), Converters::PyObjectToV3D(hkl2)()); + } + + boost::python::list getEquivalents(PointGroup & self, const object& hkl) + { + const std::vector &equivalents = self.getEquivalents(Converters::PyObjectToV3D(hkl)()); + + boost::python::list pythonEquivalents; + for(auto it = equivalents.begin(); it != equivalents.end(); ++it) { + pythonEquivalents.append(*it); + } + + return pythonEquivalents; + } + + Mantid::Kernel::V3D getReflectionFamily(PointGroup & self, const object& hkl) + { + return self.getReflectionFamily(Converters::PyObjectToV3D(hkl)()); + } + +} + +void export_PointGroup() +{ + register_ptr_to_python >(); + + scope pointGroupScope = class_("PointGroup", no_init); + + enum_("CrystalSystem") + .value("Triclinic", PointGroup::Triclinic) + .value("Monoclinic", PointGroup::Monoclinic) + .value("Orthorhombic", PointGroup::Orthorhombic) + .value("Tetragonal", PointGroup::Tetragonal) + .value("Hexagonal", PointGroup::Hexagonal) + .value("Trigonal", PointGroup::Trigonal) + .value("Cubic", PointGroup::Cubic); + + class_("PointGroup", no_init) + .def("getName", &PointGroup::getName) + .def("getSymbol", &PointGroup::getSymbol) + .def("crystalSystem", &PointGroup::crystalSystem) + .def("isEquivalent", &isEquivalent, "Check whether the two HKLs are symmetrically equivalent.") + .def("getEquivalents", &getEquivalents, "Returns an array with all symmetry equivalents of the supplied HKL.") + .def("getReflectionFamily", &getReflectionFamily, "Returns the same HKL for all symmetry equivalents."); +} + diff --git a/Code/Mantid/Framework/PythonInterface/mantid/geometry/src/Exports/PointGroupFactory.cpp b/Code/Mantid/Framework/PythonInterface/mantid/geometry/src/Exports/PointGroupFactory.cpp new file mode 100644 index 000000000000..4eeade09e87b --- /dev/null +++ b/Code/Mantid/Framework/PythonInterface/mantid/geometry/src/Exports/PointGroupFactory.cpp @@ -0,0 +1,22 @@ +#include "MantidGeometry/Crystal/PointGroupFactory.h" +#include "MantidPythonInterface/kernel/PythonObjectInstantiator.h" + +#include + +using namespace Mantid::Geometry; +using namespace boost::python; + +void export_PointGroupFactory() +{ + + class_("PointGroupFactoryImpl", no_init) + .def("exists", &PointGroupFactoryImpl::exists) + .def("createPointGroup", &PointGroupFactoryImpl::createPointGroup) + .def("getAllPointGroupSymbols", &PointGroupFactoryImpl::getAllPointGroupSymbols) + .def("getPointGroupSymbols", &PointGroupFactoryImpl::getPointGroupSymbols) + .def("Instance", &PointGroupFactory::Instance, return_value_policy(), + "Returns a reference to the PointGroupFactory singleton") + .staticmethod("Instance") + ; +} + diff --git a/Code/Mantid/Framework/PythonInterface/mantid/geometry/src/Exports/SpaceGroup.cpp b/Code/Mantid/Framework/PythonInterface/mantid/geometry/src/Exports/SpaceGroup.cpp new file mode 100644 index 000000000000..442a4783d4e0 --- /dev/null +++ b/Code/Mantid/Framework/PythonInterface/mantid/geometry/src/Exports/SpaceGroup.cpp @@ -0,0 +1,58 @@ + +#include "MantidGeometry/Crystal/SpaceGroup.h" +#include "MantidPythonInterface/kernel/Converters/PyObjectToV3D.h" + +#include +#include +#include +#include +#include + +using Mantid::Geometry::SpaceGroup; +using Mantid::Geometry::SymmetryOperation; + +using namespace boost::python; + +namespace // +{ + using namespace Mantid::PythonInterface; + + boost::python::list getEquivalentPositions(SpaceGroup & self, const object& point) + { + const std::vector &equivalents = self.getEquivalentPositions(Converters::PyObjectToV3D(point)()); + + boost::python::list pythonEquivalents; + for(auto it = equivalents.begin(); it != equivalents.end(); ++it) { + pythonEquivalents.append(*it); + } + + return pythonEquivalents; + } + + std::vector getSymmetryOperationStrings(SpaceGroup & self) + { + const std::vector &symOps = self.getSymmetryOperations(); + + std::vector pythonSymOps; + for(auto it = symOps.begin(); it != symOps.end(); ++it) { + pythonSymOps.push_back((*it).identifier()); + } + + return pythonSymOps; + } + +} + +void export_SpaceGroup() +{ + register_ptr_to_python >(); + + class_("SpaceGroup", no_init) + .def("order", &SpaceGroup::order) + .def("getSymmetryOperationStrings", &getSymmetryOperationStrings) + .def("number", &SpaceGroup::number) + .def("hmSymbol", &SpaceGroup::hmSymbol) + .def("getEquivalentPositions", &getEquivalentPositions, "Returns an array with all symmetry equivalents of the supplied HKL.") + ; +} + diff --git a/Code/Mantid/Framework/PythonInterface/mantid/geometry/src/Exports/SpaceGroupFactory.cpp b/Code/Mantid/Framework/PythonInterface/mantid/geometry/src/Exports/SpaceGroupFactory.cpp new file mode 100644 index 000000000000..de61f14cbef4 --- /dev/null +++ b/Code/Mantid/Framework/PythonInterface/mantid/geometry/src/Exports/SpaceGroupFactory.cpp @@ -0,0 +1,57 @@ +#include "MantidGeometry/Crystal/SpaceGroupFactory.h" +#include "MantidPythonInterface/kernel/PythonObjectInstantiator.h" + +#include + +using namespace Mantid::Geometry; +using namespace boost::python; + +namespace +{ + using namespace Mantid::PythonInterface; + + std::vector allSpaceGroupSymbols(SpaceGroupFactoryImpl &self) + { + return self.subscribedSpaceGroupSymbols(); + } + + std::vector spaceGroupSymbolsForNumber(SpaceGroupFactoryImpl &self, size_t number) + { + return self.subscribedSpaceGroupSymbols(number); + } + + bool isSubscribedSymbol(SpaceGroupFactoryImpl &self, const std::string &symbol) + { + return self.isSubscribed(symbol); + } + + bool isSubscribedNumber(SpaceGroupFactoryImpl &self, size_t number) + { + return self.isSubscribed(number); + } + + SpaceGroup_sptr createSpaceGroup(SpaceGroupFactoryImpl &self, const std::string &symbol) + { + SpaceGroup_const_sptr spaceGroup = self.createSpaceGroup(symbol); + + return boost::const_pointer_cast(spaceGroup); + } + +} + +void export_SpaceGroupFactory() +{ + + class_("SpaceGroupFactoryImpl", no_init) + .def("isSubscribedSymbol", &isSubscribedSymbol) + .def("isSubscribedNumber", &isSubscribedNumber) + .def("createSpaceGroup", &createSpaceGroup) + .def("allSubscribedSpaceGroupSymbols", &allSpaceGroupSymbols) + .def("subscribedSpaceGroupSymbols", &spaceGroupSymbolsForNumber) + .def("subscribedSpaceGroupNumbers", &SpaceGroupFactoryImpl::subscribedSpaceGroupNumbers) + .def("Instance", &SpaceGroupFactory::Instance, return_value_policy(), + "Returns a reference to the SpaceGroupFactory singleton") + .staticmethod("Instance") + ; +} + diff --git a/Code/Mantid/Framework/PythonInterface/mantid/geometry/src/Exports/SymmetryOperation.cpp b/Code/Mantid/Framework/PythonInterface/mantid/geometry/src/Exports/SymmetryOperation.cpp new file mode 100644 index 000000000000..4a8d7074f757 --- /dev/null +++ b/Code/Mantid/Framework/PythonInterface/mantid/geometry/src/Exports/SymmetryOperation.cpp @@ -0,0 +1,35 @@ + +#include "MantidGeometry/Crystal/SymmetryOperation.h" +#include "MantidPythonInterface/kernel/Converters/PyObjectToV3D.h" +#include "MantidPythonInterface/kernel/Converters/PyObjectToMatrix.h" + +#include +#include +#include +#include +#include + +using Mantid::Geometry::SymmetryOperation; + +using namespace boost::python; + +namespace // +{ + using namespace Mantid::PythonInterface; + + Mantid::Kernel::V3D applyToVector(SymmetryOperation & self, const object& hkl) + { + return self.operator *(Converters::PyObjectToV3D(hkl)()); + } +} + +void export_SymmetryOperation() +{ + register_ptr_to_python >(); + + class_("SymmetryOperation") + .def("order", &SymmetryOperation::order) + .def("identifier", &SymmetryOperation::identifier) + .def("apply", &applyToVector); +} + diff --git a/Code/Mantid/Framework/PythonInterface/mantid/geometry/src/Exports/SymmetryOperationFactory.cpp b/Code/Mantid/Framework/PythonInterface/mantid/geometry/src/Exports/SymmetryOperationFactory.cpp new file mode 100644 index 000000000000..70429347e117 --- /dev/null +++ b/Code/Mantid/Framework/PythonInterface/mantid/geometry/src/Exports/SymmetryOperationFactory.cpp @@ -0,0 +1,20 @@ +#include "MantidGeometry/Crystal/SymmetryOperationFactory.h" +#include "MantidPythonInterface/kernel/PythonObjectInstantiator.h" + +#include + +using namespace Mantid::Geometry; +using namespace boost::python; + +void export_SymmetryOperationFactory() +{ + class_("SymmetryOperationFactoryImpl", no_init) + .def("exists", &SymmetryOperationFactoryImpl::isSubscribed) + .def("createSymOp", &SymmetryOperationFactoryImpl::createSymOp) + .def("subscribedSymbols", &SymmetryOperationFactoryImpl::subscribedSymbols) + .def("Instance", &SymmetryOperationFactory::Instance, return_value_policy(), + "Returns a reference to the SymmetryOperationFactory singleton") + .staticmethod("Instance") + ; +} + 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 7377bf3e0366..762f446435d5 100644 --- a/Code/Mantid/Framework/PythonInterface/mantid/kernel/src/Exports/ConfigService.cpp +++ b/Code/Mantid/Framework/PythonInterface/mantid/kernel/src/Exports/ConfigService.cpp @@ -53,6 +53,9 @@ void export_ConfigService() .def("getInstrumentDirectory", &ConfigServiceImpl::getInstrumentDirectory, "Returns the directory used for the instrument definitions") + .def("getInstrumentDirectories", &ConfigServiceImpl::getInstrumentDirectories, return_value_policy(), + "Returns the list of directories searched for the instrument definitions") + .def("getFacilityNames", &ConfigServiceImpl::getFacilityNames, "Returns the default facility") .def("getFacilities", &ConfigServiceImpl::getFacilities, "Returns the default facility") diff --git a/Code/Mantid/Framework/PythonInterface/mantid/kernel/src/Exports/V3D.cpp b/Code/Mantid/Framework/PythonInterface/mantid/kernel/src/Exports/V3D.cpp index 88ff3bbe9f08..845ecc46f1b0 100644 --- a/Code/Mantid/Framework/PythonInterface/mantid/kernel/src/Exports/V3D.cpp +++ b/Code/Mantid/Framework/PythonInterface/mantid/kernel/src/Exports/V3D.cpp @@ -19,6 +19,13 @@ namespace return self.directionAngles(); } + long hashV3D(V3D & self) + { + boost::python::object tmpObj(self.toString()); + + return PyObject_Hash(tmpObj.ptr()); + } + } @@ -57,6 +64,8 @@ void export_V3D() .def(self == self) .def(self != self) // must define != as Python's default is to compare object address .def(self_ns::str(self)) + .def(self_ns::repr(self)) + .def("__hash__", &hashV3D) .def("directionAngles", &V3D::directionAngles, "Calculate direction angles from direction cosines") .def("directionAngles", &directionAnglesDefault, "Calculate direction angles from direction cosines") ; diff --git a/Code/Mantid/Framework/PythonInterface/plugins/algorithms/CalibrateRectangularDetectors.py b/Code/Mantid/Framework/PythonInterface/plugins/algorithms/CalibrateRectangularDetectors.py index 5b911dc0137c..0a9f068f51a9 100644 --- a/Code/Mantid/Framework/PythonInterface/plugins/algorithms/CalibrateRectangularDetectors.py +++ b/Code/Mantid/Framework/PythonInterface/plugins/algorithms/CalibrateRectangularDetectors.py @@ -67,6 +67,8 @@ def PyInit(self): self.declareProperty(ITableWorkspaceProperty("FitwindowTableWorkspace", "", Direction.Input, PropertyMode.Optional), "Name of input table workspace containing the fit window information for each spectrum. ") self.declareProperty("MinimumPeakHeight", 2., "Minimum value allowed for peak height") + self.declareProperty("MinimumPeakHeightObs", 0., + "Minimum value of a peak's maximum observed Y value for this peak to be used to calculate offset.") self.declareProperty(MatrixWorkspaceProperty("DetectorResolutionWorkspace", "", Direction.Input, PropertyMode.Optional), "Name of optional input matrix workspace for each detector's resolution (D(d)/d).") @@ -395,6 +397,7 @@ def _multicalibrate(self, wksp, calib): DReference=self._peakpos, FitWindowMaxWidth=self.getProperty("PeakWindowMax").value, MinimumPeakHeight=self.getProperty("MinimumPeakHeight").value, + MinimumPeakHeightObs=self.getProperty("MinimumPeakHeightObs").value, BackgroundType=self.getProperty("BackgroundType").value, MaxOffset=self._maxoffset, NumberPeaksWorkspace=str(wksp)+"peaks", MaskWorkspace=str(wksp)+"mask", diff --git a/Code/Mantid/Framework/PythonInterface/plugins/algorithms/ExportExperimentLog.py b/Code/Mantid/Framework/PythonInterface/plugins/algorithms/ExportExperimentLog.py index 808d324b667a..c5ba13a1e7fc 100644 --- a/Code/Mantid/Framework/PythonInterface/plugins/algorithms/ExportExperimentLog.py +++ b/Code/Mantid/Framework/PythonInterface/plugins/algorithms/ExportExperimentLog.py @@ -100,11 +100,10 @@ def _processInputs(self): if len(self._sampleLogNames) != len(ops): raise NotImplementedError("Size of sample log names and sample operations are unequal!") - self._sampleLogOperations = {} + self._sampleLogOperations = [] for i in xrange(len(self._sampleLogNames)): - key = self._sampleLogNames[i] value = ops[i] - self._sampleLogOperations[key] = value + self._sampleLogOperations.append(value) # ENDFOR if len(self._headerTitles) > 0 and len(self._headerTitles) != len(self._sampleLogNames): @@ -239,8 +238,14 @@ def _appendExpLog(self, logvaluedict): # Write to a buffer wbuf = "" - for logname in self._sampleLogNames: - value = logvaluedict[logname] + for il in xrange(len(self._sampleLogNames)): + logname = self._sampleLogNames[il] + optype = self._sampleLogOperations[il] + key = logname + "-" + optype + if key in logvaluedict.keys(): + value = logvaluedict[key] + elif logname in logvaluedict.keys(): + value = logvaluedict[logname] wbuf += "%s%s" % (str(value), self._valuesep) wbuf = wbuf[0:-1] @@ -270,9 +275,12 @@ def _getSampleLogsValue(self): str(self._wksp))) return None - for logname in self._sampleLogNames: + #for logname in self._sampleLogNames: + for il in xrange(len(self._sampleLogNames)): + logname = self._sampleLogNames[il] isexist = run.hasProperty(logname) + operationtype = self._sampleLogOperations[il] # check whether this property does exist. if isexist is False: # If not exist, use 0.00 as default @@ -286,17 +294,17 @@ def _getSampleLogsValue(self): # Get log value according to type if logclass == "StringPropertyWithValue": propertyvalue = logproperty.value - operationtype = self._sampleLogOperations[logname] + # operationtype = self._sampleLogOperations[il] if operationtype.lower() == "localtime": propertyvalue = self._convertLocalTimeString(propertyvalue) elif logclass == "FloatPropertyWithValue": propertyvalue = logproperty.value elif logclass == "FloatTimeSeriesProperty": - operationtype = self._sampleLogOperations[logname] + # operationtype = self._sampleLogOperations[il] if operationtype.lower() == "min": propertyvalue = min(logproperty.value) elif operationtype.lower() == "max": - propertyvalue = min(logproperty.value) + propertyvalue = max(logproperty.value) elif operationtype.lower() == "average": propertyvalue = np.average(logproperty.value) elif operationtype.lower() == "sum": @@ -308,7 +316,8 @@ def _getSampleLogsValue(self): else: raise NotImplementedError("Class type %d is not supported." % (logclass)) - valuedict[logname] = propertyvalue + key = logname + "-" + operationtype + valuedict[key] = propertyvalue # ENDFOR return valuedict diff --git a/Code/Mantid/Framework/PythonInterface/plugins/algorithms/MaskBTP.py b/Code/Mantid/Framework/PythonInterface/plugins/algorithms/MaskBTP.py index 31a208761b65..3c4466cf2705 100644 --- a/Code/Mantid/Framework/PythonInterface/plugins/algorithms/MaskBTP.py +++ b/Code/Mantid/Framework/PythonInterface/plugins/algorithms/MaskBTP.py @@ -24,8 +24,8 @@ def summary(self): def PyInit(self): self.declareProperty(mantid.api.WorkspaceProperty("Workspace", "",direction=mantid.kernel.Direction.InOut, optional = mantid.api.PropertyMode.Optional), "Input workspace (optional)") - allowedInstrumentList=mantid.kernel.StringListValidator(["","ARCS","CNCS","CORELLI","HYSPEC","NOMAD","POWGEN","SEQUOIA","SNAP","TOPAZ"]) - self.declareProperty("Instrument","",validator=allowedInstrumentList,doc="One of the following instruments: ARCS, CNCS, CORELLI, HYSPEC, NOMAD, POWGEN, SNAP, SEQUOIA, TOPAZ") + allowedInstrumentList=mantid.kernel.StringListValidator(["","ARCS","CNCS","CORELLI","HYSPEC","NOMAD","POWGEN","SEQUOIA","SNAP","SXD","TOPAZ","WISH"]) + self.declareProperty("Instrument","",validator=allowedInstrumentList,doc="One of the following instruments: ARCS, CNCS, CORELLI, HYSPEC, NOMAD, POWGEN, SNAP, SEQUOIA, SXD, TOPAZ, WISH") self.declareProperty("Bank","",doc="Bank(s) to be masked. If empty, will apply to all banks") self.declareProperty("Tube","",doc="Tube(s) to be masked. If empty, will apply to all tubes") self.declareProperty("Pixel","",doc="Pixel(s) to be masked. If empty, will apply to all pixels") @@ -47,13 +47,13 @@ def PyExec(self): self.instrument = ws.getInstrument() self.instname = self.instrument.getName() - instrumentList=["ARCS","CNCS","CORELLI","HYSPEC","NOMAD","POWGEN","SEQUOIA","SNAP","TOPAZ"] - self.bankmin={"ARCS":1,"CNCS":1,"CORELLI":1,"HYSPEC":1,"NOMAD":1,"POWGEN":1,"SEQUOIA":38,"SNAP":1,"TOPAZ":10} - self.bankmax={"ARCS":115,"CNCS":50,"CORELLI":91,"HYSPEC":20,"NOMAD":99,"POWGEN":300,"SEQUOIA":150,"SNAP":18,"TOPAZ":59} - tubemin={"ARCS":1,"CNCS":1,"CORELLI":1,"HYSPEC":1,"NOMAD":1,"POWGEN":0,"SEQUOIA":1,"SNAP":0,"TOPAZ":0} - tubemax={"ARCS":8,"CNCS":8,"CORELLI":16,"HYSPEC":8,"NOMAD":8,"POWGEN":153,"SEQUOIA":8,"SNAP":255,"TOPAZ":255} - pixmin={"ARCS":1,"CNCS":1,"CORELLI":1,"HYSPEC":1,"NOMAD":1,"POWGEN":0,"SEQUOIA":1,"SNAP":0,"TOPAZ":0} - pixmax={"ARCS":128,"CNCS":128,"CORELLI":256,"HYSPEC":128,"NOMAD":128,"POWGEN":6,"SEQUOIA":128,"SNAP":255,"TOPAZ":255} + instrumentList=["ARCS","CNCS","CORELLI","HYSPEC","NOMAD","POWGEN","SEQUOIA","SNAP","SXD","TOPAZ","WISH"] + self.bankmin={"ARCS":1,"CNCS":1,"CORELLI":1,"HYSPEC":1,"NOMAD":1,"POWGEN":1,"SEQUOIA":38,"SNAP":1,"SXD":1,"TOPAZ":10,"WISH":1} + self.bankmax={"ARCS":115,"CNCS":50,"CORELLI":91,"HYSPEC":20,"NOMAD":99,"POWGEN":300,"SEQUOIA":150,"SNAP":18,"SXD":11,"TOPAZ":59,"WISH":10} + tubemin={"ARCS":1,"CNCS":1,"CORELLI":1,"HYSPEC":1,"NOMAD":1,"POWGEN":0,"SEQUOIA":1,"SNAP":0,"SXD":0,"TOPAZ":0,"WISH":1} + tubemax={"ARCS":8,"CNCS":8,"CORELLI":16,"HYSPEC":8,"NOMAD":8,"POWGEN":153,"SEQUOIA":8,"SNAP":255,"SXD":63,"TOPAZ":255,"WISH":152} + pixmin={"ARCS":1,"CNCS":1,"CORELLI":1,"HYSPEC":1,"NOMAD":1,"POWGEN":0,"SEQUOIA":1,"SNAP":0,"SXD":0,"TOPAZ":0,"WISH":1} + pixmax={"ARCS":128,"CNCS":128,"CORELLI":256,"HYSPEC":128,"NOMAD":128,"POWGEN":6,"SEQUOIA":128,"SNAP":255,"SXD":63,"TOPAZ":255,"WISH":512} try: instrumentList.index(self.instname) @@ -74,11 +74,15 @@ def PyExec(self): if (tubeString == ""): tubes=numpy.arange(tubemax[self.instname]-tubemin[self.instname]+1)+tubemin[self.instname] + elif (tubeString == "edges"): + tubes=[tubemin[self.instname],tubemax[self.instname]] else: tubes=self._parseBTPlist(tubeString) if(pixelString == ""): pixels=numpy.arange(pixmax[self.instname]-pixmin[self.instname]+1)+pixmin[self.instname] + elif (pixelString == "edges"): + pixels=[pixmin[self.instname],pixmax[self.instname]] else: pixels=self._parseBTPlist(pixelString) @@ -169,6 +173,14 @@ def _getEightPackHandle(self,banknum): return self.instrument.getComponentByName("bank"+str(banknum))[0] else: raise ValueError("Out of range index for "+str(self.instname)+" instrument bank numbers") + elif self.instname=="WISH": + if (self.bankmin[self.instname]<=banknum<= self.bankmax[self.instname]): + try: + return self.instrument.getComponentByName("panel"+"%02d" % banknum)[0] + except: + return None + else: + raise ValueError("Out of range index for "+str(self.instname)+" instrument bank numbers") else: if (self.bankmin[self.instname]<=banknum<= self.bankmax[self.instname]): return self.instrument.getComponentByName("bank"+str(banknum)) diff --git a/Code/Mantid/Framework/PythonInterface/plugins/algorithms/PDDetermineCharacterizations.py b/Code/Mantid/Framework/PythonInterface/plugins/algorithms/PDDetermineCharacterizations.py index bd271db0e2fb..9bb2ba9ed9a7 100644 --- a/Code/Mantid/Framework/PythonInterface/plugins/algorithms/PDDetermineCharacterizations.py +++ b/Code/Mantid/Framework/PythonInterface/plugins/algorithms/PDDetermineCharacterizations.py @@ -143,11 +143,14 @@ def processInformation(self, prop_man, info_dict): # Convert comma-delimited list to array, else return the original # value. if type("") == type(val): - try: - val = [float(x) for x in val.split(',')] - except ValueError, err: - self.log().error("Error to parse key = %s value = %s. " % (str(key), str(val))) - raise NotImplementedError(str(err)) + if (len(val)==0) and (key in DEF_INFO.keys()): + val = DEF_INFO[key] + else: + try: + val = [float(x) for x in val.split(',')] + except ValueError, err: + self.log().error("Error to parse key: '%s' value = '%s'. " % (str(key), str(val))) + raise NotImplementedError(str(err)) try: prop_man[key] = val diff --git a/Code/Mantid/Framework/PythonInterface/plugins/algorithms/PoldiMerge.py b/Code/Mantid/Framework/PythonInterface/plugins/algorithms/PoldiMerge.py index 46eafcbd4886..612bd8ee0d8c 100644 --- a/Code/Mantid/Framework/PythonInterface/plugins/algorithms/PoldiMerge.py +++ b/Code/Mantid/Framework/PythonInterface/plugins/algorithms/PoldiMerge.py @@ -5,8 +5,12 @@ import numpy as np class PoldiMerge(PythonAlgorithm): - comparedPropertyNames = ["TablePositionX", "TablePositionY", "TablePositionZ", "ChopperSpeed"] + comparedPropertyNames = ["TablePositionX", "TablePositionY", "TablePositionZ"] + comparedInstrumentParameters = [("detector", "two_theta"), + ("chopper", "t0"), + ("chopper", "t0_const")] outputWorkspaceName = None + checkInstruments = True def category(self): return "SINQ\\Poldi" @@ -27,38 +31,37 @@ def PyInit(self): direction=Direction.Output), doc="Workspace where all counts from the list workspaces have been added") + self.declareProperty("CheckInstruments", True, "If checked, only workspaces with equal instrument parameters are merged. Do not disable without a very good reason.") + def PyExec(self): + self.checkInstruments = self.getProperty("CheckInstruments").value + workspaceNames = self.getProperty("WorkspaceNames").value self.outputWorkspaceName = self.getProperty("OutputWorkspace").valueAsStr self.log().information("Workspaces to merge: %i" % (len(workspaceNames))) - if False in [AnalysisDataService.doesExist(x) for x in workspaceNames]: - raise KeyError("Not all strings in the input list are valid workspace names.") - - workspaces = [AnalysisDataService.retrieve(x) for x in workspaceNames] + workspaces = [] - # Create a target workspace for the summation. It inherits the log of - # the first workspace used in the summation. - output = WorkspaceFactory.create(workspaces[0]) + for wsName in workspaceNames: + if not AnalysisDataService.doesExist(wsName): + raise KeyError("Not all strings in the input list are valid workspace names.") - xdata = workspaces[0].dataX(0) - ydata = np.zeros(len(xdata)) + ws = AnalysisDataService.retrieve(wsName) + workspaces += self.getWorkspacesRecursive(ws) - for h in range(output.getNumberHistograms()): - output.setX(h, xdata) - output.setY(h, ydata) - AnalysisDataService.addOrReplace(self.outputWorkspaceName, output) + workspaceCount = len(workspaces) - while workspaces: - current = workspaces.pop(0) + for i in range(workspaceCount): + currentWorkspace = workspaces[i] + for j in range(i + 1, workspaceCount): + try: + self.canMerge(currentWorkspace, workspaces[j]) + except RuntimeError as error: + self.handleError(error) - try: - if self.canMerge(output, current): - output += current - except RuntimeError as error: - self.handleError(error) + output = MergeRuns(workspaceNames) self.setProperty("OutputWorkspace", output) @@ -69,7 +72,10 @@ def canMerge(self, leftWorkspace, rightWorkspace): leftRun = leftWorkspace.getRun() rightRun = rightWorkspace.getRun() - return self.propertiesMatch(leftRun, rightRun) + if not self.chopperSpeedsMatch(leftRun, rightRun): + raise RuntimeError("Chopper speeds do not match (" + '&'.join((leftWorkspace.getName(), rightWorkspace.getName())) + ")") + + return self.propertiesMatch(leftRun, rightRun) and self.instrumentsMatch(leftWorkspace, rightWorkspace) def timingsMatch(self, leftXData, rightXData): leftDeltaX = leftXData[1] - leftXData[0] @@ -77,9 +83,43 @@ def timingsMatch(self, leftXData, rightXData): return abs(leftDeltaX - rightDeltaX) < 1e-4 and abs(rightXData[0] - leftXData[0]) < 1e-4 + def chopperSpeedsMatch(self, leftRun, rightRun): + chopperSpeedLeft = self.makePlausibleChopperSpeed(self.getPropertyValue(leftRun.getProperty("ChopperSpeed"))) + chopperSpeedRight = self.makePlausibleChopperSpeed(self.getPropertyValue(rightRun.getProperty("ChopperSpeed"))) + + return abs(chopperSpeedLeft - chopperSpeedRight) < 1e-4 + + def makePlausibleChopperSpeed(self, chopperSpeed): + # This is related to ticket #10090, where a new field in new data is used + # when that ticket is finished, new data files will not need this + # cleanup method anymore. + return np.floor((chopperSpeed + 250.0) / 500.0) * 500.0; + + def instrumentsMatch(self, leftWorkspace, rightWorkspace): + leftInstrument = leftWorkspace.getInstrument() + rightInstrument = rightWorkspace.getInstrument() + + return (not self.checkInstruments) or self.instrumentParametersMatch(leftInstrument, rightInstrument) + + def instrumentParametersMatch(self, leftInstrument, rightInstrument): + if not (leftInstrument.getDetector(0).getPos() == rightInstrument.getDetector(0).getPos()): + raise RuntimeError("Detector positions are not equal") + + for parameterTuple in self.comparedInstrumentParameters: + leftValue = self.getParameterValue(leftInstrument, parameterTuple) + rightValue = self.getParameterValue(rightInstrument, parameterTuple) + + if abs(leftValue - rightValue) > 1e-12: + raise RuntimeError("Instrument parameter '%s'/'%s' does not match" % parameterTuple) + + return True; + + def getParameterValue(self, instrument, parameterTuple): + return instrument.getComponentByName(parameterTuple[0]).getNumberParameter(parameterTuple[1])[0] + def propertiesMatch(self, leftRun, rightRun): for propertyName in self.comparedPropertyNames: - if abs(self.getPropertyValue(leftRun.getProperty(propertyName)) - self.getPropertyValue(rightRun.getProperty(propertyName))) > 1e-4: + if abs(self.getPropertyValue(leftRun.getProperty(propertyName)) - self.getPropertyValue(rightRun.getProperty(propertyName))) > 5e-3: raise RuntimeError("Property '%s' does not match" % (propertyName)) return True @@ -96,4 +136,18 @@ def handleError(self, error): raise RuntimeError("Workspaces can not be merged. %s. Aborting." % (str(error))) + def getWorkspacesRecursive(self, workspace): + returnList = [] + if isinstance(workspace, WorkspaceGroup): + for i in range(workspace.getNumberOfEntries()): + returnList += self.getWorkspacesRecursive(workspace.getItem(i)) + + elif isinstance(workspace, MatrixWorkspace): + returnList.append(workspace) + + else: + raise RuntimeError("Can only merge MatrixWorkspaces, this is " + type(workspace)) + + return returnList + AlgorithmFactory.subscribe(PoldiMerge) diff --git a/Code/Mantid/Framework/PythonInterface/plugins/algorithms/RefLReduction.py b/Code/Mantid/Framework/PythonInterface/plugins/algorithms/RefLReduction.py index 5ab7bc8c541e..9c173170f685 100644 --- a/Code/Mantid/Framework/PythonInterface/plugins/algorithms/RefLReduction.py +++ b/Code/Mantid/Framework/PythonInterface/plugins/algorithms/RefLReduction.py @@ -90,7 +90,6 @@ def PyExec(self): if _mt.find('_reflectivity') != -1: DeleteWorkspace(_mt) - # retrieve settings from GUI print '-> Retrieving settings from GUI' @@ -131,7 +130,7 @@ def PyExec(self): TOFrange = [0, 200000] # TOF binning parameters binTOFrange = [0, 200000] - binTOFsteps = 50 + binTOFsteps = 40 # geometry correction geometryCorrectionFlag = self.getProperty("GeometryCorrectionFlag").value @@ -144,10 +143,6 @@ def PyExec(self): # angle offset angleOffsetDeg = self.getProperty("AngleOffset").value - #dimension of the detector (256 by 304 pixels) - maxX = 304 - maxY = 256 - h = 6.626e-34 #m^2 kg s^-1 m = 1.675e-27 #kg @@ -165,11 +160,23 @@ def PyExec(self): # load data ws_event_data = wks_utility.loadNeXus(dataRunNumbers, 'data') + is_nexus_detector_rotated_flag = wks_utility.isNexusTakeAfterRefDate(ws_event_data.getRun().getProperty('run_start').value) + print '-> is NeXus taken with new detector geometry: ' + str(is_nexus_detector_rotated_flag) + + #dimension of the detector (256 by 304 pixels) + if is_nexus_detector_rotated_flag: + maxX = 256 + maxY = 304 + else: + maxX = 304 + maxY = 256 + ## retrieve general informations # calculate the central pixel (using weighted average) print '-> retrieving general informations' data_central_pixel = wks_utility.getCentralPixel(ws_event_data, - dataPeakRange) + dataPeakRange, + is_nexus_detector_rotated_flag) # get the distance moderator-detector and sample-detector [dMD, dSD] = wks_utility.getDistances(ws_event_data) # get theta @@ -201,7 +208,8 @@ def PyExec(self): # integrate over low resolution range [data_tof_axis, data_y_axis, data_y_error_axis] = wks_utility.integrateOverLowResRange(ws_histo_data, dataLowResRange, - 'data') + 'data', + is_nexus_detector_rotated_flag) # #DEBUG ONLY # wks_utility.ouput_big_ascii_file('/mnt/hgfs/j35/Matlab/DebugMantid/Strange0ValuesToData/data_file_after_low_resolution_integration.txt', @@ -256,7 +264,8 @@ def PyExec(self): # integrate over low resolution range [norm_tof_axis, norm_y_axis, norm_y_error_axis] = wks_utility.integrateOverLowResRange(ws_histo_norm, normLowResRange, - 'normalization') + 'normalization', + is_nexus_detector_rotated_flag) # substract background [norm_y_axis, norm_y_error_axis] = wks_utility.substractBackground(norm_tof_axis[0:-1], @@ -321,7 +330,6 @@ def PyExec(self): y_axis, y_error_axis, peak_range = dataPeakRange, - central_pixel = data_central_pixel, source_to_detector_distance = dMD, sample_to_detector_distance = dSD, theta = theta, diff --git a/Code/Mantid/Framework/PythonInterface/plugins/algorithms/SNSPowderReduction.py b/Code/Mantid/Framework/PythonInterface/plugins/algorithms/SNSPowderReduction.py index fa4050f0e1a1..d55ef1e9c0bd 100644 --- a/Code/Mantid/Framework/PythonInterface/plugins/algorithms/SNSPowderReduction.py +++ b/Code/Mantid/Framework/PythonInterface/plugins/algorithms/SNSPowderReduction.py @@ -1,3 +1,5 @@ +import mantid +import mantid.api import mantid.simpleapi as api from mantid.api import * from mantid.kernel import * @@ -248,7 +250,7 @@ def PyExec(self): returned = self._focusChunks(samRun, SUFFIX, timeFilterWall, calib, self._splitws, preserveEvents=preserveEvents) - if returned.__class__.__name__ == "list": + if isinstance(returned, list): # Returned with a list of workspaces focusedwksplist = returned irun = 0 @@ -272,9 +274,9 @@ def PyExec(self): for samRun in samwksplist: samRun = mtd[str(samRun)] try: - self.log().information("[F1136] Sample Run %s: number of events = %d" % (str(samRun), samRun.getNumberEvents())) + self.log().information("Sample Run %s: starting number of events = %d" % (str(samRun), samRun.getNumberEvents())) except Exception as e: - self.log().information("[F1136] Unable to get number of events of sample run %s. Error message: %s" % (str(samRun), str(e))) + self.log().information("Unable to get number of events of sample run %s. Error message: %s" % (str(samRun), str(e))) # Get run number runnumber = samRun.getRunNumber() @@ -482,7 +484,7 @@ def _loadData(self, runnumber, extension, filterWall=None, outname=None, **chunk # filter bad pulses if self._filterBadPulses > 0.: - isEventWS = str(type(wksp)).count("IEvent") > 0 + isEventWS = isinstance(wksp, mantid.api._api.IEventWorkspace) if isEventWS is True: # Event workspace: record original number of events numeventsbefore = wksp.getNumberEvents() @@ -579,7 +581,7 @@ def _focusChunks(self, runnumber, extension, filterWall, calib, splitwksp=None, # Load chunk temp = self._loadData(runnumber, extension, filterWall, **chunk) - if str(type(temp)).count("IEvent") > 0: + if isinstance(temp, mantid.api._api.IEventWorkspace) is True: # Event workspace self.log().debug("F1141C There are %d events after data is loaded in workspace %s." % ( temp.getNumberEvents(), str(temp))) @@ -649,10 +651,6 @@ def _focusChunks(self, runnumber, extension, filterWall, calib, splitwksp=None, for itemp in xrange(numwksp): temp = tempwslist[itemp] # Align and focus - self.log().information("Begin to align and focus workspace %s; Number of events = %d of chunk %d with RemovePromptPulseWidth = %s, LowResSpectrumOffset = %s" % (str(temp), - temp.getNumberEvents(), ichunk, str(self._removePromptPulseWidth), str(self._lowResTOFoffset))) - # api.CloneWorkspace(InputWorkspace=temp, OutputWorkspace="_"+str(temp)+"_Phase1") - focuspos = self._focusPos temp = api.AlignAndFocusPowder(InputWorkspace=temp, OutputWorkspace=temp, CalFileName=calib, Params=self._binning, ResampleX=self._resampleX, Dspacing=self._bin_in_dspace, @@ -665,9 +663,9 @@ def _focusChunks(self, runnumber, extension, filterWall, calib, splitwksp=None, spec = temp.getSpectrum(iws) self.log().debug("[DBx131] ws %d: spectrum ID = %d. " % (iws, spec.getSpectrumNo())) - self.log().information("After being aligned and focussed workspace %s; Number of events = %d of chunk %d " % (str(temp), - temp.getNumberEvents(), ichunk)) - # api.CloneWorkspace(InputWorkspace=temp, OutputWorkspace="_"+str(temp)+"_Phase2") + if preserveEvents is True and isinstance(temp, mantid.api._api.IEventWorkspace) is True: + self.log().information("After being aligned and focussed workspace %s; Number of events = %d of chunk %d " % (str(temp), + temp.getNumberEvents(), ichunk)) # Rename and/or add to workspace of same splitter but different chunk wkspname = wksp diff --git a/Code/Mantid/Framework/PythonInterface/plugins/algorithms/Stitch1DMany.py b/Code/Mantid/Framework/PythonInterface/plugins/algorithms/Stitch1DMany.py deleted file mode 100644 index f3d0ac1ca263..000000000000 --- a/Code/Mantid/Framework/PythonInterface/plugins/algorithms/Stitch1DMany.py +++ /dev/null @@ -1,184 +0,0 @@ -from mantid.simpleapi import * -from mantid.api import * -from mantid.kernel import * -import numpy as np - -class Stitch1DMany(DataProcessorAlgorithm): - - def category(self): - return "Reflectometry\\ISIS;" - - def name(self): - return "Stitch1D" - - def summary(self): - return "Stitches single histogram matrix workspaces together" - - def PyInit(self): - input_validator = StringMandatoryValidator() - self.declareProperty(name="InputWorkspaces", defaultValue="", direction=Direction.Input, validator=input_validator, doc="Input workspaces") - self.declareProperty(WorkspaceProperty("OutputWorkspace", "", Direction.Output), "Output stitched workspace") - self.declareProperty(FloatArrayProperty(name="StartOverlaps", values=[]), doc="Start overlaps for stitched workspaces.") - self.declareProperty(FloatArrayProperty(name="EndOverlaps", values=[]), doc="End overlap for stitched workspaces.") - self.declareProperty(FloatArrayProperty(name="Params", validator=FloatArrayMandatoryValidator()), doc="Rebinning Parameters. See Rebin for format.") - self.declareProperty(name="ScaleRHSWorkspace", defaultValue=True, doc="Scaling either with respect to workspace 1 or workspace 2.") - self.declareProperty(name="UseManualScaleFactor", defaultValue=False, doc="True to use a provided value for the scale factor.") - self.declareProperty(name="ManualScaleFactor", defaultValue=1.0, doc="Provided value for the scale factor.") - self.declareProperty(FloatArrayProperty(name="OutScaleFactors", direction = Direction.Output), doc="The actual used values for the scaling factors at each stitch step.") - - def __workspace_from_split_name(self, list_of_names, index): - return mtd[list_of_names[index].strip()] - - def __workspaces_from_split_name(self, list_of_names): - workspaces = list() - for name in list_of_names: - workspaces.append(mtd[name.strip()]) - return workspaces - - ''' - If the property value has been provided, use that. If default, then create an array of Nones so that Stitch1D can still be correctly looped over. - ''' - def __input_or_safe_default(self, property_name, n_entries): - property = self.getProperty(property_name) - property_value = property.value - if property.isDefault: - property_value = list() - for i in range(0, n_entries): - property_value.append(None) - return property_value - - - def __do_stitch_workspace(self, lhs_ws, rhs_ws, start_overlap, end_overlap, params, scale_rhs_ws, use_manual_scale_factor, manual_scale_factor): - out_name = lhs_ws.name() + rhs_ws.name() - - alg = self.createChildAlgorithm("Stitch1D") - alg.initialize() - alg.setProperty("LHSWorkspace", lhs_ws) - alg.setProperty("RHSWorkspace", rhs_ws) - if start_overlap: - alg.setProperty("StartOverlap", start_overlap) - if end_overlap: - alg.setProperty("EndOverlap", end_overlap) - alg.setProperty("Params", params) - alg.setProperty("ScaleRHSWorkspace", scale_rhs_ws) - alg.setProperty("UseManualScaleFactor", use_manual_scale_factor) - if manual_scale_factor: - alg.setProperty("ManualScaleFactor", manual_scale_factor) - alg.setProperty("OutputWorkspace", "from_sub_alg" + out_name) - alg.execute() - out_ws = alg.getProperty("OutputWorkspace").value - scale_factor = alg.getProperty("OutScaleFactor").value - logger.warning(str(scale_factor)) - - #out_ws, scale_factor = Stitch1D(LHSWorkspace=lhs_ws, RHSWorkspace=rhs_ws, StartOverlap=start_overlap, EndOverlap=end_overlap, - # Params=params, ScaleRHSWorkspace=scale_rhs_ws, UseManualScaleFactor=use_manual_scale_factor, ManualScaleFactor=manual_scale_factor, OutputWorkspace=out_name) - return (out_ws, scale_factor) - - def __check_workspaces_are_common(self, input_workspace_names): - workspaces = self.__workspaces_from_split_name(input_workspace_names) - exemplar = workspaces[0] - for i in range(1, len(workspaces)): - test_ws = workspaces[i] - if type(exemplar) != type(test_ws): - raise RuntimeError("Input Workspaces must all be of the same type.") - if isinstance(test_ws, WorkspaceGroup): - if test_ws.size() != exemplar.size(): - raise RuntimeError("Group Workspaces as InputWorkspaces must have the same number of sub-workspaces.") - - def __are_processing_groups(self, input_workspace_names): - test_ws = self.__workspace_from_split_name(input_workspace_names, 0) - return isinstance(test_ws, WorkspaceGroup) - - def PyExec(self): - - inputWorkspaces = self.getProperty("InputWorkspaces").value - inputWorkspaces = inputWorkspaces.split(',') - numberOfWorkspaces = len(inputWorkspaces) - - startOverlaps = self.__input_or_safe_default('StartOverlaps', numberOfWorkspaces-1) - endOverlaps = self.__input_or_safe_default('EndOverlaps', numberOfWorkspaces-1) - - # Just forward the other properties on. - scaleRHSWorkspace = self.getProperty('ScaleRHSWorkspace').value - useManualScaleFactor = self.getProperty('UseManualScaleFactor').value - manualScaleFactor = self.getProperty('ManualScaleFactor').value - params = self.getProperty("Params").value - - - if not numberOfWorkspaces > 1: - raise ValueError("Too few workspaces to stitch") - if not (len(startOverlaps) == len(endOverlaps)): - raise ValueError("StartOverlaps and EndOverlaps are different lengths") - if not (len(startOverlaps) == (numberOfWorkspaces- 1)): - raise ValueError("Wrong number of StartOverlaps, should be %i not %i" % (numberOfWorkspaces - 1, startOverlaps)) - self.__check_workspaces_are_common(inputWorkspaces) - - scaleFactors = list() - comma_separator = "," - no_separator = str() - - # Identify and process as group workspaces - if self.__are_processing_groups(inputWorkspaces): - workspace_groups = self.__workspaces_from_split_name(inputWorkspaces) - - out_group_separator = no_separator - out_group_workspaces = str() - - n_sub_workspaces = workspace_groups[0].size() - for i in range(n_sub_workspaces): - - to_process = str() - out_name = str() - separator = no_separator - - for j in range(0, numberOfWorkspaces, 1): - - to_process += separator + workspace_groups[j][i].name() - out_name += workspace_groups[j][i].name() - separator=comma_separator - - startOverlaps = self.getProperty("StartOverlaps").value - endOverlaps = self.getProperty("EndOverlaps").value - - stitched, scaleFactorsOfIndex = Stitch1DMany(InputWorkspaces=to_process, OutputWorkspace=out_name, StartOverlaps=startOverlaps, EndOverlaps=endOverlaps, - Params=params, ScaleRHSWorkspace=scaleRHSWorkspace, UseManualScaleFactor=useManualScaleFactor, - ManualScaleFactor=manualScaleFactor) - # Flatten out scale factors. - for sf in scaleFactorsOfIndex: - scaleFactors.append(sf) - - out_group_workspaces += out_group_separator + out_name - out_group_separator = comma_separator - - out_workspace_name = self.getPropertyValue("OutputWorkspace") - out_group = GroupWorkspaces(InputWorkspaces=out_group_workspaces, OutputWorkspace=out_workspace_name) - self.setProperty("OutputWorkspace", out_group) - - else: - - # Iterate forward through the workspaces - if scaleRHSWorkspace: - lhsWS = self.__workspace_from_split_name(inputWorkspaces, 0) - - for i in range(1, numberOfWorkspaces, 1): - rhsWS = self.__workspace_from_split_name(inputWorkspaces, i) - lhsWS, scaleFactor = self.__do_stitch_workspace(lhsWS, rhsWS, startOverlaps[i-1], endOverlaps[i-1], params, scaleRHSWorkspace, useManualScaleFactor, manualScaleFactor) - scaleFactors.append(scaleFactor) - self.setProperty('OutputWorkspace', lhsWS) - - # Iterate backwards through the workspaces. - else: - rhsWS = self.__workspace_from_split_name(inputWorkspaces, -1) - for i in range(0, numberOfWorkspaces-1, 1): - lhsWS = self.__workspace_from_split_name(inputWorkspaces, i) - rhsWS, scaleFactor = Stitch1D(LHSWorkspace=lhsWS, RHSWorkspace=rhsWS, StartOverlap=startOverlaps[i-1], EndOverlap=endOverlaps[i-1], Params=params, ScaleRHSWorkspace=scaleRHSWorkspace, UseManualScaleFactor=useManualScaleFactor, ManualScaleFactor=manualScaleFactor) - scaleFactors.append(scaleFactor) - self.setProperty('OutputWorkspace', rhsWS) - - self.setProperty('OutScaleFactors', scaleFactors) - return None - - -############################################################################################# - -AlgorithmFactory.subscribe(Stitch1DMany) diff --git a/Code/Mantid/Framework/PythonInterface/plugins/algorithms/Symmetrise.py b/Code/Mantid/Framework/PythonInterface/plugins/algorithms/Symmetrise.py new file mode 100644 index 000000000000..38f3aeb7b819 --- /dev/null +++ b/Code/Mantid/Framework/PythonInterface/plugins/algorithms/Symmetrise.py @@ -0,0 +1,325 @@ +from mantid import logger, mtd +from mantid.api import PythonAlgorithm, AlgorithmFactory, WorkspaceProperty, PropertyMode +from mantid.kernel import Direction, IntArrayProperty +from mantid.simpleapi import CreateWorkspace, CopyLogs, CopySample, CopyInstrumentParameters, SaveNexusProcessed, CreateEmptyTableWorkspace, RenameWorkspace + +import math +import os.path +import numpy as np + + +class Symmetrise(PythonAlgorithm): + + def category(self): + return 'Workflow\\MIDAS;PythonAlgorithms' + + + def summary(self): + return 'Takes an asymmetric S(Q,w) and makes it symmetric' + + + def PyInit(self): + self.declareProperty(WorkspaceProperty('Sample', '', Direction.Input), + doc='Sample to run with') + + self.declareProperty(IntArrayProperty(name='SpectraRange'), + doc='Range of spectra to symmetrise (defaults to entire range if not set)') + + self.declareProperty('XMin', 0.0, doc='X value marking lower limit of curve to copy') + self.declareProperty('XMax', 0.0, doc='X value marking upper limit of curve to copy') + + self.declareProperty('Verbose', defaultValue=False, + doc='Switch verbose output Off/On') + self.declareProperty('Plot', defaultValue=False, + doc='Switch plotting Off/On') + self.declareProperty('Save', defaultValue=False, + doc='Switch saving result to nxs file Off/On') + + self.declareProperty(WorkspaceProperty('OutputWorkspace', '', + Direction.Output), doc='Name to call the output workspace.') + + self.declareProperty(WorkspaceProperty('OutputPropertiesTable', '', + Direction.Output, PropertyMode.Optional), doc='Name to call the properties output table workspace.') + + + def PyExec(self): + from IndirectCommon import StartTime, EndTime + + StartTime('Symmetrise') + self._setup() + temp_ws_name = '__symm_temp' + + # The number of spectra that will actually be changed + num_symm_spectra = self._spectra_range[1] - self._spectra_range[0] + 1 + + # Find the smallest data array in the first spectra + len_x = len(mtd[self._sample].readX(0)) + len_y = len(mtd[self._sample].readY(0)) + len_e = len(mtd[self._sample].readE(0)) + sample_array_len = min(len_x, len_y, len_e) + + sample_x = mtd[self._sample].readX(0) + + # Get slice bounds of array + try: + self._calculate_array_points(sample_x, sample_array_len) + except Exception as e: + raise RuntimeError('Failed to calculate array slice boundaries: %s' % e.message) + + max_sample_index = sample_array_len - 1 + centre_range_len = self._positive_min_index + self._negative_min_index + posiive_diff_range_len = max_sample_index - self._positive_max_index + + output_cut_index = max_sample_index - self._positive_min_index - posiive_diff_range_len + new_array_len = 2 * max_sample_index - centre_range_len - 2 * posiive_diff_range_len + + if self._verbose: + logger.notice('Sample array length = %d' % sample_array_len) + + logger.notice('Positive X min at i=%d, x=%f' + % (self._positive_min_index, sample_x[self._positive_min_index])) + logger.notice('Negative X min at i=%d, x=%f' + % (self._negative_min_index, sample_x[self._negative_min_index])) + + logger.notice('Positive X max at i=%d, x=%f' + % (self._positive_max_index, sample_x[self._positive_max_index])) + + logger.notice('New array length = %d' % new_array_len) + logger.notice('Output array LR split index = %d' % output_cut_index) + + x_unit = mtd[self._sample].getAxis(0).getUnit().unitID() + + # Create an empty workspace with enough storage for the new data + zeros = np.zeros(new_array_len * num_symm_spectra) + CreateWorkspace(OutputWorkspace=temp_ws_name, + DataX=zeros, DataY=zeros, DataE=zeros, + NSpec=int(num_symm_spectra), + UnitX=x_unit) + + # Copy logs and properties from sample workspace + CopyLogs(InputWorkspace=self._sample, OutputWorkspace=temp_ws_name) + CopyInstrumentParameters(InputWorkspace=self._sample, OutputWorkspace=temp_ws_name) + + # For each spectrum copy positive values to the negative + output_spectrum_index = 0 + for spectrum_no in range(self._spectra_range[0], self._spectra_range[1] + 1): + # Get index of original spectra + spectrum_index = mtd[self._sample].getIndexFromSpectrumNumber(spectrum_no) + + # Strip any additional array cells + x_in = mtd[self._sample].readX(spectrum_index)[:sample_array_len] + y_in = mtd[self._sample].readY(spectrum_index)[:sample_array_len] + e_in = mtd[self._sample].readE(spectrum_index)[:sample_array_len] + + # Get some zeroed data to overwrite with copies from sample + x_out = np.zeros(new_array_len) + y_out = np.zeros(new_array_len) + e_out = np.zeros(new_array_len) + + # Left hand side (reflected) + x_out[:output_cut_index] = -x_in[self._positive_max_index:self._positive_min_index:-1] + y_out[:output_cut_index] = y_in[self._positive_max_index:self._positive_min_index:-1] + e_out[:output_cut_index] = e_in[self._positive_max_index:self._positive_min_index:-1] + + # Right hand side (copied) + x_out[output_cut_index:] = x_in[self._negative_min_index:self._positive_max_index] + y_out[output_cut_index:] = y_in[self._negative_min_index:self._positive_max_index] + e_out[output_cut_index:] = e_in[self._negative_min_index:self._positive_max_index] + + # Set output spectrum data + mtd[temp_ws_name].setX(output_spectrum_index, x_out) + mtd[temp_ws_name].setY(output_spectrum_index, y_out) + mtd[temp_ws_name].setE(output_spectrum_index, e_out) + + # Set output spectrum number + mtd[temp_ws_name].getSpectrum(output_spectrum_index).setSpectrumNo(spectrum_no) + output_spectrum_index += 1 + + logger.information('Symmetrise spectrum %d' % spectrum_no) + + RenameWorkspace(InputWorkspace=temp_ws_name, OutputWorkspace=self._output_workspace) + + if self._save: + self._save_output() + + if self._plot: + self._plot_output() + + if self._props_output_workspace != '': + self._generate_props_table() + + self.setProperty('OutputWorkspace', self._output_workspace) + + EndTime('Symmetrise') + + + def validateInputs(self): + """ + Checks for invalid input properties. + """ + from IndirectCommon import CheckHistZero + issues = dict() + + input_workspace_name = self.getPropertyValue('Sample') + + # Validate spectra range + spectra_range = self.getProperty('SpectraRange').value + if len(spectra_range) != 0 and len(spectra_range) != 2: + issues['SpectraRange'] = 'Must be in format "spec_min,spec_max"' + + if len(spectra_range) == 2: + spec_min = spectra_range[0] + spec_max = spectra_range[1] + + num_sample_spectra, _ = CheckHistZero(input_workspace_name) + min_spectra_number = mtd[input_workspace_name].getSpectrum(0).getSpectrumNo() + max_spectra_number = mtd[input_workspace_name].getSpectrum(num_sample_spectra - 1).getSpectrumNo() + + if spec_min < min_spectra_number: + issues['SpectraRange'] = 'Minimum spectra must be greater than or equal to %d' % min_spectra_number + + if spec_max > max_spectra_number: + issues['SpectraRange'] = 'Maximum spectra must be less than or equal to %d' % max_spectra_number + + if spec_max < spec_min: + issues['SpectraRange'] = 'Minimum spectra must be smaller than maximum spectra' + + # Validate X range + x_min = self.getProperty('XMin').value + if x_min < -1e-5: + issues['XMin'] = 'XMin must be greater than or equal to zero' + + x_max = self.getProperty('XMax').value + if x_max < 1e-5: + issues['XMax'] = 'XMax must be greater than zero' + + if math.fabs(x_max - x_min) < 1e-5: + issues['XMin'] = 'X range is close to zero' + issues['XMax'] = 'X range is close to zero' + + if x_max < x_min: + issues['XMin'] = 'XMin must be less than XMax' + issues['XMax'] = 'XMax must be greater than XMin' + + # Valudate X range against workspace X range + sample_x = mtd[input_workspace_name].readX(0) + + if x_max > sample_x[len(sample_x) - 1]: + issues['XMax'] = 'XMax value (%f) is greater than largest X value (%f)' % (x_max, sample_x[len(sample_x) - 1]) + + if -x_min < sample_x[0]: + issues['XMin'] = 'Negative XMin value (%f) is less than smallest X value (%f)' % (-x_min, sample_x[0]) + + return issues + + + def _setup(self): + """ + Get the algorithm properties and validate them. + """ + from IndirectCommon import CheckHistZero + + self._sample = self.getPropertyValue('Sample') + + self._x_min = math.fabs(self.getProperty('XMin').value) + self._x_max = math.fabs(self.getProperty('XMax').value) + + self._verbose = self.getProperty('Verbose').value + self._plot = self.getProperty('Plot').value + self._save = self.getProperty('Save').value + + self._spectra_range = self.getProperty('SpectraRange').value + # If the user did not enter a spectra range, use the spectra range of the workspace + if len(self._spectra_range) == 0: + num_sample_spectra, _ = CheckHistZero(self._sample) + min_spectra_number = mtd[self._sample].getSpectrum(0).getSpectrumNo() + max_spectra_number = mtd[self._sample].getSpectrum(num_sample_spectra - 1).getSpectrumNo() + self._spectra_range = [min_spectra_number, max_spectra_number] + + self._output_workspace = self.getPropertyValue('OutputWorkspace') + self._props_output_workspace = self.getPropertyValue('OutputPropertiesTable') + + + def _calculate_array_points(self, sample_x, sample_array_len): + """ + Finds the points in the array that match the cut points. + + @param sample_x - Sample X axis data + @param sample_array_len - Lengh of data array for sample data + """ + delta_x = sample_x[1] - sample_x[0] + + # Find array index of negative XMin + negative_min_diff = np.absolute(sample_x + self._x_min) + self._negative_min_index = np.where(negative_min_diff < delta_x)[0][-1] + self._check_bounds(self._negative_min_index, sample_array_len, label='Negative') + + # Find array index of positive XMin + positive_min_diff = np.absolute(sample_x + sample_x[self._negative_min_index]) + self._positive_min_index = np.where(positive_min_diff < delta_x)[0][-1] + self._check_bounds(self._positive_min_index, sample_array_len, label='Positive') + + # Find array index of positive XMax + positive_max_diff = np.absolute(sample_x - self._x_max) + self._positive_max_index = np.where(positive_max_diff < delta_x)[0][-1] + if self._positive_max_index == sample_array_len: + self._positive_max_index -= 1 + self._check_bounds(self._positive_max_index, sample_array_len, label='Positive') + + + def _check_bounds(self, index, num_pts, label=''): + """ + Check if the index falls within the bounds of the x range. + Throws a ValueError if the x point falls outside of the range. + + @param index - value of the index within the x range. + @param num_pts - total number of points in the range. + @param label - label to call the point if an error is thrown. + """ + if index < 0: + raise ValueError('%s point %d < 0' % (label, index)) + elif index >= num_pts: + raise ValueError('%s point %d > %d' % (label, index, num_pts)) + + + def _generate_props_table(self): + """ + Creates a table workspace with values calculated in algorithm. + """ + props_table = CreateEmptyTableWorkspace(OutputWorkspace=self._props_output_workspace) + + props_table.addColumn('int', 'NegativeXMinIndex') + props_table.addColumn('int', 'PositiveXMinIndex') + props_table.addColumn('int', 'PositiveXMaxIndex') + + props_table.addRow([int(self._negative_min_index), int(self._positive_min_index), int(self._positive_max_index)]) + + self.setProperty('OutputPropertiesTable', self._props_output_workspace) + + + def _save_output(self): + """ + Save the output workspace to the user's default working directory + """ + from IndirectCommon import getDefaultWorkingDirectory + workdir = getDefaultWorkingDirectory() + file_path = os.path.join(workdir, self._output_workspace + '.nxs') + SaveNexusProcessed(InputWorkspace=self._output_workspace, + Filename=file_path) + + if self._verbose: + logger.notice('Output file : ' + file_path) + + + def _plot_output(self): + """ + Plot the first spectrum of the input and output workspace together. + """ + from IndirectImport import import_mantidplot + mtd_plot = import_mantidplot() + + mtd_plot.plotSpectrum([self._sample, self._output_workspace], 0) + + +# Register algorithm with Mantid +AlgorithmFactory.subscribe(Symmetrise) diff --git a/Code/Mantid/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/CreateCalibrationWorkspace.py b/Code/Mantid/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/CreateCalibrationWorkspace.py new file mode 100644 index 000000000000..e8aa6020978f --- /dev/null +++ b/Code/Mantid/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/CreateCalibrationWorkspace.py @@ -0,0 +1,154 @@ +from mantid.kernel import * +from mantid.api import * +from mantid.simpleapi import * + +import os.path + + +class CreateCalibrationWorkspace(DataProcessorAlgorithm): + + 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') + + self.declareProperty(WorkspaceProperty('OutputWorkspace', '', + direction=Direction.Output), + doc='Output workspace for calibration data') + + self.declareProperty(IntArrayProperty(name='DetectorRange', values=[0, 1], + validator=IntArrayMandatoryValidator()), + doc='Range of detectors') + + self.declareProperty(FloatArrayProperty(name='PeakRange', values=[0.0, 100.0], + validator=FloatArrayMandatoryValidator()), + doc='') + + self.declareProperty(FloatArrayProperty(name='BackgroundRange', values=[0.0, 1000.0], + validator=FloatArrayMandatoryValidator()), + doc='') + + self.declareProperty(name='ScaleFactor', defaultValue=1.0, + doc='') + + self.declareProperty(name='Plot', defaultValue=False, doc='Plot the calibration data') + + def validateInputs(self): + """ + Validates input ranges. + """ + issues = dict() + + issues['DetectorRange'] = self._validate_range('DetectorRange') + issues['PeakRange'] = self._validate_range('PeakRange') + issues['BackgroundRange'] = self._validate_range('BackgroundRange') + + return issues + + def _validate_range(self, property_name): + """ + Validates a range property. + + @param property_name Name of the property to validate + @returns String detailing error, None if no error + """ + + prop_range = self.getProperty(property_name).value + if len(prop_range) == 2: + if prop_range[0] > prop_range[1]: + return 'Invalid range' + else: + return 'Incorrect number of values (should be 2)' + + 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: + (_, filename) = os.path.split(in_file) + (root, _) = os.path.splitext(filename) + try: + Load(Filename=in_file, OutputWorkspace=root, + SpectrumMin=int(self._spec_range[0]), SpectrumMax=int(self._spec_range[1]), + LoadLogFiles=False) + runs.append(root) + except Exception as exc: + logger.error('Could not load raw file "%s": %s' % (in_file, str(exc))) + + calib_ws_name = 'calibration' + if len(runs) > 1: + MergeRuns(InputWorkspaces=",".join(runs), OutputWorkspace=calib_ws_name) + factor = 1.0 / len(runs) + Scale(InputWorkspace=calib_ws_name, OutputWorkspace=calib_ws_name, Factor=factor) + else: + calib_ws_name = runs[0] + + CalculateFlatBackground(InputWorkspace=calib_ws_name, OutputWorkspace=calib_ws_name, + StartX=self._back_range[0], EndX=self._back_range[1], Mode='Mean') + + from inelastic_indirect_reduction_steps import NormaliseToUnityStep + ntu = NormaliseToUnityStep() + ntu.set_factor(self._intensity_scale) + ntu.set_peak_range(self._peak_range[0], self._peak_range[1]) + ntu.execute(None, calib_ws_name) + + RenameWorkspace(InputWorkspace=calib_ws_name, OutputWorkspace=self._out_ws) + + # Remove old workspaces + if len(runs) > 1: + for run in runs: + DeleteWorkspace(Workspace=run) + + self.setProperty('OutputWorkspace', self._out_ws) + self._post_process() + + EndTime('CreateCalibrationWorkspace') + + def _setup(self): + """ + Gets properties. + """ + + self._input_files = self.getProperty('InputFiles').value + self._out_ws = self.getPropertyValue('OutputWorkspace') + + self._peak_range = self.getProperty('PeakRange').value + self._back_range = self.getProperty('BackgroundRange').value + self._spec_range = self.getProperty('DetectorRange').value + + self._intensity_scale = self.getProperty('ScaleFactor').value + if self._intensity_scale == 1.0: + self._intensity_scale = None + + self._plot = self.getProperty('Plot').value + + def _post_process(self): + """ + Handles adding logs and plotting. + """ + + # Add sample logs to output workspace + if self._intensity_scale is not None: + AddSampleLog(Workspace=self._out_ws, LogName='Scale Factor', LogType='Number', LogText=str(self._intensity_scale)) + AddSampleLog(Workspace=self._out_ws, LogName='Peak Min', LogType='Number', LogText=str(self._peak_range[0])) + AddSampleLog(Workspace=self._out_ws, LogName='Peak Max', LogType='Number', LogText=str(self._peak_range[1])) + AddSampleLog(Workspace=self._out_ws, LogName='Back Min', LogType='Number', LogText=str(self._back_range[0])) + AddSampleLog(Workspace=self._out_ws, LogName='Back Max', LogType='Number', LogText=str(self._back_range[1])) + + if self._plot: + from mantidplot import plotBin + plotBin(mtd[self._out_ws], 0) + +# Register algorithm with Mantid +AlgorithmFactory.subscribe(CreateCalibrationWorkspace) diff --git a/Code/Mantid/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/Fury.py b/Code/Mantid/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/Fury.py new file mode 100644 index 000000000000..ba626f47d217 --- /dev/null +++ b/Code/Mantid/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/Fury.py @@ -0,0 +1,233 @@ +from mantid.simpleapi import * +from mantid.api import PythonAlgorithm, AlgorithmFactory, MatrixWorkspaceProperty, PropertyMode +from mantid.kernel import StringListValidator, StringMandatoryValidator, Direction, logger +from mantid import config +import math +import os + + +class Fury(PythonAlgorithm): + + def category(self): + return "Workflow\\MIDAS;PythonAlgorithms" + + def PyInit(self): + self.declareProperty(MatrixWorkspaceProperty('Sample', '', + optional=PropertyMode.Mandatory, direction=Direction.Input), + doc="Name for the Sample workspace.") + + self.declareProperty(MatrixWorkspaceProperty('Resolution', '', + optional=PropertyMode.Mandatory, direction=Direction.Input), + 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=10, doc='Binning value (integer) for sample. Default=1') + + self.declareProperty(MatrixWorkspaceProperty('ParameterWorkspace', '', + direction=Direction.Output, optional=PropertyMode.Optional), + doc='Table workspace for saving Fury properties') + + self.declareProperty(MatrixWorkspaceProperty('OutputWorkspace', '', + direction=Direction.Output, optional=PropertyMode.Optional), + doc='Output workspace') + + self.declareProperty(name='Plot', defaultValue=False, doc='Switch Plot Off/On') + self.declareProperty(name='Verbose', defaultValue=False, doc='Switch Verbose Off/On') + self.declareProperty(name='Save', defaultValue=False, doc='Switch Save result to nxs file Off/On') + self.declareProperty(name='DryRun', defaultValue=False, doc='Only calculate and output the parameters') + + + def PyExec(self): + self._setup() + + self._calculate_parameters() + + if not self._dry_run: + self._fury('__Fury_sample_cropped') + + self._add_logs() + + if self._save: + workdir = config['defaultsave.directory'] + opath = os.path.join(workdir, self._output_workspace + '.nxs') + SaveNexusProcessed(InputWorkspace=self._output_workspace, Filename=opath) + if self._verbose: + logger.notice('Output file : ' + opath) + + if self._plot: + self._plot_output() + else: + if self._verbose: + logger.notice('Dry run, will not run Fury') + + DeleteWorkspace('__Fury_sample_cropped') + + self.setProperty('ParameterWorkspace', self._parameter_table) + self.setProperty('OutputWorkspace', self._output_workspace) + + + def _setup(self): + """ + Gets algorithm properties. + """ + from IndirectCommon import getWSprefix + + self._sample = self.getPropertyValue('Sample') + self._resolution = self.getPropertyValue('Resolution') + + self._e_min = self.getProperty('EnergyMin').value + self._e_max = self.getProperty('EnergyMax').value + self._num_bins = self.getProperty('NumBins').value + + self._parameter_table = self.getPropertyValue('ParameterWorkspace') + if self._parameter_table == '': + self._parameter_table = getWSprefix(self._sample) + 'FuryParameters' + + self._output_workspace = self.getPropertyValue('OutputWorkspace') + if self._output_workspace == '': + self._output_workspace = getWSprefix(self._sample) + 'iqt' + + self._verbose = self.getProperty('Verbose').value + self._plot = self.getProperty('Plot').value + self._save = self.getProperty('Save').value + self._dry_run = self.getProperty('DryRun').value + + + def validateInputs(self): + """ + Validate input properties. + """ + issues = dict() + + e_min = self.getProperty('EnergyMin').value + e_max = self.getProperty('EnergyMax').value + + # Check for swapped energy values + if e_min > e_max: + energy_swapped = 'EnergyMin is greater than EnergyMax' + issues['EnergyMin'] = energy_swapped + issues['EnergyMax'] = energy_swapped + + return issues + + + def _calculate_parameters(self): + """ + Calculates the Fury parameters and saves in a table workspace. + """ + CropWorkspace(InputWorkspace=self._sample, OutputWorkspace='__Fury_sample_cropped', Xmin=self._e_min, Xmax=self._e_max) + x_data = mtd['__Fury_sample_cropped'].readX(0) + number_input_points = len(x_data) - 1 + number_points_per_bin = number_input_points / self._num_bins + self._e_width = (abs(self._e_min) + abs(self._e_max)) / number_points_per_bin + + try: + instrument = mtd[self._sample].getInstrument() + analyser = instrument.getStringParameter('analyser')[0] + resolution = instrument.getComponentByName(analyser).getNumberParameter('resolution')[0] + + if self._verbose: + logger.information('Got resolution from IPF: %f' % resolution) + except IndexError: + logger.warning('Could not get resolution from IPF, using default value.') + resolution = 0.0175 + + resolution_bins = int(round((2 * resolution) / self._e_width)) + + if resolution_bins < 5: + logger.warning('Resolution curve has <5 points. Results may be unreliable.') + + param_table = CreateEmptyTableWorkspace(OutputWorkspace=self._parameter_table) + + param_table.addColumn('int', 'SampleInputBins') + param_table.addColumn('int', 'NumberBins') + param_table.addColumn('int', 'SampleOutputBins') + param_table.addColumn('float', 'EnergyMin') + param_table.addColumn('float', 'EnergyMax') + param_table.addColumn('float', 'EnergyWidth') + param_table.addColumn('float', 'Resolution') + param_table.addColumn('int', 'ResolutionBins') + + param_table.addRow([number_input_points, self._num_bins, number_points_per_bin, + self._e_min, self._e_max, self._e_width, + resolution, resolution_bins]) + + self.setProperty('ParameterWorkspace', param_table) + + + def _plot_output(self): + """ + Plot output. + """ + from IndirectImport import import_mantidplot + mtd_plot = import_mantidplot() + + spectra_range = range(0, mtd[self._output_workspace].getNumberHistograms()) + + graph = mtd_plot.plotSpectrum(self._output_workspace, spectra_range) + + layer = graph.activeLayer() + layer.setScale(mtd_plot.Layer.Left, 0, 1.0) + + + def _add_logs(self): + AddSampleLog(Workspace=self._output_workspace, LogName='fury_resolution_ws', LogType='String', LogText=self._resolution) + AddSampleLog(Workspace=self._output_workspace, LogName='fury_rebin_emin', LogType='Number', LogText=str(self._e_min)) + AddSampleLog(Workspace=self._output_workspace, LogName='fury_rebin_ewidth', LogType='Number', LogText=str(self._e_width)) + AddSampleLog(Workspace=self._output_workspace, LogName='fury_rebin_emax', LogType='Number', LogText=str(self._e_max)) + + + def _fury(self, sam_workspace): + """ + Run Fury. + """ + from IndirectCommon import StartTime, EndTime, CheckHistZero, CheckHistSame, CheckAnalysers + + StartTime('Fury') + + rebin_param = str(self._e_min) + ',' + str(self._e_width) + ',' + str(self._e_max) + Rebin(InputWorkspace=sam_workspace, OutputWorkspace=sam_workspace, Params=rebin_param, FullBinsOnly=True) + + # Process RES Data Only Once + CheckAnalysers(sam_workspace, self._resolution, self._verbose) + nres, _ = CheckHistZero(self._resolution) + if nres > 1: + CheckHistSame(sam_workspace, 'Sample', self._resolution, 'Resolution') + + tmp_res_workspace = '__tmp_' + self._resolution + Rebin(InputWorkspace=self._resolution, OutputWorkspace=tmp_res_workspace, Params=rebin_param, FullBinsOnly=True) + Integration(InputWorkspace=tmp_res_workspace, OutputWorkspace='res_int') + ConvertToPointData(InputWorkspace=tmp_res_workspace, OutputWorkspace=tmp_res_workspace) + ExtractFFTSpectrum(InputWorkspace=tmp_res_workspace, OutputWorkspace='res_fft', FFTPart=2) + Divide(LHSWorkspace='res_fft', RHSWorkspace='res_int', OutputWorkspace='res') + Rebin(InputWorkspace=sam_workspace, OutputWorkspace='sam_data', Params=rebin_param) + Integration(InputWorkspace='sam_data', OutputWorkspace='sam_int') + ConvertToPointData(InputWorkspace='sam_data', OutputWorkspace='sam_data') + ExtractFFTSpectrum(InputWorkspace='sam_data', OutputWorkspace='sam_fft', FFTPart=2) + Divide(LHSWorkspace='sam_fft', RHSWorkspace='sam_int', OutputWorkspace='sam') + + Divide(LHSWorkspace='sam', RHSWorkspace='res', OutputWorkspace=self._output_workspace) + + # Cleanup Sample Files + DeleteWorkspace('sam_data') + DeleteWorkspace('sam_int') + DeleteWorkspace('sam_fft') + DeleteWorkspace('sam') + + # Crop nonsense values off workspace + binning = int(math.ceil(mtd[self._output_workspace].blocksize() / 2.0)) + bin_v = mtd[self._output_workspace].dataX(0)[binning] + CropWorkspace(InputWorkspace=self._output_workspace, OutputWorkspace=self._output_workspace, XMax=bin_v) + + # Clean up RES files + DeleteWorkspace(tmp_res_workspace) + DeleteWorkspace('res_int') + DeleteWorkspace('res_fft') + DeleteWorkspace('res') + + EndTime('Fury') + + +# Register algorithm with Mantid +AlgorithmFactory.subscribe(Fury) diff --git a/Code/Mantid/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/IndirectResolution.py b/Code/Mantid/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/IndirectResolution.py new file mode 100644 index 000000000000..d521ad91d69e --- /dev/null +++ b/Code/Mantid/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/IndirectResolution.py @@ -0,0 +1,146 @@ +from mantid.simpleapi import * +from mantid.api import * +from mantid.kernel import * +from mantid import config, logger + + +class IndirectResolution(DataProcessorAlgorithm): + + def category(self): + return 'Workflow\\Inelastic;PythonAlgorithms;Inelastic' + + def summary(self): + return 'Creates a resolution workspace' + + def PyInit(self): + self.declareProperty(StringArrayProperty(name='InputFiles'), + doc='Comma seperated list if input files') + + self.declareProperty(WorkspaceProperty('OutputWorkspace', '', + optional=PropertyMode.Optional, + direction=Direction.Output), + doc='Output resolution workspace (if left blank a name will be gernerated automatically)') + + self.declareProperty(name='Instrument', defaultValue='', + validator=StringListValidator(['IRIS', 'OSIRIS', 'TOSCA']), + doc='Instrument used during run') + self.declareProperty(name='Analyser', defaultValue='', + validator=StringListValidator(['graphite', 'mica', 'fmica']), + doc='Analyser used during run') + self.declareProperty(name='Reflection', defaultValue='', + validator=StringListValidator(['002', '004', '006']), + doc='Reflection used during run') + + self.declareProperty(IntArrayProperty(name='DetectorRange', values=[0, 1]), + doc='Range of detetcors to use in resolution calculation') + self.declareProperty(FloatArrayProperty(name='BackgroundRange', values=[0.0, 0.0]), + doc='Energy range to use as background') + + self.declareProperty(name='RebinParam', defaultValue='', doc='Rebinning parameters (min,width,max)') + self.declareProperty(name='ScaleFactor', defaultValue=1.0, doc='Factor to scale resolution curve by') + self.declareProperty(name='Smooth', defaultValue=False, doc='Apply WienerSmooth to resolution') + + self.declareProperty(name='Verbose', defaultValue=False, doc='Print more information to results log') + self.declareProperty(name='Plot', defaultValue=False, doc='Plot resolution curve') + self.declareProperty(name='Save', defaultValue=False, doc='Save resolution workspace as a Nexus file') + + + def PyExec(self): + from IndirectCommon import StartTime, EndTime, getWSprefix + import inelastic_indirect_reducer + + StartTime('IndirectResolution') + self._setup() + + InelasticIndirectReduction(Instrument=self._instrument, + Analyser=self._analyser, + Reflection=self._reflection, + Grouping='All', + SumFiles=True, + InputFiles=self._input_files, + DetectorRange=self._detector_range, + OutputWorkspaceGroup='__icon_ws_group') + + icon_ws = mtd['__icon_ws_group'].getItem(0).getName() + + if self._out_ws == "": + self._out_ws = getWSprefix(icon_ws) + 'res' + + if self._scale_factor != 1.0: + Scale(InputWorkspace=icon_ws, OutputWorkspace=icon_ws, Factor=self._scale_factor) + + CalculateFlatBackground(InputWorkspace=icon_ws, OutputWorkspace=self._out_ws, + StartX=self._background[0], EndX=self._background[1], + Mode='Mean', OutputMode='Subtract Background') + + Rebin(InputWorkspace=self._out_ws, OutputWorkspace=self._out_ws, Params=self._rebin_string) + + if self._smooth: + WienerSmooth(InputWorkspace=self._out_ws, OutputWorkspace='__smooth_temp') + CopyLogs(InputWorkspace=self._out_ws, OutputWorkspace='__smooth_temp') + RenameWorkspace(InputWorkspace='__smooth_temp', OutputWorkspace=self._out_ws) + + self._post_process() + self.setProperty('OutputWorkspace', self._out_ws) + + EndTime('IndirectResolution') + + + def _setup(self): + """ + Gets algorithm properties. + """ + + self._input_files = self.getProperty('InputFiles').value + self._out_ws = self.getPropertyValue('OutputWorkspace') + + self._instrument = self.getProperty('Instrument').value + self._analyser = self.getProperty('Analyser').value + self._reflection = self.getProperty('Reflection').value + + self._detector_range = self.getProperty('DetectorRange').value + self._background = self.getProperty('BackgroundRange').value + self._rebin_string = self.getProperty('RebinParam').value + self._scale_factor = self.getProperty('ScaleFactor').value + self._smooth = self.getProperty('Smooth').value + + self._verbose = self.getProperty('Verbose').value + self._plot = self.getProperty('Plot').value + self._save = self.getProperty('Save').value + + + def _post_process(self): + """ + Handles adding logs, saving and plotting. + """ + + use_scale_factor = self._scale_factor == 1.0 + AddSampleLog(Workspace=self._out_ws, LogName='scale', LogType='String', LogText=str(use_scale_factor)) + if use_scale_factor: + AddSampleLog(Workspace=self._out_ws, LogName='scale_factor', LogType='Number', LogText=str(self._scale_factor)) + + AddSampleLog(Workspace=self._out_ws, LogName='res_smoothing_applied', LogType='String', LogText=str(self._smooth)) + + AddSampleLog(Workspace=self._out_ws, LogName='back_start', LogType='Number', LogText=str(self._background[0])) + AddSampleLog(Workspace=self._out_ws, LogName='back_end', LogType='Number', LogText=str(self._background[1])) + + rebin_params = self._rebin_string.split(',') + if len(rebin_params) == 3: + AddSampleLog(Workspace=self._out_ws, LogName='rebin_low', LogType='Number', LogText=rebin_params[0]) + AddSampleLog(Workspace=self._out_ws, LogName='rebin_width', LogType='Number', LogText=rebin_params[1]) + AddSampleLog(Workspace=self._out_ws, LogName='rebin_high', LogType='Number', LogText=rebin_params[2]) + + self.setProperty('OutputWorkspace', self._out_ws) + + if self._save: + if self._verbose: + logger.notice("Resolution file saved to default save directory.") + SaveNexusProcessed(InputWorkspace=self._out_ws, Filename=self._out_ws + '.nxs') + + if self._plot: + from IndirectImport import import_mantidplot + mtd_plot = import_mantidplot() + mtd_plot.plotSpectrum(self._out_ws, 0) + + +AlgorithmFactory.subscribe(IndirectResolution) diff --git a/Code/Mantid/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/IndirectTransmissionMonitor.py b/Code/Mantid/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/IndirectTransmissionMonitor.py new file mode 100644 index 000000000000..beb5308debe6 --- /dev/null +++ b/Code/Mantid/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/IndirectTransmissionMonitor.py @@ -0,0 +1,208 @@ +from mantid.simpleapi import * +from mantid.api import * +from mantid.kernel import * +from mantid import config, logger +from IndirectImport import import_mantidplot +import numpy +import os.path + + +class IndirectTransmissionMonitor(PythonAlgorithm): + + 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') + + self.declareProperty(WorkspaceProperty('CanWorkspace', '', direction=Direction.Input), + doc='Background/can workspace') + + self.declareProperty(WorkspaceProperty('OutputWorkspace', '', direction=Direction.Output, + optional=PropertyMode.Optional), + doc='Output workspace group') + + self.declareProperty(name='Verbose', defaultValue=False, doc='Output more verbose message to log') + 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) + self._trans_mon(ws_basename, 'Can', self._can_ws_in) + + # Generate workspace names + sam_ws = ws_basename + '_Sam' + can_ws = ws_basename + '_Can' + trans_ws = ws_basename + '_Trans' + + # Divide sample and can workspaces + Divide(LHSWorkspace=sam_ws, RHSWorkspace=can_ws, OutputWorkspace=trans_ws) + trans = numpy.average(mtd[trans_ws].readY(0)) + + AddSampleLog(Workspace=trans_ws, LogName='can_workspace', LogType='String', LogText=self._can_ws_in) + + # Generate an output workspace name if none provided + if self._out_ws == '': + self._out_ws = ws_basename + '_Transmission' + + # Group workspaces + group = sam_ws + ',' + can_ws + ',' + trans_ws + GroupWorkspaces(InputWorkspaces=group, OutputWorkspace=self._out_ws) + + self.setProperty('OutputWorkspace', self._out_ws) + + if self._verbose: + logger.notice('Transmission : ' + str(trans)) + + # Save the tranmissin workspace group to a nexus file + if self._save: + workdir = config['defaultsave.directory'] + path = os.path.join(workdir, self._out_ws + '.nxs') + SaveNexusProcessed(InputWorkspace=self._out_ws, Filename=path) + if self._verbose: + logger.notice('Output file created : ' + path) + + # Plot spectra from transmission workspace + if self._plot: + mtd_plot = import_mantidplot() + mtd_plot.plotSpectrum(self._out_ws, 0) + + EndTime('IndirectTransmissionMonitor') + + def _setup(self): + """ + Get properties. + """ + + self._sample_ws_in = self.getPropertyValue("SampleWorkspace") + self._can_ws_in = self.getPropertyValue("CanWorkspace") + self._out_ws = self.getPropertyValue('OutputWorkspace') + self._verbose = self.getProperty("Verbose").value + 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. + Assumes monitors are named monitor1 and monitor2 + """ + + instrument = mtd[input_ws].getInstrument() + + try: + analyser = instrument.getStringParameter('analyser')[0] + detector_1_idx = instrument.getComponentByName(analyser)[0].getID() - 1 + if self._verbose: + logger.information('Got index of first detector for analyser %s: %d' % (analyser, detector_1_idx)) + except IndexError: + detector_1_idx = 2 + logger.warning('Could not determine index of first detetcor, using default value.') + + try: + monitor_1_idx = self._get_detector_spectrum_index(input_ws, instrument.getComponentByName('monitor1').getID()) + + monitor_2 = instrument.getComponentByName('monitor2') + if monitor_2 is not None: + monitor_2_idx = self._get_detector_spectrum_index(input_ws, monitor_2.getID()) + else: + monitor_2_idx = None + + if self._verbose: + logger.information('Got index of monitors: %d, %s' % (monitor_1_idx, str(monitor_2_idx))) + except IndexError: + monitor_1_idx = 0 + monitor_2_idx = 1 + logger.warning('Could not determine index of monitors, using default values.') + + 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. + + @param workspace Workspace to find detector in + @param detector_id Detector ID to search for + """ + + for spec_idx in range(0, mtd[workspace].getNumberHistograms()): + if mtd[workspace].getDetector(spec_idx).getID() == detector_id: + return spec_idx + + return None + + def _unwrap_mon(self, input_ws): + out_ws = '_unwrap_mon_out' + + # Unwrap monitor - inWS contains M1,M2,S1 - outWS contains unwrapped Mon + # Unwrap s1>2 to L of S2 (M2) ie 38.76 Ouput is in wavelength + _, join = UnwrapMonitor(InputWorkspace=input_ws, OutputWorkspace=out_ws, LRef='37.86') + + # Fill bad (dip) in spectrum + RemoveBins(InputWorkspace=out_ws, OutputWorkspace=out_ws, Xmin=join - 0.001, Xmax=join + 0.001, Interpolation="Linear") + FFTSmooth(InputWorkspace=out_ws, OutputWorkspace=out_ws, WorkspaceIndex=0, IgnoreXBins=True) # Smooth - FFT + + DeleteWorkspace(input_ws) + + 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) + 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) + + # Check for single or multiple time regimes + mon_tcb_start = mtd['__m1'].readX(0)[0] + spec_tcb_start = mtd['__det'].readX(0)[0] + + DeleteWorkspace('__det') + mon_ws = '__Mon' + + if spec_tcb_start == mon_tcb_start: + mon_ws = self._unwrap_mon('__m1') # unwrap the monitor spectrum and convert to wavelength + RenameWorkspace(InputWorkspace=mon_ws, OutputWorkspace='__Mon1') + else: + ConvertUnits(InputWorkspace='__m1', OutputWorkspace='__Mon1', Target="Wavelength") + + mon_ws = ws_basename + '_' + file_type + + if monitor_2_idx is not None: + ConvertUnits(InputWorkspace='__m2', OutputWorkspace='__Mon2', Target="Wavelength") + DeleteWorkspace('__m2') + + x_in = mtd['__Mon1'].readX(0) + xmin1 = mtd['__Mon1'].readX(0)[0] + xmax1 = mtd['__Mon1'].readX(0)[len(x_in) - 1] + + x_in = mtd['__Mon2'].readX(0) + xmin2 = mtd['__Mon2'].readX(0)[0] + xmax2 = mtd['__Mon2'].readX(0)[len(x_in) - 1] + + wmin = max(xmin1, xmin2) + wmax = min(xmax1, xmax2) + + CropWorkspace(InputWorkspace='__Mon1', OutputWorkspace='__Mon1', XMin=wmin, XMax=wmax) + RebinToWorkspace(WorkspaceToRebin='__Mon2', WorkspaceToMatch='__Mon1', OutputWorkspace='__Mon2') + Divide(LHSWorkspace='__Mon2', RHSWorkspace='__Mon1', OutputWorkspace=mon_ws) + + DeleteWorkspace('__Mon1') + DeleteWorkspace('__Mon2') + else: + RenameWorkspace(InputWorkspace='__Mon1', OutputWorkspace=mon_ws) + + +# Register algorithm with Mantid +AlgorithmFactory.subscribe(IndirectTransmissionMonitor) diff --git a/Code/Mantid/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/InelasticIndirectReduction.py b/Code/Mantid/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/InelasticIndirectReduction.py new file mode 100644 index 000000000000..059a46744d5c --- /dev/null +++ b/Code/Mantid/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/InelasticIndirectReduction.py @@ -0,0 +1,223 @@ +from mantid.kernel import * +from mantid.api import * +from mantid.simpleapi import * + +class InelasticIndirectReduction(DataProcessorAlgorithm): + + def category(self): + return 'Workflow\\Inelastic;PythonAlgorithms;Inelastic' + + + def summary(self): + return 'Runs a reduction for an inelastic indirect geometry instrument.' + + + def PyInit(self): + self.declareProperty(StringArrayProperty(name='InputFiles'), + doc='Comma separated list of input files') + + self.declareProperty(WorkspaceGroupProperty('OutputWorkspaceGroup', '', + direction=Direction.Output, optional=PropertyMode.Optional), + doc='Optionally group the resulting workspaces') + + self.declareProperty(name='SumFiles', defaultValue=False, doc='Toggle input file summing or sequential processing') + self.declareProperty(name='LoadLogs', defaultValue=False, doc='Load sample logs from input files') + + self.declareProperty(name='Instrument', defaultValue='', doc='Instrument used during run', + validator=StringListValidator(['IRIS', 'OSIRIS', 'TOSCA', 'BASIS', 'VISION'])) + self.declareProperty(name='Analyser', defaultValue='', doc='Analyser used during run', + validator=StringListValidator(['graphite', 'mica', 'fmica', 'silicon'])) + self.declareProperty(name='Reflection', defaultValue='', doc='Reflection used during run', + validator=StringListValidator(['002', '004', '006', '111'])) + + self.declareProperty(WorkspaceProperty('CalibrationWorkspace', '', + direction=Direction.Input, optional=PropertyMode.Optional), doc='Workspace contining calibration data') + + self.declareProperty(IntArrayProperty(name='DetectorRange', values=[0, 1], + validator=IntArrayMandatoryValidator()), + doc='Comma separated range of detectors to use') + self.declareProperty(FloatArrayProperty(name='BackgroundRange'), + doc='') + + self.declareProperty(name='RebinString', defaultValue='', doc='Rebin string parameters') + self.declareProperty(name='DetailedBalance', defaultValue=-1.0, doc='') + self.declareProperty(name='ScaleFactor', defaultValue=1.0, doc='') + self.declareProperty(name='Grouping', defaultValue='', + doc='Method used to group spectra, can be either: Individual, All, a .map fielname or a group workspace name') + self.declareProperty(name='Fold', defaultValue=False, doc='') + self.declareProperty(name='SaveCM1', defaultValue=False, doc='') + self.declareProperty(StringArrayProperty(name='SaveFormats'), doc='Comma separated list of save formats') + + self.declareProperty(name='Plot', defaultValue='none', doc='Type of plot to output after reduction', + validator=StringListValidator(['none', 'spectra', 'contour'])) + + + 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() + + reducer.set_rename(True) + + reducer.set_instrument_name(self._instrument) + reducer.set_parameter_file(self._param_file) + + for data_file in self._data_files: + reducer.append_data_file(data_file) + + reducer.set_sum_files(self._sum_files) + + reducer.set_detector_range(int(self._detector_range[0]) - 1, int(self._detector_range[1]) - 1) + + self._use_calib_ws = self._calib_ws.value is not None + if self._use_calib_ws: + logger.debug('Using calibration workspace') + reducer.set_calibration_workspace(self._calib_ws.valueAsStr) + + if len(self._background_range) == 2: + logger.debug('Using background range: ' + str(self._background_range)) + reducer.set_background(float(self._background_range[0]), float(self._background_range[1])) + + # TODO: There should be a better way to do this + self._use_detailed_balance = self._detailed_balance != -1.0 + if self._use_detailed_balance: + logger.debug('Using detailed balance: ' + str(self._detailed_balance)) + reducer.set_detailed_balance(self._detailed_balance) + + if self._rebin_string != '': + logger.debug('Using rebin string: ' + self._rebin_string) + reducer.set_rebin_string(self._rebin_string) + + self._use_scale_factor = self._scale_factor != 1.0 + if self._use_scale_factor: + logger.debug('Using scale factor: ' + str(self._scale_factor)) + reducer.set_scale_factor(self._scale_factor) + + if self._map_file != '': + logger.debug('Using mapping file: ' + str(self._map_file)) + reducer.set_grouping_policy(self._map_file) + + reducer.set_fold_multiple_frames(self.getProperty('Fold').value) + reducer.set_save_to_cm_1(self.getProperty('SaveCM1').value) + reducer.set_save_formats(self._save_formats) + + # Do reduction and get result workspaces + reducer.reduce() + ws_list = reducer.get_result_workspaces() + + self._plot_ws = ws_list[0] + + if len(ws_list) < 1: + logger.error('Failed to complete reduction') + return + + # Add sample logs to output workspace(s) + for workspace in ws_list: + self._add_ws_logs(workspace) + + # Group output workspaces + if self._out_ws_group != '': + GroupWorkspaces(InputWorkspaces=ws_list, OutputWorkspace=self._out_ws_group) + self.setProperty('OutputWorkspaceGroup', self._out_ws_group) + + # Do plotting + if self._plot_type != 'none': + self._plot() + + EndTime('InelasticIndirectReduction') + + def validateInputs(self): + """ + Validates algorithm properties. + """ + issues = dict() + + # Validate save format string + save_formats = self.getProperty('SaveFormats').value + valid_formats = ['nxs', 'spe', 'nxspe', 'ascii', 'aclimax', 'davegrp'] + invalid_formats = list() + for save_format in save_formats: + if save_format not in valid_formats: + invalid_formats.append(save_format) + if len(invalid_formats) > 0: + issues['SaveFormats'] = 'The following save formats are not valid' + ','.join(invalid_formats) + + return issues + + def _setup(self): + """ + Gets and algorithm properties. + """ + + # Get parameter values + self._out_ws_group = self.getPropertyValue('OutputWorkspaceGroup') + self._data_files = self.getProperty('InputFiles').value + + self._instrument = self.getPropertyValue('Instrument') + self._analyser = self.getPropertyValue('Analyser') + self._reflection = self.getPropertyValue('Reflection') + + self._param_file = config['instrumentDefinition.directory'] + self._instrument + '_' + self._analyser + '_' + self._reflection + '_Parameters.xml' + + self._detector_range = self.getProperty('DetectorRange').value + self._background_range = self.getProperty('BackgroundRange').value + + self._calib_ws = self.getProperty('CalibrationWorkspace') + self._calib_ws_name = self.getPropertyValue('CalibrationWorkspace') + + self._detailed_balance = self.getProperty('DetailedBalance').value + self._rebin_string = self.getPropertyValue('RebinString') + self._scale_factor = self.getProperty('ScaleFactor').value + self._sum_files = self.getProperty('SumFiles').value + + self._map_file = self.getPropertyValue('Grouping') + + self._save_formats = self.getProperty('SaveFormats').value + self._plot_type = self.getPropertyValue('Plot') + + def _add_ws_logs(self, workspace_name): + """ + Adds sample logs to a given output workspace. + """ + + AddSampleLog(Workspace=workspace_name, LogName='use_calib_wokspace', LogType='String', LogText=str(self._use_calib_ws)) + if self._use_calib_ws: + AddSampleLog(Workspace=workspace_name, LogName='calib_workspace_name', LogType='String', LogText=str(self._calib_ws_name)) + + AddSampleLog(Workspace=workspace_name, LogName='use_detailed_balance', LogType='String', LogText=str(self._use_detailed_balance)) + if self._use_detailed_balance: + AddSampleLog(Workspace=workspace_name, LogName='detailed_balance', LogType='Number', LogText=str(self._detailed_balance)) + + AddSampleLog(Workspace=workspace_name, LogName='use_scale_factor', LogType='String', LogText=str(self._use_scale_factor)) + if self._use_scale_factor: + AddSampleLog(Workspace=workspace_name, LogName='scale_factor', LogType='Number', LogText=str(self._scale_factor)) + + + def _plot(self): + """ + Plots results. + """ + + if self._plot_type == 'spectra': + from mantidplot import plotSpectrum + num_spectra = mtd[self._plot_ws].getNumberHistograms() + try: + plotSpectrum(self._plot_ws, range(0, num_spectra)) + except RuntimeError: + logger.notice('Spectrum plotting canceled by user') + + if self._plot_type == 'contour': + from mantidplot import importMatrixWorkspace + plot_workspace = importMatrixWorkspace(self._plot_ws) + plot_workspace.plotGraph2D() + + +# Register algorithm with Mantid +AlgorithmFactory.subscribe(InelasticIndirectReduction) diff --git a/Code/Mantid/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/JumpFit.py b/Code/Mantid/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/JumpFit.py new file mode 100644 index 000000000000..92a6ebdad781 --- /dev/null +++ b/Code/Mantid/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/JumpFit.py @@ -0,0 +1,162 @@ +from mantid.kernel import * +from mantid.api import * +import os + + +class JumpFit(PythonAlgorithm): + + + def category(self): + return 'Workflow\\Inelastic;PythonAlgorithms;Inelastic' + + + def PyInit(self): + self.declareProperty(WorkspaceProperty('InputWorkspace', '', direction=Direction.Input), + doc='Input workspace in HWHM') + + valid_functions = ['ChudleyElliot', 'HallRoss', 'FickDiffusion', 'TeixeiraWater'] + self.declareProperty(name='Function', defaultValue=valid_functions[0], + validator=StringListValidator(valid_functions), + doc='The fit function to use') + + self.declareProperty(name='Width', defaultValue=0, validator=IntMandatoryValidator(), + doc='Spectrum in the workspace to use for fiting') + + self.declareProperty(name='QMin', defaultValue=0.0, validator=FloatMandatoryValidator(), + doc='Lower bound of Q range to use for fitting') + self.declareProperty(name='QMax', defaultValue=0.0, validator=FloatMandatoryValidator(), + doc='Upper bound of Q range to use for fitting') + + self.declareProperty(name='Output', defaultValue='', direction=Direction.InOut, + doc='Output name') + + self.declareProperty(name='Verbose', defaultValue=False, + doc='Output more verbose message to log') + 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 mantid.simpleapi import ExtractSingleSpectrum, Scale, 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, WorkspaceIndex=self._width) + + if self._verbose: + logger.notice('Cropping from Q= ' + str(self._q_min) + ' to ' + str(self._q_max)) + in_run = mtd[self._in_ws].getRun() + try: + log = in_run.getLogData('fit_program') + if log: + val = log.value + logger.notice('Fit program was : ' + val) + except RuntimeError: + # If we couldn't find the fit program, just pass + pass + + logger.notice('Parameters in ' + self._in_ws) + + x_data = mtd[self._in_ws].readX(0) + m_max = x_data[-1] + + # Select fit function to use + if self._jump_function == 'ChudleyElliot': + # Chudley-Elliott: HWHM=(1-sin*(Q*L)/(Q*L))/Tau + # for Q->0 W=Q^2*L^2/(6*Tau) + + t_val = 1.0 / m_max + l_val = 1.5 + function = 'name=ChudleyElliot, Tau=' + str(t_val) + ', L=' + str(l_val) + + elif self._jump_function == 'HallRoss': + # Hall-Ross: HWHM=(1-exp(-L*Q^2))/Tau + # for Q->0 W=A*Q^2*r + + t_val = 1.0 / m_max + l_val = 1.5 + function = 'name=HallRoss, Tau=' + str(t_val) + ', L=' + str(l_val) + + elif self._jump_function == 'FickDiffusion': + # Fick: HWHM=D*Q^2 + + y_data = mtd[self._in_ws].readY(0) + diff = (y_data[2] - y_data[0]) / ((x_data[2] - x_data[0]) * (x_data[2] - x_data[0])) + function = 'name=FickDiffusion, D=' + str(diff) + + elif self._jump_function == 'TeixeiraWater': + # Teixeira: HWHM=Q^2*L/((1+Q^2*L)*tau) + # for Q->0 W= + + t_val = 1.0 / m_max + l_val = 1.5 + function = 'name=TeixeiraWater, Tau=' + str(t_val) + ', L=' + str(l_val) + + # Run fit function + if self._out_name is "": + ws_suffix_index = self._in_ws.rfind('_') + 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, + StartX=self._q_min, EndX=self._q_max) + fit_workspace = self._out_name + '_Workspace' + + # Populate sample logs + CopyLogs(InputWorkspace=self._in_ws, OutputWorkspace=fit_workspace) + AddSampleLog(Workspace=fit_workspace, LogName="jump_function", LogType="String", + LogText=self._jump_function) + AddSampleLog(Workspace=fit_workspace, LogName="q_min", LogType="Number", + LogText=str(self._q_min)) + AddSampleLog(Workspace=fit_workspace, LogName="q_max", LogType="Number", + LogText=str(self._q_max)) + + self._process_output(fit_workspace) + + self.setProperty('Output', self._out_name) + + DeleteWorkspace(Workspace=spectrum_ws) + + EndTime('Jump fit : ' + self._jump_function + ' ; ') + + + def _setup(self): + self._in_ws = self.getPropertyValue('InputWorkspace') + self._out_name = self.getPropertyValue('Output') + + self._jump_function = self.getProperty('Function').value + self._width = self.getProperty('Width').value + self._q_min = self.getProperty('QMin').value + self._q_max = self.getProperty('QMax').value + + self._verbose = self.getProperty('Verbose').value + self._plot = self.getProperty('Plot').value + self._save = self.getProperty('Save').value + + + def _process_output(self, workspace): + if self._save: + from mantid.simpleapi import SaveNexusProcessed + from IndirectCommon import getDefaultWorkingDirectory + workdir = getDefaultWorkingDirectory() + fit_path = os.path.join(workdir, workspace + '.nxs') + SaveNexusProcessed(InputWorkspace=workspace, Filename=fit_path) + + if self._verbose: + logger.notice('Fit file is ' + fit_path) + + if self._plot: + from IndirectImport import import_mantidplot + mtd_plot = import_mantidplot() + mtd_plot.plotSpectrum(workspace, [0, 1, 2], True) + + +# Register algorithm with Mantid +AlgorithmFactory.subscribe(JumpFit) diff --git a/Code/Mantid/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/MSGDiffractionReduction.py b/Code/Mantid/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/MSGDiffractionReduction.py new file mode 100644 index 000000000000..ed75174e90ee --- /dev/null +++ b/Code/Mantid/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/MSGDiffractionReduction.py @@ -0,0 +1,122 @@ +from mantid.simpleapi import * +from mantid.api import * +from mantid.kernel import * +from mantid import config +import os.path, math + +class MSGDiffractionReduction(PythonAlgorithm): + + def category(self): + return 'Diffraction;PythonAlgorithms' + + def summary(self): + return 'Calculates the scattering & transmission for Indirect Geometry spectrometers.' + + def PyInit(self): + self.declareProperty(StringArrayProperty(name='InputFiles'), + doc='Comma separated list of input files.') + + self.declareProperty(name='SumFiles', defaultValue=False, + doc='Enabled to sum spectra from each input file.') + + self.declareProperty(name='IndividualGrouping', defaultValue=False, + doc='Do not group results into a single spectra.') + + self.declareProperty(name='Instrument', defaultValue='IRIS', + validator=StringListValidator(['IRIS', 'OSIRIS', 'TOSCA', 'VESUVIO']), + doc='Instrument used for run') + + self.declareProperty(name='Mode', defaultValue='diffspec', + validator=StringListValidator(['diffspec', 'diffonly']), + doc='Diffraction mode used') + + self.declareProperty(IntArrayProperty(name='DetectorRange'), + doc='Range of detectors to use.') + + self.declareProperty(name='RebinParam', defaultValue='', + doc='Rebin parameters.') + + self.declareProperty(WorkspaceGroupProperty('OutputWorkspaceGroup', '', + direction=Direction.Output, optional=PropertyMode.Optional), + doc='Optionally group the result workspaces.') + + self.declareProperty(StringArrayProperty(name='SaveFormats'), + doc='Save formats to save output in.') + + def validateInputs(self): + """ + Checks for issues with user input. + """ + issues = dict() + + # Validate input files + input_files = self.getProperty('InputFiles').value + if len(input_files) == 0: + issues['InputFiles'] = 'InputFiles must contain at least one filename' + + # Validate detector range + detector_range = self.getProperty('DetectorRange').value + if len(detector_range) != 2: + issues['DetectorRange'] = 'DetectorRange must be an array of 2 values only' + else: + if detector_range[0] > detector_range[1]: + issues['DetectorRange'] = 'DetectorRange must be in format [lower_index,upper_index]' + + # Validate save formats + save_formats = self.getProperty('SaveFormats').value + valid_formats = ['gss', 'nxs', 'ascii'] + for s_format in save_formats: + if s_format not in valid_formats: + issues['SaveFormats'] = 'Contains invalid save formats' + break + + return issues + + 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 + instrument_name = self.getPropertyValue('Instrument') + mode = self.getPropertyValue('Mode') + detector_range = self.getProperty('DetectorRange').value + rebin_string = self.getPropertyValue('RebinParam') + output_ws_group = self.getPropertyValue('OutputWorkspaceGroup') + save_formats = self.getProperty('SaveFormats').value + + ipf_filename = instrument_name + '_diffraction_' + mode + '_Parameters.xml' + + reducer = MSGDiffractionReducer() + reducer.set_instrument_name(instrument_name) + reducer.set_detector_range(int(detector_range[0] - 1), int(detector_range[1] - 1)) + reducer.set_parameter_file(ipf_filename) + reducer.set_sum_files(sum_files) + reducer.set_save_formats(save_formats) + + if individual_grouping: + reducer.set_grouping_policy('Individual') + + for in_file in input_files: + reducer.append_data_file(in_file) + + if rebin_string != '': + reducer.set_rebin_string(rebin_string) + + if instrument_name == 'VESUVIO': + reducer.append_load_option('Mode', 'FoilOut') + + reducer.reduce() + + if output_ws_group != '': + result_ws_list = reducer.get_result_workspaces() + GroupWorkspaces(InputWorkspaces=result_ws_list, OutputWorkspace=output_ws_group) + self.setProperty('OutputWorkspaceGroup', 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 new file mode 100644 index 000000000000..b3b68ebf9d25 --- /dev/null +++ b/Code/Mantid/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/MolDyn.py @@ -0,0 +1,591 @@ +from mantid.simpleapi import * +from mantid.kernel import * +from mantid.api import * + +import os +import numpy as np +import math + + +def _split_line(a): + elements = a.split() # split line on character + extracted = [] + for n in elements: + extracted.append(float(n)) + return extracted # values as list + +def _find_starts(data, c, l1): + for l in range(l1, len(data)): + char = data[l] + if char.startswith(c): + line = l + break + return line + +def _find_tab_starts(data, c, l1): + for l in range(l1, len(data)): + char = data[l][1:] + if char.startswith(c): + line = l + break + return line + +def _find_ends(data, c, l1): + for l in range(l1, len(data)): + char = data[l] + if char.endswith(c): + line = l + break + return line + +def _find_char(data, c, l1): + for l in range(l1, len(data)): + char = data[l] + if char.find(c): + line = l + break + return line + +def _make_list(a, l1, l2): + data = '' + for m in range(l1, l2 + 1): + data += a[m] + alist = data.split(',') + return alist + + +class MolDyn(PythonAlgorithm): + + def category(self): + return 'Workflow\\Inelastic;PythonAlgorithms;Inelastic' + + def summary(self): + return 'Imports nMOLDYN simulations from CDL and ASCII files.' + + def PyInit(self): + self.declareProperty(FileProperty('Filename', '', + action=FileAction.OptionalLoad, + extensions=['.cdl', '.dat']), + doc='File path for data') + + self.declareProperty(StringArrayProperty('Functions'), + doc='The Function to use') + + self.declareProperty(WorkspaceProperty('Resolution', '', Direction.Input, PropertyMode.Optional), + doc='Resolution workspace') + + self.declareProperty(name='MaxEnergy', defaultValue='', + doc='Crop the result spectra at a given energy (leave blank for no crop)') + + self.declareProperty(name='Plot', defaultValue='None', + validator=StringListValidator(['None', 'Spectra', 'Contour', 'Both']), + doc='Plot result workspace') + + self.declareProperty(name='Verbose', defaultValue=False, + doc='Output more verbose message to log') + + self.declareProperty(name='Save', defaultValue=False, + doc='Save result workspace to nexus file in the default save directory') + + self.declareProperty(WorkspaceProperty('OutputWorkspace', '', Direction.Output), + doc='Output workspace name') + + + def validateInputs(self): + issues = dict() + + sample_filename = self.getPropertyValue('Filename') + function_list = self.getProperty('Functions').value + res_ws = self.getPropertyValue('Resolution') + e_max = self.getPropertyValue('MaxEnergy') + + if len(function_list) == 0 and os.path.splitext(sample_filename)[1] == 'cdl': + issues['Functions'] = 'Must specify at least one function when loading a CDL file' + + if len(function_list) > 0 and os.path.splitext(sample_filename)[1] == 'dat': + issues['Functions'] = 'Cannot specify functions when loading an ASCII file' + + if res_ws is not '' and e_max is '': + issues['MaxEnergy'] = 'MaxEnergy must be set when convolving with an instrument resolution' + + return issues + + + def PyExec(self): + from IndirectImport import import_mantidplot + + self._mtd_plot = import_mantidplot() + + # Do setup + self._setup() + + # Load data file + data, name, ext = self._load_file() + + # Run nMOLDYN import + if ext == 'cdl': + self._cdl_import(data, name) + elif ext == 'dat': + self._ascii_import(data, name) + else: + raise RuntimeError('Unrecognised file format: %s' % ext) + + # Do convolution if given a resolution workspace + if self._res_ws is not '': + # Create a workspace with enough spectra for convolution + num_sample_hist = mtd[self._out_ws].getItem(0).getNumberHistograms() + resolution_ws = self._create_res_ws(num_sample_hist) + + # Convolve all workspaces in output group + for ws_name in mtd[self._out_ws].getNames(): + if ws_name.lower().find('sqw') != -1: + self._convolve_with_res(resolution_ws, ws_name) + else: + if self._verbose: + logger.notice('Ignoring workspace %s in convolution step' % ws_name) + + # Remove the generated resolution workspace + DeleteWorkspace(resolution_ws) + + # Do energy crop + if self._emax is not None: + self._energy_crop() + + # Save result workspace group + if self._save: + workdir = config['defaultsave.directory'] + out_filename = os.path.join(workdir, self._out_ws + '.nxs') + if self._verbose: + logger.information('Creating file: %s' % out_filename) + SaveNexus(InputWorkspace=self._out_ws, Filename=out_filename) + + # Set the output workspace + self.setProperty('OutputWorkspace', self._out_ws) + + # Plot spectra plots + if self._plot == 'Spectra' or self._plot == 'Both': + if isinstance(mtd[self._out_ws], WorkspaceGroup): + for ws_name in mtd[self._out_ws].getNames(): + self._plot_spectra(ws_name) + else: + self._plot_spectra(self._out_ws) + + # Plot contour plot + if self._plot == 'Contour' or self._plot == 'Both': + self._mtd_plot.plot2D(self._out_ws) + + + def _setup(self): + """ + Gets algorithm properties. + """ + + self._verbose = self.getProperty('Verbose').value + self._plot = self.getProperty('Plot').value + self._save = self.getProperty('Save').value + + self._sam_path = self.getPropertyValue('Filename') + + raw_functions = self.getProperty('Functions').value + self._functions = [x.strip() for x in raw_functions] + + emax_str = self.getPropertyValue('MaxEnergy') + self._emax = None + if emax_str != '': + self._emax = float(emax_str) + + self._res_ws = self.getPropertyValue('Resolution') + self._out_ws = self.getPropertyValue('OutputWorkspace') + + + def _load_file(self): + """ + Attempts to load the sample file. + + @returns A tuple with the ASCII data, sample file name and file extension + """ + + # Get some data about the file + path = self._sam_path + base = os.path.basename(path) + name = os.path.splitext(base)[0] + ext = os.path.splitext(path)[1] + + # Remove dot from extension + if len(ext) > 1: + ext = ext[1:] + + if self._verbose: + logger.information('Base filename for %s is %s' % (self._sam_path, name)) + logger.information('File type of %s is %s' % (self._sam_path, ext)) + + if not os.path.isfile(path): + path = FileFinder.getFullPath(path) + + if self._verbose: + logger.information('Got file path for %s: %s' % (self._sam_path, path)) + + # Open file and get data + try: + handle = open(path, 'r') + data = [] + for line in handle: + line = line.rstrip() + data.append(line) + handle.close() + + return data, name, ext + + except: + raise RuntimeError('Could not load file: %s' % path) + + + def _find_dimensions(self, data): + """ + Gets the number of Q, time and frequency values in given raw data. + + @param data Raw data to search + """ + + num_q_values = _find_tab_starts(data, 'NQVALUES', 0) + num_time_values = _find_tab_starts(data, 'NTIMES', 0) + num_freq_values = _find_tab_starts(data, 'NFREQUENCIES', 0) + + q_el = data[num_q_values].split() + num_q = int(q_el[2]) + t_el = data[num_time_values].split() + num_t = int(t_el[2]) + f_el = data[num_freq_values].split() + num_f = int(f_el[2]) + + if self._verbose: + logger.debug(data[2][1:-1]) + logger.debug(data[3][1:-1]) + logger.debug(data[6][1:-1]) + + return num_q, num_t, num_f + + + def _cdl_import(self, data, name): + """ + Import data from CDL file. + + @param data Raw data + @param name Name of data file + """ + + if self._verbose: + logger.notice('Loading CDL file: %s' % name) + + len_data = len(data) + + # raw head + nQ, nT, nF = self._find_dimensions(data) + ldata = _find_starts(data, 'data:', 0) + lq1 = _find_starts(data, ' q =', ldata) # start Q values + lq2 = _find_starts(data, ' q =', lq1 - 1) + Qlist = _make_list(data, lq1, lq2) + if nQ != len(Qlist): + raise RUntimeError('Error reading Q values') + Qf = Qlist[0].split() + Q = [float(Qf[2]) / 10.0] + for m in range(1, nQ - 1): + Q.append(float(Qlist[m]) / 10.0) + + Q.append(float(Qlist[nQ - 1][:-1]) / 10.0) + if self._verbose: + logger.information('Q values = ' + str(Q)) + + lt1 = _find_starts(data, ' time =', lq2) # start T values + lt2 = _find_ends(data, ';', lt1) + Tlist = _make_list(data, lt1, lt2) + if nT != len(Tlist): + raise RuntimeError('Error reading Time values') + + Tf = Tlist[0].split() + T = [float(Tf[2])] + for m in range(1, nT - 1): + T.append(float(Tlist[m])) + + T.append(float(Tlist[nT - 1][:-1])) + T.append(2 * T[nT - 1] - T[nT - 2]) + if self._verbose: + logger.information('T values = ' + str(T[:2]) + ' to ' + str(T[-3:])) + + lf1 = _find_starts(data, ' frequency =', lq2) # start F values + lf2 = _find_ends(data, ';', lf1) + Flist = _make_list(data, lf1, lf2) + if nF != len(Flist): + raise RuntimeError('Error reading Freq values') + + Ff = Flist[0].split() + F = [float(Ff[2])] + for m in range(1, nF - 1): + F.append(float(Flist[m])) + + F.append(float(Flist[nF - 1][:-1])) + F.append(2 * F[nF - 1] - T[nF - 2]) + if self._verbose: + logger.information('F values = ' + str(F[:2]) + ' to ' + str(F[-3:])) + + # Function + output_ws_list = list() + for func in self._functions: + start = [] + lstart = lt2 + if func[:3] == 'Fqt': + nP = nT + xEn = np.array(T) + eZero = np.zeros(nT) + xUnit = 'TOF' + elif func[:3] == 'Sqw': + nP = nF + xEn = np.array(F) + eZero = np.zeros(nF) + xUnit = 'Energy' + else: + raise RuntimeError('Failed to parse function string ' + func) + + for n in range(0, nQ): + for m in range(lstart, len_data): + char = data[m] + if char.startswith(' // ' + func): + start.append(m) + lstart = m + 1 + lend = _find_ends(data, ';', lstart) + start.append(lend + 1) + + # Throw error if we couldn't find the function + if len(start) < 2: + raise RuntimeError('Failed to parse function string ' + func) + + Qaxis = '' + for n in range(0, nQ): + if self._verbose: + logger.information(str(start)) + logger.information('Reading : ' + data[start[n]]) + + Slist = _make_list(data, start[n] + 1, start[n + 1] - 1) + if n == nQ - 1: + Slist[nP - 1] = Slist[nP - 1][:-1] + S = [] + for m in range(0, nP): + S.append(float(Slist[m])) + if nP != len(S): + raise RuntimeError('Error reading S values') + else: + if self._verbose: + logger.information('S values = ' + str(S[:2]) + ' to ' + str(S[-2:])) + if n == 0: + Qaxis += str(Q[n]) + xDat = xEn + yDat = np.array(S) + eDat = eZero + else: + Qaxis += ',' + str(Q[n]) + xDat = np.append(xDat, xEn) + yDat = np.append(yDat, np.array(S)) + eDat = np.append(eDat, eZero) + outWS = name + '_' + func + CreateWorkspace(OutputWorkspace=outWS, DataX=xDat, DataY=yDat, DataE=eDat, + Nspec=nQ, UnitX=xUnit, VerticalAxisUnit='MomentumTransfer', VerticalAxisValues=Qaxis) + output_ws_list.append(outWS) + + GroupWorkspaces(InputWorkspaces=output_ws_list, OutputWorkspace=self._out_ws) + + + def _ascii_import(self, data, name): + """ + Import ASCII data. + + @param data Raw ASCII data + @param name Name of data file + """ + + from IndirectNeutron import ChangeAngles, InstrParas, RunParas + + if self._verbose: + logger.notice('Loading ASCII data: %s' % name) + + val = _split_line(data[3]) + Q = [] + for n in range(1, len(val)): + Q.append(val[n]) + + nQ = len(Q) + x = [] + y = [] + for n in range(4, len(data)): + val = _split_line(data[n]) + x.append(val[0]) + yval = val[1:] + y.append(yval) + + nX = len(x) + if self._verbose: + logger.information('nQ = ' + str(nQ)) + logger.information('nT = ' + str(nX)) + + xT = np.array(x) + eZero = np.zeros(nX) + Qaxis = '' + for m in range(0, nQ): + if self._verbose: + logger.information('Q[' + str(m + 1) + '] : ' + str(Q[m])) + + S = [] + for n in range(0, nX): + S.append(y[n][m]) + + if m == 0: + Qaxis += str(Q[m]) + xDat = xT + yDat = np.array(S) + eDat = eZero + else: + Qaxis += ',' + str(Q[m]) + xDat = np.append(xDat, xT) + yDat = np.append(yDat, np.array(S)) + eDat = np.append(eDat, eZero) + + CreateWorkspace(OutputWorkspace=self._out_ws, DataX=xDat, DataY=yDat, DataE=eDat, + Nspec=nQ, UnitX='TOF') + Qmax = Q[nQ - 1] + instr = 'MolDyn' + ana = 'qmax' + if Qmax <= 2.0: + refl = '2' + else: + refl = '4' + + InstrParas(self._out_ws, instr, ana, refl) + efixed = RunParas(self._out_ws, instr, name, name, self._verbose) + if self._verbose: + logger.information('Qmax = ' + str(Qmax) + ' ; efixed = ' + str(efixed)) + pi4 = 4.0 * math.pi + wave = 1.8 * math.sqrt(25.2429 / efixed) + theta = [] + for n in range(0, nQ): + qw = wave * Q[n] / pi4 + ang = 2.0 * math.degrees(math.asin(qw)) + theta.append(ang) + + ChangeAngles(self._out_ws, instr, theta, self._verbose) + + + def _create_res_ws(self, num_sample_hist): + """ + Creates a resolution workspace. + + @param num_sample_hist Number of histgrams required in workspace + @returns The generated resolution workspace + """ + + num_res_hist = mtd[self._res_ws].getNumberHistograms() + + if self._verbose: + logger.notice('Creating resolution workspace.') + logger.information('Sample has %d spectra\nResolution has %d spectra' + % (num_sample_hist, num_res_hist)) + + # If the sample workspace has more spectra than the resolution then copy the first spectra + # to make a workspace with equal spectra count to sample + if num_sample_hist > num_res_hist: + if self._verbose: + logger.information('Copying first resolution spectra for convolution') + + res_ws_list = [] + for _ in range(0, num_sample_hist): + res_ws_list.append(self._res_ws) + + res_ws_str_list = ','.join(res_ws_list) + resolution_ws = ConjoinSpectra(res_ws_str_list, 0) + + # If sample has less spectra then crop the resolution to the same number of spectra as + # resolution + elif num_sample_hist < num_res_hist: + if self._verbose: + logger.information('Cropping resolution workspace to sample') + + resolution_ws = CropWorkspace(InputWorkspace=self._res_ws, StartWorkspaceIndex=0, + EndWorkspaceIndex=num_sample_hist) + + # If the spectra counts match then just use the resolution as it is + else: + if self._verbose: + logger.information('Using resolution workspace as is') + + resolution_ws = CloneWorkspace(self._res_ws) + + return resolution_ws + + + def _convolve_with_res(self, resolution_ws, function_ws_name): + """ + Performs convolution with an instrument resolution workspace. + + @param resolution_ws The resolution workspace to convolve with + @param function_ws_name The workspace name for the function to convolute + """ + + if self._verbose: + logger.notice('Convoluting sample %s with resolution %s' + % (function_ws_name, resolution_ws)) + + # Symmetrise the sample WS in x=0 as nMOLDYN only gives positive energy values + Symmetrise(Sample=function_ws_name, XMin=0, XMax=self._emax, + Verbose=self._verbose, Plot=False, Save=False, + OutputWorkspace=function_ws_name) + + # Convolve the symmetrised sample with the resolution + ConvolveWorkspaces(OutputWorkspace=function_ws_name, + Workspace1=function_ws_name, Workspace2=resolution_ws) + + + def _energy_crop(self): + """ + For each workspace in the result that has an X unit in Energy, apply + a crop to MaxEnergy + """ + + if self._verbose: + logger.notice('Cropping workspaces in energy to %f' + % self._emax) + + for ws_name in mtd[self._out_ws].getNames(): + if mtd[ws_name].getAxis(0).getUnit().unitID() == 'Energy': + if self._verbose: + logger.debug('Workspace %s has energy on X axis, will crop to %f' + % (ws_name, self._emax)) + + CropWorkspace(InputWorkspace=ws_name, OutputWorkspace=ws_name, + XMax=self._emax) + else: + if self._verbose: + logger.debug('Workspace %s does not have energy on X axis, will not crop.' + % ws_name) + + + def _plot_spectra(self, ws_name): + """ + Plots up to the first 10 spectra from a workspace. + + @param ws_name Name of workspace to plot + """ + + num_hist = mtd[ws_name].getNumberHistograms() + + # Limit number of plotted histograms to 10 + if num_hist > 10: + num_hist = 10 + + # Build plot list + plot_list = [] + for i in range(0, num_hist): + plot_list.append(i) + + self._mtd_plot.plotSpectrum(ws_name, plot_list) + + +# Register algorithm with Mantid +AlgorithmFactory.subscribe(MolDyn) diff --git a/Code/Mantid/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/SofQWMoments.py b/Code/Mantid/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/SofQWMoments.py index 375ef4ef1c7e..88cc2e3dbcaf 100644 --- a/Code/Mantid/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/SofQWMoments.py +++ b/Code/Mantid/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/SofQWMoments.py @@ -112,7 +112,6 @@ def PyExec(self): workdir = getDefaultWorkingDirectory() opath = os.path.join(workdir,output_workspace+'.nxs') SaveNexusProcessed(InputWorkspace=output_workspace, Filename=opath) - if Verbose: logger.notice('Output file : ' + opath) diff --git a/Code/Mantid/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/Symmetrise.py b/Code/Mantid/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/Symmetrise.py deleted file mode 100644 index 94e8e682d788..000000000000 --- a/Code/Mantid/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/Symmetrise.py +++ /dev/null @@ -1,40 +0,0 @@ -# Algorithm to start Symmetrise -from mantid.api import PythonAlgorithm, AlgorithmFactory -from mantid.kernel import StringListValidator, StringMandatoryValidator - -class Symmetrise(PythonAlgorithm): - - def category(self): - return "Workflow\\MIDAS;PythonAlgorithms" - - def summary (self): - return "Takes and asymmetric S(Q,w) and makes it symmetric" - - def PyInit(self): - self.declareProperty(name='InputType',defaultValue='File',validator=StringListValidator(['File','Workspace']), doc='Origin of data input - File (_red.nxs) or Workspace') - self.declareProperty(name='Instrument',defaultValue='iris',validator=StringListValidator(['irs','iris','osi','osiris']), doc='Instrument') - self.declareProperty(name='Analyser',defaultValue='graphite002',validator=StringListValidator(['graphite002','graphite004']), doc='Analyser & reflection') - self.declareProperty(name='SamNumber',defaultValue='',validator=StringMandatoryValidator(), doc='Sample run number') - self.declareProperty(name='Xcut',defaultValue='',validator=StringMandatoryValidator(), doc='X cutoff value') - self.declareProperty('Verbose',defaultValue=True, doc='Switch Verbose Off/On') - self.declareProperty('Plot',defaultValue=True, doc='Switch Plot Off/On') - self.declareProperty('Save',defaultValue=False, doc='Switch Save result to nxs file Off/On') - - def PyExec(self): - - self.log().information('Symmetrise') - inType = self.getPropertyValue('InputType') - prefix = self.getPropertyValue('Instrument') - ana = self.getPropertyValue('Analyser') - sn = self.getPropertyValue('SamNumber') - sam = prefix+sn+'_'+ana+'_red' - cut = self.getPropertyValue('Xcut') - cut = float(cut) - - verbOp = self.getProperty('Verbose').value - plotOp = self.getProperty('Plot').value - saveOp = self.getProperty('Save').value - import IndirectSymm as Main - Main.SymmStart(inType,sam,cut,verbOp,plotOp,saveOp) - -AlgorithmFactory.subscribe(Symmetrise) # Register algorithm with Mantid diff --git a/Code/Mantid/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/TimeSlice.py b/Code/Mantid/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/TimeSlice.py new file mode 100644 index 000000000000..6a6a12ea599b --- /dev/null +++ b/Code/Mantid/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/TimeSlice.py @@ -0,0 +1,278 @@ +from mantid.kernel import * +from mantid.api import * +from mantid.simpleapi import * + +import os + + +def _count_monitors(raw_file): + """ + Returns the number of monitors and if they're at the start or end of the file + """ + + raw_file = mtd[raw_file] + num_hist = raw_file.getNumberHistograms() + detector = raw_file.getDetector(0) + mon_count = 1 + + if detector.isMonitor(): + # Monitors are at the start + for i in range(1, num_hist): + detector = raw_file.getDetector(i) + + if detector.isMonitor(): + mon_count += 1 + else: + break + + return mon_count, True + else: + # Monitors are at the end + detector = raw_file.getDetector(num_hist) + + if not detector.isMonitor(): + #if it's not, we don't have any monitors! + return 0, True + + for i in range(num_hist, 0, -1): + detector = raw_file.getDetector(i) + + if detector.isMonitor(): + mon_count += 1 + else: + break + + return mon_count, False + + +class TimeSlice(PythonAlgorithm): + + def category(self): + return 'PythonAlgorithms;Inelastic' + + + def summary(self): + return 'Performa an integration on a raw file over a specified time of flight range' + + + def PyInit(self): + self.declareProperty(StringArrayProperty(name='InputFiles'), + doc='Comma separated list of input files') + + self.declareProperty(WorkspaceProperty(name='CalibrationWorkspace', defaultValue='', + direction=Direction.Input, optional=PropertyMode.Optional), + doc='Calibration workspace') + + self.declareProperty(IntArrayProperty(name='SpectraRange'), + doc='Range of spectra to use') + + self.declareProperty(FloatArrayProperty(name='PeakRange'), + doc='Peak range in time of flight') + + self.declareProperty(FloatArrayProperty(name='BackgroundRange'), + doc='Background range in time of flight') + + self.declareProperty(name='Verbose', defaultValue=False, + doc='Output more messages to results log') + + self.declareProperty(name='Plot', defaultValue=False, + doc='Plot result workspaces') + + self.declareProperty(name='Save', defaultValue=False, + doc='Save result workspaces as nexus files to default save directory') + + self.declareProperty(name='OutputNameSuffix', defaultValue='_slice', + doc='Suffix to append to raw file name for name of output workspace') + + self.declareProperty(WorkspaceGroupProperty(name='OutputWorkspaceGroup', defaultValue='', + optional=PropertyMode.Optional, direction=Direction.Output), + doc='Name of workspace group to group result workspaces into') + + + def _validate_range(self, name): + """ + Validates a range property + + @param name Name of the property + """ + + range_prop = self.getProperty(name).value + + if len(range_prop) != 2: + return 'Range must have two values' + + if range_prop[0] > range_prop[1]: + return 'Range must be in format "low,high"' + + return '' + + + def validateInput(self): + issues = dict() + + issues['SpectraRange'] = self._validate_range('SpectraRange') + issues['PeakRange'] = self._validate_range('PeakRange') + + if self.getPropertyValue('BackgroundRange') != '': + issues['BackgroundRange'] = self._validate_range('BackgroundRange') + + return issues + + + def PyExec(self): + from IndirectCommon import CheckXrange + + self._setup() + + # CheckXrange(xRange, 'Time') + out_ws_list = [] + + for index, filename in enumerate(self._raw_files): + raw_file = self._read_raw_file(filename) + + # Only need to process the calib file once + if index == 0 and self._calib_ws is not None: + self._process_calib(raw_file) + + slice_file = self._process_raw_file(raw_file) + Transpose(InputWorkspace=slice_file, OutputWorkspace=slice_file) + unit = mtd[slice_file].getAxis(0).setUnit("Label") + unit.setLabel("Spectrum Number", "") + + out_ws_list.append(slice_file) + DeleteWorkspace(raw_file) + + if self._save: + work_dir = config['defaultsave.directory'] + save_path = os.path.join(work_dir, slice_file + '.nxs') + SaveNexusProcessed(InputWorkspace=slice_file, Filename=save_path) + + if self._verbose: + logger.notice('Output file :' + save_path) + + if self._out_ws_group is not None: + all_workspaces = ','.join(out_ws_list) + GroupWorkspaces(InputWorkspaces=all_workspaces, OutputWorkspace=self._out_ws_group) + + if self._plot: + try: + from IndirectImport import import_mantidplot + mp = import_mantidplot() + mp.plotSpectrum(slice_file, 0) + except RuntimeError, e: + # User clicked cancel on plot so don't do anything + pass + + + def _setup(self): + """ + Gets properties. + """ + + self._raw_files = self.getProperty('InputFiles').value + self._spectra_range = self.getProperty('SpectraRange').value + self._peak_range = self.getProperty('PeakRange').value + self._output_ws_name_suffix = self.getPropertyValue('OutputNameSuffix') + + self._background_range = self.getProperty('BackgroundRange').value + if len(self._background_range) == 0: + self._background_range = None + + self._calib_ws = self.getPropertyValue('CalibrationWorkspace') + if self._calib_ws == '': + self._calib_ws = None + + self._out_ws_group = self.getPropertyValue('OutputWorkspaceGroup') + if self._out_ws_group == '': + self._out_ws_group = None + + self._verbose = self.getProperty('Verbose').value + self._plot = self.getProperty('Plot').value + self._save = self.getProperty('Save').value + + + def _read_raw_file(self, filename): + """ + Loads a raw run file. + + @param filename Data file name + @returns Name of workspace loaded into + """ + + if self._verbose: + logger.notice('Reading file :' + filename) + + # Load the raw file + f_name = os.path.split(filename)[1] + workspace_name = os.path.splitext(f_name)[0] + + Load(Filename=filename, OutputWorkspace=workspace_name, LoadLogFiles=False) + + return workspace_name + + + def _process_calib(self, raw_file): + """ + Run the calibration file with the raw file workspace. + + @param raw_file Name of calibration file + """ + + calib_spec_min = int(self._spectra_range[0]) + calib_spec_max = int(self._spectra_range[1]) + + if calib_spec_max - calib_spec_min > mtd[self._calib_ws].getNumberHistograms(): + raise IndexError('Number of spectra used is greater than the number of spectra in the calibration file.') + + # Offset cropping range to account for monitors + (mon_count, at_start) = _count_monitors(raw_file) + + if at_start: + calib_spec_min -= mon_count + 1 + calib_spec_max -= mon_count + 1 + + # Crop the calibration workspace, excluding the monitors + CropWorkspace(InputWorkspace=self._calib_ws, OutputWorkspace=self._calib_ws, + StartWorkspaceIndex=calib_spec_min, EndWorkspaceIndex=calib_spec_max) + + + def _process_raw_file(self, raw_file): + """ + Process a raw sample file. + + @param raw_file Name of file to process + """ + from IndirectCommon import CheckHistZero + + # Crop the raw file to use the desired number of spectra + # less one because CropWorkspace is zero based + CropWorkspace(InputWorkspace=raw_file, OutputWorkspace=raw_file, + StartWorkspaceIndex=int(self._spectra_range[0]) - 1, + EndWorkspaceIndex=int(self._spectra_range[1]) - 1) + + num_hist = CheckHistZero(raw_file)[0] + + # Use calibration file if desired + if self._calib_ws is not None: + Divide(LHSWorkspace=raw_file, RHSWorkspace=self._calib_ws, OutputWorkspace=raw_file) + + # Construct output workspace name + run = mtd[raw_file].getRun().getLogData('run_number').value + slice_file = raw_file[:3].lower() + run + self._output_ws_name_suffix + + if self._background_range is None: + Integration(InputWorkspace=raw_file, OutputWorkspace=slice_file, + RangeLower=self._peak_range[0], RangeUpper=self._peak_range[1], + StartWorkspaceIndex=0, EndWorkspaceIndex=num_hist - 1) + else: + CalculateFlatBackground(InputWorkspace=raw_file, OutputWorkspace=slice_file, + StartX=self._background_range[0], EndX=self._background_range[1], + Mode='Mean') + Integration(InputWorkspace=slice_file, OutputWorkspace=slice_file, + RangeLower=self._peak_range[0], RangeUpper=self._peak_range[1], + StartWorkspaceIndex=0, EndWorkspaceIndex=num_hist - 1) + + return slice_file + + +AlgorithmFactory.subscribe(TimeSlice) diff --git a/Code/Mantid/Framework/PythonInterface/test/python/mantid/geometry/CMakeLists.txt b/Code/Mantid/Framework/PythonInterface/test/python/mantid/geometry/CMakeLists.txt index dc670926c537..e62846514130 100644 --- a/Code/Mantid/Framework/PythonInterface/test/python/mantid/geometry/CMakeLists.txt +++ b/Code/Mantid/Framework/PythonInterface/test/python/mantid/geometry/CMakeLists.txt @@ -10,6 +10,9 @@ set ( TEST_PY_FILES RectangularDetectorTest.py ReferenceFrameTest.py UnitCellTest.py + PointGroupTest.py + SpaceGroupTest.py + SymmetryOperationTest.py ) check_tests_valid ( ${CMAKE_CURRENT_SOURCE_DIR} ${TEST_PY_FILES} ) diff --git a/Code/Mantid/Framework/PythonInterface/test/python/mantid/geometry/PointGroupTest.py b/Code/Mantid/Framework/PythonInterface/test/python/mantid/geometry/PointGroupTest.py new file mode 100644 index 000000000000..358491f5964b --- /dev/null +++ b/Code/Mantid/Framework/PythonInterface/test/python/mantid/geometry/PointGroupTest.py @@ -0,0 +1,47 @@ +import unittest +from mantid.geometry import PointGroup, PointGroupFactoryImpl +from mantid.kernel import V3D + +class PointGroupTest(unittest.TestCase): + + def test_creation(self): + self.assertRaises(RuntimeError, PointGroupFactoryImpl.Instance().createPointGroup, "none") + + PointGroupFactoryImpl.Instance().createPointGroup("m-3m") + + def test_getInfo(self): + pg = PointGroupFactoryImpl.Instance().createPointGroup("m-3m") + self.assertEquals(pg.getName(), "m-3m (Cubic)") + self.assertEquals(pg.getSymbol(), "m-3m") + self.assertEquals(pg.crystalSystem(), PointGroup.CrystalSystem.Cubic) + + def test_isEquivalent(self): + hkl1 = V3D(1, 1, 1) + hkl2 = V3D(-1, -1, -1) + hkl3 = V3D(-1, -1, 2) + + pg = PointGroupFactoryImpl.Instance().createPointGroup("m-3m") + self.assertTrue(pg.isEquivalent(hkl1, hkl2)) + self.assertFalse(pg.isEquivalent(hkl1, hkl3)) + + def test_getEquivalents(self): + hkl1 = V3D(1, 0, 0) + hkl2 = V3D(-1, 0, 0) + + pg = PointGroupFactoryImpl.Instance().createPointGroup("-1") + equivalents = pg.getEquivalents(hkl1) + + self.assertTrue(hkl1 in equivalents) + self.assertTrue(hkl2 in equivalents) + + self.assertEquals(len(equivalents), 2) + + def test_getReflectionFamily(self): + hkl1 = V3D(0, 0, 1) + hkl2 = V3D(-1, 0, 0) + + pg = PointGroupFactoryImpl.Instance().createPointGroup("m-3m") + self.assertEquals(pg.getReflectionFamily(hkl1), pg.getReflectionFamily(hkl2)) + +if __name__ == '__main__': + unittest.main() \ No newline at end of file diff --git a/Code/Mantid/Framework/PythonInterface/test/python/mantid/geometry/SpaceGroupTest.py b/Code/Mantid/Framework/PythonInterface/test/python/mantid/geometry/SpaceGroupTest.py new file mode 100644 index 000000000000..db6e8a16261d --- /dev/null +++ b/Code/Mantid/Framework/PythonInterface/test/python/mantid/geometry/SpaceGroupTest.py @@ -0,0 +1,31 @@ +import unittest +from mantid.geometry import SpaceGroup, SpaceGroupFactoryImpl + +class SpaceGroupTest(unittest.TestCase): + + def test_creation(self): + self.assertRaises(ValueError, SpaceGroupFactoryImpl.Instance().createSpaceGroup, "none") + + SpaceGroupFactoryImpl.Instance().createSpaceGroup("I m -3 m") + + def test_interface(self): + spaceGroup = SpaceGroupFactoryImpl.Instance().createSpaceGroup("P -1") + self.assertEquals(spaceGroup.hmSymbol(), "P -1") + self.assertEquals(spaceGroup.order(), 2) + + symOpStrings = spaceGroup.getSymmetryOperationStrings() + + self.assertEqual(len(symOpStrings), 2) + self.assertTrue("x,y,z" in symOpStrings) + self.assertTrue("-x,-y,-z" in symOpStrings) + + def test_equivalentPositions(self): + spaceGroup = SpaceGroupFactoryImpl.Instance().createSpaceGroup("P -1") + + position = [0.34, 0.3, 0.4] + equivalentPositions = spaceGroup.getEquivalentPositions(position) + + self.assertEqual(len(equivalentPositions), 2) + +if __name__ == '__main__': + unittest.main() \ No newline at end of file diff --git a/Code/Mantid/Framework/PythonInterface/test/python/mantid/geometry/SymmetryOperationTest.py b/Code/Mantid/Framework/PythonInterface/test/python/mantid/geometry/SymmetryOperationTest.py new file mode 100644 index 000000000000..453b2be7ec45 --- /dev/null +++ b/Code/Mantid/Framework/PythonInterface/test/python/mantid/geometry/SymmetryOperationTest.py @@ -0,0 +1,28 @@ +import unittest +from mantid.geometry import SymmetryOperation, SymmetryOperationFactoryImpl +from mantid.kernel import V3D + +class SymmetryOperationTest(unittest.TestCase): + + def test_creation(self): + self.assertRaises(RuntimeError, SymmetryOperationFactoryImpl.Instance().createSymOp, "none") + + SymmetryOperationFactoryImpl.Instance().createSymOp("x,y,-z") + + def test_getInfo(self): + symOp = SymmetryOperationFactoryImpl.Instance().createSymOp("x, y, -z") + self.assertEquals(symOp.order(), 2) + self.assertEquals(symOp.identifier(), "x,y,-z") + + def test_apply(self): + symOp = SymmetryOperationFactoryImpl.Instance().createSymOp("x,y,-z") + + hkl1 = V3D(1, 1, 1) + hkl2 = symOp.apply(hkl1) + + self.assertEquals(hkl2, V3D(1, 1, -1)) + self.assertEquals(symOp.apply(hkl2), hkl1) + + +if __name__ == '__main__': + unittest.main() \ No newline at end of file diff --git a/Code/Mantid/Framework/PythonInterface/test/python/mantid/kernel/V3DTest.py b/Code/Mantid/Framework/PythonInterface/test/python/mantid/kernel/V3DTest.py index 4bdc8f3b4593..cead6c3fee99 100644 --- a/Code/Mantid/Framework/PythonInterface/test/python/mantid/kernel/V3DTest.py +++ b/Code/Mantid/Framework/PythonInterface/test/python/mantid/kernel/V3DTest.py @@ -95,7 +95,14 @@ def test_directionAngles(self): self.assertAlmostEquals(math.acos(1.0/math.sqrt(3.0)) * 180 / math.pi, angles.Y()) self.assertAlmostEquals(math.acos(1.0/math.sqrt(3.0)) * 180 / math.pi, angles.Z()) + def test_hash(self): + v1 = V3D(1, 1, 1) + v2 = V3D(1, 1, 1) + v3 = V3D(1, 0, 0) + a = set([v1, v2, v3]) + + self.assertEquals(len(a), 2) if __name__ == '__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 f1a60d76c0b6..582f2cc6ecd2 100644 --- a/Code/Mantid/Framework/PythonInterface/test/python/plugins/algorithms/CMakeLists.txt +++ b/Code/Mantid/Framework/PythonInterface/test/python/plugins/algorithms/CMakeLists.txt @@ -7,6 +7,7 @@ set ( TEST_PY_FILES ConjoinSpectraTest.py CorrectLogTimesTest.py CreateLeBailFitInputTest.py + CreateCalibrationWorkspaceTest.py CreateWorkspaceTest.py DakotaChiSquaredTest.py DensityOfStatesTest.py @@ -15,7 +16,9 @@ set ( TEST_PY_FILES FindReflectometryLinesTest.py GetEiT0atSNSTest.py IndirectILLReductionTest.py + InelasticIndirectReductionTest.py IndirectTransmissionTest.py + IndirectTransmissionMonitorTest.py LoadFullprofFileTest.py LoadLiveDataTest.py LoadLogPropertyTableTest.py @@ -25,6 +28,7 @@ set ( TEST_PY_FILES MaskWorkspaceToCalFileTest.py MeanTest.py MergeCalFilesTest.py + MolDynTest.py PDDetermineCharacterizationsTest.py RetrieveRunInfoTest.py SANSWideAngleCorrectionTest.py @@ -37,8 +41,10 @@ set ( TEST_PY_FILES Stitch1DManyTest.py SuggestTibCNCSTest.py SuggestTibHYSPECTest.py + SymmetriseTest.py UpdatePeakParameterTableValueTest.py SANSSubtractTest.py + TimeSliceTest.py ExportSampleLogsToCSVFileTest.py ExportExperimentLogTest.py PoldiMergeTest.py diff --git a/Code/Mantid/Framework/PythonInterface/test/python/plugins/algorithms/CreateCalibrationWorkspaceTest.py b/Code/Mantid/Framework/PythonInterface/test/python/plugins/algorithms/CreateCalibrationWorkspaceTest.py new file mode 100644 index 000000000000..ced70c8a2ab1 --- /dev/null +++ b/Code/Mantid/Framework/PythonInterface/test/python/plugins/algorithms/CreateCalibrationWorkspaceTest.py @@ -0,0 +1,19 @@ +import unittest +import mantid +from mantid.simpleapi import CreateCalibrationWorkspace + + +class CreateCalibrationWorkspaceTest(unittest.TestCase): + + def test_simple(self): + cal_ws = CreateCalibrationWorkspace(InputFiles='IRS38633.raw', + DetectorRange=[3,53], + PeakRange=[62000,65000], + BackgroundRange=[59000,61000]) + + self.assertEqual(cal_ws.getNumberHistograms(), 51) + self.assertEqual(cal_ws.blocksize(), 1) + + +if __name__ == "__main__": + unittest.main() diff --git a/Code/Mantid/Framework/PythonInterface/test/python/plugins/algorithms/IndirectTransmissionMonitorTest.py b/Code/Mantid/Framework/PythonInterface/test/python/plugins/algorithms/IndirectTransmissionMonitorTest.py new file mode 100644 index 000000000000..76065d62623c --- /dev/null +++ b/Code/Mantid/Framework/PythonInterface/test/python/plugins/algorithms/IndirectTransmissionMonitorTest.py @@ -0,0 +1,54 @@ +import unittest +import os +import mantid +from mantid.simpleapi import * + + +class IndirectTransmissionMonitorTest(unittest.TestCase): + + def setUp(self): + self._sample_workspace = 'IndirectTransmissionMonitorTest_sample' + self._can_workspace = 'IndirectTransmissionMonitorTest_can' + + Load(Filename='IRS26176.RAW', OutputWorkspace=self._sample_workspace) + Load(Filename='IRS26173.RAW', OutputWorkspace=self._can_workspace) + + self.kwargs = {} + self.kwargs['SampleWorkspace'] = self._sample_workspace + self.kwargs['CanWorkspace'] = self._can_workspace + self.kwargs['Verbose'] = True + self.kwargs['Plot'] = False + + def tearDown(self): + # Clean up saved nexus files + path = os.path.join(config['defaultsave.directory'], 'IndirectTransmissionMonitorTest.nxs') + if os.path.isfile(path): + try: + os.remove(path) + except IOError, _: + pass + + def test_basic(self): + trans_workspace = IndirectTransmissionMonitor(**self.kwargs) + + self.assertTrue(isinstance(trans_workspace, mantid.api.WorkspaceGroup), msg='Result should be a workspace group') + self.assertEqual(trans_workspace.size(), 3, msg='Transmission workspace group should have 3 workspaces: sample, can and transfer') + + expected_names = set() + expected_names.add(self._sample_workspace + '_Can') + expected_names.add(self._sample_workspace + '_Sam') + expected_names.add(self._sample_workspace + '_Trans') + self.assertEqual(set(trans_workspace.getNames()), expected_names) + + + def test_nexus_save(self): + self.kwargs['Save'] = True + self.kwargs['OutputWorkspace'] = 'IndirectTransmissionMonitorTest' + + IndirectTransmissionMonitor(**self.kwargs) + + path = os.path.join(config['defaultsave.directory'], 'IndirectTransmissionMonitorTest.nxs') + self.assertTrue(os.path.isfile(path), msg='Transmission workspace should be saved to default save directory') + +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 new file mode 100644 index 000000000000..860dde95c5a1 --- /dev/null +++ b/Code/Mantid/Framework/PythonInterface/test/python/plugins/algorithms/InelasticIndirectReductionTest.py @@ -0,0 +1,22 @@ +import unittest +from mantid import mtd +from mantid.simpleapi import InelasticIndirectReduction + + +class InelasticIndirectReductionTest(unittest.TestCase): + + def test_basic(self): + InelasticIndirectReduction(InputFiles='IRS26176.RAW', + OutputWorkspaceGroup='IndirectReductions', + Instrument='IRIS', + Analyser='graphite', + Reflection='002', + DetectorRange=[3, 53], + SaveFormats=['nxs']) + + reduction_workspace = mtd['IndirectReductions'].getItem(0) + self.assertEquals(reduction_workspace.getName(), 'irs26176_graphite002_red') + + +if __name__ == "__main__": + unittest.main() diff --git a/Code/Mantid/Framework/PythonInterface/test/python/plugins/algorithms/MolDynTest.py b/Code/Mantid/Framework/PythonInterface/test/python/plugins/algorithms/MolDynTest.py new file mode 100644 index 000000000000..3f85912fb21d --- /dev/null +++ b/Code/Mantid/Framework/PythonInterface/test/python/plugins/algorithms/MolDynTest.py @@ -0,0 +1,72 @@ +import unittest +from mantid.simpleapi import * +from mantid.api import * + + +class MolDynTest(unittest.TestCase): + + def test_loadFqt(self): + # Load an Fwt function from a nMOLDYN file + moldyn_group = MolDyn(Filename='NaF_DISF.cdl', Functions=['Fqt-total']) + + # A workspace should exist in this name format + self.assertTrue(mtd.doesExist('NaF_DISF_Fqt-total')) + + # X axis should be in TOF for an Fqt function + units = mtd['NaF_DISF_Fqt-total'].getAxis(0).getUnit().unitID() + self.assertEqual(units, 'TOF') + + + def test_loadSqw(self): + # Load an Sqw function from a nMOLDYN file + moldyn_group = MolDyn(Filename='NaF_DISF.cdl', Functions=['Sqw-total']) + + # A workspace should exist in this name format + self.assertTrue(mtd.doesExist('NaF_DISF_Sqw-total')) + + # X axis should be in Energy for an Sqw function + units = mtd['NaF_DISF_Sqw-total'].getAxis(0).getUnit().unitID() + self.assertEqual(units, 'Energy') + + + def test_loadSqwWithEMax(self): + # Load an Sqw function from a nMOLDYN file + moldyn_group = MolDyn(Filename='NaF_DISF.cdl', Functions=['Sqw-total'], MaxEnergy="1.0") + + # A workspace should exist in this name format + self.assertTrue(mtd.doesExist('NaF_DISF_Sqw-total')) + + # Get max enery from result workspace + x_data = mtd['NaF_DISF_Sqw-total'].dataX(0) + x_max = x_data[len(x_data) - 1] + + # Check that it is less that what was passed to algorithm + self.assertTrue(x_max <= 1.0) + + + def test_loadSqwWithRes(self): + # Create a sample workspace thet looks like an instrument resolution + sample_res = CreateSampleWorkspace(NumBanks=1, BankPixelWidth=1, XUnit='Energy', XMin=-10, XMax=10, BinWidth=0.1) + + # Load an Sqw function from a nMOLDYN file + moldyn_group = MolDyn(Filename='NaF_DISF.cdl', Functions=['Sqw-total'], MaxEnergy="1.0", Resolution=sample_res) + + # A workspace should exist in this name format + self.assertTrue(mtd.doesExist('NaF_DISF_Sqw-total')) + + + def test_loadSqwWithResWithNoEMaxFails(self): + """ + Tests that trying to use an instrument resolution without a Max Energy will fail. + """ + + # Create a sample workspace thet looks like an instrument resolution + sample_res = CreateSampleWorkspace(NumBanks=1, BankPixelWidth=1, XUnit='Energy', XMin=-10, XMax=10, BinWidth=0.1) + + # Load an Sqw function from a nMOLDYN file + self.assertRaises(RuntimeError, MolDyn, + Filename='NaF_DISF.cdl', Functions=['Sqw-total'], Resolution=sample_res, OutputWorkspace='moldyn_group') + + +if __name__ == '__main__': + unittest.main() diff --git a/Code/Mantid/Framework/PythonInterface/test/python/plugins/algorithms/PoldiMergeTest.py b/Code/Mantid/Framework/PythonInterface/test/python/plugins/algorithms/PoldiMergeTest.py index 97fdde8f1946..d139c7d894b1 100644 --- a/Code/Mantid/Framework/PythonInterface/test/python/plugins/algorithms/PoldiMergeTest.py +++ b/Code/Mantid/Framework/PythonInterface/test/python/plugins/algorithms/PoldiMergeTest.py @@ -25,6 +25,8 @@ def __init__(self, *args): self.badTimingOffset = CreateWorkspace(rightDataBadOffset, ydata, OutputWorkspace="BadTimingOffset") self.badTimingDelta = CreateWorkspace(rightDataBadDelta, ydata, OutputWorkspace="BadTimingDelta") + self.groupGood = GroupWorkspaces(["Base", "GoodTiming"], OutputWorkspace="GoodGroup") + goodProperty = 10.0 badProperty = 20.0 @@ -37,7 +39,7 @@ def __init__(self, *args): self.goodTimingBadProperties.getRun().addProperty(p, badProperty, True) def __runMerge__(self, workspaceNames): - return PoldiMerge(WorkspaceNames=workspaceNames, OutputWorkspace="PoldiMergeOutput") + return PoldiMerge(WorkspaceNames=workspaceNames, OutputWorkspace="PoldiMergeOutput", CheckInstruments=False) def test_happyCase(self): output = self.__runMerge__("Base,GoodTiming") @@ -56,6 +58,23 @@ def test_happyCase(self): DeleteWorkspace("PoldiMergeOutput") + def test_workspaceGroup(self): + output = self.__runMerge__("GoodGroup") + + self.assertTrue(isinstance(output, MatrixWorkspace)) + + dataX = output.dataX(0) + self.assertEqual(dataX[0], 0.0) + self.assertEqual(dataX[-1], 3.0) + self.assertEqual(len(dataX), 4) + + dataY = output.dataY(0) + self.assertEqual(dataY[0], 2.0) + self.assertEqual(dataY[1], 2.0) + self.assertEqual(len(dataY), 4) + + DeleteWorkspace("PoldiMergeOutput") + def test_timingDelta(self): self.assertRaises(RuntimeError, lambda: self.__runMerge__("Base,BadTimingDelta")) self.assertFalse(AnalysisDataService.doesExist("PoldiMergeOutput")) diff --git a/Code/Mantid/Framework/PythonInterface/test/python/plugins/algorithms/SymmetriseTest.py b/Code/Mantid/Framework/PythonInterface/test/python/plugins/algorithms/SymmetriseTest.py new file mode 100644 index 000000000000..fb1d14c7db12 --- /dev/null +++ b/Code/Mantid/Framework/PythonInterface/test/python/plugins/algorithms/SymmetriseTest.py @@ -0,0 +1,90 @@ +import unittest +import numpy as np +from mantid.simpleapi import * +from mantid.api import * + + +def _rayleigh(x, sigma): + return (x / sigma ** 2) * np.exp(-x ** 2 / (2 * sigma ** 2)) + + +def _generate_sample_ws(ws_name): + data_x = np.arange(0, 10, 0.01) + data_y = _rayleigh(data_x, 1) + + CreateWorkspace(DataX=data_x, DataY=data_y, OutputWorkspace=ws_name) + ScaleX(InputWorkspace=ws_name, Factor=-1, Operation="Add", OutputWorkspace=ws_name) # centre the peak over 0 + + return mtd[ws_name] + + +class SymmetriseTest(unittest.TestCase): + + def setUp(self): + self._sample_ws = _generate_sample_ws('symm_test_sample_ws') + + def test_basic(self): + """ + Tests a very minimal execution. + """ + symm_test_out_ws = Symmetrise(Sample=self._sample_ws, + XMin=0.05, XMax=0.2) + + def test_with_spectra_range(self): + """ + Tests running with a given spectra range. + """ + symm_test_out_ws = Symmetrise(Sample=self._sample_ws, + XMin=0.05, XMax=0.2, + SpectraRange=[1, 1]) + + def test_failure_xmin_out_of_range(self): + """ + Tests validation on entering an XMin value lower than the smallest value in the X range. + """ + self.assertRaises(RuntimeError, Symmetrise, + Sample=self._sample_ws, + OutputWOrkspace='__Symmetrise_TestWS', + XMin=-5, XMax=0.2) + + def test_failure_xmax_out_of_range(self): + """ + Tests validation on entering an XMax value greater than the largest value in the X range. + """ + self.assertRaises(RuntimeError, Symmetrise, + Sample=self._sample_ws, + OutputWOrkspace='__Symmetrise_TestWS', + XMin=0.05, XMax=15) + + def test_failure_invalid_x_range(self): + """ + Tests validation on entering an XMax value lower then XMin. + """ + self.assertRaises(RuntimeError, Symmetrise, + Sample=self._sample_ws, + OutputWOrkspace='__Symmetrise_TestWS', + XMin=0.2, XMax=0.1) + + def test_failure_spectra_range_lower(self): + """ + Tests validation on entering a minimum spectra number lower then that of the workspace. + """ + self.assertRaises(RuntimeError, Symmetrise, + Sample=self._sample_ws, + OutputWOrkspace='__Symmetrise_TestWS', + XMin=0.05, XMax=0.2, + SpectraRange=[0, 1]) + + def test_failure_spectra_range_upper(self): + """ + Tests validation on entering a maximum spectra number higher then that of the workspace. + """ + self.assertRaises(RuntimeError, Symmetrise, + Sample=self._sample_ws, + OutputWOrkspace='__Symmetrise_TestWS', + XMin=0.05, XMax=0.2, + SpectraRange=[1, 2]) + + +if __name__ == '__main__': + unittest.main() diff --git a/Code/Mantid/Framework/PythonInterface/test/python/plugins/algorithms/TimeSliceTest.py b/Code/Mantid/Framework/PythonInterface/test/python/plugins/algorithms/TimeSliceTest.py new file mode 100644 index 000000000000..093118b8effe --- /dev/null +++ b/Code/Mantid/Framework/PythonInterface/test/python/plugins/algorithms/TimeSliceTest.py @@ -0,0 +1,47 @@ +import unittest +from mantid.simpleapi import * +from mantid.api import * + +class TimeSliceTest(unittest.TestCase): + + def test_basic(self): + """ + Test to ensure that algorithm completes succesfully. + """ + + TimeSlice(InputFiles=['IRS26173.raw'], + SpectraRange=[3, 53], + PeakRange=[62500, 65000], + BackgroundRange=[59000, 61500]) + + self.assertTrue(mtd.doesExist('irs26173_slice')) + + def test_group(self): + """ + Tests to ensure that result workspaces are goruped correctly. + """ + + TimeSlice(InputFiles=['IRS26173.raw'], + SpectraRange=[3, 53], + PeakRange=[62500, 65000], + BackgroundRange=[59000, 61500], + OutputWorkspaceGroup='SliceTestOut') + + self.assertTrue(mtd.doesExist('SliceTestOut')) + self.assertTrue(mtd.doesExist('irs26173_slice')) + + def test_suffix(self): + """ + Tests to ensure that output names have a suffic appended correctly. + """ + + TimeSlice(InputFiles=['IRS26173.raw'], + SpectraRange=[3, 53], + PeakRange=[62500, 65000], + BackgroundRange=[59000, 61500], + OutputNameSuffix='_graphite002_slice') + + self.assertTrue(mtd.doesExist('irs26173_graphite002_slice')) + +if __name__ == '__main__': + unittest.main() diff --git a/Code/Mantid/Framework/SINQ/inc/MantidSINQ/PoldiUtilities/PoldiInstrumentAdapter.h b/Code/Mantid/Framework/SINQ/inc/MantidSINQ/PoldiUtilities/PoldiInstrumentAdapter.h index 61ff7e428831..b602f307e4d0 100644 --- a/Code/Mantid/Framework/SINQ/inc/MantidSINQ/PoldiUtilities/PoldiInstrumentAdapter.h +++ b/Code/Mantid/Framework/SINQ/inc/MantidSINQ/PoldiUtilities/PoldiInstrumentAdapter.h @@ -42,16 +42,11 @@ namespace Poldi class AbstractDoubleValueExtractor { public: - AbstractDoubleValueExtractor(std::string doubleValueKey) : - m_doubleValueKey(doubleValueKey) - { } + AbstractDoubleValueExtractor() { } virtual ~AbstractDoubleValueExtractor() { } - virtual double operator()(const API::Run &runInformation) const = 0; - -protected: - std::string m_doubleValueKey; + virtual double operator()(const API::Run &runInformation, const std::string &propertyName) const = 0; }; typedef boost::shared_ptr AbstractDoubleValueExtractor_sptr; @@ -59,26 +54,39 @@ typedef boost::shared_ptr AbstractDoubleValueExtra class NumberDoubleValueExtractor : public AbstractDoubleValueExtractor { public: - NumberDoubleValueExtractor(std::string doubleValueKey) : - AbstractDoubleValueExtractor(doubleValueKey) + NumberDoubleValueExtractor() : + AbstractDoubleValueExtractor() { } virtual ~NumberDoubleValueExtractor() { } - virtual double operator()(const API::Run &runInformation) const { - return runInformation.getPropertyValueAsType(m_doubleValueKey); + virtual double operator()(const API::Run &runInformation, const std::string &propertyName) const { + return runInformation.getPropertyValueAsType(propertyName); } }; class VectorDoubleValueExtractor : public AbstractDoubleValueExtractor { public: - VectorDoubleValueExtractor(std::string doubleValueKey) : - AbstractDoubleValueExtractor(doubleValueKey) + VectorDoubleValueExtractor() : + AbstractDoubleValueExtractor() { } virtual ~VectorDoubleValueExtractor() { } - virtual double operator()(const API::Run &runInformation) const { - return runInformation.getPropertyValueAsType >(m_doubleValueKey).front(); + virtual double operator()(const API::Run &runInformation, const std::string &propertyName) const { + return runInformation.getPropertyValueAsType >(propertyName).front(); + } +}; + +class VectorIntValueExtractor : public AbstractDoubleValueExtractor +{ +public: + VectorIntValueExtractor() : + AbstractDoubleValueExtractor() + { } + virtual ~VectorIntValueExtractor() { } + + virtual double operator()(const API::Run &runInformation, const std::string &propertyName) const { + return static_cast(runInformation.getPropertyValueAsType >(propertyName).front()); } }; @@ -92,26 +100,33 @@ class MANTID_SINQ_DLL PoldiInstrumentAdapter PoldiAbstractChopper_sptr chopper() const; PoldiAbstractDetector_sptr detector() const; PoldiSourceSpectrum_sptr spectrum() const; - - static const std::string getChopperSpeedPropertyName(); - + protected: PoldiInstrumentAdapter() { } void initializeFromInstrumentAndRun(const Geometry::Instrument_const_sptr &mantidInstrument, const API::Run &runInformation); void setDetector(const Geometry::Instrument_const_sptr &mantidInstrument); + void setChopper(const Geometry::Instrument_const_sptr &mantidInstrument, const API::Run &runInformation); + double getCleanChopperSpeed(double rawChopperSpeed) const; + double getChopperSpeedFromRun(const API::Run &runInformation) const; + double getChopperSpeedTargetFromRun(const API::Run &runInformation) const; + bool chopperSpeedMatchesTarget(const API::Run &runInformation, double chopperSpeed) const; + + double extractPropertyFromRun(const API::Run &runInformation, const std::string &propertyName) const; + AbstractDoubleValueExtractor_sptr getExtractorForProperty(Kernel::Property *chopperSpeedProperty) const; + void setSpectrum(const Geometry::Instrument_const_sptr &mantidInstrument); - double getChopperSpeedFromRun(const API::Run &runInformation); - AbstractDoubleValueExtractor_sptr getExtractorForProperty(Kernel::Property *chopperSpeedProperty); PoldiAbstractChopper_sptr m_chopper; PoldiAbstractDetector_sptr m_detector; PoldiSourceSpectrum_sptr m_spectrum; static const std::string m_chopperSpeedPropertyName; + static const std::string m_chopperSpeedTargetPropertyName; + static std::map m_extractors; }; diff --git a/Code/Mantid/Framework/SINQ/src/PoldiTruncateData.cpp b/Code/Mantid/Framework/SINQ/src/PoldiTruncateData.cpp index ed88e0fec6a6..ade09e2cc463 100644 --- a/Code/Mantid/Framework/SINQ/src/PoldiTruncateData.cpp +++ b/Code/Mantid/Framework/SINQ/src/PoldiTruncateData.cpp @@ -1,5 +1,5 @@ #include "MantidSINQ/PoldiTruncateData.h" -#include "MantidSINQ/PoldiUtilities/PoldiChopperFactory.h" +#include "MantidSINQ/PoldiUtilities/PoldiInstrumentAdapter.h" namespace Mantid { @@ -41,25 +41,8 @@ const std::string PoldiTruncateData::summary() const { return "Truncate POLDI ti */ void PoldiTruncateData::setChopperFromWorkspace(MatrixWorkspace_const_sptr workspace) { - /* This stuff will be gone once the changes from ticket #9445 have been integrated (PoldiInstrumentAdapter). */ - double chopperSpeed = 0.0; - - try { - chopperSpeed = workspace->run().getPropertyValueAsType >("chopperspeed").front(); - } catch(std::invalid_argument&) { - throw(std::runtime_error("Chopper speed could not be extracted from Workspace '" + workspace->name() + "'. Aborting.")); - } - - // Instrument definition - Instrument_const_sptr poldiInstrument = workspace->getInstrument(); - - // Chopper configuration - PoldiChopperFactory chopperFactory; - PoldiAbstractChopper_sptr chopper(chopperFactory.createChopper(std::string("default-chopper"))); - chopper->loadConfiguration(poldiInstrument); - chopper->setRotationSpeed(chopperSpeed); - - setChopper(chopper); + PoldiInstrumentAdapter poldiInstrument(workspace); + setChopper(poldiInstrument.chopper()); } /** Sets the chopper used for the calculations. diff --git a/Code/Mantid/Framework/SINQ/src/PoldiUtilities/PoldiInstrumentAdapter.cpp b/Code/Mantid/Framework/SINQ/src/PoldiUtilities/PoldiInstrumentAdapter.cpp index 4c824bbf53c1..0eb034d896ac 100644 --- a/Code/Mantid/Framework/SINQ/src/PoldiUtilities/PoldiInstrumentAdapter.cpp +++ b/Code/Mantid/Framework/SINQ/src/PoldiUtilities/PoldiInstrumentAdapter.cpp @@ -16,11 +16,13 @@ using namespace Mantid::API; // Initializing static variables for DoubleValueExtractors const std::string PoldiInstrumentAdapter::m_chopperSpeedPropertyName = "chopperspeed"; +const std::string PoldiInstrumentAdapter::m_chopperSpeedTargetPropertyName = "ChopperSpeedTarget"; std::map PoldiInstrumentAdapter::m_extractors = boost::assign::map_list_of - ("dbl list", boost::static_pointer_cast(boost::make_shared(PoldiInstrumentAdapter::m_chopperSpeedPropertyName))) - ("number", boost::static_pointer_cast(boost::make_shared(PoldiInstrumentAdapter::m_chopperSpeedPropertyName))); + ("dbl list", boost::static_pointer_cast(boost::make_shared())) + ("int list", boost::static_pointer_cast(boost::make_shared())) + ("number", boost::static_pointer_cast(boost::make_shared())); /** Constructor with workspace argument * @@ -48,11 +50,6 @@ PoldiInstrumentAdapter::PoldiInstrumentAdapter(const Instrument_const_sptr &mant PoldiInstrumentAdapter::~PoldiInstrumentAdapter() { } - - const std::string PoldiInstrumentAdapter::getChopperSpeedPropertyName() - { - return PoldiInstrumentAdapter::m_chopperSpeedPropertyName; - } /** Returns the chopper stored in the adapter * @@ -127,7 +124,12 @@ void PoldiInstrumentAdapter::setDetector(const Instrument_const_sptr &mantidInst */ void PoldiInstrumentAdapter::setChopper(const Instrument_const_sptr &mantidInstrument, const Run &runInformation) { - double chopperSpeed = getChopperSpeedFromRun(runInformation); + double rawChopperSpeed = getChopperSpeedFromRun(runInformation); + double chopperSpeed = getCleanChopperSpeed(rawChopperSpeed); + + if(!chopperSpeedMatchesTarget(runInformation, chopperSpeed)) { + throw std::invalid_argument("Chopper speed deviates from target speed."); + } PoldiChopperFactory chopperFactory; m_chopper = PoldiAbstractChopper_sptr(chopperFactory.createChopper(std::string("default-chopper"))); @@ -135,30 +137,105 @@ void PoldiInstrumentAdapter::setChopper(const Instrument_const_sptr &mantidInstr m_chopper->setRotationSpeed(chopperSpeed); } +/** + * Returns a plausible chopper speed + * + * Sometimes the measured chopper speed is off by a few ms, which is a result of + * the measuring method. Since only multiples of 500 are allowed, the speed is + * rounded to the next multiple of 500. + * + * @param rawChopperSpeed :: Raw chopper rotation speed as found in the HDF-file + * @return Next multiple of 500. + */ +double PoldiInstrumentAdapter::getCleanChopperSpeed(double rawChopperSpeed) const +{ + return floor((rawChopperSpeed + 250.0) / 500.0) * 500.0; +} + /** * Extracts the chopper speed from run information * - * This method tries to extract the chopper rotation speed from the run information, using - * an appropriate functor of type AbstractDoubleValueExtractor. + * This method tries to extract the chopper rotation speed from the run information, + * using extractPropertyFromRun with the correct property name. * - * @param runInformation :: Run information that contains a "chopperspeed" property + * @param runInformation :: Run information that contains a property with the chopper speed. * @return Chopper speed as stored in run information */ -double PoldiInstrumentAdapter::getChopperSpeedFromRun(const Run &runInformation) +double PoldiInstrumentAdapter::getChopperSpeedFromRun(const Run &runInformation) const +{ + return extractPropertyFromRun(runInformation, m_chopperSpeedPropertyName); +} + +/** + * Extracts the target chopper speed from run information + * + * Tries to extract the target chopper speed from run information. + * + * @param runInformation :: Run information that contains a property with the target chopper speed. + * @return Target chopper speed as stored in run information + */ +double PoldiInstrumentAdapter::getChopperSpeedTargetFromRun(const Run &runInformation) const +{ + return extractPropertyFromRun(runInformation, m_chopperSpeedTargetPropertyName); +} + +/** + * Checks if the chopper speed matches the target value + * + * If runInformation contains the chopper target speed, this method checks whether the actural speed + * agrees with the target. + * + * If the information is not present, it's most likely an older data file, where this information + * is not available. In this case it is not possible to compare anything, so the function returns + * true for any value of chopperSpeed. + * + * @param runInformation :: Run information that may or may not contain information about chopper target speed. + * @param chopperSpeed :: Chopper speed, "cleaned" by PoldiInstrumentAdapter::getCleanChopperSpeed. + * @return True if speed matches target or information is absent, false otherwise. + */ +bool PoldiInstrumentAdapter::chopperSpeedMatchesTarget(const Run &runInformation, double chopperSpeed) const +{ + try { + double targetChopperSpeed = getChopperSpeedTargetFromRun(runInformation); + + if(fabs(targetChopperSpeed - chopperSpeed) > 1e-4) { + return false; + } + + return true; + } catch(std::runtime_error) { + // Old data files don't have information on target chopper speed. Do nothing. + return true; + } +} + +/** + * Extracts a property from run information + * + * This method extracts the property with the supplied name from the run information, + * using the appropriate AbstractDoubleValueExtractor. If the property is not found, + * an std::runtime_error exception is thrown. If there is no extractor for the requested + * data type, an std::invalid_argument exception is thrown. + * + * @param runInformation :: Run information that cotains the property with propertyName + * @param propertyName :: Property name that should be extracted + * @return Value of property as double + */ +double PoldiInstrumentAdapter::extractPropertyFromRun(const Run &runInformation, const std::string &propertyName) const { - if(!runInformation.hasProperty(m_chopperSpeedPropertyName)) { - throw std::runtime_error("Cannot construct instrument without " + m_chopperSpeedPropertyName + "property in log. Aborting."); + if(!runInformation.hasProperty(propertyName)) { + throw std::runtime_error("Cannot construct instrument without " + propertyName + "-property in log. Aborting."); } - Kernel::Property *chopperSpeedProperty = runInformation.getProperty(m_chopperSpeedPropertyName); + Kernel::Property *property = runInformation.getProperty(propertyName); - AbstractDoubleValueExtractor_sptr extractor = getExtractorForProperty(chopperSpeedProperty); + AbstractDoubleValueExtractor_sptr extractor = getExtractorForProperty(property); if(!extractor) { throw std::invalid_argument("Cannot extract chopper speed from run information."); } - return (*extractor)(runInformation); + return (*extractor)(runInformation, propertyName); } /** @@ -170,7 +247,7 @@ double PoldiInstrumentAdapter::getChopperSpeedFromRun(const Run &runInformation) * @param chopperSpeedProperty :: Property containing the chopper speed * @return Functor of type AbstractDoubleValueExtractor */ -AbstractDoubleValueExtractor_sptr PoldiInstrumentAdapter::getExtractorForProperty(Kernel::Property *chopperSpeedProperty) +AbstractDoubleValueExtractor_sptr PoldiInstrumentAdapter::getExtractorForProperty(Kernel::Property *chopperSpeedProperty) const { if(!chopperSpeedProperty) { throw std::invalid_argument("Cannot process null-Property."); diff --git a/Code/Mantid/Framework/SINQ/test/PoldiInstrumentAdapterTest.h b/Code/Mantid/Framework/SINQ/test/PoldiInstrumentAdapterTest.h index 60b8fdca1358..1f3201986a83 100644 --- a/Code/Mantid/Framework/SINQ/test/PoldiInstrumentAdapterTest.h +++ b/Code/Mantid/Framework/SINQ/test/PoldiInstrumentAdapterTest.h @@ -25,58 +25,124 @@ class PoldiInstrumentAdapterTest : public CxxTest::TestSuite PoldiInstrumentAdapterTest() { + // Replace static member variables for property names by class members + m_testableChopperSpeedPropertyName = "ChopperSpeed"; + m_testableChopperSpeedTargetPropertyName = "ChopperSpeedTarget"; + // special properties for testing AbstractDoubleValueExtractor m_run.addProperty("chopperspeed_double", 10000.0); std::vector chopperSpeed(1, 10000.0); m_run.addProperty >("chopperspeed_vector", chopperSpeed); + std::vector chopperSpeedTargetsInt(1, 10000); + m_run.addProperty >("chopperspeed_target_int_vector", chopperSpeedTargetsInt); + // add string property, for which there is no extractor - m_stringRun.addProperty(PoldiInstrumentAdapter::getChopperSpeedPropertyName(), "10000.0"); + m_stringRun.addProperty(getChopperSpeedPropertyName(), "10000.0"); + m_stringRun.addProperty(getChopperSpeedTargetPropertyName(), "10000.0"); + // run with correct chopperspeed property - m_correctRun.addProperty(PoldiInstrumentAdapter::getChopperSpeedPropertyName(), 10000.0); + m_correctRun.addProperty(getChopperSpeedPropertyName(), 10000.0); + m_correctRun.addProperty(getChopperSpeedTargetPropertyName(), 10000.0); } void testVectorDoubleValueExtractor() { // Extract vector value with vector value extractor - this should work. - AbstractDoubleValueExtractor_sptr extractorGood(new VectorDoubleValueExtractor("chopperspeed_vector")); - TS_ASSERT_THROWS_NOTHING((*extractorGood)(const_cast(m_run))); + AbstractDoubleValueExtractor_sptr extractorGood(new VectorDoubleValueExtractor); + TS_ASSERT_THROWS_NOTHING((*extractorGood)(const_cast(m_run), "chopperspeed_vector")); + + // this should not work, because it's a "number" property (see constructor above) + AbstractDoubleValueExtractor_sptr extractorBad(new VectorDoubleValueExtractor); + TS_ASSERT_THROWS((*extractorBad)(const_cast(m_run), "chopperspeed_double"), std::invalid_argument); + + // check that the value comes out correctly + TS_ASSERT_EQUALS((*extractorGood)(const_cast(m_run), "chopperspeed_vector"), 10000.0); + } + + void testVectorIntValueExtractor() + { + // Extract vector value with vector value extractor - this should work. + AbstractDoubleValueExtractor_sptr extractorGood(new VectorIntValueExtractor); + TS_ASSERT_THROWS_NOTHING((*extractorGood)(const_cast(m_run), "chopperspeed_target_int_vector")); // this should not work, because it's a "number" property (see constructor above) - AbstractDoubleValueExtractor_sptr extractorBad(new VectorDoubleValueExtractor("chopperspeed_double")); - TS_ASSERT_THROWS((*extractorBad)(const_cast(m_run)), std::invalid_argument); + AbstractDoubleValueExtractor_sptr extractorBad(new VectorDoubleValueExtractor); + TS_ASSERT_THROWS((*extractorBad)(const_cast(m_run), "chopperspeed_double"), std::invalid_argument); // check that the value comes out correctly - TS_ASSERT_EQUALS((*extractorGood)(const_cast(m_run)), 10000.0); + TS_ASSERT_EQUALS((*extractorGood)(const_cast(m_run), "chopperspeed_target_int_vector"), 10000.0); } void testNumberDoubleValueExtractor() { // Same as above test - AbstractDoubleValueExtractor_sptr extractorGood(new NumberDoubleValueExtractor("chopperspeed_double")); - TS_ASSERT_THROWS_NOTHING((*extractorGood)(const_cast(m_run))); + AbstractDoubleValueExtractor_sptr extractorGood(new NumberDoubleValueExtractor); + TS_ASSERT_THROWS_NOTHING((*extractorGood)(const_cast(m_run), "chopperspeed_double")); - AbstractDoubleValueExtractor_sptr extractorBad(new NumberDoubleValueExtractor("chopperspeed_vector")); - TS_ASSERT_THROWS((*extractorBad)(const_cast(m_run)), std::invalid_argument); + AbstractDoubleValueExtractor_sptr extractorBad(new NumberDoubleValueExtractor); + TS_ASSERT_THROWS((*extractorBad)(const_cast(m_run), "chopperspeed_vector"), std::invalid_argument); // check that the value comes out correctly - TS_ASSERT_EQUALS((*extractorGood)(const_cast(m_run)), 10000.0); + TS_ASSERT_EQUALS((*extractorGood)(const_cast(m_run), "chopperspeed_double"), 10000.0); } void testGetChopperSpeedFromRun() { TestablePoldiInstrumentAdapter instrumentAdapter; + TS_ASSERT_EQUALS(instrumentAdapter.getChopperSpeedFromRun(m_correctRun), 10000.0); + } + + void testGetChopperSpeedTargetFromRun() + { + TestablePoldiInstrumentAdapter instrumentAdapter; + + TS_ASSERT_EQUALS(instrumentAdapter.getChopperSpeedTargetFromRun(m_correctRun), 10000.0); + } + + void testExtractPropertyFromRun() { + TestablePoldiInstrumentAdapter instrumentAdapter; + // Throws, because "chopperspeed" is missing - TS_ASSERT_THROWS(instrumentAdapter.getChopperSpeedFromRun(m_run), std::runtime_error); + TS_ASSERT_THROWS(instrumentAdapter.extractPropertyFromRun(m_run, "DOESNOTEXIST"), std::runtime_error); // Throws, because there is no extractor for supplied type - TS_ASSERT_THROWS(instrumentAdapter.getChopperSpeedFromRun(m_stringRun), std::invalid_argument); + const std::string propertyName = getChopperSpeedPropertyName(); + TS_ASSERT_THROWS(instrumentAdapter.extractPropertyFromRun(m_stringRun, propertyName), std::invalid_argument); // Should be ok. - TS_ASSERT_THROWS_NOTHING(instrumentAdapter.getChopperSpeedFromRun(m_correctRun)); - TS_ASSERT_EQUALS(instrumentAdapter.getChopperSpeedFromRun(m_correctRun), 10000.0); + TS_ASSERT_THROWS_NOTHING(instrumentAdapter.extractPropertyFromRun(m_correctRun, propertyName)); + TS_ASSERT_EQUALS(instrumentAdapter.extractPropertyFromRun(m_correctRun, propertyName), 10000.0); + } + + void testChopperSpeedMatchesTarget() { + TestablePoldiInstrumentAdapter instrumentAdapter; + + // This throws, because there is no extractor and the exception is not caught in the method + TS_ASSERT_THROWS(instrumentAdapter.chopperSpeedMatchesTarget(m_stringRun, 10000.0), std::invalid_argument); + + // If the property is not present, it is an old file and there can't be any comparison, so it's always true + TS_ASSERT_THROWS_NOTHING(instrumentAdapter.chopperSpeedMatchesTarget(m_run, 10000.0)); + TS_ASSERT_EQUALS(instrumentAdapter.chopperSpeedMatchesTarget(m_run, 10000.0), true); + TS_ASSERT_EQUALS(instrumentAdapter.chopperSpeedMatchesTarget(m_run, 100.0), true); + + // Otherwise, the values are compared with a tolerance of 1e-4 + TS_ASSERT_EQUALS(instrumentAdapter.chopperSpeedMatchesTarget(m_correctRun, 10000.0), true); + TS_ASSERT_EQUALS(instrumentAdapter.chopperSpeedMatchesTarget(m_correctRun, 10000.00009), true); + TS_ASSERT_EQUALS(instrumentAdapter.chopperSpeedMatchesTarget(m_correctRun, 10000.0002), false); + TS_ASSERT_EQUALS(instrumentAdapter.chopperSpeedMatchesTarget(m_correctRun, 9000.0), false); + } + + void testGetCleanChopperSpeed() { + TestablePoldiInstrumentAdapter instrumentAdapter; + + TS_ASSERT_EQUALS(instrumentAdapter.getCleanChopperSpeed(4750.0), 5000.0); + TS_ASSERT_EQUALS(instrumentAdapter.getCleanChopperSpeed(4749.9), 4500.0); + TS_ASSERT_EQUALS(instrumentAdapter.getCleanChopperSpeed(4999.3), 5000.0); + TS_ASSERT_EQUALS(instrumentAdapter.getCleanChopperSpeed(5001.0), 5000.0); + TS_ASSERT_EQUALS(instrumentAdapter.getCleanChopperSpeed(12499.1), 12500.0); } void testGetExtractorForProperty() { @@ -101,7 +167,7 @@ class PoldiInstrumentAdapterTest : public CxxTest::TestSuite TS_ASSERT(!boost::dynamic_pointer_cast(extractor)); // unregistered property type - invalid extractor - extractor = instrumentAdapter.getExtractorForProperty(m_stringRun.getProperty(PoldiInstrumentAdapter::getChopperSpeedPropertyName())); + extractor = instrumentAdapter.getExtractorForProperty(m_stringRun.getProperty(getChopperSpeedPropertyName())); TS_ASSERT(!extractor); } @@ -114,6 +180,20 @@ class PoldiInstrumentAdapterTest : public CxxTest::TestSuite Run m_correctRun; Run m_stringRun; + std::string m_testableChopperSpeedPropertyName; + std::string m_testableChopperSpeedTargetPropertyName; + + + std::string getChopperSpeedPropertyName() + { + return m_testableChopperSpeedPropertyName; + } + + std::string getChopperSpeedTargetPropertyName() + { + return m_testableChopperSpeedTargetPropertyName; + } + class TestablePoldiInstrumentAdapter : public PoldiInstrumentAdapter { friend class PoldiInstrumentAdapterTest; diff --git a/Code/Mantid/Framework/SINQ/test/PoldiPeakCollectionTest.h b/Code/Mantid/Framework/SINQ/test/PoldiPeakCollectionTest.h index 65e85b839ada..66a83925053d 100644 --- a/Code/Mantid/Framework/SINQ/test/PoldiPeakCollectionTest.h +++ b/Code/Mantid/Framework/SINQ/test/PoldiPeakCollectionTest.h @@ -10,6 +10,8 @@ #include "MantidAPI/TableRow.h" #include "MantidAPI/WorkspaceFactory.h" +#include "MantidGeometry/Crystal/PointGroupFactory.h" + #include using namespace Mantid::Poldi; @@ -250,7 +252,7 @@ class PoldiPeakCollectionTest : public CxxTest::TestSuite void testStructureConstructor() { UnitCell CsCl(4.126, 4.126, 4.126); - PointGroup_sptr m3m = boost::make_shared(); + PointGroup_sptr m3m = PointGroupFactory::Instance().createPointGroup("m-3m"); CrystalStructure_sptr structure = boost::make_shared(CsCl, m3m); @@ -286,7 +288,7 @@ class PoldiPeakCollectionTest : public CxxTest::TestSuite void testSetPeaks() { UnitCell CsCl(4.126, 4.126, 4.126); - PointGroup_sptr m3m = boost::make_shared(); + PointGroup_sptr m3m = PointGroupFactory::Instance().createPointGroup("m-3m"); CrystalStructure_sptr structure = boost::make_shared(CsCl, m3m); diff --git a/Code/Mantid/Framework/ScriptRepository/CMakeLists.txt b/Code/Mantid/Framework/ScriptRepository/CMakeLists.txt index b60601fb4843..5435dd1cb9bb 100644 --- a/Code/Mantid/Framework/ScriptRepository/CMakeLists.txt +++ b/Code/Mantid/Framework/ScriptRepository/CMakeLists.txt @@ -1,15 +1,15 @@ # Mantid source -set ( SRC_FILES - src/ScriptRepositoryImpl.cpp +set ( SRC_FILES + src/ScriptRepositoryImpl.cpp ) -set ( INC_FILES inc/MantidScriptRepository/ScriptRepositoryImpl.h +set ( INC_FILES + inc/MantidScriptRepository/ScriptRepositoryImpl.h ) -# set ( TEST_FILES - ScriptRepositoryTestImpl.h) -# ScriptRepositoryFactoryTest.h) + ScriptRepositoryTestImpl.h +) # Add the target for this directory @@ -22,10 +22,10 @@ set_target_properties ( ScriptRepository PROPERTIES OUTPUT_NAME MantidScriptRepo set_property (TARGET ScriptRepository PROPERTY FOLDER "MantidFramework") -include_directories(inc) set ( LIBS ${MANTIDLIBS} ) + +include_directories(inc) + target_link_libraries(ScriptRepository ${LIBS}) -if ( MSVC ) -target_link_libraries(ScriptRepository Winhttp) -endif() + install (TARGETS ScriptRepository ${SYSTEM_PACKAGE_TARGET} DESTINATION ${PLUGINS_DIR} ) diff --git a/Code/Mantid/Framework/ScriptRepository/src/ScriptRepositoryImpl.cpp b/Code/Mantid/Framework/ScriptRepository/src/ScriptRepositoryImpl.cpp index d4ae114396e2..94e44bbca25b 100644 --- a/Code/Mantid/Framework/ScriptRepository/src/ScriptRepositoryImpl.cpp +++ b/Code/Mantid/Framework/ScriptRepository/src/ScriptRepositoryImpl.cpp @@ -3,11 +3,15 @@ #include "MantidAPI/ScriptRepositoryFactory.h" #include "MantidKernel/Logger.h" #include "MantidKernel/ConfigService.h" +#include "MantidKernel/NetworkProxy.h" +#include "MantidKernel/ProxyInfo.h" #include using Mantid::Kernel::DateAndTime; using Mantid::Kernel::Logger; using Mantid::Kernel::ConfigService; -using Mantid::Kernel::ConfigServiceImpl; +using Mantid::Kernel::ConfigServiceImpl; +using Mantid::Kernel::ProxyInfo; +using Mantid::Kernel::NetworkProxy; // from poco #include @@ -22,8 +26,7 @@ using Mantid::Kernel::ConfigServiceImpl; #include #include "Poco/Net/FilePartSource.h" - -// Visual Studion compains with the inclusion of Poco/FileStream +// Visual Studio complains with the inclusion of Poco/FileStream // disabling this warning. #if defined(_WIN32) || defined(_WIN64) #pragma warning( push ) @@ -54,38 +57,40 @@ using boost::property_tree::ptree; namespace Mantid { -namespace API -{ - namespace + namespace API { - /// static logger - Kernel::Logger g_log("ScriptRepositoryImpl"); - } + namespace + { + /// static logger + Kernel::Logger g_log("ScriptRepositoryImpl"); + } + static ScriptRepoException pocoException(const std::string & info, Poco::Exception & ex) + { + std::stringstream ss; + if (dynamic_cast(&ex)) + ss << info << ", because you do not have access to write to this path :" << ex.message() + << std::ends; + else if (dynamic_cast(&ex)) + ss << info + << ". The definition of the remote url is not correct. Please check the Mantid settings, the ScriptRepository entry. Current: " + << ex.message() << std::ends; + else + { + ss << info << " . Unknown:" << ex.displayText() << std::ends; + } - static ScriptRepoException pocoException(const std::string & info, - Poco::Exception & ex){ - std::stringstream ss; - if (dynamic_cast(&ex)) - ss << info << ", because you do not have access to write to this path :"<< ex.message() << std::ends; - else if (dynamic_cast(&ex)) - ss << info << ". The definition of the remote url is not correct. Please check the Mantid settings, the ScriptRepository entry. Current: " << ex.message() << std::ends; - else{ - ss << info << " . Unkown:" << ex.displayText() < - + false @@ -1301,7 +1308,7 @@ Later steps in the process (saving, renaming) will not be done. - + false @@ -1330,6 +1337,16 @@ Later steps in the process (saving, renaming) will not be done. + + + + Apply WienerSmooth algorithm to resolution + + + Smooth RES + + + @@ -1455,52 +1472,50 @@ Later steps in the process (saving, renaming) will not be done. - - - - Plot Raw - - - - + + + + 0 + 0 + + - Use Calibration File + Use Calibration - - - false - + - + 0 - 41 + 0 - - false + + true - + - - false - - - true + + + _calib + - + _calib.nxs + + false + @@ -1513,32 +1528,27 @@ Later steps in the process (saving, renaming) will not be done. Time Slice - + - - - - - - - - + + + + - - - Qt::Vertical - - - - 20 - 40 - + + + Preview - + + + + + + @@ -1617,40 +1627,70 @@ Later steps in the process (saving, renaming) will not be done. - - + + + + 0 + 0 + + + + true + + - + + + + .raw + + false + + + + + + + Sample: + - - + + + + 0 + 0 + + + + true + + - + + + + .raw - - - - - - Sample File: + + false - + - Can/Background File: + Background: @@ -1658,21 +1698,23 @@ Later steps in the process (saving, renaming) will not be done. - - - - - Qt::Vertical - - - - 20 - 40 - - - - - + + + Preview + + + + + + QLayout::SetMinimumSize + + + + + + + + @@ -1739,6 +1781,160 @@ Later steps in the process (saving, renaming) will not be done. + + + Symmetrise + + + + + + Input + + + + + + + 0 + 0 + + + + false + + + _red + + + _red.nxs + + + + + + + + + + Symmetrise + + + + 6 + + + + + + + + + + + + + + Preview + + + + + + + + Preview + + + + + + + + + + + + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + Output + + + + 6 + + + + + true + + + Verbose + + + + + + + Qt::Horizontal + + + + 165 + 20 + + + + + + + + Plot Result + + + + + + + Qt::Horizontal + + + + 164 + 20 + + + + + + + + Save Result + + + + + + + + S(Q, w) @@ -1765,7 +1961,7 @@ Later steps in the process (saving, renaming) will not be done. - false + true Plot Input @@ -2319,8 +2515,12 @@ Later steps in the process (saving, renaming) will not be done. - - + + + + + Options + @@ -2329,20 +2529,70 @@ Later steps in the process (saving, renaming) will not be done. - - - - - Qt::Vertical + + + + + + Preview + + + + 6 - - - 20 - 40 - - - - + + + + + + + + + color: green; + + + M0 + + + + + + + color: black; + + + M2 + + + + + + + color: red; + + + M4 + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + + @@ -2483,6 +2733,7 @@ Later steps in the process (saving, renaming) will not be done. + @@ -2534,11 +2785,7 @@ Later steps in the process (saving, renaming) will not be done. save_ckNxSPE save_ckAscii save_ckAclimax - ckVerbose ind_cbPlotOutput - ckRenameWorkspace - ckFold - ckCm1Units cal_ckIntensityScaleMultiplier cal_leIntensityScaleMultiplier cal_ckResScale @@ -2546,14 +2793,9 @@ Later steps in the process (saving, renaming) will not be done. cal_ckRES cal_ckPlotResult slice_inputFile - slice_pbPlotRaw - slice_ckUseCalib - slice_calibFile slice_ckVerbose slice_ckPlot slice_ckSave - transInputFile - transCanFile trans_ckVerbose trans_ckPlot trans_ckSave diff --git a/Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/IndirectDataReductionTab.h b/Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/IndirectDataReductionTab.h index 816d12016471..1d9a5208d410 100644 --- a/Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/IndirectDataReductionTab.h +++ b/Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/IndirectDataReductionTab.h @@ -5,9 +5,11 @@ #include "MantidAPI/AnalysisDataService.h" #include "MantidKernel/System.h" #include "MantidQtAPI/AlgorithmRunner.h" +#include "MantidQtAPI/BatchAlgorithmRunner.h" #include "MantidQtAPI/PythonRunner.h" #include "MantidQtAPI/QwtWorkspaceSpectrumData.h" #include "MantidQtCustomInterfaces/IndirectDataReduction.h" +#include "MantidQtCustomInterfaces/IndirectTab.h" #include "MantidQtMantidWidgets/RangeSelector.h" #include @@ -40,8 +42,10 @@ namespace MantidQt { namespace CustomInterfaces { - /** IndirectDataReductionTab : TODO: DESCRIPTION - + /** IndirectDataReductionTab + + This class defines common functionality of tabs used in the Indirect Data Reduction interface. + @author Samuel Jackson @date 13/08/2013 @@ -65,7 +69,7 @@ namespace CustomInterfaces File change history is stored at: Code Documentation is available at: */ - class DLLExport IndirectDataReductionTab : public QObject + class DLLExport IndirectDataReductionTab : public IndirectTab { Q_OBJECT @@ -75,95 +79,29 @@ namespace CustomInterfaces public slots: void runTab(); - void setupTab(); - void validateTab(); - - protected slots: - /// Slot to handle when an algorithm finishes running - virtual void algorithmFinished(bool error); protected: - /// Run the load algorithm with the given file name, output name and spectrum range - bool loadFile(const QString& filename, const QString& outputName, const int specMin = -1, const int specMax = -1); - + Mantid::API::MatrixWorkspace_sptr loadInstrumentIfNotExist(std::string instrumentName, std::string analyser="", std::string reflection=""); /// Function to get details about the instrument configuration defined on C2E tab std::map getInstrumentDetails(); - /// Function to plot a workspace to the miniplot using a workspace name - void plotMiniPlot(const QString& workspace, size_t index, const QString& plotID, const QString& curveID = ""); - /// Function to plot a workspace to the miniplot using a workspace pointer - void plotMiniPlot(const Mantid::API::MatrixWorkspace_const_sptr & workspace, size_t wsIndex, const QString& plotID, const QString& curveID = ""); - /// Function to replot a miniplot - void replot(const QString& plotID); - - /// Function to get the range of the curve displayed on the mini plot - std::pair getCurveRange(const QString& plotID); - /// Function to set the range of an axis on a plot - void setAxisRange(const QString& plotID, QwtPlot::Axis axis, std::pair range); - /// Function to autoscale a given axis based on the data in a curve - void setXAxisToCurve(const QString& plotID, const QString& curveID); - - /// Function to set the range limits of the plot - void setPlotRange(const QString& rsID, QtProperty* min, QtProperty* max, const std::pair& bounds); - /// Function to set the range selector on the mini plot - void setMiniPlotGuides(const QString& rsID, QtProperty* lower, QtProperty* upper, const std::pair& bounds); - - /// Function to run an algorithm on a seperate thread - void runAlgorithm(const Mantid::API::IAlgorithm_sptr algorithm); - - /// Parent QWidget (if applicable) - QWidget *m_parentWidget; - - /// Plot of the input - std::map m_plots; - /// Curve on the plot - std::map m_curves; - /// Range selector widget for mini plot - std::map m_rangeSelectors; - /// Tree of the properties - std::map m_propTrees; - - /// Internal list of the properties - QMap m_properties; - - /// Double manager to create properties - QtDoublePropertyManager* m_dblManager; - /// Boolean manager to create properties - QtBoolPropertyManager* m_blnManager; - /// Group manager to create properties - QtGroupPropertyManager* m_grpManager; - - /// Double editor facotry for the properties browser - DoubleEditorFactory* m_dblEdFac; - /// Algorithm runner object to execute algorithms on a seperate thread from the gui - MantidQt::API::AlgorithmRunner* m_algRunner; - - /// Use a Python runner for when we need the output of a script - MantidQt::API::PythonRunner m_pythonRunner; - - /// Validator for int inputs - QIntValidator *m_valInt; - /// Validator for double inputs - QDoubleValidator *m_valDbl; - /// Validator for positive double inputs - QDoubleValidator *m_valPosDbl; + std::map getRangesFromInstrument(QString instName = "", QString analyser = "", QString reflection = ""); + + Ui::IndirectDataReduction m_uiForm; signals: - /// Send signal to parent window to show a message box to user - void showMessageBox(const QString& message); - /// Run a python script - void runAsPythonScript(const QString & code, bool no_output); + /// Update the Run button on the IDR main window + void updateRunButton(bool enabled = true, QString message = "Run", QString tooltip = ""); + /// Emitted when the instrument setup is changed + void newInstrumentConfiguration(); private: - /// Overidden by child class. - virtual void setup() = 0; - /// Overidden by child class. - virtual void run() = 0; - /// Overidden by child class. - virtual bool validate() = 0; + bool m_tabRunning; - protected: - Ui::IndirectDataReduction m_uiForm; + QString getInstrumentParameterFrom(Mantid::Geometry::IComponent_const_sptr comp, std::string param); + + private slots: + void tabExecutionComplete(bool error); }; } // namespace CustomInterfaces diff --git a/Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/IndirectDiagnostics.h b/Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/IndirectDiagnostics.h index 6e502e6ddeb9..decaea8f79e0 100644 --- a/Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/IndirectDiagnostics.h +++ b/Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/IndirectDiagnostics.h @@ -69,10 +69,17 @@ namespace CustomInterfaces void slicePlotRaw(); void sliceTwoRanges(QtProperty*, bool); void sliceCalib(bool state); - void sliceMinChanged(double val); - void sliceMaxChanged(double val); + void rangeSelectorDropped(double, double); void sliceUpdateRS(QtProperty*, double); void setDefaultInstDetails(); + void updatePreviewPlot(); + void sliceAlgDone(bool error); + void pbRunEditing(); //< Called when a user starts to type / edit the runs to load. + void pbRunFinding(); //< Called when the FileFinder starts finding the files. + void pbRunFinished(); //< Called when the FileFinder has finished finding the files. + + private: + QString m_lastDiagFilename; }; } // namespace CustomInterfaces diff --git a/Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/IndirectDiffractionReduction.h b/Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/IndirectDiffractionReduction.h index fd6934e7e3a6..2631379786e7 100644 --- a/Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/IndirectDiffractionReduction.h +++ b/Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/IndirectDiffractionReduction.h @@ -5,6 +5,8 @@ // Includes //---------------------- #include "ui_IndirectDiffractionReduction.h" + +#include "MantidQtAPI/BatchAlgorithmRunner.h" #include "MantidQtAPI/UserSubWindow.h" namespace MantidQt @@ -27,28 +29,40 @@ class IndirectDiffractionReduction : public MantidQt::API::UserSubWindow ~IndirectDiffractionReduction(); public slots: - void demonRun(); + void demonRun(); void instrumentSelected(int); void reflectionSelected(int); void openDirectoryDialog(); void help(); + void plotResults(bool error); + void runFilesChanged(); + void runFilesFinding(); + void runFilesFound(); + void individualGroupingToggled(int state); private: - /// Initialize the layout virtual void initLayout(); void initLocalPython(); + void loadSettings(); void saveSettings(); - bool validateDemon(); + bool validateRebin(); + bool validateVanCal(); + + Mantid::API::MatrixWorkspace_sptr loadInstrument(std::string instrumentName, + std::string reflection = ""); + + void runGenericReduction(QString instName, QString mode); + void runOSIRISdiffonlyReduction(); private: - /// The form generated using Qt Designer - Ui::IndirectDiffractionReduction m_uiForm; + Ui::IndirectDiffractionReduction m_uiForm; /// The form generated using Qt Designer QIntValidator * m_valInt; QDoubleValidator * m_valDbl; - /// The settings group - QString m_settingsGroup; + QString m_settingsGroup; /// The settings group + MantidQt::API::BatchAlgorithmRunner *m_batchAlgoRunner; + QStringList m_plotWorkspaces; }; diff --git a/Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/IndirectDiffractionReduction.ui b/Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/IndirectDiffractionReduction.ui index 4422356f6181..c439e8803cf6 100644 --- a/Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/IndirectDiffractionReduction.ui +++ b/Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/IndirectDiffractionReduction.ui @@ -1,406 +1,463 @@ IndirectDiffractionReduction - + 0 0 495 - 351 + 433 Indirect Diffraction - - - - - - - - 0 - 0 - - - - Instrument - - - - - - - - 0 - 0 - - - - - TOF Indirect Geometry Spectroscopy - TOF Indirect Geometry Diffraction - - - - - - - - Reflection - - - - - - - - 0 - 0 - - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - - - - 0 - 41 - - - - Run Numbers - - - true - - - - - - - Sum Files - - - - - - - - - - - Spectra Min - - - - - - - - - - Spectra Max - - - - - - - - - - - - - 0 - 0 - - - - 1 - - - - - 0 - 0 - + + + + + + Instrument - - - 0 - + - + - + 0 0 - - Cal File - - - false - - - false - - + - .cal + TOF Indirect Geometry Spectroscopy + TOF Indirect Geometry Diffraction - - - true + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + Reflection + + + + - + 0 0 - - Vanadium Runs - - - true - - + + + + + Input + + + + 6 + + + + + + + + 0 + 41 + + + + Run Numbers + + + true + + + + + + + Sum Files + + + + + + + + + + + Spectra Min + + + + + + + + + + Spectra Max + + + + + + + + + + + + + - + 0 0 - + + 0 + + + + + 0 + 0 + + + + + 0 + + + + + Calibration + + + + 6 + + + + + + 0 + 0 + + + + Cal File + + + false + + + false + + + + .cal + + + + + + + + true + + + + 0 + 0 + + + + Vanadium Runs + + + true + + + + + + + + + + + + 0 + 0 + + + + + 0 + + + + + Rebin in D-Spacing (optional) + + + + 6 + + + 6 + + + + + Start: + + + + + + + + + + color: rgb(170, 0, 0); + + + * + + + + + + + Width: + + + + + + + + + + color: rgb(170, 0, 0); + + + * + + + + + + + End: + + + + + + + + + + color: rgb(170, 0, 0); + + + * + + + + + + + + + + + + + + Options + + - - - Rebin in D-Spacing (optional) + + + <html><head/><body><p>When enabled spectra are not grouped and the output workspace will contain one spectrum per detector.</p></body></html> + + + Use Individual Grouping - - - - - Start: - - - - - - - - - - color: rgb(170, 0, 0); - - - * - - - - - - - Width: - - - - - - - - - - color: rgb(170, 0, 0); - - - * - - - - - - - End: - - - - - - - - - - color: rgb(170, 0, 0); - - - * - - - - - - - - - - - - Plot Type: + + + + + Output + + + + 6 - - - - - - None - + + + Plot Type: + + - - Spectra - + + + + None + + + + + Spectra + + + - - - - - - - - Select which file formats the data should be saved in. - - - Save Formats - - + + + + + + + Select which file formats the data should be saved in. + + + Save Formats + + + + 6 + + + + + GSS + + + + + + + Nexus + + + + + + + ASCII (DAT) + + + + + + + + - + + + true + + + + 0 + 0 + + + + + 20 + 20 + + - GSS + ? - + + + Qt::Horizontal + + + + 40 + 20 + + + + + + - Nexus + Run - + + + Qt::Horizontal + + + + 40 + 20 + + + + + + - ASCII (DAT) + Manage Directories - - - - - - - - true - - - - 0 - 0 - - - - - 20 - 20 - - - - ? - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - Run - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - Manage Directories - - - - - - + + + diff --git a/Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/IndirectLoadAscii.h b/Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/IndirectLoadAscii.h index 632683c79c74..b2a77f454644 100644 --- a/Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/IndirectLoadAscii.h +++ b/Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/IndirectLoadAscii.h @@ -51,8 +51,7 @@ namespace MantidQt /// Enumeration for the index of each tab enum TabChoice { - NEUTRON, - MOLDYN, + LOAD_ILL, }; public: // public constructor, destructor and functions diff --git a/Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/IndirectLoadAscii.ui b/Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/IndirectLoadAscii.ui index 5b1c2651f3e5..bd53f6986355 100644 --- a/Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/IndirectLoadAscii.ui +++ b/Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/IndirectLoadAscii.ui @@ -1,7 +1,7 @@ IndirectLoadAscii - + 0 @@ -13,6 +13,7 @@ Indirect Load ASCII + @@ -27,7 +28,7 @@ - Neutron + Load ILL @@ -99,6 +100,7 @@ + diff --git a/Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/IndirectNeutron.h b/Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/IndirectLoadILL.h similarity index 77% rename from Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/IndirectNeutron.h rename to Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/IndirectLoadILL.h index 2b78a27910df..99f62b9d9ec3 100644 --- a/Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/IndirectNeutron.h +++ b/Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/IndirectLoadILL.h @@ -1,7 +1,7 @@ -#ifndef MANTIDQTCUSTOMINTERFACES_INDIRECTNEUTRON_H_ -#define MANTIDQTCUSTOMINTERFACES_INDIRECTNEUTRON_H_ +#ifndef MANTIDQTCUSTOMINTERFACES_INDIRECTLOADILL_H_ +#define MANTIDQTCUSTOMINTERFACES_INDIRECTLOADILL_H_ -#include "ui_IndirectNeutron.h" +#include "ui_IndirectLoadILL.h" #include "MantidQtCustomInterfaces/IndirectLoadAsciiTab.h" #include "MantidAPI/ExperimentInfo.h" @@ -13,17 +13,19 @@ namespace MantidQt { namespace CustomInterfaces { - class DLLExport IndirectNeutron : public IndirectLoadAsciiTab + class DLLExport IndirectLoadILL : public IndirectLoadAsciiTab { Q_OBJECT public: - IndirectNeutron(QWidget * parent = 0); + IndirectLoadILL(QWidget * parent = 0); // Inherited methods from IndirectLoadAsciiTab - QString help() { return "Indirect_Neutron"; }; + QString help() { return "LoadILL"; }; + bool validate(); void run(); + /// Load default settings into the interface void loadSettings(const QSettings& settings); @@ -41,7 +43,7 @@ namespace MantidQt /// Map to store instrument analysers and reflections for this instrument QMap m_paramMap; /// The ui form - Ui::IndirectNeutron m_uiForm; + Ui::IndirectLoadILL m_uiForm; }; } // namespace CustomInterfaces diff --git a/Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/IndirectNeutron.ui b/Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/IndirectLoadILL.ui similarity index 98% rename from Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/IndirectNeutron.ui rename to Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/IndirectLoadILL.ui index 175e866f7aa4..ea0c5a5b8d4f 100644 --- a/Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/IndirectNeutron.ui +++ b/Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/IndirectLoadILL.ui @@ -1,7 +1,7 @@ - IndirectNeutron - + IndirectLoadILL + 0 diff --git a/Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/IndirectMolDyn.h b/Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/IndirectMolDyn.h index 54e3ca5b83b8..000c1a164acd 100644 --- a/Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/IndirectMolDyn.h +++ b/Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/IndirectMolDyn.h @@ -15,10 +15,13 @@ namespace MantidQt public: IndirectMolDyn(QWidget * parent = 0); - // Inherited methods from IndirectForeignTab QString help() { return "IndirectMolDyn"; }; + + // Inherited methods from IndirectTab + void setup(); bool validate(); void run(); + /// Load default settings into the interface void loadSettings(const QSettings& settings); diff --git a/Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/IndirectMolDyn.ui b/Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/IndirectMolDyn.ui index 89f9584b2279..d6f6ce99e94c 100644 --- a/Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/IndirectMolDyn.ui +++ b/Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/IndirectMolDyn.ui @@ -6,8 +6,8 @@ 0 0 - 444 - 155 + 445 + 450 @@ -15,50 +15,189 @@ - - - - - - 0 - 0 - - - - Function Names: - - - - - - - - - - - 0 - 0 - - - - - - - - .dat - .cdl - - - - - - - - Sample Run: - - - - + + + nMOLDYN + + + + + + Sample Run: + + + + + + + + 0 + 0 + + + + <html><head/><body><p>Simulation filename.</p></body></html> + + + + + + + .dat + .cdl + + + + + + + + + 0 + 0 + + + + Function Names: + + + + + + + <html><head/><body><p>Comma separated list of functions to load from the input file.</p></body></html> + + + + + + + + + + Options + + + + + + + + Crop Max Energy + + + true + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + 150 + 0 + + + + <html><head/><body><p>Crop the upper energy range of any workspaces with energy as the X unit (e.g. S(Q,w)).</p></body></html> + + + meV + + + 1000.000000000000000 + + + 10.000000000000000 + + + + + + + + + + + + Instrument Resolution + + + + + + Resolution: + + + + + + + false + + + + 0 + 0 + + + + <html><head/><body><p>Instrument resolution file or workspace.</p></body></html> + + + true + + + + + + + _red + _res + + + + + _red.nxs + _res.nxs + + + + false + + + + + + + true + + + <html><head/><body><p>Convolve suitable workspaces with an instrument resolution.</p></body></html> + + + Use Instrument Resolution + + + false + + + + + @@ -86,7 +225,7 @@ - + true @@ -124,7 +263,7 @@ - Spectrum + Spectra @@ -153,7 +292,7 @@ - + Save Result @@ -165,12 +304,28 @@ + + MantidQt::MantidWidgets::DataSelector + QWidget +
MantidQtMantidWidgets/DataSelector.h
+
MantidQt::MantidWidgets::MWRunFiles QWidget
MantidQtMantidWidgets/MWRunFiles.h
+ + mwRun + leFunctionNames + ckCropEnergy + dspMaxEnergy + ckResolution + dsResolution + ckVerbose + cbPlot + ckSave +
diff --git a/Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/IndirectMoments.h b/Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/IndirectMoments.h index f3602cc1124b..5adaacaded42 100644 --- a/Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/IndirectMoments.h +++ b/Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/IndirectMoments.h @@ -52,12 +52,14 @@ namespace CustomInterfaces protected slots: // Handle when a file/workspace is ready for plotting void handleSampleInputReady(const QString&); - /// Slot for when the min range on the range selector changes - void minValueChanged(double min); - /// Slot for when the min range on the range selector changes - void maxValueChanged(double max); + /// Slot for when the range selector changes + void rangeChanged(double min, double max); /// Slot to update the guides when the range properties change void updateProperties(QtProperty* prop, double val); + /// Triggers an update of the preview plot + void updatePreviewPlot(QString workspaceName = ""); + /// Called when the algorithm completes to update preview plot + void momentsAlgComplete(bool error); }; } // namespace CustomInterfaces diff --git a/Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/IndirectSassena.h b/Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/IndirectSassena.h new file mode 100644 index 000000000000..dc373046b05a --- /dev/null +++ b/Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/IndirectSassena.h @@ -0,0 +1,41 @@ +#ifndef MANTIDQTCUSTOMINTERFACES_INDIRECTSASSENA_H_ +#define MANTIDQTCUSTOMINTERFACES_INDIRECTSASSENA_H_ + +#include "ui_IndirectSassena.h" +#include "MantidQtCustomInterfaces/IndirectSimulationTab.h" + +namespace MantidQt +{ + namespace CustomInterfaces + { + class DLLExport IndirectSassena : public IndirectSimulationTab + { + Q_OBJECT + + public: + IndirectSassena(QWidget * parent = 0); + + QString help() { return "IndirectSassena"; }; + + void setup(); + bool validate(); + void run(); + + /// Load default settings into the interface + void loadSettings(const QSettings& settings); + + private slots: + /// Handle completion of the algorithm batch + void handleAlgorithmFinish(bool error); + + private: + /// The ui form + Ui::IndirectSassena m_uiForm; + /// Name of the output workspace group + QString m_outWsName; + + }; + } // namespace CustomInterfaces +} // namespace MantidQt + +#endif //MANTIDQTCUSTOMINTERFACES_INDIRECTSASSENA_H_ diff --git a/Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/IndirectSassena.ui b/Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/IndirectSassena.ui new file mode 100644 index 000000000000..db0f69caa544 --- /dev/null +++ b/Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/IndirectSassena.ui @@ -0,0 +1,170 @@ + + + IndirectSassena + + + + 0 + 0 + 444 + 251 + + + + Form + + + + + + Input File + + + + 6 + + + + + + 0 + 0 + + + + + + + + .h5 + .hd5 + + + + + + + + Sample File: + + + + + + + + + + Options + + + + + + Time per Data Point: + + + + + + + <html><head/><body><p>The time in pico seconds between each consecutive data point.</p></body></html> + + + ps + + + 1000.000000000000000 + + + 1.000000000000000 + + + + + + + Sort by Q Vectors + + + + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + + 0 + 0 + + + + Output Options + + + + + + true + + + Plot Result + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + Save Result + + + + + + + + + + + MantidQt::MantidWidgets::MWRunFiles + QWidget +
MantidQtMantidWidgets/MWRunFiles.h
+
+
+ + mwInputFile + sbTimeUnit + cbSortQ + chkPlot + chkSave + + + +
diff --git a/Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/IndirectSimulation.h b/Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/IndirectSimulation.h index e41c4934451e..3bffa70998b5 100644 --- a/Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/IndirectSimulation.h +++ b/Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/IndirectSimulation.h @@ -15,8 +15,8 @@ namespace MantidQt { namespace CustomInterfaces { - /** - This class defines the Indirect Simulation interface. It handles the creation of the interface window and + /** + This class defines the Indirect Simulation interface. It handles the creation of the interface window and handles the interaction between the child tabs on the window. @author Samuel Jackson, STFC @@ -39,7 +39,7 @@ namespace MantidQt along with this program. If not, see . File change history is stored at: - Code Documentation is available at: + Code Documentation is available at: */ class DLLExport IndirectSimulation : public MantidQt::API::UserSubWindow @@ -52,22 +52,22 @@ namespace MantidQt enum TabChoice { MOLDYN, + SASSENA, }; public: // public constructor, destructor and functions /// Default Constructor IndirectSimulation(QWidget *parent = 0); - ///Destructor + /// Destructor ~IndirectSimulation(); /// Interface name static std::string name() { return "Simulation"; } - // This interface's categories. + /// This interface's categories. static QString categoryInfo() { return "Indirect"; } + /// Setup tab UI virtual void initLayout(); private slots: - // Run the appropriate action depending based on the selected tab - /// Slot for clicking on the run button void runClicked(); /// Slot for clicking on the hlep button @@ -86,11 +86,12 @@ namespace MantidQt void handleDirectoryChange(Mantid::Kernel::ConfigValChangeNotification_ptr pNf); /// Map of tabs indexed by position on the window - std::map m_loadAsciiTabs; + std::map m_simulationTabs; /// Change Observer for ConfigService (monitors user directories) Poco::NObserver m_changeObserver; ///Main interface window Ui::IndirectSimulation m_uiForm; + }; } } diff --git a/Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/IndirectSimulation.ui b/Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/IndirectSimulation.ui index 5bef7c7232ea..0143af0267c7 100644 --- a/Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/IndirectSimulation.ui +++ b/Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/IndirectSimulation.ui @@ -1,18 +1,19 @@ IndirectSimulation - + 0 0 - 504 - 277 + 445 + 450 Indirect Simulation + @@ -30,6 +31,11 @@ MolDyn + + + Sassena + + @@ -99,6 +105,7 @@ + diff --git a/Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/IndirectSimulationTab.h b/Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/IndirectSimulationTab.h index 7665376b8177..2db3a71aa18b 100644 --- a/Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/IndirectSimulationTab.h +++ b/Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/IndirectSimulationTab.h @@ -1,7 +1,10 @@ #ifndef MANTID_CUSTOMINTERFACES_INDIRECTSIMULATIONTAB_H_ #define MANTID_CUSTOMINTERFACES_INDIRECTSIMULATIONTAB_H_ +#include "MantidAPI/AlgorithmManager.h" #include "MantidKernel/System.h" +#include "MantidQtAPI/AlgorithmRunner.h" +#include "MantidQtCustomInterfaces/IndirectTab.h" #include #include @@ -13,7 +16,7 @@ namespace MantidQt This class defines a abstract base class for the different tabs of the Indirect Simulation interface. Any joint functionality shared between each of the tabs should be implemented here as well as defining shared member functions. - + @author Samuel Jackson, STFC Copyright © 2013 ISIS Rutherford Appleton Laboratory & NScD Oak Ridge National Laboratory @@ -37,7 +40,7 @@ namespace MantidQt Code Documentation is available at: */ - class DLLExport IndirectSimulationTab : public QWidget + class DLLExport IndirectSimulationTab : public IndirectTab { Q_OBJECT @@ -48,23 +51,11 @@ namespace MantidQt /// Returns a URL for the wiki help page for this interface QString tabHelpURL(); - /// Base methods implemented in derived classes virtual QString help() = 0; - virtual bool validate() = 0; - virtual void run() = 0; virtual void loadSettings(const QSettings& settings) = 0; - signals: - /// Send signal to parent window to execute python script - void executePythonScript(const QString& pyInput, bool output); - /// Send signal to parent window to show a message box to user - void showMessageBox(const QString& message); - - protected: - void runPythonScript(const QString& pyInput); - }; } // namespace CustomInterfaces } // namespace Mantid -#endif \ No newline at end of file +#endif diff --git a/Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/IndirectSqw.h b/Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/IndirectSqw.h index ad26ef5efddf..e616371e5669 100644 --- a/Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/IndirectSqw.h +++ b/Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/IndirectSqw.h @@ -47,8 +47,13 @@ namespace CustomInterfaces virtual bool validate(); private slots: - void sOfQwRebinE(bool state); - void sOfQwPlotInput(); + void energyRebinToggle(bool state); + void plotContour(); + void sqwAlgDone(bool error); + + private: + bool validateQRebin(); + bool validateEnergyRebin(); }; } // namespace CustomInterfaces diff --git a/Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/IndirectSymmetrise.h b/Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/IndirectSymmetrise.h new file mode 100644 index 000000000000..10a9ad3b6c62 --- /dev/null +++ b/Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/IndirectSymmetrise.h @@ -0,0 +1,83 @@ +#ifndef MANTIDQTCUSTOMINTERFACES_INDIRECTSYMMETRISE_H_ +#define MANTIDQTCUSTOMINTERFACES_INDIRECTSYMMETRISE_H_ + +#include "MantidQtCustomInterfaces/IndirectDataReductionTab.h" + +#include "MantidAPI/MatrixWorkspace.h" +#include "MantidKernel/System.h" + +// Suppress a warning coming out of code that isn't ours +#if defined(__INTEL_COMPILER) + #pragma warning disable 1125 +#elif defined(__GNUC__) + #if (__GNUC__ >= 4 && __GNUC_MINOR__ >= 6 ) + #pragma GCC diagnostic push + #endif + #pragma GCC diagnostic ignored "-Woverloaded-virtual" +#endif +#include +#if defined(__INTEL_COMPILER) + #pragma warning enable 1125 +#elif defined(__GNUC__) + #if (__GNUC__ >= 4 && __GNUC_MINOR__ >= 6 ) + #pragma GCC diagnostic pop + #endif +#endif + +namespace MantidQt +{ +namespace CustomInterfaces +{ + /** IndirectSymmetrise + + @author Dan Nixon + @date 23/07/2014 + + Copyright © 2013 ISIS Rutherford Appleton Laboratory & NScD Oak Ridge National Laboratory + + This file is part of Mantid. + + Mantid is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + Mantid is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + + File change history is stored at: + Code Documentation is available at: + */ + class DLLExport IndirectSymmetrise : public IndirectDataReductionTab + { + Q_OBJECT + + public: + IndirectSymmetrise(Ui::IndirectDataReduction& uiForm, QWidget * parent = 0); + virtual ~IndirectSymmetrise(); + + virtual void setup(); + virtual void run(); + virtual bool validate(); + + private slots: + void plotRawInput(const QString &workspaceName); + void updateMiniPlots(); + void replotNewSpectrum(QtProperty *prop, double value); + void verifyERange(QtProperty *prop, double value); + void updateRangeSelectors(QtProperty *prop, double value); + void preview(); + void previewAlgDone(bool error); + void xRangeMaxChanged(double value); + void xRangeMinChanged(double value); + + }; +} // namespace CustomInterfaces +} // namespace Mantid + +#endif //MANTIDQTCUSTOMINTERFACES_INDIRECTSYMMETRISE_H_ diff --git a/Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/IndirectTab.h b/Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/IndirectTab.h new file mode 100644 index 000000000000..dd32eeed6506 --- /dev/null +++ b/Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/IndirectTab.h @@ -0,0 +1,167 @@ +#ifndef MANTID_CUSTOMINTERFACES_INDIRECTTAB_H_ +#define MANTID_CUSTOMINTERFACES_INDIRECTTAB_H_ + +#include "MantidAPI/AlgorithmManager.h" +#include "MantidAPI/AnalysisDataService.h" +#include "MantidKernel/System.h" +#include "MantidQtAPI/AlgorithmRunner.h" +#include "MantidQtAPI/BatchAlgorithmRunner.h" +#include "MantidQtAPI/PythonRunner.h" +#include "MantidQtAPI/QwtWorkspaceSpectrumData.h" +#include "MantidQtMantidWidgets/RangeSelector.h" + +#include +#include +#include +#include + +#include +#include + +// Suppress a warning coming out of code that isn't ours +#if defined(__INTEL_COMPILER) + #pragma warning disable 1125 +#elif defined(__GNUC__) + #if (__GNUC__ >= 4 && __GNUC_MINOR__ >= 6 ) + #pragma GCC diagnostic push + #endif + #pragma GCC diagnostic ignored "-Woverloaded-virtual" +#endif +#include "DoubleEditorFactory.h" +#if defined(__INTEL_COMPILER) + #pragma warning enable 1125 +#elif defined(__GNUC__) + #if (__GNUC__ >= 4 && __GNUC_MINOR__ >= 6 ) + #pragma GCC diagnostic pop + #endif +#endif + +namespace MantidQt +{ +namespace CustomInterfaces +{ + /** IndirectTab : TODO: DESCRIPTION + + @author Dan Nixon + @date 08/10/2014 + + Copyright © 2013 ISIS Rutherford Appleton Laboratory & NScD Oak Ridge National Laboratory + + This file is part of Mantid. + + Mantid is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + Mantid is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + + File change history is stored at: + Code Documentation is available at: + */ + class DLLExport IndirectTab : public QObject + { + Q_OBJECT + + public: + IndirectTab(QObject* parent = 0); + virtual ~IndirectTab(); + + public slots: + void runTab(); + void setupTab(); + bool validateTab(); + + protected slots: + /// Slot to handle when an algorithm finishes running + virtual void algorithmFinished(bool error); + + protected: + /// Run the load algorithm with the given file name, output name and spectrum range + bool loadFile(const QString& filename, const QString& outputName, const int specMin = -1, const int specMax = -1); + + /// Function to plot a workspace to the miniplot using a workspace name + void plotMiniPlot(const QString& workspace, size_t index, const QString& plotID, const QString& curveID = ""); + /// Function to plot a workspace to the miniplot using a workspace pointer + void plotMiniPlot(const Mantid::API::MatrixWorkspace_const_sptr & workspace, size_t wsIndex, const QString& plotID, const QString& curveID = ""); + /// Function to replot a miniplot + void replot(const QString& plotID); + + /// Function to get the range of the curve displayed on the mini plot + std::pair getCurveRange(const QString& plotID); + /// Function to set the range of an axis on a plot + void setAxisRange(const QString& plotID, QwtPlot::Axis axis, std::pair range); + /// Function to autoscale a given axis based on the data in a curve + void setXAxisToCurve(const QString& plotID, const QString& curveID); + + /// Function to set the range limits of the plot + void setPlotRange(const QString& rsID, QtProperty* min, QtProperty* max, const std::pair& bounds); + /// Function to set the range selector on the mini plot + void setMiniPlotGuides(const QString& rsID, QtProperty* lower, QtProperty* upper, const std::pair& bounds); + + /// Function to run an algorithm on a seperate thread + void runAlgorithm(const Mantid::API::IAlgorithm_sptr algorithm); + + /// Parent QWidget (if applicable) + QWidget *m_parentWidget; + + /// Plot of the input + std::map m_plots; + /// Curve on the plot + std::map m_curves; + /// Range selector widget for mini plot + std::map m_rangeSelectors; + /// Tree of the properties + std::map m_propTrees; + + /// Internal list of the properties + QMap m_properties; + + /// Double manager to create properties + QtDoublePropertyManager* m_dblManager; + /// Boolean manager to create properties + QtBoolPropertyManager* m_blnManager; + /// Group manager to create properties + QtGroupPropertyManager* m_grpManager; + + /// Double editor facotry for the properties browser + DoubleEditorFactory* m_dblEdFac; + + /// Algorithm runner object to execute chains algorithms on a seperate thread from the GUI + MantidQt::API::BatchAlgorithmRunner *m_batchAlgoRunner; + + /// Use a Python runner for when we need the output of a script + MantidQt::API::PythonRunner m_pythonRunner; + + /// Validator for int inputs + QIntValidator *m_valInt; + /// Validator for double inputs + QDoubleValidator *m_valDbl; + /// Validator for positive double inputs + QDoubleValidator *m_valPosDbl; + + signals: + /// Send signal to parent window to show a message box to user + void showMessageBox(const QString& message); + /// Run a python script + void runAsPythonScript(const QString & code, bool noOutput = false); + + protected: + /// Overidden by child class. + virtual void setup() = 0; + /// Overidden by child class. + virtual void run() = 0; + /// Overidden by child class. + virtual bool validate() = 0; + + }; +} // namespace CustomInterfaces +} // namespace Mantid + +#endif /* MANTID_CUSTOMINTERFACES_INDIRECTTAB_H_ */ diff --git a/Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/IndirectTransmission.h b/Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/IndirectTransmission.h index 8fa3ad3cb3b7..5bb1c63186cc 100644 --- a/Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/IndirectTransmission.h +++ b/Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/IndirectTransmission.h @@ -10,7 +10,7 @@ namespace MantidQt namespace CustomInterfaces { /** IndirectTransmission : TODO: DESCRIPTION - + @author Samuel Jackson @date 13/08/2013 @@ -46,6 +46,11 @@ namespace CustomInterfaces virtual void setup(); virtual void run(); virtual bool validate(); + + private slots: + void dataLoaded(); + void previewPlot(); + void transAlgDone(bool error); }; } // namespace CustomInterfaces diff --git a/Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/JumpFit.h b/Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/JumpFit.h index 582079841a94..fbde3aabb082 100644 --- a/Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/JumpFit.h +++ b/Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/JumpFit.h @@ -17,8 +17,10 @@ namespace MantidQt // Inherited methods from IndirectBayesTab QString help() { return "JumpFit"; }; + void setup(); bool validate(); void run(); + void runImpl(bool verbose = false, bool plot = false, bool save = false); /// Load default settings into the interface void loadSettings(const QSettings& settings); @@ -27,20 +29,25 @@ namespace MantidQt void handleSampleInputReady(const QString& filename); /// Slot to handle plotting a different spectrum of the workspace void handleWidthChange(const QString& text); - /// Slot for when the min range on the range selector changes - virtual void minValueChanged(double min); - /// Slot for when the min range on the range selector changes - virtual void maxValueChanged(double max); + /// Slot for when the range on the range selector changes + void qRangeChanged(double min, double max); /// Slot to update the guides when the range properties change void updateProperties(QtProperty* prop, double val); /// Find all spectra with width data in the workspace void findAllWidths(Mantid::API::MatrixWorkspace_const_sptr ws); + /// Handles plotting results of algorithm on miniplot + void fitAlgDone(bool error); + /// Handles running preview algorithm + void runPreviewAlgorithm(); private: - //The ui form + // The UI form Ui::JumpFit m_uiForm; - // map of axis labels to spectrum number - std::map spectraList; + + // Map of axis labels to spectrum number + std::map m_spectraList; + + Mantid::API::IAlgorithm_sptr fitAlg; }; } // namespace CustomInterfaces diff --git a/Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/JumpFit.ui b/Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/JumpFit.ui index 7ba4749fa6f7..ae6a514a585d 100644 --- a/Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/JumpFit.ui +++ b/Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/JumpFit.ui @@ -24,7 +24,7 @@ - + 0 @@ -110,7 +110,55 @@ - + + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + Data + + + + + + + color: rgb(255, 0, 0); + + + Fit + + + + + + + color: rgb(0, 255, 0); + + + Diff + + + + + + diff --git a/Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/MantidEV.ui b/Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/MantidEV.ui index 6bfc0442db09..bffc3627533b 100644 --- a/Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/MantidEV.ui +++ b/Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/MantidEV.ui @@ -1,7 +1,7 @@ MantidEV - + 0 @@ -19,6 +19,7 @@ SCD Event Data Reduction + @@ -3444,6 +3445,7 @@ + diff --git a/Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/Muon/ALCInterface.ui b/Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/Muon/ALCInterface.ui index 44952e1addd1..4449fe94c794 100644 --- a/Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/Muon/ALCInterface.ui +++ b/Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/Muon/ALCInterface.ui @@ -1,7 +1,7 @@ ALCInterface - + 0 @@ -13,6 +13,7 @@ ALC Analysis + @@ -107,6 +108,7 @@ + diff --git a/Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/Muon/MuonAnalysisResultTableTab.h b/Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/Muon/MuonAnalysisResultTableTab.h index 19a616e58b88..090de9cb0741 100644 --- a/Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/Muon/MuonAnalysisResultTableTab.h +++ b/Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/Muon/MuonAnalysisResultTableTab.h @@ -1,4 +1,4 @@ -#ifndef MANTIDQTCUSTOMINTERFACES_MUONANALYSITREESULTTABLETAB_H_ +#ifndef MANTIDQTCUSTOMINTERFACES_MUONANALYSISRESULTTABLETAB_H_ #define MANTIDQTCUSTOMINTERFACES_MUONANALYSISRESULTTABLETAB_H_ //---------------------- @@ -151,4 +151,4 @@ private slots: } } -#endif //MANTIDQTCUSTOMINTERFACES_MUONANALYSISTESULTTABLETAB_H_ +#endif //MANTIDQTCUSTOMINTERFACES_MUONANALYSISRESULTTABLETAB_H_ diff --git a/Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/QReflTableModel.h b/Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/QReflTableModel.h index 0b43cbce7a2d..3e66f90a96f8 100644 --- a/Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/QReflTableModel.h +++ b/Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/QReflTableModel.h @@ -44,16 +44,20 @@ namespace MantidQt //emit a signal saying things have changed void update(); //row and column counts - int rowCount(const QModelIndex &parent) const; - int columnCount(const QModelIndex &parent) const; + int rowCount(const QModelIndex &parent = QModelIndex()) const; + int columnCount(const QModelIndex &parent = QModelIndex()) const; //get data fro a cell - QVariant data(const QModelIndex &index, int role) const; + QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const; //get header data for the table QVariant headerData(int section, Qt::Orientation orientation, int role) const; //get flags for a cell Qt::ItemFlags flags(const QModelIndex &index) const; - //chage or add data to the model - bool setData ( const QModelIndex & index, const QVariant & value, int role = Qt::EditRole ); + //change or add data to the model + bool setData(const QModelIndex& index, const QVariant& value, int role = Qt::EditRole); + //add new rows to the model + bool insertRows(int row, int count, const QModelIndex& parent = QModelIndex()); + //remove rows from the model + bool removeRows(int row, int count, const QModelIndex& parent = QModelIndex()); private: typedef QString ColumnNameType; @@ -77,6 +81,8 @@ namespace MantidQt static const QString SCALE; /// Label for group column static const QString GROUP; + /// Label for options column + static const QString OPTIONS; private: /// Index for run number column @@ -95,6 +101,8 @@ namespace MantidQt static const int COL_SCALE; /// Index for group column static const int COL_GROUP; + /// Index for options column + static const int COL_OPTIONS; //cache for a row's data mutable std::vector m_dataCache; @@ -115,6 +123,8 @@ namespace MantidQt ColumnIndexNameMap m_columnNameMap; }; + /// Typedef for a shared pointer to \c QReflTableModel + typedef boost::shared_ptr QReflTableModel_sptr; } // namespace CustomInterfaces } // namespace Mantid diff --git a/Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/QtReflMainView.h b/Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/QtReflMainView.h index 90a4f5eafa6d..c77727b0878c 100644 --- a/Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/QtReflMainView.h +++ b/Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/QtReflMainView.h @@ -5,7 +5,10 @@ #include "MantidQtAPI/UserSubWindow.h" #include "MantidQtCustomInterfaces/ReflMainView.h" #include "MantidQtCustomInterfaces/IReflPresenter.h" +#include "MantidQtCustomInterfaces/ReflSearchModel.h" +#include "MantidQtCustomInterfaces/QReflTableModel.h" #include +#include #include "ui_ReflMainWidget.h" namespace MantidQt @@ -48,7 +51,8 @@ namespace MantidQt static QString categoryInfo() { return "Reflectometry"; } //Connect the model - virtual void showTable(Mantid::API::ITableWorkspace_sptr model); + virtual void showTable(QReflTableModel_sptr model); + virtual void showSearch(ReflSearchModel_sptr model); //Dialog/Prompt methods virtual std::string askUserString(const std::string& prompt, const std::string& title, const std::string& defaultValue); @@ -56,26 +60,68 @@ namespace MantidQt virtual void giveUserInfo(std::string prompt, std::string title); virtual void giveUserWarning(std::string prompt, std::string title); virtual void giveUserCritical(std::string prompt, std::string title); + virtual void showAlgorithmDialog(const std::string& algorithm); + + //Set the status of the progress bar + virtual void setProgressRange(int min, int max); + virtual void setProgress(int progress); + + //Settor methods + virtual void setSelection(const std::set& rows); + virtual void setTableList(const std::set& tables); + virtual void setInstrumentList(const std::vector& instruments, const std::string& defaultInstrument); + virtual void setOptionsHintStrategy(MantidQt::MantidWidgets::HintStrategy* hintStrategy); + virtual void setClipboard(const std::string& text); //Accessor methods - virtual std::vector getSelectedRowIndexes() const; + virtual std::set getSelectedRows() const; + virtual std::set getSelectedSearchRows() const; + virtual std::string getSearchInstrument() const; + virtual std::string getProcessInstrument() const; + virtual std::string getWorkspaceToOpen() const; + virtual std::string getClipboard() const; + virtual std::string getSearchString() const; + + virtual boost::shared_ptr getPresenter() const; private: //initialise the interface virtual void initLayout(); //the presenter - boost::scoped_ptr m_presenter; + boost::shared_ptr m_presenter; + //the models + QReflTableModel_sptr m_model; + ReflSearchModel_sptr m_searchModel; //the interface Ui::reflMainWidget ui; + //the workspace the user selected to open + std::string m_toOpen; + QSignalMapper* m_openMap; private slots: + void on_actionNewTable_triggered(); + void on_actionSaveTable_triggered(); + void on_actionSaveTableAs_triggered(); + void on_actionAppendRow_triggered(); + void on_actionPrependRow_triggered(); + void on_actionDeleteRow_triggered(); + void on_actionProcess_triggered(); + void on_actionGroupRows_triggered(); + void on_actionClearSelected_triggered(); + void on_actionCopySelected_triggered(); + void on_actionCutSelected_triggered(); + void on_actionPasteSelected_triggered(); + void on_actionExpandSelection_triggered(); + void on_actionOptionsDialog_triggered(); + void on_actionSearch_triggered(); + void on_actionTransfer_triggered(); + void on_actionImportTable_triggered(); + void on_actionExportTable_triggered(); + void setModel(QString name); - void setNew(); - void saveButton(); - void saveAsButton(); - void addRowButton(); - void deleteRowButton(); - void processButton(); + void tableUpdated(const QModelIndex& topLeft, const QModelIndex& bottomRight); + void showContextMenu(const QPoint& pos); + void showSearchContextMenu(const QPoint& pos); }; diff --git a/Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/ReflBlankMainViewPresenter.h b/Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/QtReflOptionsDialog.h similarity index 54% rename from Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/ReflBlankMainViewPresenter.h rename to Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/QtReflOptionsDialog.h index f2870504ff7b..670f77947576 100644 --- a/Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/ReflBlankMainViewPresenter.h +++ b/Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/QtReflOptionsDialog.h @@ -1,18 +1,20 @@ -#ifndef MANTID_CUSTOMINTERFACES_REFLBLANKMAINVIEWPRESENTER_H_ -#define MANTID_CUSTOMINTERFACES_REFLBLANKMAINVIEWPRESENTER_H_ +#ifndef MANTID_CUSTOMINTERFACES_QTREFLOPTIONSDIALOG_H +#define MANTID_CUSTOMINTERFACES_QTREFLOPTIONSDIALOG_H #include "MantidKernel/System.h" -#include "MantidQtCustomInterfaces/ReflMainViewPresenter.h" -#include "MantidAPI/ITableWorkspace.h" +#include "MantidQtCustomInterfaces/IReflPresenter.h" #include "MantidQtCustomInterfaces/ReflMainView.h" +#include + +#include "ui_ReflOptionsDialog.h" + namespace MantidQt { namespace CustomInterfaces { - /** ReflBlankMainViewPresenter : Handles presentation logic for the reflectometry interface - when a table workspace has not been loaded or selected. + /** QtReflOptionsDialog : Provides a dialog for setting Reflectometry UI options. Copyright © 2014 ISIS Rutherford Appleton Laboratory & NScD Oak Ridge National Laboratory @@ -34,21 +36,29 @@ namespace MantidQt File change history is stored at: Code Documentation is available at: */ - class DLLExport ReflBlankMainViewPresenter: public ReflMainViewPresenter + + class DLLExport QtReflOptionsDialog : public QDialog { + Q_OBJECT public: - - ReflBlankMainViewPresenter(ReflMainView* view); - virtual ~ReflBlankMainViewPresenter(); + QtReflOptionsDialog(ReflMainView* view, boost::shared_ptr presenter); + virtual ~QtReflOptionsDialog(); + protected: + void initLayout(); + void initBindings(); + protected slots: + void saveOptions(); + void loadOptions(); protected: - //press changes to a previously saved-to item in the ADS, or ask for a name if never given one - virtual void save(); - //press changes to a new item in the ADS - virtual void saveAs(); + //the interface + Ui::reflOptionsDialog ui; + //the presenter + boost::shared_ptr m_presenter; + //maps option names to widget names + std::map m_bindings; }; + } //CustomInterfaces +} //MantidQt - } // namespace CustomInterfaces -} // namespace Mantid - -#endif /* MANTID_CUSTOMINTERFACES_REFLBLANKMAINVIEWPRESENTER_H_ */ +#endif /* MANTID_CUSTOMINTERFACES_QTREFLOPTIONSDIALOG_H */ diff --git a/Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/Quasi.h b/Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/Quasi.h index eefcaad95e9c..f574f325c3d6 100644 --- a/Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/Quasi.h +++ b/Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/Quasi.h @@ -17,6 +17,7 @@ namespace MantidQt // Inherited methods from IndirectBayesTab QString help() { return "Quasi"; }; + void setup(); bool validate(); void run(); /// Load default settings into the interface @@ -24,9 +25,9 @@ namespace MantidQt private slots: /// Slot for when the min range on the range selector changes - virtual void minValueChanged(double min); + void minValueChanged(double min); /// Slot for when the min range on the range selector changes - virtual void maxValueChanged(double max); + void maxValueChanged(double max); /// Slot to update the guides when the range properties change void updateProperties(QtProperty* prop, double val); /// Slot to handle when a new sample file is available diff --git a/Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/ReflCatalogSearcher.h b/Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/ReflCatalogSearcher.h new file mode 100644 index 000000000000..c00d2afd7956 --- /dev/null +++ b/Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/ReflCatalogSearcher.h @@ -0,0 +1,42 @@ +#ifndef MANTID_CUSTOMINTERFACES_REFLCATALOGSEARCHER_H +#define MANTID_CUSTOMINTERFACES_REFLCATALOGSEARCHER_H + +#include "MantidQtCustomInterfaces/IReflSearcher.h" + +namespace MantidQt +{ + namespace CustomInterfaces + { + /** @class ReflCatalogSearcher + + ReflCatalogSearcher implements IReflSearcher to provide ICAT search functionality. + + Copyright © 2011-14 ISIS Rutherford Appleton Laboratory & NScD Oak Ridge National Laboratory + + This file is part of Mantid. + + Mantid is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + Mantid is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + + File change history is stored at: . + Code Documentation is available at: + */ + class ReflCatalogSearcher : public IReflSearcher + { + public: + virtual ~ReflCatalogSearcher() {}; + Mantid::API::ITableWorkspace_sptr search(const std::string& text, const std::string& instrument); + }; + } +} +#endif diff --git a/Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/ReflLoadedMainViewPresenter.h b/Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/ReflLegacyTransferStrategy.h similarity index 50% rename from Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/ReflLoadedMainViewPresenter.h rename to Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/ReflLegacyTransferStrategy.h index b7572cc5cf75..c3849db0bcad 100644 --- a/Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/ReflLoadedMainViewPresenter.h +++ b/Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/ReflLegacyTransferStrategy.h @@ -1,18 +1,15 @@ -#ifndef MANTID_CUSTOMINTERFACES_REFLLOADEDMAINVIEWPRESENTER_H_ -#define MANTID_CUSTOMINTERFACES_REFLLOADEDMAINVIEWPRESENTER_H_ +#ifndef MANTID_CUSTOMINTERFACES_REFLLEGACYTRANSFERSTRATEGY_H +#define MANTID_CUSTOMINTERFACES_REFLLEGACYTRANSFERSTRATEGY_H #include "MantidKernel/System.h" -#include "MantidQtCustomInterfaces/ReflMainViewPresenter.h" -#include "MantidAPI/ITableWorkspace.h" -#include "MantidQtCustomInterfaces/ReflMainView.h" +#include "MantidQtCustomInterfaces/ReflTransferStrategy.h" namespace MantidQt { namespace CustomInterfaces { - /** ReflLoadedMainViewPresenter : Handles presentation logic for the reflectometry interface - when a table workspace is loaded as the active table. + /** ReflLegacyTransferStrategy : Replicates the old Reflectometry UI's transfer behaviour. Copyright © 2014 ISIS Rutherford Appleton Laboratory & NScD Oak Ridge National Laboratory @@ -34,21 +31,12 @@ namespace MantidQt File change history is stored at: Code Documentation is available at: */ - class DLLExport ReflLoadedMainViewPresenter: public ReflMainViewPresenter + class DLLExport ReflLegacyTransferStrategy : public ReflTransferStrategy { public: - ReflLoadedMainViewPresenter(Mantid::API::ITableWorkspace_sptr model, ReflMainView* view); - ReflLoadedMainViewPresenter(std::string model, ReflMainView* view); - virtual ~ReflLoadedMainViewPresenter(); - protected: - //press changes to the same item in the ADS - virtual void save(); - //press changes to a new item in the ADS - virtual void saveAs(); + std::vector > transferRuns(const std::map& runRows); }; + } +} - - } // namespace CustomInterfaces -} // namespace Mantid - -#endif /* MANTID_CUSTOMINTERFACES_REFLLOADEDMAINVIEWPRESENTER_H_ */ +#endif diff --git a/Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/ReflMainView.h b/Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/ReflMainView.h index 105e5ddae3c6..e92a8ca7fe73 100644 --- a/Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/ReflMainView.h +++ b/Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/ReflMainView.h @@ -2,7 +2,10 @@ #define MANTID_CUSTOMINTERFACES_REFLMAINVIEW_H #include "MantidKernel/System.h" -#include "MantidAPI/ITableWorkspace.h" +#include "MantidQtCustomInterfaces/IReflPresenter.h" +#include "MantidQtCustomInterfaces/ReflSearchModel.h" +#include "MantidQtCustomInterfaces/QReflTableModel.h" +#include "MantidQtMantidWidgets/HintStrategy.h" namespace MantidQt { @@ -36,11 +39,12 @@ namespace MantidQt class DLLExport ReflMainView { public: - ReflMainView(); - virtual ~ReflMainView() = 0; + ReflMainView() {}; + virtual ~ReflMainView() {}; //Connect the model - virtual void showTable(Mantid::API::ITableWorkspace_sptr model) = 0; + virtual void showTable(QReflTableModel_sptr model) = 0; + virtual void showSearch(ReflSearchModel_sptr model) = 0; //Dialog/Prompt methods virtual std::string askUserString(const std::string& prompt, const std::string& title, const std::string& defaultValue) = 0; @@ -48,16 +52,29 @@ namespace MantidQt virtual void giveUserInfo(std::string prompt, std::string title) = 0; virtual void giveUserWarning(std::string prompt, std::string title) = 0; virtual void giveUserCritical(std::string prompt, std::string title) = 0; + virtual void showAlgorithmDialog(const std::string& algorithm) = 0; + + //Set the status of the progress bar + virtual void setProgressRange(int min, int max) = 0; + virtual void setProgress(int progress) = 0; + + //Settor methods + virtual void setSelection(const std::set& rows) = 0; + virtual void setTableList(const std::set& tables) = 0; + virtual void setInstrumentList(const std::vector& instruments, const std::string& defaultInstrument) = 0; + virtual void setOptionsHintStrategy(MantidQt::MantidWidgets::HintStrategy* hintStrategy) = 0; + virtual void setClipboard(const std::string& text) = 0; //Accessor methods - virtual std::vector getSelectedRowIndexes() const = 0; - - static const int NoFlags = 0; - static const int SaveFlag = 1; - static const int SaveAsFlag = 2; - static const int AddRowFlag = 3; - static const int DeleteRowFlag = 4; - static const int ProcessFlag = 5; + virtual std::set getSelectedRows() const = 0; + virtual std::set getSelectedSearchRows() const = 0; + virtual std::string getSearchInstrument() const = 0; + virtual std::string getProcessInstrument() const = 0; + virtual std::string getWorkspaceToOpen() const = 0; + virtual std::string getClipboard() const = 0; + virtual std::string getSearchString() const = 0; + + virtual boost::shared_ptr getPresenter() const = 0; }; } } diff --git a/Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/ReflMainViewPresenter.h b/Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/ReflMainViewPresenter.h index 5fbf37abb6d7..c2e58c3fce67 100644 --- a/Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/ReflMainViewPresenter.h +++ b/Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/ReflMainViewPresenter.h @@ -1,11 +1,19 @@ #ifndef MANTID_CUSTOMINTERFACES_REFLMAINVIEWPRESENTER_H #define MANTID_CUSTOMINTERFACES_REFLMAINVIEWPRESENTER_H -#include "MantidKernel/System.h" +#include "MantidAPI/AnalysisDataService.h" #include "MantidAPI/ITableWorkspace.h" #include "MantidAPI/MatrixWorkspace.h" -#include "MantidQtCustomInterfaces/ReflMainView.h" +#include "MantidKernel/System.h" #include "MantidQtCustomInterfaces/IReflPresenter.h" +#include "MantidQtCustomInterfaces/IReflSearcher.h" +#include "MantidQtCustomInterfaces/ReflMainView.h" +#include "MantidQtCustomInterfaces/ReflTransferStrategy.h" +#include "MantidQtCustomInterfaces/QReflTableModel.h" + +#include +#include + namespace MantidQt { namespace CustomInterfaces @@ -37,44 +45,112 @@ namespace MantidQt class DLLExport ReflMainViewPresenter: public IReflPresenter { public: - ReflMainViewPresenter(Mantid::API::ITableWorkspace_sptr model, ReflMainView* view); - ReflMainViewPresenter(ReflMainView* view); - virtual ~ReflMainViewPresenter() = 0; - virtual void notify(int flag); + ReflMainViewPresenter(ReflMainView* view, boost::shared_ptr searcher = boost::shared_ptr()); + virtual ~ReflMainViewPresenter(); + virtual void notify(IReflPresenter::Flag flag); + virtual const std::map& options() const; + virtual void setOptions(const std::map& options); + //Public for the purposes of unit testing + static std::map parseKeyValueString(const std::string& str); protected: - //The model and backup copy of the original model - Mantid::API::ITableWorkspace_sptr m_model; - Mantid::API::ITableWorkspace_sptr m_cache; - std::string m_cache_name; - //the view + //the workspace the model is currently representing + Mantid::API::ITableWorkspace_sptr m_ws; + //the models + QReflTableModel_sptr m_model; + ReflSearchModel_sptr m_searchModel; + //the name of the workspace/table/model in the ADS, blank if unsaved + std::string m_wsName; + //the view we're managing ReflMainView* m_view; + //stores whether or not the table has changed since it was last saved + bool m_tableDirty; + //stores the user options for the presenter + std::map m_options; + //the search implementation + boost::shared_ptr m_searcher; + boost::shared_ptr m_transferStrategy; - //Load the model into the view - virtual void load(); //process selected rows virtual void process(); - //make a transmission workspace name - std::string makeTransWSName(const std::string& transString); + //Reduce a row + void reduceRow(int rowNo); + //load a run into the ADS, or re-use one in the ADS if possible + Mantid::API::Workspace_sptr loadRun(const std::string& run, const std::string& instrument); + //get the run number of a TOF workspace + std::string getRunNumber(const Mantid::API::Workspace_sptr& ws); + //get an unused group id + int getUnusedGroup(std::set ignoredRows = std::set()) const; //make a transmission workspace Mantid::API::MatrixWorkspace_sptr makeTransWS(const std::string& transString); - //Process a row - void processRow(size_t rowNo); + //Validate a row + void validateRow(int rowNo) const; + //Autofill a row with sensible values + void autofillRow(int rowNo); + //calculates qmin and qmax + std::vector calcQRange(Mantid::API::MatrixWorkspace_sptr ws, double theta); + //get the number of rows in a group + size_t numRowsInGroup(int groupId) const; + //Stitch some rows + void stitchRows(std::set rows); + //insert a row in the model before the given index + virtual void insertRow(int index); //add row(s) to the model - virtual void addRow(); + virtual void appendRow(); + virtual void prependRow(); //delete row(s) from the model virtual void deleteRow(); - //virtual save methods - virtual void save() = 0; - virtual void saveAs() = 0; + //clear selected row(s) in the model + virtual void clearSelected(); + //copy selected rows to clipboard + virtual void copySelected(); + //copy selected rows to clipboard and then delete them + virtual void cutSelected(); + //paste clipboard into selected rows + virtual void pasteSelected(); + //group selected rows together + virtual void groupRows(); + //expand selection to group + virtual void expandSelection(); + //table io methods + virtual void newTable(); + virtual void openTable(); + virtual void saveTable(); + virtual void saveTableAs(); + virtual void importTable(); + virtual void exportTable(); + //searching + virtual void search(); + virtual void transfer(); + //options + void showOptionsDialog(); + void initOptions(); + + //List of workspaces the user can open + std::set m_workspaceList; + + //To maintain a list of workspaces the user may open, we observe the ADS + Poco::NObserver m_addObserver; + Poco::NObserver m_remObserver; + Poco::NObserver m_clearObserver; + Poco::NObserver m_renameObserver; + Poco::NObserver m_replaceObserver; - static const int COL_RUNS; - static const int COL_ANGLE; - static const int COL_TRANSMISSION; - static const int COL_QMIN; - static const int COL_QMAX; - static const int COL_DQQ; - static const int COL_SCALE; - static const int COL_GROUP; + void handleAddEvent(Mantid::API::WorkspaceAddNotification_ptr pNf); + void handleRemEvent(Mantid::API::WorkspacePostDeleteNotification_ptr pNf); + void handleClearEvent(Mantid::API::ClearADSNotification_ptr pNf); + void handleRenameEvent(Mantid::API::WorkspaceRenameNotification_ptr pNf); + void handleReplaceEvent(Mantid::API::WorkspaceAfterReplaceNotification_ptr pNf); + + public: + static const int COL_RUNS = 0; + static const int COL_ANGLE = 1; + static const int COL_TRANSMISSION = 2; + static const int COL_QMIN = 3; + static const int COL_QMAX = 4; + static const int COL_DQQ = 5; + static const int COL_SCALE = 6; + static const int COL_GROUP = 7; + static const int COL_OPTIONS = 8; }; } } diff --git a/Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/ReflMainWidget.ui b/Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/ReflMainWidget.ui index 07216ff0f5fe..6a9ca25866ee 100644 --- a/Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/ReflMainWidget.ui +++ b/Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/ReflMainWidget.ui @@ -1,358 +1,694 @@ reflMainWidget - + 0 0 - 1043 - 490 + 959 + 346 ISIS Reflectometry - - - - - - 12 - 75 - true - false - - - - PROTOTYPE - - - Qt::AlignCenter - - - - - - - - 0 - 0 - - - - Qt::Horizontal - - - false - - - - Search Runs + + + + 1 + + + + + + 12 + 75 + true + false + + + + PROTOTYPE + + + Qt::AlignCenter - - - - - - - Instrument: - - - comboInstrument - - - - - - - - 0 - 0 - - - - - 150 - 0 - - - - - 75 - true - - - - Sets the instrument to use. - - - - - - - - 0 - 0 - - - - RB Search: - - - textRB - - - - - - - - 0 - 0 - - - - - 40 - 0 - - - - The term to search the archives for - - - Qt::ImhDigitsOnly - - - 0 - - - - - - - - - Search - - - - - - - false - - - true - - - false - - - false - - - - Run # - - - - - Title - - - - - - - - - - - 0 - 0 - - - - Add Run - - - - - - - - - Process Runs + + + + + + 0 + 0 + + + + Qt::Horizontal + + + true - - - - - - - - - New Table - - - - - - - Save Table - - - - - - - Save Table As - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - Qt::Horizontal - - - - - - - - - Table: - - - - - - - - 0 - 0 - - - - - 150 - 0 - - - - - TableWorkspace - - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - Add Row - - - - - - - Delete Row - - - - - - - - - - 0 - 0 - - - - QAbstractItemView::AnyKeyPressed|QAbstractItemView::DoubleClicked|QAbstractItemView::EditKeyPressed|QAbstractItemView::SelectedClicked - - - QAbstractItemView::ContiguousSelection - - - 60 - - - 20 - - - 20 - - - - - - - - 0 - 0 - - - - Process - - - - - - + + + Search Runs + + + + 1 + + + 1 + + + + + + + Instrument: + + + comboSearchInstrument + + + + + + + + 0 + 0 + + + + + 150 + 0 + + + + Select the instrument to search with + + + Specifies which instrument you're searching for data from. + + + + + + + + 0 + 0 + + + + Investigation Id: + + + textSearch + + + + + + + + 0 + 0 + + + + + 40 + 0 + + + + Investigation to search for + + + Specifies the investigation id that you are searching for runs from. + + + Qt::ImhDigitsOnly + + + 0 + + + + + + + + 0 + 0 + + + + Search + + + Searches ICAT for runs from the given instrument with the given investigation id. + + + Search + + + + + + + + + Qt::CustomContextMenu + + + QAbstractItemView::ExtendedSelection + + + QAbstractItemView::SelectRows + + + 60 + + + 20 + + + true + + + false + + + 20 + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + Transfer + + + Qt::ToolButtonTextBesideIcon + + + + + + + + + + Process Runs + + + + 1 + + + 1 + + + + + 1 + + + + + QToolBar{border: none;} + + + + + + + + + + + + + + + + + + + 0 + 0 + + + + Qt::CustomContextMenu + + + QAbstractItemView::AnyKeyPressed|QAbstractItemView::DoubleClicked|QAbstractItemView::EditKeyPressed|QAbstractItemView::SelectedClicked + + + true + + + QAbstractItemView::ExtendedSelection + + + QAbstractItemView::SelectRows + + + 60 + + + 20 + + + true + + + 20 + + + + + + + 1 + + + + + Shows the current progress when processing. + + + 0 + + + + + + + Instrument: + + + + + + + + 0 + 0 + + + + Select the instrument to assume for fetching runs + + + Specifies the instrument that data being processed was generated by. This is used to help identify the correct data to load when given sample run numbers to process. + + + + + + + Process + + + Qt::ToolButtonTextBesideIcon + + + Qt::NoArrow + + + + + + + + + + + + + + + + 0 + 0 + 959 + 23 + + + + false + + + + &Reflectometry + + + + Open Table + + + + :/multiload.png:/multiload.png + - - + + + + + + + + + + + + + &Edit + + + + + + + + + + + + + + + + + + + + + + :/new.png:/new.png + + + New Table + + + Discards the current contents of the processing table and starts afresh. + + + + + + :/filesave.png:/filesave.png + + + Save Table + + + Saves the current contents of the table to the table workspace that was last saved to or opened. If none exist, it prompts for a workspace name to save as. + + + + + + :/filesaveas.png:/filesaveas.png + + + Save Table As + + + Prompts for a workspace name to save the current contents of the table to. + + + + + + :/insert_row.png:/insert_row.png + + + Insert Row After + + + Insert Row After + + + Inserts a new row after the first selected row. If no rows are selected then a new row is added at the end of the table. + + + + + + :/insert_row.png:/insert_row.png + + + Insert Row Before + + + Insert Row Before + + + Inserts a new row before the first selected row. If no rows are selected then a new row is inserted at the start of the table. + + + + + + :/delete_row.png:/delete_row.png + + + Delete Row + + + Deletes the selected rows. + + + + + + :/drag_curves.png:/drag_curves.png + + + Group Selected + + + Places all of the selected rows into the same group. + + + + + + :/stat_rows.png:/stat_rows.png + + + Process + + + Processes the selected rows. If no rows are selected then all rows are processed. + + + + + + :/fit_frame.png:/fit_frame.png + + + Expand Selection + + + Select an entire group + + + Expands the current selection to include any rows that are in the same group as any selected row. + + + + + + :/configure.png:/configure.png + + + Options... + + + Set options for the Reflectometry UI + + + Opens a dialog that allows the behaviour of the Reflectometry UI to be customised. + + + + + + :/erase.png:/erase.png + + + Clear Selected + + + Clears the contents of the selected rows and ungroups them, placing each row into a unique group. + + + + + + :/copy.png:/copy.png + + + Copy Selected + + + Copies the selected rows to the clipboard. Each row is placed on a new line, and each cell is separated by a tab. + + + Ctrl+C + + + + + + :/paste.png:/paste.png + + + Paste Selected + + + Pastes the contents of the clipboard into the selected rows. If no rows are selected, new ones are added at the end of the table. + + + Ctrl+V + + + + + + :/cut.png:/cut.png + + + Cut Selected + + + Copies the selected rows to the clipboard, and then deletes them. Each row is placed on a new line, and each cell is separated by a tab. + + + Ctrl+X + + + + + + :/folder.png:/folder.png + + + Search + + + + + + :/append_drag_curves.png:/append_drag_curves.png + + + Transfer + + + Transfer the selected run(s) to the processing table. + + + Transfers the selected runs into the processing table. + + + + + + :/open_template.png:/open_template.png + + + Import .TBL + + + Import a .TBL file + + + Imports a .TBL file to a workspace using the LoadReflTBL algorithm. The resulting workspace can then be loaded as a table as normal. + + + + + + :/save_template.png:/save_template.png + + + Export .TBL + + + Export a .TBL file + + + Exports a table workspace to a .TBL file that can be used by the ISIS Reflectometry UI in older versions of Mantid. + + - - - MantidQt::MantidWidgets::WorkspaceSelector - QComboBox -
MantidQtMantidWidgets/WorkspaceSelector.h
-
-
- comboInstrument - tableRuns + comboSearchInstrument + tableSearchResults viewTable - buttonProcess - - + + + + + + buttonSearch + clicked() + actionSearch + trigger() + + + 217 + 143 + + + -1 + -1 + + + + + textSearch + returnPressed() + actionSearch + trigger() + + + 228 + 112 + + + -1 + -1 + + + +
diff --git a/Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/ReflOptionsDialog.ui b/Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/ReflOptionsDialog.ui new file mode 100644 index 000000000000..d436410bd92a --- /dev/null +++ b/Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/ReflOptionsDialog.ui @@ -0,0 +1,293 @@ + + + reflOptionsDialog + + + + 0 + 0 + 372 + 222 + + + + + 0 + 0 + + + + Reflectometry UI Options + + + + + + 0 + + + + Warnings + + + + + + Warn when processing all rows + + + WarnProcessAll + + + + + + + Warn when discarding unsaved changes + + + WarnDiscardChanges + + + + + + + Warn when processing only part of a group + + + WarnProcessPartialGroup + + + + + + + + Rounding + + + + + + Round q_max column to + + + RoundQMax + + + + + + + false + + + RoundQMinPrecision + + + + + + + false + + + RoundQMaxPrecision + + + + + + + false + + + RoundDQQPrecision + + + + + + + Round q_min column to + + + RoundQMin + + + + + + + Round dq/q column to + + + RoundDQQ + + + + + + + Round Angle column to + + + RoundAngle + + + + + + + false + + + RoundAnglePrecision + + + + + + + decimal places + + + + + + + decimal places + + + + + + + decimal places + + + + + + + decimal places + + + + + + + + + + + Qt::Horizontal + + + QDialogButtonBox::Cancel|QDialogButtonBox::Ok + + + + + + + + + buttonBox + accepted() + reflOptionsDialog + accept() + + + 248 + 254 + + + 157 + 274 + + + + + buttonBox + rejected() + reflOptionsDialog + reject() + + + 316 + 260 + + + 286 + 274 + + + + + checkRoundAngle + toggled(bool) + spinAnglePrecision + setEnabled(bool) + + + 106 + 53 + + + 226 + 53 + + + + + checkRoundQMin + toggled(bool) + spinQMinPrecision + setEnabled(bool) + + + 106 + 84 + + + 226 + 84 + + + + + checkRoundQMax + toggled(bool) + spinQMaxPrecision + setEnabled(bool) + + + 106 + 115 + + + 226 + 115 + + + + + checkRoundDQQ + toggled(bool) + spinDQQPrecision + setEnabled(bool) + + + 106 + 146 + + + 226 + 146 + + + + + diff --git a/Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/ReflSearchModel.h b/Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/ReflSearchModel.h new file mode 100644 index 000000000000..9659554a59ab --- /dev/null +++ b/Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/ReflSearchModel.h @@ -0,0 +1,67 @@ +#ifndef MANTID_CUSTOMINTERFACES_REFLSEARCHMODEL_H_ +#define MANTID_CUSTOMINTERFACES_REFLSEARCHMODEL_H_ + +#include "MantidAPI/ITableWorkspace.h" +#include +#include +#include +#include + +namespace MantidQt +{ + namespace CustomInterfaces + { + + /** ReflSearchModel : Provides a QAbstractTableModel for a Mantid ITableWorkspace of Reflectometry search results. + + Copyright © 2014 ISIS Rutherford Appleton Laboratory & NScD Oak Ridge National Laboratory + + This file is part of Mantid. + + Mantid is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + Mantid is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + + File change history is stored at: + Code Documentation is available at: + */ + class ReflSearchModel : public QAbstractTableModel + { + Q_OBJECT + public: + ReflSearchModel(Mantid::API::ITableWorkspace_sptr tableWorkspace); + virtual ~ReflSearchModel(); + //row and column counts + int rowCount(const QModelIndex &parent = QModelIndex()) const; + int columnCount(const QModelIndex &parent = QModelIndex()) const; + //get data from a cell + QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const; + //get header data for the table + QVariant headerData(int section, Qt::Orientation orientation, int role) const; + //get flags for a cell + Qt::ItemFlags flags(const QModelIndex &index) const; + + protected: + //vector of the run numbers + std::vector m_runs; + + //maps each run number to its description + std::map m_descriptions; + }; + + /// Typedef for a shared pointer to \c ReflSearchModel + typedef boost::shared_ptr ReflSearchModel_sptr; + + } // namespace CustomInterfaces +} // namespace Mantid + +#endif /* MANTID_CUSTOMINTERFACES_REFLSEARCHMODEL_H_ */ diff --git a/Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/ReflTransferStrategy.h b/Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/ReflTransferStrategy.h new file mode 100644 index 000000000000..781d8b563f64 --- /dev/null +++ b/Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/ReflTransferStrategy.h @@ -0,0 +1,49 @@ +#ifndef MANTID_CUSTOMINTERFACES_REFLTRANSFERSTRATEGY_H +#define MANTID_CUSTOMINTERFACES_REFLTRANSFERSTRATEGY_H + +#include +#include +#include + +namespace MantidQt +{ + namespace CustomInterfaces + { + + /** ReflTransferStrategy : Provides an stratgegy for transferring runs from search results to a format suitable for processing. + + Copyright © 2014 ISIS Rutherford Appleton Laboratory & NScD Oak Ridge National Laboratory + + This file is part of Mantid. + + Mantid is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + Mantid is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + + File change history is stored at: + Code Documentation is available at: + */ + class ReflTransferStrategy + { + public: + virtual ~ReflTransferStrategy() {}; + + /** + * @param runRows : A map where the keys are the runs and the values the descriptions + * @returns A vector of maps where each map represents a row, with values for "runs", "theta", and "group" + */ + virtual std::vector > transferRuns(const std::map& runRows) = 0; + }; + } +} + +#endif diff --git a/Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/ResNorm.h b/Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/ResNorm.h index d84a5506743a..1ed67276dacf 100644 --- a/Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/ResNorm.h +++ b/Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/ResNorm.h @@ -17,6 +17,7 @@ namespace MantidQt // Inherited methods from IndirectBayesTab QString help() { return "ResNorm"; }; + void setup(); bool validate(); void run(); /// Load default settings into the interface @@ -26,9 +27,9 @@ namespace MantidQt /// Handle when the vanadium input is ready void handleVanadiumInputReady(const QString& filename); /// Slot for when the min range on the range selector changes - virtual void minValueChanged(double min); + void minValueChanged(double min); /// Slot for when the min range on the range selector changes - virtual void maxValueChanged(double max); + void maxValueChanged(double max); /// Slot to update the guides when the range properties change void updateProperties(QtProperty* prop, double val); diff --git a/Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/SANSEventSlicing.ui b/Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/SANSEventSlicing.ui index 208b21ab6bbe..35dd6727ceda 100644 --- a/Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/SANSEventSlicing.ui +++ b/Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/SANSEventSlicing.ui @@ -1,7 +1,7 @@ SANSEventSlicing - + 0 @@ -13,6 +13,7 @@ SANS Time Slicing + @@ -214,6 +215,7 @@ + diff --git a/Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/SANSRunWindow.ui b/Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/SANSRunWindow.ui index 1784318c1272..5bf81709ed93 100644 --- a/Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/SANSRunWindow.ui +++ b/Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/SANSRunWindow.ui @@ -1,7 +1,7 @@ SANSRunWindow - + 0 @@ -31,6 +31,7 @@ ISIS SANS + @@ -4166,6 +4167,7 @@ p, li { white-space: pre-wrap; } + diff --git a/Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/StepScan.ui b/Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/StepScan.ui index 8f2896530e41..7f5bb7414559 100644 --- a/Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/StepScan.ui +++ b/Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/StepScan.ui @@ -1,7 +1,7 @@ StepScan - + 0 @@ -13,6 +13,7 @@ Step Scan Analysis + @@ -351,6 +352,7 @@ p, li { white-space: pre-wrap; } + diff --git a/Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/Stretch.h b/Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/Stretch.h index 998ce12dc601..b35d2dec4adf 100644 --- a/Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/Stretch.h +++ b/Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/Stretch.h @@ -17,6 +17,7 @@ namespace MantidQt // Inherited methods from IndirectBayesTab QString help() { return "Stretch"; }; + void setup(); bool validate(); void run(); /// Load default settings into the interface @@ -24,9 +25,9 @@ namespace MantidQt private slots: /// Slot for when the min range on the range selector changes - virtual void minValueChanged(double min); + void minValueChanged(double min); /// Slot for when the min range on the range selector changes - virtual void maxValueChanged(double max); + void maxValueChanged(double max); /// Slot to update the guides when the range properties change void updateProperties(QtProperty* prop, double val); /// Slot to handle when a new sample file is available diff --git a/Code/Mantid/MantidQt/CustomInterfaces/src/ApplyCorr.cpp b/Code/Mantid/MantidQt/CustomInterfaces/src/ApplyCorr.cpp index 4687e3d6da2f..b3ea0d159d27 100644 --- a/Code/Mantid/MantidQt/CustomInterfaces/src/ApplyCorr.cpp +++ b/Code/Mantid/MantidQt/CustomInterfaces/src/ApplyCorr.cpp @@ -127,8 +127,9 @@ namespace IDA } pyInput += "sample = '"+sample+"'\n"; - + pyInput += "rebin_can = False\n"; bool noContainer = false; + if ( uiForm().abscor_ckUseCan->isChecked() ) { QString container = uiForm().abscor_dsContainer->getCurrentDataName(); @@ -154,10 +155,6 @@ namespace IDA return; } } - else - { - pyInput += "rebin_can = False\n"; - } pyInput += "container = '" + container + "'\n"; } diff --git a/Code/Mantid/MantidQt/CustomInterfaces/src/CalcCorr.cpp b/Code/Mantid/MantidQt/CustomInterfaces/src/CalcCorr.cpp index e6941a69f899..8ae5b3c6e9c0 100644 --- a/Code/Mantid/MantidQt/CustomInterfaces/src/CalcCorr.cpp +++ b/Code/Mantid/MantidQt/CustomInterfaces/src/CalcCorr.cpp @@ -26,9 +26,9 @@ class QDoubleMultiRangeValidator : public QValidator } ~QDoubleMultiRangeValidator() {} - + /** - * Reimplemented from QValidator::validate(). + * Reimplemented from QValidator::validate(). * * Returns Acceptable if the string input contains a double that is within at least one * of the ranges and is in the correct format. @@ -286,7 +286,7 @@ namespace IDA "plotOpt = '" + uiForm().absp_cbPlotOutput->currentText() + "'\n" "sampleFormula = " + sampleFormula + "\n" "canFormula = " + canFormula + "\n" - "IndirectAbsCor.AbsRunFeeder(inputws, canws, geom, ncan, size, avar, density, beam, sampleFormula, canFormula, sigs, siga, plotOpt=plotOpt, Save=save, Verbose=verbose)\n"; + "IndirectAbsCor.AbsRunFeeder(inputws, canws, geom, ncan, size, avar, density, beam, sampleFormula, canFormula, sigs, siga, plot_opt=plotOpt, save=save, verbose=verbose)\n"; QString pyOutput = runPythonCode(pyInput).trimmed(); } diff --git a/Code/Mantid/MantidQt/CustomInterfaces/src/ConvFit.cpp b/Code/Mantid/MantidQt/CustomInterfaces/src/ConvFit.cpp index ff96fe15096a..33aa8d97ffd7 100644 --- a/Code/Mantid/MantidQt/CustomInterfaces/src/ConvFit.cpp +++ b/Code/Mantid/MantidQt/CustomInterfaces/src/ConvFit.cpp @@ -30,7 +30,8 @@ namespace IDA m_cfPlot(NULL), m_cfProp(), m_fixedProps(), m_cfRangeS(NULL), m_cfBackgS(NULL), m_cfHwhmRange(NULL), m_cfGrpMng(NULL), m_cfDblMng(NULL), m_cfBlnMng(NULL), m_cfDataCurve(NULL), m_cfCalcCurve(NULL), m_cfInputWS(), m_cfInputWSName(), m_confitResFileType() - {} + { + } void ConvFit::setup() { @@ -67,6 +68,13 @@ namespace IDA m_cfHwhmRange->setColour(Qt::red); // Populate Property Widget + + // Option to convolve members + m_cfProp["Convolve"] = m_cfBlnMng->addProperty("Convolve"); + m_cfTree->addProperty(m_cfProp["Convolve"]); + m_cfBlnMng->setValue(m_cfProp["Convolve"], true); + + // Fit Range m_cfProp["FitRange"] = m_cfGrpMng->addProperty("Fitting Range"); m_cfProp["StartX"] = m_cfDblMng->addProperty("StartX"); m_cfDblMng->setDecimals(m_cfProp["StartX"], NUM_DECIMALS); @@ -76,6 +84,7 @@ namespace IDA m_cfProp["FitRange"]->addSubProperty(m_cfProp["EndX"]); m_cfTree->addProperty(m_cfProp["FitRange"]); + // Background Range m_cfProp["LinearBackground"] = m_cfGrpMng->addProperty("Background"); m_cfProp["BGA0"] = m_cfDblMng->addProperty("A0"); m_cfDblMng->setDecimals(m_cfProp["BGA0"], NUM_DECIMALS); @@ -118,15 +127,16 @@ namespace IDA bgTypeSelection(uiForm().confit_cbBackground->currentIndex()); // Replot input automatically when file / spec no changes - connect(uiForm().confit_leSpecNo, SIGNAL(editingFinished()), this, SLOT(plotInput())); + connect(uiForm().confit_lePlotSpectrum, SIGNAL(editingFinished()), this, SLOT(plotInput())); connect(uiForm().confit_dsSampleInput, SIGNAL(dataReady(const QString&)), this, SLOT(plotInput())); connect(uiForm().confit_cbFitType, SIGNAL(currentIndexChanged(int)), this, SLOT(typeSelection(int))); connect(uiForm().confit_cbBackground, SIGNAL(currentIndexChanged(int)), this, SLOT(bgTypeSelection(int))); connect(uiForm().confit_pbSingle, SIGNAL(clicked()), this, SLOT(singleFit())); - uiForm().confit_leSpecNo->setValidator(m_intVal); - uiForm().confit_leSpecMax->setValidator(m_intVal); + uiForm().confit_lePlotSpectrum->setValidator(m_intVal); + uiForm().confit_leSpectraMin->setValidator(m_intVal); + uiForm().confit_leSpectraMax->setValidator(m_intVal); // Context menu m_cfTree->setContextMenuPolicy(Qt::CustomContextMenu); @@ -173,14 +183,21 @@ namespace IDA "func = r'" + QString::fromStdString(function) + "'\n" "startx = " + stX + "\n" "endx = " + enX + "\n" - "specMin = " + uiForm().confit_leSpecNo->text() + "\n" - "specMax = " + uiForm().confit_leSpecMax->text() + "\n" "plot = '" + uiForm().confit_cbPlotOutput->currentText() + "'\n" "ties = " + ties + "\n" "save = "; + if(uiForm().confit_leSpectraMin->text() != "") + pyInput += "specMin = " + uiForm().confit_leSpectraMin->text() + "\n"; + + if(uiForm().confit_leSpectraMax->text() != "") + pyInput += "specMax = " + uiForm().confit_leSpectraMax->text() + "\n"; + pyInput += uiForm().confit_ckSaveSeq->isChecked() ? "True\n" : "False\n"; + if ( m_cfBlnMng->value(m_cfProp["Convolve"]) ) pyInput += "convolve = True\n"; + else pyInput += "convolve = False\n"; + if ( uiForm().confit_ckVerbose->isChecked() ) pyInput += "verbose = True\n"; else pyInput += "verbose = False\n"; @@ -198,7 +215,7 @@ namespace IDA pyInput += "bg = '" + bg + "'\n" "ftype = '" + ftype + "'\n" - "confitSeq(input, func, startx, endx, ftype, bg, temp, specMin, specMax, Verbose=verbose, Plot=plot, Save=save)\n"; + "confitSeq(input, func, startx, endx, ftype, bg, temp, specMin, specMax, convolve, Verbose=verbose, Plot=plot, Save=save)\n"; QString pyOutput = runPythonCode(pyInput); } @@ -467,6 +484,43 @@ namespace IDA product->applyTies(); } + double ConvFit::getInstrumentResolution(std::string workspaceName) + { + using namespace Mantid::API; + + double resolution = 0.0; + try + { + Mantid::Geometry::Instrument_const_sptr inst = + AnalysisDataService::Instance().retrieveWS(workspaceName)->getInstrument(); + std::string analyser = inst->getStringParameter("analyser")[0]; + + // If the analyser component is not already in the data file the laod it from the parameter file + if(inst->getComponentByName(analyser)->getNumberParameter("resolution").size() == 0) + { + std::string reflection = inst->getStringParameter("reflection")[0]; + + IAlgorithm_sptr loadParamFile = AlgorithmManager::Instance().create("LoadParameterFile"); + loadParamFile->initialize(); + loadParamFile->setProperty("Workspace", workspaceName); + loadParamFile->setProperty("Filename", inst->getName()+"_"+analyser+"_"+reflection+"_Parameters.xml"); + loadParamFile->execute(); + + inst = AnalysisDataService::Instance().retrieveWS(workspaceName)->getInstrument(); + } + + resolution = inst->getComponentByName(analyser)->getNumberParameter("resolution")[0]; + } + catch(Mantid::Kernel::Exception::NotFoundError &e) + { + UNUSED_ARG(e); + + resolution = 0; + } + + return resolution; + } + QtProperty* ConvFit::createLorentzian(const QString & name) { QtProperty* lorentzGroup = m_cfGrpMng->addProperty(name); @@ -616,19 +670,25 @@ namespace IDA } } - int specNo = uiForm().confit_leSpecNo->text().toInt(); + int specNo = uiForm().confit_lePlotSpectrum->text().toInt(); // Set spectra max value - size_t specMax = m_cfInputWS->getNumberHistograms(); - if( specMax > 0 ) specMax -= 1; - if ( specNo < 0 || static_cast(specNo) > specMax ) //cast is okay as the first check is for less-than-zero + int specMin = 0; + int specMax = static_cast(m_cfInputWS->getNumberHistograms()) - 1; + + m_intVal->setRange(specMin, specMax); + uiForm().confit_leSpectraMin->setText(QString::number(specMin)); + uiForm().confit_leSpectraMax->setText(QString::number(specMax)); + + if ( specNo < 0 || specNo > specMax ) { - uiForm().confit_leSpecNo->setText("0"); + uiForm().confit_lePlotSpectrum->setText("0"); specNo = 0; } - int smCurrent = uiForm().confit_leSpecMax->text().toInt(); - if ( smCurrent < 0 || static_cast(smCurrent) > specMax ) + + int smCurrent = uiForm().confit_leSpectraMax->text().toInt(); + if ( smCurrent < 0 || smCurrent > specMax ) { - uiForm().confit_leSpecMax->setText(QString::number(specMax)); + uiForm().confit_leSpectraMax->setText(QString::number(specMax)); } m_cfDataCurve = plotMiniplot(m_cfPlot, m_cfDataCurve, m_cfInputWS, specNo); @@ -642,6 +702,14 @@ namespace IDA { showInformationBox(exc.what()); } + + // Default FWHM to resolution of instrument + double resolution = getInstrumentResolution(m_cfInputWSName.toStdString()); + if(resolution > 0) + { + m_cfDblMng->setValue(m_cfProp["Lorentzian 1.FWHM"], resolution); + m_cfDblMng->setValue(m_cfProp["Lorentzian 2.FWHM"], resolution); + } } void ConvFit::plotGuess(QtProperty*) @@ -737,17 +805,20 @@ namespace IDA } QString outputNm = runPythonCode(QString("from IndirectCommon import getWSprefix\nprint getWSprefix('") + m_cfInputWSName + QString("')\n")).trimmed(); - outputNm += QString("conv_") + ftype + bg + uiForm().confit_leSpecNo->text(); + outputNm += QString("conv_") + ftype + bg + uiForm().confit_lePlotSpectrum->text(); std::string output = outputNm.toStdString(); Mantid::API::IAlgorithm_sptr alg = Mantid::API::AlgorithmManager::Instance().create("Fit"); alg->initialize(); alg->setPropertyValue("Function", function->asString()); alg->setPropertyValue("InputWorkspace", m_cfInputWSName.toStdString()); - alg->setProperty("WorkspaceIndex", uiForm().confit_leSpecNo->text().toInt()); + alg->setProperty("WorkspaceIndex", uiForm().confit_lePlotSpectrum->text().toInt()); alg->setProperty("StartX", m_cfDblMng->value(m_cfProp["StartX"])); alg->setProperty("EndX", m_cfDblMng->value(m_cfProp["EndX"])); - alg->setPropertyValue("Output", output); + alg->setProperty("Output", output); + alg->setProperty("CreateOutput", true); + alg->setProperty("OutputCompositeMembers", true); + alg->setProperty("ConvolveMembers", true); alg->execute(); if ( ! alg->isExecuted() ) diff --git a/Code/Mantid/MantidQt/CustomInterfaces/src/Fury.cpp b/Code/Mantid/MantidQt/CustomInterfaces/src/Fury.cpp index aaae513b86c8..b18a67f68cbb 100644 --- a/Code/Mantid/MantidQt/CustomInterfaces/src/Fury.cpp +++ b/Code/Mantid/MantidQt/CustomInterfaces/src/Fury.cpp @@ -10,6 +10,14 @@ #include +namespace +{ + Mantid::Kernel::Logger g_log("Fury"); +} + +using Mantid::API::MatrixWorkspace; +using Mantid::API::MatrixWorkspace_const_sptr; + namespace MantidQt { namespace CustomInterfaces @@ -17,9 +25,10 @@ namespace CustomInterfaces namespace IDA { Fury::Fury(QWidget * parent) : IDATab(parent), - m_furPlot(NULL), m_furRange(NULL), m_furCurve(NULL), m_furTree(NULL), + m_furPlot(NULL), m_furRange(NULL), m_furCurve(NULL), m_furTree(NULL), m_furProp(), m_furDblMng(NULL), m_furyResFileType() - {} + { + } void Fury::setup() { @@ -34,73 +43,94 @@ namespace IDA m_furPlot->setAxisFont(QwtPlot::xBottom, this->font()); m_furPlot->setAxisFont(QwtPlot::yLeft, this->font()); + // Create and configure properties m_furProp["ELow"] = m_furDblMng->addProperty("ELow"); m_furDblMng->setDecimals(m_furProp["ELow"], NUM_DECIMALS); + m_furProp["EWidth"] = m_furDblMng->addProperty("EWidth"); m_furDblMng->setDecimals(m_furProp["EWidth"], NUM_DECIMALS); + m_furProp["EWidth"]->setEnabled(false); + m_furProp["EHigh"] = m_furDblMng->addProperty("EHigh"); m_furDblMng->setDecimals(m_furProp["EHigh"], NUM_DECIMALS); + m_furProp["SampleBinning"] = m_furDblMng->addProperty("SampleBinning"); + m_furDblMng->setDecimals(m_furProp["SampleBinning"], 0); + + m_furProp["SampleBins"] = m_furDblMng->addProperty("SampleBins"); + m_furDblMng->setDecimals(m_furProp["SampleBins"], 0); + m_furProp["SampleBins"]->setEnabled(false); + + m_furProp["ResolutionBins"] = m_furDblMng->addProperty("ResolutionBins"); + m_furDblMng->setDecimals(m_furProp["ResolutionBins"], 0); + m_furProp["ResolutionBins"]->setEnabled(false); + m_furTree->addProperty(m_furProp["ELow"]); m_furTree->addProperty(m_furProp["EWidth"]); m_furTree->addProperty(m_furProp["EHigh"]); + m_furTree->addProperty(m_furProp["SampleBinning"]); + m_furTree->addProperty(m_furProp["SampleBins"]); + m_furTree->addProperty(m_furProp["ResolutionBins"]); + + m_furDblMng->setValue(m_furProp["SampleBinning"], 10); m_furTree->setFactoryForManager(m_furDblMng, doubleEditorFactory()); m_furRange = new MantidQt::MantidWidgets::RangeSelector(m_furPlot); - m_furRange->setInfoOnly(true); // signals / slots & validators - connect(m_furRange, SIGNAL(minValueChanged(double)), this, SLOT(minChanged(double))); - connect(m_furRange, SIGNAL(maxValueChanged(double)), this, SLOT(maxChanged(double))); + connect(m_furRange, SIGNAL(selectionChangedLazy(double, double)), this, SLOT(rsRangeChangedLazy(double, double))); connect(m_furDblMng, SIGNAL(valueChanged(QtProperty*, double)), this, SLOT(updateRS(QtProperty*, double))); + connect(m_furDblMng, SIGNAL(valueChanged(QtProperty*, double)), this, SLOT(updatePropertyValues(QtProperty*, double))); connect(uiForm().fury_dsInput, SIGNAL(dataReady(const QString&)), this, SLOT(plotInput(const QString&))); + connect(uiForm().fury_dsResInput, SIGNAL(dataReady(const QString&)), this, SLOT(calculateBinning())); } void Fury::run() { - QString pyInput = - "from IndirectDataAnalysis import fury\n"; + using namespace Mantid::API; + + calculateBinning(); QString wsName = uiForm().fury_dsInput->getCurrentDataName(); QString resName = uiForm().fury_dsResInput->getCurrentDataName(); - if(uiForm().fury_dsResInput->isFileSelectorVisible()) - { - runLoadNexus(uiForm().fury_dsResInput->getFullFilePath(), resName); - } + double energyMin = m_furDblMng->value(m_furProp["ELow"]); + double energyMax = m_furDblMng->value(m_furProp["EHigh"]); + long numBins = static_cast(m_furDblMng->value(m_furProp["SampleBinning"])); + + bool plot = uiForm().fury_ckPlot->isChecked(); + bool verbose = uiForm().fury_ckVerbose->isChecked(); + bool save = uiForm().fury_ckSave->isChecked(); - pyInput += "samples = [r'" + wsName + "']\n" - "resolution = r'" + resName + "'\n" - "rebin = '" + m_furProp["ELow"]->valueText() +","+ m_furProp["EWidth"]->valueText() +","+m_furProp["EHigh"]->valueText()+"'\n"; + IAlgorithm_sptr furyAlg = AlgorithmManager::Instance().create("Fury", -1); + furyAlg->initialize(); - if ( uiForm().fury_ckVerbose->isChecked() ) pyInput += "verbose = True\n"; - else pyInput += "verbose = False\n"; + furyAlg->setProperty("Sample", wsName.toStdString()); + furyAlg->setProperty("Resolution", resName.toStdString()); - if ( uiForm().fury_ckPlot->isChecked() ) pyInput += "plot = True\n"; - else pyInput += "plot = False\n"; + furyAlg->setProperty("EnergyMin", energyMin); + furyAlg->setProperty("EnergyMax", energyMax); + furyAlg->setProperty("NumBins", numBins); - if ( uiForm().fury_ckSave->isChecked() ) pyInput += "save = True\n"; - else pyInput += "save = False\n"; + furyAlg->setProperty("Plot", plot); + furyAlg->setProperty("Verbose", verbose); + furyAlg->setProperty("Save", save); + furyAlg->setProperty("DryRun", false); - pyInput += - "fury_ws = fury(samples, resolution, rebin, Save=save, Verbose=verbose, Plot=plot)\n"; - QString pyOutput = runPythonCode(pyInput).trimmed(); + runAlgorithm(furyAlg); } /** - * Ensure we have present and valid file/ws inputs. The underlying Fourier transform of Fury + * Ensure we have present and valid file/ws inputs. + * + * The underlying Fourier transform of Fury * also means we must enforce several rules on the parameters. */ QString Fury::validate() { UserInputValidator uiv; - double eLow = m_furDblMng->value(m_furProp["ELow"]); - double eWidth = m_furDblMng->value(m_furProp["EWidth"]); - double eHigh = m_furDblMng->value(m_furProp["EHigh"]); - - uiv.checkBins(eLow, eWidth, eHigh); uiv.checkDataSelectorIsValid("Sample", uiForm().fury_dsInput); uiv.checkDataSelectorIsValid("Resolution", uiForm().fury_dsResInput); @@ -109,6 +139,104 @@ namespace IDA return message; } + /** + * Ensures that absolute min and max energy are equal. + * + * @param prop Qt property that was changed + * @param val New value of that property + */ + void Fury::updatePropertyValues(QtProperty *prop, double val) + { + disconnect(m_furDblMng, SIGNAL(valueChanged(QtProperty*, double)), this, SLOT(updatePropertyValues(QtProperty*, double))); + + if(prop == m_furProp["EHigh"]) + { + // If the user enters a negative value for EHigh assume they did not mean to add a - + if(val < 0) + { + val = -val; + m_furDblMng->setValue(m_furProp["EHigh"], val); + } + + m_furDblMng->setValue(m_furProp["ELow"], -val); + } + else if(prop == m_furProp["ELow"]) + { + // If the user enters a positive value for ELow, assume they ment to add a + if(val > 0) + { + val = -val; + m_furDblMng->setValue(m_furProp["ELow"], val); + } + + m_furDblMng->setValue(m_furProp["EHigh"], -val); + } + + connect(m_furDblMng, SIGNAL(valueChanged(QtProperty*, double)), this, SLOT(updatePropertyValues(QtProperty*, double))); + + calculateBinning(); + } + + /** + * Calculates binning parameters. + */ + void Fury::calculateBinning() + { + using namespace Mantid::API; + + disconnect(m_furDblMng, SIGNAL(valueChanged(QtProperty*, double)), this, SLOT(updatePropertyValues(QtProperty*, double))); + + QString wsName = uiForm().fury_dsInput->getCurrentDataName(); + QString resName = uiForm().fury_dsResInput->getCurrentDataName(); + + double energyMin = m_furDblMng->value(m_furProp["ELow"]); + double energyMax = m_furDblMng->value(m_furProp["EHigh"]); + long numBins = static_cast(m_furDblMng->value(m_furProp["SampleBinning"])); + + if(wsName.isEmpty() || resName.isEmpty() || numBins == 0) + return; + + bool verbose = uiForm().fury_ckVerbose->isChecked(); + + IAlgorithm_sptr furyAlg = AlgorithmManager::Instance().create("Fury"); + furyAlg->initialize(); + + furyAlg->setProperty("Sample", wsName.toStdString()); + furyAlg->setProperty("Resolution", resName.toStdString()); + furyAlg->setProperty("ParameterWorkspace", "__FuryProperties_temp"); + + furyAlg->setProperty("EnergyMin", energyMin); + furyAlg->setProperty("EnergyMax", energyMax); + furyAlg->setProperty("NumBins", numBins); + + furyAlg->setProperty("Plot", false); + furyAlg->setProperty("Verbose", verbose); + furyAlg->setProperty("Save", false); + furyAlg->setProperty("DryRun", true); + + furyAlg->execute(); + + // Get property table from algorithm + ITableWorkspace_sptr propsTable = AnalysisDataService::Instance().retrieveWS("__FuryProperties_temp"); + + // Get data from property table + double energyWidth = propsTable->getColumn("EnergyWidth")->cell(0); + int sampleBins = propsTable->getColumn("SampleOutputBins")->cell(0); + int resolutionBins = propsTable->getColumn("ResolutionBins")->cell(0); + + // Update data in property editor + m_furDblMng->setValue(m_furProp["EWidth"], energyWidth); + m_furDblMng->setValue(m_furProp["ResolutionBins"], resolutionBins); + m_furDblMng->setValue(m_furProp["SampleBins"], sampleBins); + + connect(m_furDblMng, SIGNAL(valueChanged(QtProperty*, double)), this, SLOT(updatePropertyValues(QtProperty*, double))); + + // Warn for low number of resolution bins + int numResolutionBins = static_cast(m_furDblMng->value(m_furProp["ResolutionBins"])); + if(numResolutionBins < 5) + showInformationBox("Number of resolution bins is less than 5.\nResults may be inaccurate."); + } + void Fury::loadSettings(const QSettings & settings) { uiForm().fury_dsInput->readSettings(settings.group()); @@ -117,9 +245,6 @@ namespace IDA void Fury::plotInput(const QString& wsname) { - using Mantid::API::MatrixWorkspace; - using Mantid::API::MatrixWorkspace_const_sptr; - MatrixWorkspace_const_sptr workspace; try { @@ -134,9 +259,9 @@ namespace IDA m_furCurve = plotMiniplot(m_furPlot, m_furCurve, workspace, 0); try { - const std::pair range = getCurveRange(m_furCurve); - double rounded_min = floor(range.first*10+0.5)/10.0; - double rounded_max = floor(range.second*10+0.5)/10.0; + const std::pair range = getCurveRange(m_furCurve); + double rounded_min = floor(range.first * 10 + 0.5) / 10.0; + double rounded_max = floor(range.second * 10 + 0.5) / 10.0; //corrections for if nearest value is outside of range if (rounded_max > range.second) @@ -170,25 +295,36 @@ namespace IDA { showInformationBox(exc.what()); } - } - void Fury::maxChanged(double val) - { - m_furDblMng->setValue(m_furProp["EHigh"], val); + calculateBinning(); } - void Fury::minChanged(double val) + /** + * Updates the range selectors and properties when range selector is moved. + * + * @param min Range selector min value + * @param max Range selector amx value + */ + void Fury::rsRangeChangedLazy(double min, double max) { - m_furDblMng->setValue(m_furProp["ELow"], val); + double oldMin = m_furDblMng->value(m_furProp["ELow"]); + double oldMax = m_furDblMng->value(m_furProp["EHigh"]); + + if(fabs(oldMin - min) > 0.0000001) + m_furDblMng->setValue(m_furProp["ELow"], min); + + if(fabs(oldMax - max) > 0.0000001) + m_furDblMng->setValue(m_furProp["EHigh"], max); } void Fury::updateRS(QtProperty* prop, double val) { - if ( prop == m_furProp["ELow"] ) + if(prop == m_furProp["ELow"]) m_furRange->setMinimum(val); - else if ( prop == m_furProp["EHigh"] ) + else if(prop == m_furProp["EHigh"]) m_furRange->setMaximum(val); } + } // namespace IDA } // namespace CustomInterfaces } // namespace MantidQt diff --git a/Code/Mantid/MantidQt/CustomInterfaces/src/FuryFit.cpp b/Code/Mantid/MantidQt/CustomInterfaces/src/FuryFit.cpp index ad02b7e64810..e9d80f7d07b1 100644 --- a/Code/Mantid/MantidQt/CustomInterfaces/src/FuryFit.cpp +++ b/Code/Mantid/MantidQt/CustomInterfaces/src/FuryFit.cpp @@ -99,7 +99,7 @@ namespace IDA // Signal/slot ui connections connect(uiForm().furyfit_inputFile, SIGNAL(fileEditingFinished()), this, SLOT(plotInput())); connect(uiForm().furyfit_cbFitType, SIGNAL(currentIndexChanged(int)), this, SLOT(typeSelection(int))); - connect(uiForm().furyfit_leSpecNo, SIGNAL(editingFinished()), this, SLOT(plotInput())); + connect(uiForm().furyfit_lePlotSpectrum, SIGNAL(editingFinished()), this, SLOT(plotInput())); connect(uiForm().furyfit_cbInputType, SIGNAL(currentIndexChanged(int)), uiForm().furyfit_swInput, SLOT(setCurrentIndex(int))); connect(uiForm().furyfit_pbSingle, SIGNAL(clicked()), this, SLOT(singleFit())); @@ -110,7 +110,9 @@ namespace IDA connect(uiForm().furyfit_cbInputType, SIGNAL(currentIndexChanged(int)), this, SLOT(plotInput())); // apply validators - furyfit - uiForm().furyfit_leSpecNo->setValidator(m_intVal); + uiForm().furyfit_lePlotSpectrum->setValidator(m_intVal); + uiForm().furyfit_leSpectraMin->setValidator(m_intVal); + uiForm().furyfit_leSpectraMax->setValidator(m_intVal); // Set a custom handler for the QTreePropertyBrowser's ContextMenu event m_ffTree->setContextMenuPolicy(Qt::CustomContextMenu); @@ -150,8 +152,13 @@ namespace IDA "ftype = '" + fitTypeString() + "'\n" "startx = " + m_ffProp["StartX"]->valueText() + "\n" "endx = " + m_ffProp["EndX"]->valueText() + "\n" - "plot = '" + uiForm().furyfit_cbPlotOutput->currentText() + "'\n"; + "plot = '" + uiForm().furyfit_cbPlotOutput->currentText() + "'\n" + "spec_min = " + uiForm().furyfit_leSpectraMin->text() + "\n" + "spec_max = None\n"; + if(uiForm().furyfit_leSpectraMax->text() != "") + pyInput += "spec_max = " + uiForm().furyfit_leSpectraMax->text() + "\n"; + if (constrainIntens) pyInput += "constrain_intens = True \n"; else pyInput += "constrain_intens = False \n"; @@ -163,11 +170,11 @@ namespace IDA if( !constrainBeta ) { - pyInput += "furyfitSeq(input, func, ftype, startx, endx, constrain_intens, Save=save, Plot=plot, Verbose=verbose)\n"; + pyInput += "furyfitSeq(input, func, ftype, startx, endx, spec_min=spec_min, spec_max=spec_max, intensities_constrained=constrain_intens, Save=save, Plot=plot, Verbose=verbose)\n"; } else { - pyInput += "furyfitMult(input, func, ftype, startx, endx, constrain_intens, Save=save, Plot=plot, Verbose=verbose)\n"; + pyInput += "furyfitMult(input, func, ftype, startx, endx, spec_min=spec_min, spec_max=spec_max, intensities_constrained=constrain_intens, Save=save, Plot=plot, Verbose=verbose)\n"; } QString pyOutput = runPythonCode(pyInput); @@ -421,8 +428,14 @@ namespace IDA break; } - int specNo = uiForm().furyfit_leSpecNo->text().toInt(); + int specNo = uiForm().furyfit_lePlotSpectrum->text().toInt(); int nHist = static_cast(m_ffInputWS->getNumberHistograms()); + int specMin = 0; + int specMax = nHist - 1; + + m_intVal->setRange(specMin, specMax); + uiForm().furyfit_leSpectraMin->setText(QString::number(specMin)); + uiForm().furyfit_leSpectraMax->setText(QString::number(specMax)); if( specNo < 0 || specNo >= nHist ) { @@ -434,7 +447,7 @@ namespace IDA { specNo = nHist-1; } - uiForm().furyfit_leSpecNo->setText(QString::number(specNo)); + uiForm().furyfit_lePlotSpectrum->setText(QString::number(specNo)); } m_ffDataCurve = plotMiniplot(m_ffPlot, m_ffDataCurve, m_ffInputWS, specNo); @@ -599,7 +612,7 @@ namespace IDA QString pyInput = "from IndirectCommon import getWSprefix\nprint getWSprefix('%1')\n"; pyInput = pyInput.arg(m_ffInputWSName); QString outputNm = runPythonCode(pyInput).trimmed(); - outputNm += QString("fury_") + ftype + uiForm().furyfit_leSpecNo->text(); + outputNm += QString("fury_") + ftype + uiForm().furyfit_lePlotSpectrum->text(); std::string output = outputNm.toStdString(); // Create the Fit Algorithm @@ -607,7 +620,7 @@ namespace IDA alg->initialize(); alg->setPropertyValue("Function", function->asString()); alg->setPropertyValue("InputWorkspace", m_ffInputWSName.toStdString()); - alg->setProperty("WorkspaceIndex", uiForm().furyfit_leSpecNo->text().toInt()); + alg->setProperty("WorkspaceIndex", uiForm().furyfit_lePlotSpectrum->text().toInt()); alg->setProperty("StartX", m_ffRangeManager->value(m_ffProp["StartX"])); alg->setProperty("EndX", m_ffRangeManager->value(m_ffProp["EndX"])); alg->setProperty("Ties", m_ties.toStdString()); diff --git a/Code/Mantid/MantidQt/CustomInterfaces/src/IDATab.cpp b/Code/Mantid/MantidQt/CustomInterfaces/src/IDATab.cpp index c61030eba070..8e629fed9f21 100644 --- a/Code/Mantid/MantidQt/CustomInterfaces/src/IDATab.cpp +++ b/Code/Mantid/MantidQt/CustomInterfaces/src/IDATab.cpp @@ -21,7 +21,7 @@ namespace IDA * * @param parent :: the parent widget (an IndirectDataAnalysis object). */ - IDATab::IDATab(QWidget * parent) : QWidget(parent), m_parent(NULL) + IDATab::IDATab(QWidget * parent) : QWidget(parent), m_algRunner(new MantidQt::API::AlgorithmRunner(parent)), m_parent(NULL) { m_parent = dynamic_cast(parent); } @@ -104,6 +104,17 @@ namespace IDA return m_parent->runPythonCode(code, no_output); } + /** + * Runs an algorithm async + * + * @param algorithm :: The algorithm to be run + */ + void IDATab::runAlgorithm(const Mantid::API::IAlgorithm_sptr algorithm) + { + algorithm->setRethrows(true); + m_algRunner->startAlgorithm(algorithm); + } + /** * Run load nexus and return the workspace * @param filename A full path to the filename diff --git a/Code/Mantid/MantidQt/CustomInterfaces/src/IndirectBayes.cpp b/Code/Mantid/MantidQt/CustomInterfaces/src/IndirectBayes.cpp index 8f791ef1f140..073f0c610255 100644 --- a/Code/Mantid/MantidQt/CustomInterfaces/src/IndirectBayes.cpp +++ b/Code/Mantid/MantidQt/CustomInterfaces/src/IndirectBayes.cpp @@ -110,9 +110,9 @@ void IndirectBayes::runClicked() { int tabIndex = m_uiForm.indirectBayesTabs->currentIndex(); - if(m_bayesTabs[tabIndex]->validate()) + if(m_bayesTabs[tabIndex]->validateTab()) { - m_bayesTabs[tabIndex]->run(); + m_bayesTabs[tabIndex]->runTab(); } } diff --git a/Code/Mantid/MantidQt/CustomInterfaces/src/IndirectBayesTab.cpp b/Code/Mantid/MantidQt/CustomInterfaces/src/IndirectBayesTab.cpp index 7139ae889bf1..0e3a0cbdfe8f 100644 --- a/Code/Mantid/MantidQt/CustomInterfaces/src/IndirectBayesTab.cpp +++ b/Code/Mantid/MantidQt/CustomInterfaces/src/IndirectBayesTab.cpp @@ -4,6 +4,8 @@ #include "MantidQtAPI/UserSubWindow.h" #include "MantidQtCustomInterfaces/IndirectBayesTab.h" +using MantidQt::MantidWidgets::RangeSelector; + namespace MantidQt { namespace CustomInterfaces @@ -12,22 +14,13 @@ namespace MantidQt //---------------------------------------------------------------------------------------------- /** Constructor */ - IndirectBayesTab::IndirectBayesTab(QWidget * parent) : QWidget(parent), - m_plot(new QwtPlot(parent)), m_curve(new QwtPlotCurve()), m_rangeSelector(new MantidWidgets::RangeSelector(m_plot)), - m_propTree(new QtTreePropertyBrowser()), m_properties(), m_dblManager(new QtDoublePropertyManager()), - m_dblEdFac(new DoubleEditorFactory()) + IndirectBayesTab::IndirectBayesTab(QWidget * parent) : IndirectTab(parent), + m_propTree(new QtTreePropertyBrowser()) { m_propTree->setFactoryForManager(m_dblManager, m_dblEdFac); - m_rangeSelector->setInfoOnly(false); - connect(m_rangeSelector, SIGNAL(minValueChanged(double)), this, SLOT(minValueChanged(double))); - connect(m_rangeSelector, SIGNAL(maxValueChanged(double)), this, SLOT(maxValueChanged(double))); + // Connect double maneger signals connect(m_dblManager, SIGNAL(valueChanged(QtProperty*, double)), this, SLOT(updateProperties(QtProperty*, double))); - - // initilise plot - m_plot->setCanvasBackground(Qt::white); - m_plot->setAxisFont(QwtPlot::xBottom, parent->font()); - m_plot->setAxisFont(QwtPlot::yLeft, parent->font()); } //---------------------------------------------------------------------------------------------- @@ -39,18 +32,18 @@ namespace MantidQt /** * Method to build a URL to the appropriate page on the wiki for this tab. - * + * * @return The URL to the wiki page */ QString IndirectBayesTab::tabHelpURL() - { + { return "http://www.mantidproject.org/IndirectBayes:" + help(); } /** * Emits a signal to run a python script using the method in the parent * UserSubWindow - * + * * @param pyInput :: A string of python code to execute */ void IndirectBayesTab::runPythonScript(const QString& pyInput) @@ -59,63 +52,7 @@ namespace MantidQt } /** - * Plot a workspace to the miniplot given a workspace name and - * a specturm index. - * - * This method uses the analysis data service to retrieve the workspace. - * - * @param workspace :: The name of the workspace - * @param index :: The spectrum index of the workspace - */ - void IndirectBayesTab::plotMiniPlot(const QString& workspace, size_t index) - { - auto ws = Mantid::API::AnalysisDataService::Instance().retrieveWS(workspace.toStdString()); - plotMiniPlot(ws, index); - } - - /** - * Plot a workspace to the miniplot given a workspace pointer and - * a specturm index. - * - * @param workspace :: Pointer to the workspace - * @param wsIndex :: The spectrum index of the workspace - */ - void IndirectBayesTab::plotMiniPlot(const Mantid::API::MatrixWorkspace_const_sptr & workspace, size_t wsIndex) - { - using Mantid::MantidVec; - - //check if we can plot - if( wsIndex >= workspace->getNumberHistograms() || workspace->readX(0).size() < 2 ) - { - return; - } - - QwtWorkspaceSpectrumData wsData(*workspace, static_cast(wsIndex), false); - - if ( m_curve != NULL ) - { - m_curve->attach(0); - delete m_curve; - m_curve = NULL; - } - - size_t nhist = workspace->getNumberHistograms(); - if ( wsIndex >= nhist ) - { - emit showMessageBox("Error: Workspace index out of range."); - } - else - { - m_curve = new QwtPlotCurve(); - m_curve->setData(wsData); - m_curve->attach(m_plot); - - m_plot->replot(); - } - } - - /** - * Checks the workspace's intrument for a resolution parameter to use as + * Checks the workspace's intrument for a resolution parameter to use as * a default for the energy range on the mini plot * * @param workspace :: Name of the workspace to use @@ -128,7 +65,7 @@ namespace MantidQt } /** - * Checks the workspace's intrument for a resolution parameter to use as + * Checks the workspace's intrument for a resolution parameter to use as * a default for the energy range on the mini plot * * @param ws :: Pointer to the workspace to use @@ -155,90 +92,39 @@ namespace MantidQt return false; } - /** - * Gets the range of the curve plotted in the mini plot - * - * @return A pair containing the maximum and minimum points of the curve - */ - std::pair IndirectBayesTab::getCurveRange() - { - size_t npts = m_curve->data().size(); - - if( npts < 2 ) - throw std::invalid_argument("Too few points on data curve to determine range."); - - return std::make_pair(m_curve->data().x(0), m_curve->data().x(npts-1)); - } - - /** - * Sets the edge bounds of plot to prevent the user inputting invalid values - * - * @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 IndirectBayesTab::setPlotRange(QtProperty* min, QtProperty* max, const std::pair& 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_rangeSelector->setRange(bounds.first, bounds.second); - } - - /** - * Set the position of the guides on the mini plot - * - * @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 IndirectBayesTab::setMiniPlotGuides(QtProperty* lower, QtProperty* upper, const std::pair& bounds) - { - m_dblManager->setValue(lower, bounds.first); - m_dblManager->setValue(upper, bounds.second); - m_rangeSelector->setMinimum(bounds.first); - m_rangeSelector->setMaximum(bounds.second); - } - /** * Set the position of the lower guide on the mini plot - * + * + * @param rs :: Range selector to update * @param lower :: The lower guide property in the property browser * @param upper :: The upper guide property in the property browser * @param value :: The value of the lower guide */ - void IndirectBayesTab::updateLowerGuide(QtProperty* lower, QtProperty* upper, double value) + void IndirectBayesTab::updateLowerGuide(RangeSelector* rs, QtProperty* lower, QtProperty* upper, double value) { // Check if the user is setting the max less than the min if(value > m_dblManager->value(upper)) - { m_dblManager->setValue(lower, m_dblManager->value(upper)); - } else - { - m_rangeSelector->setMinimum(value); - } + rs->setMinimum(value); } /** * Set the position of the upper guide on the mini plot - * + * + * @param rs :: Range selector to update * @param lower :: The lower guide property in the property browser * @param upper :: The upper guide property in the property browser * @param value :: The value of the upper guide */ - void IndirectBayesTab::updateUpperGuide(QtProperty* lower, QtProperty* upper, double value) + void IndirectBayesTab::updateUpperGuide(RangeSelector* rs, QtProperty* lower, QtProperty* upper, double value) { // Check if the user is setting the min greater than the max if(value < m_dblManager->value(lower)) - { m_dblManager->setValue(upper, m_dblManager->value(lower)); - } else - { - m_rangeSelector->setMaximum(value); - } + rs->setMaximum(value); } + } } // namespace MantidQt diff --git a/Code/Mantid/MantidQt/CustomInterfaces/src/IndirectCalibration.cpp b/Code/Mantid/MantidQt/CustomInterfaces/src/IndirectCalibration.cpp index 9ffb09e31f8c..51b186d669fd 100644 --- a/Code/Mantid/MantidQt/CustomInterfaces/src/IndirectCalibration.cpp +++ b/Code/Mantid/MantidQt/CustomInterfaces/src/IndirectCalibration.cpp @@ -4,11 +4,16 @@ #include +using namespace Mantid::API; + namespace { Mantid::Kernel::Logger g_log("IndirectCalibration"); } +using namespace Mantid::API; +using MantidQt::API::BatchAlgorithmRunner; + namespace MantidQt { namespace CustomInterfaces @@ -17,7 +22,7 @@ namespace CustomInterfaces /** Constructor */ IndirectCalibration::IndirectCalibration(Ui::IndirectDataReduction& uiForm, QWidget * parent) : - IndirectDataReductionTab(uiForm, parent) + IndirectDataReductionTab(uiForm, parent), m_lastCalPlotFilename("") { DoubleEditorFactory *doubleEditorFactory = new DoubleEditorFactory(); @@ -108,13 +113,16 @@ namespace CustomInterfaces m_rangeSelectors["ResBackground"]->setColour(Qt::darkGreen); m_rangeSelectors["ResPeak"] = new MantidWidgets::RangeSelector(m_plots["ResPlot"], MantidQt::MantidWidgets::RangeSelector::XMINMAX, true, true); - + // MISC UI m_uiForm.cal_leIntensityScaleMultiplier->setValidator(m_valDbl); m_uiForm.cal_leResScale->setValidator(m_valDbl); m_uiForm.cal_valIntensityScaleMultiplier->setText(" "); // 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))); // Update property map when a range seclector is moved @@ -134,8 +142,6 @@ namespace CustomInterfaces connect(m_uiForm.cal_pbPlot, SIGNAL(clicked()), this, SLOT(calPlotRaw())); // Toggle RES file options when user toggles Create RES File checkbox connect(m_uiForm.cal_ckRES, SIGNAL(toggled(bool)), this, SLOT(resCheck(bool))); - // Toggle RES range selector when user toggles Create RES File checkbox - connect(m_uiForm.cal_ckRES, SIGNAL(toggled(bool)), m_uiForm.cal_ckResScale, SLOT(setEnabled(bool))); // Enable/disable RES scaling option when user toggles Scale RES checkbox connect(m_uiForm.cal_ckResScale, SIGNAL(toggled(bool)), m_uiForm.cal_leResScale, SLOT(setEnabled(bool))); // Enable/dosable scale factor option when user toggles Intensity Scale Factor checkbox @@ -143,80 +149,99 @@ namespace CustomInterfaces // Validate the value entered in scale factor option whenever it changes connect(m_uiForm.cal_leIntensityScaleMultiplier, SIGNAL(textChanged(const QString &)), this, SLOT(calibValidateIntensity(const QString &))); + // Shows message on run buton when user is inputting a run number + connect(m_uiForm.cal_leRunNo, SIGNAL(fileTextChanged(const QString &)), this, SLOT(pbRunEditing())); + // Shows message on run button when Mantid is finding the file for a given run number + connect(m_uiForm.cal_leRunNo, SIGNAL(findingFiles()), this, SLOT(pbRunFinding())); + // Reverts run button back to normal when file finding has finished + connect(m_uiForm.cal_leRunNo, SIGNAL(fileFindingFinished()), this, SLOT(pbRunFinished())); + // Nudge resCheck to ensure res range selectors are only shown when Create RES file is checked resCheck(m_uiForm.cal_ckRES->isChecked()); } - + //---------------------------------------------------------------------------------------------- /** Destructor */ IndirectCalibration::~IndirectCalibration() { } - + void IndirectCalibration::setup() { } void IndirectCalibration::run() { - QString file = m_uiForm.cal_leRunNo->getFirstFilename(); - QString filenames = "[r'"+m_uiForm.cal_leRunNo->getFilenames().join("', r'")+"']"; - - QString reducer = "from mantid.simpleapi import SaveNexus\n" - "from inelastic_indirect_reduction_steps import CreateCalibrationWorkspace\n" - "calib = CreateCalibrationWorkspace()\n" - "calib.set_files(" + filenames + ")\n" - "calib.set_detector_range(" + m_uiForm.leSpectraMin->text() + "-1, " + m_uiForm.leSpectraMax->text() + "-1)\n" - "calib.set_parameters(" + m_properties["CalBackMin"]->valueText() + "," - + m_properties["CalBackMax"]->valueText() + "," - + m_properties["CalPeakMin"]->valueText() + "," - + m_properties["CalPeakMax"]->valueText() + ")\n" - "calib.set_analyser('" + m_uiForm.cbAnalyser->currentText() + "')\n" - "calib.set_reflection('" + m_uiForm.cbReflection->currentText() + "')\n"; - - //Scale values by arbitrary scalar if requested + connect(m_batchAlgoRunner, SIGNAL(batchComplete(bool)), this, SLOT(algorithmsComplete(bool))); + + // Get properties + QString firstFile = m_uiForm.cal_leRunNo->getFirstFilename(); + QString filenames = m_uiForm.cal_leRunNo->getFilenames().join(","); + + auto instDetails = getInstrumentDetails(); + QString detectorRange = instDetails["spectra-min"] + "," + instDetails["spectra-max"]; + + QString peakRange = m_properties["CalPeakMin"]->valueText() + "," + m_properties["CalPeakMax"]->valueText(); + QString backgroundRange = m_properties["CalBackMin"]->valueText() + "," + m_properties["CalBackMax"]->valueText(); + + QFileInfo firstFileInfo(firstFile); + QString outputWorkspaceName = firstFileInfo.baseName() + "_" + m_uiForm.cbAnalyser->currentText() + m_uiForm.cbReflection->currentText() + "_calib"; + + // Configure the calibration algorithm + IAlgorithm_sptr calibrationAlg = AlgorithmManager::Instance().create("CreateCalibrationWorkspace", -1); + calibrationAlg->initialize(); + + calibrationAlg->setProperty("InputFiles", filenames.toStdString()); + calibrationAlg->setProperty("OutputWorkspace", outputWorkspaceName.toStdString()); + + calibrationAlg->setProperty("DetectorRange", detectorRange.toStdString()); + calibrationAlg->setProperty("PeakRange", peakRange.toStdString()); + calibrationAlg->setProperty("BackgroundRange", backgroundRange.toStdString()); + + calibrationAlg->setProperty("Plot", m_uiForm.cal_ckPlotResult->isChecked()); + if(m_uiForm.cal_ckIntensityScaleMultiplier->isChecked()) { - QString scale = m_uiForm.cal_leIntensityScaleMultiplier->text(); + QString scale = m_uiForm.cal_leIntensityScaleMultiplier->text(); if(scale.isEmpty()) - { - scale = "1.0"; - } - reducer += "calib.set_intensity_scale("+scale+")\n"; - } + scale = "1.0"; + calibrationAlg->setProperty("ScaleFactor", scale.toStdString()); + } + m_batchAlgoRunner->addAlgorithm(calibrationAlg); - reducer += "calib.execute(None, None)\n" - "result = calib.result_workspace()\n" - "print result\n"; + // Properties for algorithms that use data from calibration as an input + BatchAlgorithmRunner::AlgorithmRuntimeProps inputFromCalProps; + inputFromCalProps["InputWorkspace"] = outputWorkspaceName.toStdString(); - if( m_uiForm.cal_ckSave->isChecked() ) - { - reducer += - "SaveNexus(InputWorkspace=result, Filename=result+'.nxs')\n"; - } + // Add save algorithm to queue if ticked + if( m_uiForm.cal_ckSave->isChecked() ) + { + IAlgorithm_sptr saveAlg = AlgorithmManager::Instance().create("SaveNexus", -1); + saveAlg->initialize(); + saveAlg->setProperty("Filename", outputWorkspaceName.toStdString() + ".nxs"); - if ( m_uiForm.cal_ckPlotResult->isChecked() ) - { - reducer += "from mantidplot import plotTimeBin\n" - "plotTimeBin(result, 0)\n"; - } + m_batchAlgoRunner->addAlgorithm(saveAlg, inputFromCalProps); + } - QString pyOutput = m_pythonRunner.runPythonCode(reducer).trimmed(); + m_batchAlgoRunner->executeBatchAsync(); + } - if ( pyOutput == "" ) - { - emit showMessageBox("An error occurred creating the calib file.\n"); - } - else - { - if ( m_uiForm.cal_ckRES->isChecked() ) - { - createRESfile(filenames); - } - m_uiForm.ind_calibFile->setFileTextWithSearch(pyOutput + ".nxs"); - m_uiForm.ckUseCalib->setChecked(true); - } + void IndirectCalibration::algorithmsComplete(bool error) + { + if(error) + return; + + if(m_uiForm.cal_ckRES->isChecked()) + { + QString filenames = m_uiForm.cal_leRunNo->getFilenames().join(","); + createRESfile(filenames); + } + + /* m_uiForm.ind_calibFile->setFileTextWithSearch(pyOutput + ".nxs"); */ + m_uiForm.ckUseCalib->setChecked(true); + + disconnect(m_batchAlgoRunner, SIGNAL(batchComplete(bool)), this, SLOT(algorithmsComplete(bool))); } bool IndirectCalibration::validate() @@ -264,7 +289,7 @@ namespace CustomInterfaces } /** - * Sets default spectra, peak and background ranges + * Sets default spectra, peak and background ranges. */ void IndirectCalibration::setDefaultInstDetails() { @@ -272,17 +297,17 @@ namespace CustomInterfaces std::map instDetails = getInstrumentDetails(); //Set spectra range - m_dblManager->setValue(m_properties["ResSpecMin"], instDetails["SpectraMin"].toDouble()); - m_dblManager->setValue(m_properties["ResSpecMax"], instDetails["SpectraMax"].toDouble()); + m_dblManager->setValue(m_properties["ResSpecMin"], instDetails["spectra-min"].toDouble()); + m_dblManager->setValue(m_properties["ResSpecMax"], instDetails["spectra-max"].toDouble()); - //Set pean and background ranges - if(instDetails.size() >= 8) - { - setMiniPlotGuides("CalPeak", m_properties["CalPeakMin"], m_properties["CalPeakMax"], - std::pair(instDetails["PeakMin"].toDouble(), instDetails["PeakMax"].toDouble())); - setMiniPlotGuides("CalBackground", m_properties["CalBackMin"], m_properties["CalBackMax"], - std::pair(instDetails["BackMin"].toDouble(), instDetails["BackMax"].toDouble())); - } + //Set peak and background ranges + std::map ranges = getRangesFromInstrument(); + + std::pair peakRange(ranges["peak-start-tof"], ranges["peak-end-tof"]); + std::pair backgroundRange(ranges["back-start-tof"], ranges["back-end-tof"]); + + setMiniPlotGuides("CalPeak", m_properties["CalPeakMin"], m_properties["CalPeakMax"], peakRange); + setMiniPlotGuides("CalBackground", m_properties["CalBackMin"], m_properties["CalBackMax"], backgroundRange); } /** @@ -294,6 +319,12 @@ namespace CustomInterfaces QString filename = m_uiForm.cal_leRunNo->getFirstFilename(); + // Don't do anything if the file we would plot has not changed + if(filename == m_lastCalPlotFilename) + return; + + m_lastCalPlotFilename = filename; + if ( filename.isEmpty() ) { emit showMessageBox("Cannot plot raw data without filename"); @@ -303,7 +334,11 @@ namespace CustomInterfaces QFileInfo fi(filename); QString wsname = fi.baseName(); - if(!loadFile(filename, wsname, m_uiForm.leSpectraMin->text().toInt(), m_uiForm.leSpectraMax->text().toInt())) + auto instDetails = getInstrumentDetails(); + int specMin = instDetails["spectra-min"].toInt(); + int specMax = instDetails["spectra-max"].toInt(); + + if(!loadFile(filename, wsname, specMin, specMax)) { emit showMessageBox("Unable to load file.\nCheck whether your file exists and matches the selected instrument in the Energy Transfer tab."); return; @@ -338,28 +373,26 @@ namespace CustomInterfaces return; } - QString files = "[r'" + m_uiForm.cal_leRunNo->getFilenames().join("', r'") + "']"; - QString pyInput = - "from IndirectEnergyConversion import resolution\n" - "iconOpt = { 'first': " +QString::number(m_dblManager->value(m_properties["ResSpecMin"]))+ - ", 'last': " +QString::number(m_dblManager->value(m_properties["ResSpecMax"]))+ "}\n" - "instrument = '" + m_uiForm.cbInst->currentText() + "'\n" - "analyser = '" + m_uiForm.cbAnalyser->currentText() + "'\n" - "reflection = '" + m_uiForm.cbReflection->currentText() + "'\n" - "files = " + files + "\n" - "outWS = resolution(files, iconOpt, '', '', instrument, analyser, reflection, Res=False)\n" - "print outWS\n"; - QString pyOutput = m_pythonRunner.runPythonCode(pyInput).trimmed(); - - //Something went wrong in the Python - if(pyOutput == "None") - { - emit showMessageBox("Failed to convert to energy. See log for details."); - return; - } + QString files = m_uiForm.cal_leRunNo->getFilenames().join(","); + + QFileInfo fi(m_uiForm.cal_leRunNo->getFirstFilename()); + QString outWS = fi.baseName() + "_" + m_uiForm.cbAnalyser->currentText() + + m_uiForm.cbReflection->currentText() + "_red"; + + QString detRange = QString::number(m_dblManager->value(m_properties["ResSpecMin"])) + "," + + QString::number(m_dblManager->value(m_properties["ResSpecMax"])); + + IAlgorithm_sptr reductionAlg = AlgorithmManager::Instance().create("InelasticIndirectReduction"); + reductionAlg->initialize(); + reductionAlg->setProperty("Instrument", m_uiForm.cbInst->currentText().toStdString()); + reductionAlg->setProperty("Analyser", m_uiForm.cbAnalyser->currentText().toStdString()); + reductionAlg->setProperty("Reflection", m_uiForm.cbReflection->currentText().toStdString()); + reductionAlg->setProperty("InputFiles", files.toStdString()); + reductionAlg->setProperty("DetectorRange", detRange.toStdString()); + reductionAlg->execute(); Mantid::API::MatrixWorkspace_sptr input = boost::dynamic_pointer_cast( - Mantid::API::AnalysisDataService::Instance().retrieve(pyOutput.toStdString())); + Mantid::API::AnalysisDataService::Instance().retrieve(outWS.toStdString())); const Mantid::MantidVec & dataX = input->readX(0); std::pair range(dataX.front(), dataX.back()); @@ -491,11 +524,16 @@ namespace CustomInterfaces { m_rangeSelectors["ResPeak"]->setVisible(state); m_rangeSelectors["ResBackground"]->setVisible(state); + + // Toggle scale and smooth options + m_uiForm.cal_ckResScale->setEnabled(state); + m_uiForm.cal_ckResScale->setChecked(false); + m_uiForm.cal_ckSmooth->setEnabled(state); } /** * This function is called after calib has run and creates a RES file for use in later analysis (Fury,etc) - * + * * @param file :: the input file (WBV run.raw) */ void IndirectCalibration::createRESfile(const QString& file) @@ -509,57 +547,48 @@ namespace CustomInterfaces } } - QString pyInput = - "from IndirectEnergyConversion import resolution\n" - "iconOpt = { 'first': " +QString::number(m_dblManager->value(m_properties["ResSpecMin"]))+ - ", 'last': " +QString::number(m_dblManager->value(m_properties["ResSpecMax"]))+"}\n" + QFileInfo fi(file); + QString outWS = fi.baseName() + "_" + m_uiForm.cbAnalyser->currentText() + + m_uiForm.cbReflection->currentText() + "_res"; + /* outWS = outWS.toLower(); */ - "instrument = '" + m_uiForm.cbInst->currentText() + "'\n" - "analyser = '" + m_uiForm.cbAnalyser->currentText() + "'\n" - "reflection = '" + m_uiForm.cbReflection->currentText() + "'\n"; + QString detRange = QString::number(m_dblManager->value(m_properties["ResSpecMin"])) + "," + + QString::number(m_dblManager->value(m_properties["ResSpecMax"])); - if ( m_uiForm.cal_ckPlotResult->isChecked() ) { pyInput += "plot = True\n"; } - else { pyInput += "plot = False\n"; } + QString rebinString = QString::number(m_dblManager->value(m_properties["ResELow"])) + "," + + QString::number(m_dblManager->value(m_properties["ResEWidth"])) + "," + + QString::number(m_dblManager->value(m_properties["ResEHigh"])); - if ( m_uiForm.cal_ckVerbose->isChecked() ) { pyInput += "verbose = True\n"; } - else { pyInput += "verbose = False\n"; } + QString background = QString::number(m_dblManager->value(m_properties["ResStart"])) + "," + + QString::number(m_dblManager->value(m_properties["ResEnd"])); - if ( m_uiForm.cal_ckSave->isChecked() ) { pyInput += "save = True\n"; } - else { pyInput += "save = False\n"; } + Mantid::API::IAlgorithm_sptr resAlg = Mantid::API::AlgorithmManager::Instance().create("IndirectResolution", -1); + resAlg->initialize(); - QString rebinParam = QString::number(m_dblManager->value(m_properties["ResELow"])) + "," + - QString::number(m_dblManager->value(m_properties["ResEWidth"])) + "," + - QString::number(m_dblManager->value(m_properties["ResEHigh"])); + resAlg->setProperty("InputFiles", file.toStdString()); + resAlg->setProperty("OutputWorkspace", outWS.toStdString()); + + resAlg->setProperty("Instrument", m_uiForm.cbInst->currentText().toStdString()); + resAlg->setProperty("Analyser", m_uiForm.cbAnalyser->currentText().toStdString()); + resAlg->setProperty("Reflection", m_uiForm.cbReflection->currentText().toStdString()); + + resAlg->setProperty("RebinParam", rebinString.toStdString()); + + resAlg->setProperty("DetectorRange", detRange.toStdString()); + resAlg->setProperty("BackgroundRange", background.toStdString()); + + resAlg->setProperty("ScaleFactor", m_uiForm.cal_leIntensityScaleMultiplier->text().toDouble()); + resAlg->setProperty("Smooth", m_uiForm.cal_ckSmooth->isChecked()); + + resAlg->setProperty("Verbose", m_uiForm.cal_ckVerbose->isChecked()); + resAlg->setProperty("Plot", m_uiForm.cal_ckPlotResult->isChecked()); + resAlg->setProperty("Save", m_uiForm.cal_ckSave->isChecked()); + + resAlg->execute(); - QString background = "[ " +QString::number(m_dblManager->value(m_properties["ResStart"]))+ ", " +QString::number(m_dblManager->value(m_properties["ResEnd"]))+"]"; - - QString scaled = m_uiForm.cal_ckIntensityScaleMultiplier->isChecked() ? "True" : "False"; - pyInput += - "background = " + background + "\n" - "rebinParam = '" + rebinParam + "'\n" - "file = " + file + "\n" - "ws = resolution(file, iconOpt, rebinParam, background, instrument, analyser, reflection, Verbose=verbose, Plot=plot, Save=save, factor="+scaleFactor+")\n" - "scaled = "+ scaled +"\n" - "scaleFactor = "+m_uiForm.cal_leIntensityScaleMultiplier->text()+"\n" - "backStart = "+QString::number(m_dblManager->value(m_properties["CalBackMin"]))+"\n" - "backEnd = "+QString::number(m_dblManager->value(m_properties["CalBackMax"]))+"\n" - "rebinLow = "+QString::number(m_dblManager->value(m_properties["ResELow"]))+"\n" - "rebinWidth = "+QString::number(m_dblManager->value(m_properties["ResEWidth"]))+"\n" - "rebinHigh = "+QString::number(m_dblManager->value(m_properties["ResEHigh"]))+"\n" - "AddSampleLog(Workspace=ws, LogName='scale', LogType='String', LogText=str(scaled))\n" - "if scaled:" - " AddSampleLog(Workspace=ws, LogName='scale_factor', LogType='Number', LogText=str(scaleFactor))\n" - "AddSampleLog(Workspace=ws, LogName='back_start', LogType='Number', LogText=str(backStart))\n" - "AddSampleLog(Workspace=ws, LogName='back_end', LogType='Number', LogText=str(backEnd))\n" - "AddSampleLog(Workspace=ws, LogName='rebin_low', LogType='Number', LogText=str(rebinLow))\n" - "AddSampleLog(Workspace=ws, LogName='rebin_width', LogType='Number', LogText=str(rebinWidth))\n" - "AddSampleLog(Workspace=ws, LogName='rebin_high', LogType='Number', LogText=str(rebinHigh))\n"; - - QString pyOutput = m_pythonRunner.runPythonCode(pyInput).trimmed(); - - if ( pyOutput != "" ) + if(!resAlg->isExecuted()) { - emit showMessageBox("Unable to create RES file: \n" + pyOutput); + emit showMessageBox("Unable to create RES file"); } } @@ -592,5 +621,39 @@ namespace CustomInterfaces } } + /** + * Called when a user starts to type / edit the runs to load. + */ + void IndirectCalibration::pbRunEditing() + { + emit updateRunButton(false, "Editing...", "Run numbers are curently being edited."); + } + + /** + * Called when the FileFinder starts finding the files. + */ + void IndirectCalibration::pbRunFinding() + { + emit updateRunButton(false, "Finding files...", "Searchig for data files for the run numbers entered..."); + m_uiForm.cal_leRunNo->setEnabled(false); + } + + /** + * Called when the FileFinder has finished finding the files. + */ + void IndirectCalibration::pbRunFinished() + { + if(!m_uiForm.cal_leRunNo->isValid()) + { + emit updateRunButton(false, "Invalid Run(s)", "Cannot find data files for some of the run numbers enetered."); + } + else + { + emit updateRunButton(); + } + + m_uiForm.cal_leRunNo->setEnabled(true); + } + } // namespace CustomInterfaces } // namespace Mantid diff --git a/Code/Mantid/MantidQt/CustomInterfaces/src/IndirectConvertToEnergy.cpp b/Code/Mantid/MantidQt/CustomInterfaces/src/IndirectConvertToEnergy.cpp index 1fed6a127f35..9718efca4d08 100644 --- a/Code/Mantid/MantidQt/CustomInterfaces/src/IndirectConvertToEnergy.cpp +++ b/Code/Mantid/MantidQt/CustomInterfaces/src/IndirectConvertToEnergy.cpp @@ -2,6 +2,7 @@ #include "MantidQtCustomInterfaces/Background.h" +#include #include namespace MantidQt @@ -25,12 +26,10 @@ namespace CustomInterfaces m_uiForm.entryRebinLow->setValidator(m_valDbl); m_uiForm.entryRebinWidth->setValidator(m_valDbl); m_uiForm.entryRebinHigh->setValidator(m_valDbl); - + // SIGNAL/SLOT CONNECTIONS - // Updates current analyser when analyser is selected from drop down - connect(m_uiForm.cbAnalyser, SIGNAL(activated(int)), this, SLOT(analyserSelected(int))); - // Updates current reflection when reflection is selected from drop down - connect(m_uiForm.cbReflection, SIGNAL(activated(int)), this, SLOT(reflectionSelected(int))); + // Update instrument information when a new instrument config is selected + connect(this, SIGNAL(newInstrumentConfiguration()), this, SLOT(setInstrumentDefault())); // Shows required mapping option UI widgets when a new mapping option is selected from drop down connect(m_uiForm.cbMappingOptions, SIGNAL(currentIndexChanged(const QString&)), this, SLOT(mappingOptionSelected(const QString&))); // Shows background removal dialog when user clicks Background Removal @@ -78,144 +77,108 @@ namespace CustomInterfaces IndirectConvertToEnergy::~IndirectConvertToEnergy() { } - + void IndirectConvertToEnergy::setup() { + detailedBalanceCheck(m_uiForm.ckDetailedBalance->isChecked()); + scaleMultiplierCheck(m_uiForm.ckScaleMultiplier->isChecked()); + + // Load the default instrument parameters + setInstrumentDefault(); } void IndirectConvertToEnergy::run() { - QString pyInput = - "import inelastic_indirect_reducer as iir\n" - "reducer = iir.IndirectReducer()\n" - "reducer.set_instrument_name('" + m_uiForm.cbInst->currentText() + "')\n" - "reducer.set_detector_range(" +m_uiForm.leSpectraMin->text()+ "-1, " +m_uiForm.leSpectraMax->text()+ "-1)\n" - "reducer.set_parameter_file('" + QString::fromStdString(Mantid::Kernel::ConfigService::Instance().getString("instrumentDefinition.directory")) + m_uiForm.cbInst->currentText() + "_" + m_uiForm.cbAnalyser->currentText() + "_" + m_uiForm.cbReflection->currentText() + "_Parameters.xml')\n"; + using namespace Mantid::API; + using MantidQt::API::BatchAlgorithmRunner; - QStringList files = m_uiForm.ind_runFiles->getFilenames(); - for ( QStringList::iterator it = files.begin(); it != files.end(); ++it ) - { - pyInput += "reducer.append_data_file(r'" + *it + "')\n"; - } + IAlgorithm_sptr reductionAlg = AlgorithmManager::Instance().create("InelasticIndirectReduction", -1); + reductionAlg->initialize(); + BatchAlgorithmRunner::AlgorithmRuntimeProps reductionRuntimeProps; - if ( m_uiForm.ckSumFiles->isChecked() ) - { - pyInput += "reducer.set_sum_files(True)\n"; - } + reductionAlg->setProperty("Instrument", m_uiForm.cbInst->currentText().toStdString()); + reductionAlg->setProperty("Analyser", m_uiForm.cbAnalyser->currentText().toStdString()); + reductionAlg->setProperty("Reflection", m_uiForm.cbReflection->currentText().toStdString()); - if ( m_bgRemoval ) - { - QPair background = m_backgroundDialog->getRange(); - pyInput += "reducer.set_background("+QString::number(background.first)+", "+QString::number(background.second)+")\n"; - } + QString files = m_uiForm.ind_runFiles->getFilenames().join(","); + reductionAlg->setProperty("InputFiles", files.toStdString()); - if ( m_uiForm.ckUseCalib->isChecked() ) + reductionAlg->setProperty("SumFiles", m_uiForm.ckSumFiles->isChecked()); + reductionAlg->setProperty("LoadLogs", m_uiForm.ckLoadLogs->isChecked()); + + // If using a calibration file, load it + if(m_uiForm.ckUseCalib->isChecked()) { - pyInput += - "from IndirectCommon import loadNexus\n" - "reducer.set_calibration_workspace(loadNexus(r'"+m_uiForm.ind_calibFile->getFirstFilename()+"'))\n"; + QString calibFilename = m_uiForm.ind_calibFile->getFirstFilename(); + + QFileInfo fi(calibFilename); + std::string calibWorkspaceName = fi.baseName().toStdString(); + + IAlgorithm_sptr calibLoadAlg = AlgorithmManager::Instance().create("LoadNexus", -1); + calibLoadAlg->initialize(); + calibLoadAlg->setProperty("Filename", calibFilename.toStdString()); + calibLoadAlg->setProperty("OutputWorkspace", calibWorkspaceName); + m_batchAlgoRunner->addAlgorithm(calibLoadAlg); + + reductionRuntimeProps["CalibrationWorkspace"] = calibWorkspaceName; } - if ( m_uiForm.ckLoadLogs->isChecked() ) + std::vector detectorRange; + detectorRange.push_back(m_uiForm.leSpectraMin->text().toInt()); + detectorRange.push_back(m_uiForm.leSpectraMax->text().toInt()); + reductionAlg->setProperty("DetectorRange", detectorRange); + + if(m_bgRemoval) { - pyInput += "reducer.set_load_logs(True)\n"; + QPair background = m_backgroundDialog->getRange(); + std::vector backgroundRange; + backgroundRange.push_back(background.first); + backgroundRange.push_back(background.second); + reductionAlg->setProperty("BackgroundRange", backgroundRange); } - if ( ! m_uiForm.rebin_ckDNR->isChecked() ) + if(!m_uiForm.rebin_ckDNR->isChecked()) { QString rebin; - if ( m_uiForm.comboRebinType->currentIndex() == 0 ) - { + if(m_uiForm.comboRebinType->currentIndex() == 0) rebin = m_uiForm.entryRebinLow->text() + "," + m_uiForm.entryRebinWidth->text() + "," + m_uiForm.entryRebinHigh->text(); - } else - { rebin = m_uiForm.entryRebinString->text(); - } - pyInput += "reducer.set_rebin_string('"+rebin+"')\n"; - } - - if ( m_uiForm.ckDetailedBalance->isChecked() ) - { - pyInput += "reducer.set_detailed_balance(" + m_uiForm.leDetailedBalance->text() + ")\n"; - } - if ( m_uiForm.ckScaleMultiplier->isChecked() ) - { - pyInput += "reducer.set_scale_factor(" + m_uiForm.leScaleMultiplier->text() + ")\n"; - } - - if ( m_uiForm.cbMappingOptions->currentText() != "Default" ) - { - QString grouping = createMapFile(m_uiForm.cbMappingOptions->currentText()); - pyInput += "reducer.set_grouping_policy('" + grouping + "')\n"; + reductionAlg->setProperty("RebinString", rebin.toStdString()); } - if ( ! m_uiForm.ckRenameWorkspace->isChecked() ) - { - pyInput += "reducer.set_rename(False)\n"; - } + if(m_uiForm.ckDetailedBalance->isChecked()) + reductionAlg->setProperty("DetailedBalance", m_uiForm.leDetailedBalance->text().toDouble()); - if ( ! m_uiForm.ckFold->isChecked() ) - { - pyInput += "reducer.set_fold_multiple_frames(False)\n"; - } + if(m_uiForm.ckScaleMultiplier->isChecked()) + reductionAlg->setProperty("ScaleFactor", m_uiForm.leScaleMultiplier->text().toDouble()); - if( m_uiForm.ckCm1Units->isChecked() ) + if(m_uiForm.cbMappingOptions->currentText() != "Default") { - pyInput += "reducer.set_save_to_cm_1(True)\n"; + QString grouping = createMapFile(m_uiForm.cbMappingOptions->currentText()); + reductionAlg->setProperty("Grouping", grouping.toStdString()); } - pyInput += "reducer.set_save_formats([" + savePyCode() + "])\n"; - - pyInput += - "reducer.reduce()\n" - "ws_list = reducer.get_result_workspaces()\n"; + reductionAlg->setProperty("Fold", m_uiForm.ckFold->isChecked()); + reductionAlg->setProperty("SaveCM1", m_uiForm.ckCm1Units->isChecked()); + reductionAlg->setProperty("SaveFormats", getSaveFormats()); // Plot Output options - switch ( m_uiForm.ind_cbPlotOutput->currentIndex() ) + switch(m_uiForm.ind_cbPlotOutput->currentIndex()) { case 0: // "None" break; case 1: // "Spectra" - { - // Plot a spectra of the first result workspace - pyInput += - "if ( len(ws_list) > 0 ):\n" - " nSpec = mtd[ws_list[0]].getNumberHistograms()\n" - " plotSpectrum(ws_list[0], range(0, nSpec))\n"; - } + reductionAlg->setProperty("Plot", "spectra"); break; case 2: // "Contour" - { - // Plot a 2D Contour Lines of the first result workspace - pyInput += - "if ( len(ws_list) > 0 ):\n" - " ws = importMatrixWorkspace(ws_list[0])\n" - " ws.plotGraph2D()\n"; - } + reductionAlg->setProperty("Plot", "contour"); break; } - // add sample logs to each of the workspaces - QString calibChecked = m_uiForm.ckUseCalib->isChecked() ? "True" : "False"; - QString detailedBalance = m_uiForm.ckDetailedBalance->isChecked() ? "True" : "False"; - QString scaled = m_uiForm.ckScaleMultiplier->isChecked() ? "True" : "False"; - pyInput += "calibCheck = "+calibChecked+"\n" - "detailedBalance = "+detailedBalance+"\n" - "scaled = "+scaled+"\n" - "for ws in ws_list:\n" - " AddSampleLog(Workspace=ws, LogName='calib_file', LogType='String', LogText=str(calibCheck))\n" - " if calibCheck:\n" - " AddSampleLog(Workspace=ws, LogName='calib_file_name', LogType='String', LogText='"+m_uiForm.ind_calibFile->getFirstFilename()+"')\n" - " AddSampleLog(Workspace=ws, LogName='detailed_balance', LogType='String', LogText=str(detailedBalance))\n" - " if detailedBalance:\n" - " AddSampleLog(Workspace=ws, LogName='detailed_balance_temp', LogType='Number', LogText='"+m_uiForm.leDetailedBalance->text()+"')\n" - " AddSampleLog(Workspace=ws, LogName='scale', LogType='String', LogText=str(scaled))\n" - " if scaled:\n" - " AddSampleLog(Workspace=ws, LogName='scale_factor', LogType='Number', LogText='"+m_uiForm.leScaleMultiplier->text()+"')\n"; - - QString pyOutput = m_pythonRunner.runPythonCode(pyInput).trimmed(); + m_batchAlgoRunner->addAlgorithm(reductionAlg); + m_batchAlgoRunner->executeBatchAsync(); } bool IndirectConvertToEnergy::validate() @@ -236,7 +199,7 @@ namespace CustomInterfaces // mapping selection if ( - ( m_uiForm.cbMappingOptions->currentText() == "Groups" && m_uiForm.leNoGroups->text() == "" ) + ( m_uiForm.cbMappingOptions->currentText() == "Groups" && m_uiForm.leNoGroups->text() == "" ) || ( m_uiForm.cbMappingOptions->currentText() == "File" && ! m_uiForm.ind_mapFile->isValid() ) ) @@ -286,7 +249,7 @@ namespace CustomInterfaces const QString specMax = m_uiForm.leSpectraMax->text(); if (specMin.isEmpty() || specMax.isEmpty() || - (specMin.toDouble() < 1 || specMax.toDouble() < 1) || + (specMin.toDouble() < 1 || specMax.toDouble() < 1) || (specMin.toDouble() > specMax.toDouble())) { valid = false; @@ -358,97 +321,58 @@ namespace CustomInterfaces return valid; } - /** - * This function is called when the user selects an analyser from the cbAnalyser QComboBox - * object. It's main purpose is to initialise the values for the Reflection ComboBox. - * @param index :: Index of the value selected in the combo box. - */ - void IndirectConvertToEnergy::analyserSelected(int index) - { - // populate Reflection combobox with correct values for Analyser selected. - m_uiForm.cbReflection->clear(); - clearReflectionInfo(); - - QVariant currentData = m_uiForm.cbAnalyser->itemData(index); - if ( currentData == QVariant::Invalid ) - { - m_uiForm.lbReflection->setEnabled(false); - m_uiForm.cbReflection->setEnabled(false); - return; - } - else - { - m_uiForm.lbReflection->setEnabled(true); - m_uiForm.cbReflection->setEnabled(true); - QStringList reflections = currentData.toStringList(); - for ( int i = 0; i < reflections.count(); i++ ) - { - m_uiForm.cbReflection->addItem(reflections[i]); - } - } - - reflectionSelected(m_uiForm.cbReflection->currentIndex()); - } /** - * This function is called when the user selects a reflection from the cbReflection QComboBox - * object. - * @param index :: Index of the value selected in the combo box. + * Called when the instrument has changed, used to update default values. */ - void IndirectConvertToEnergy::reflectionSelected(int index) + void IndirectConvertToEnergy::setInstrumentDefault() { - UNUSED_ARG(index); - // first, clear values in assosciated boxes: - clearReflectionInfo(); + m_uiForm.leSpectraMin->clear(); + m_uiForm.leSpectraMax->clear(); + m_uiForm.leEfixed->clear(); std::map instDetails = getInstrumentDetails(); - if ( instDetails.size() < 3 ) + if(instDetails["spectra-min"].isEmpty() || instDetails["spectra-max"].isEmpty()) { emit showMessageBox("Could not gather necessary data from parameter file."); return; } - else - { - m_uiForm.leSpectraMin->setText(instDetails["SpectraMin"]); - m_uiForm.leSpectraMax->setText(instDetails["SpectraMax"]); - if ( instDetails.size() >= 8 ) - { - m_uiForm.leEfixed->setText(instDetails["EFixed"]); - } - else - { - m_uiForm.leEfixed->clear(); - } + m_uiForm.leSpectraMin->setText(instDetails["spectra-min"]); + m_uiForm.leSpectraMax->setText(instDetails["spectra-max"]); + + if(!instDetails["efixed-val"].isEmpty()) + m_uiForm.leEfixed->setText(instDetails["efixed-val"]); + else + m_uiForm.leEfixed->clear(); - // Default rebinning parameters can be set in instrument parameter file - if ( instDetails.size() == 9 ) + // Default rebinning parameters can be set in instrument parameter file + if(!instDetails["rebin-default"].isEmpty()) + { + m_uiForm.entryRebinString->setText(instDetails["rebin-default"]); + m_uiForm.rebin_ckDNR->setChecked(false); + QStringList rbp = instDetails["rebin-default"].split(",", QString::SkipEmptyParts); + if ( rbp.size() == 3 ) { - m_uiForm.entryRebinString->setText(instDetails["RebinString"]); - m_uiForm.rebin_ckDNR->setChecked(false); - QStringList rbp = instDetails["RebinString"].split(",", QString::SkipEmptyParts); - if ( rbp.size() == 3 ) - { - m_uiForm.entryRebinLow->setText(rbp[0]); - m_uiForm.entryRebinWidth->setText(rbp[1]); - m_uiForm.entryRebinHigh->setText(rbp[2]); - m_uiForm.comboRebinType->setCurrentIndex(0); - } - else - { - m_uiForm.comboRebinType->setCurrentIndex(1); - } + m_uiForm.entryRebinLow->setText(rbp[0]); + m_uiForm.entryRebinWidth->setText(rbp[1]); + m_uiForm.entryRebinHigh->setText(rbp[2]); + m_uiForm.comboRebinType->setCurrentIndex(0); } else { - m_uiForm.rebin_ckDNR->setChecked(true); - m_uiForm.entryRebinLow->setText(""); - m_uiForm.entryRebinWidth->setText(""); - m_uiForm.entryRebinHigh->setText(""); - m_uiForm.entryRebinString->setText(""); + m_uiForm.comboRebinType->setCurrentIndex(1); } } + else + { + m_uiForm.rebin_ckDNR->setChecked(true); + m_uiForm.entryRebinLow->setText(""); + m_uiForm.entryRebinWidth->setText(""); + m_uiForm.entryRebinHigh->setText(""); + m_uiForm.entryRebinString->setText(""); + } } /** @@ -502,85 +426,13 @@ namespace CustomInterfaces m_uiForm.pbBack_2->setText("Background Removal (Off)"); } - /** - * This function holds any steps that must be performed on the selection of an instrument, - * for example loading values from the Instrument Definition File (IDF). - * @param prefix :: The selected instruments prefix in Mantid. - */ - void IndirectConvertToEnergy::setIDFValues(const QString & prefix) - { - UNUSED_ARG(prefix); - // empty ComboBoxes, LineEdits,etc of previous values - m_uiForm.cbAnalyser->clear(); - m_uiForm.cbReflection->clear(); - clearReflectionInfo(); - - rebinEntryToggle(m_uiForm.rebin_ckDNR->isChecked()); - detailedBalanceCheck(m_uiForm.ckDetailedBalance->isChecked()); - /* resCheck(m_uiForm.cal_ckRES->isChecked()); */ - - scaleMultiplierCheck(m_uiForm.ckScaleMultiplier->isChecked()); - - // Get list of analysers and populate cbAnalyser - QString pyInput = - "from IndirectEnergyConversion import getInstrumentDetails\n" - "result = getInstrumentDetails('" + m_uiForm.cbInst->currentText() + "')\n" - "print result\n"; - - QString pyOutput = m_pythonRunner.runPythonCode(pyInput, false).trimmed(); - - if ( pyOutput == "" ) - { - emit showMessageBox("Could not get list of analysers from Instrument Parameter file."); - } - else - { - QStringList analysers = pyOutput.split("\n", QString::SkipEmptyParts); - - for (int i = 0; i< analysers.count(); i++ ) - { - QStringList analyser = analysers[i].split("-", QString::SkipEmptyParts); - QString text = analyser[0]; - - if ( text != "diffraction" ) // do not put diffraction into the analyser list - { - QVariant data; // holds Data field of combo box (list of reflections) - - if ( analyser.count() > 1 ) - { - QStringList reflections = analyser[1].split(",", QString::SkipEmptyParts); - data = QVariant(reflections); - m_uiForm.cbAnalyser->addItem(text, data); - } - else - { - m_uiForm.cbAnalyser->addItem(text); - } - } - } - - analyserSelected(m_uiForm.cbAnalyser->currentIndex()); - } - } - - /** - * This function clears the values of the QLineEdit objec ts used to hold Reflection-specific - * information. - */ - void IndirectConvertToEnergy::clearReflectionInfo() - { - m_uiForm.leSpectraMin->clear(); - m_uiForm.leSpectraMax->clear(); - m_uiForm.leEfixed->clear(); - } - /** * This function will disable the necessary elements of the interface when the user selects "Do Not Rebin" * and enable them again when this is de-selected. * * @param state :: whether the "Do Not Rebin" checkbox is checked */ - void IndirectConvertToEnergy::rebinEntryToggle(bool state) + void IndirectConvertToEnergy::rebinEntryToggle(bool state) { //Determine value for single rebin field QString val; @@ -642,76 +494,66 @@ namespace CustomInterfaces */ QString IndirectConvertToEnergy::createMapFile(const QString& groupType) { - QString groupFile, ngroup, nspec; - QString ndet = "( "+m_uiForm.leSpectraMax->text()+" - "+m_uiForm.leSpectraMin->text()+") + 1"; + using namespace Mantid::API; - if ( groupType == "File" ) + QString specRange = m_uiForm.leSpectraMin->text() + "," + m_uiForm.leSpectraMax->text(); + + if(groupType == "File") { - groupFile = m_uiForm.ind_mapFile->getFirstFilename(); - if ( groupFile == "" ) + QString groupFile = m_uiForm.ind_mapFile->getFirstFilename(); + if(groupFile == "") { emit showMessageBox("You must enter a path to the .map file."); } return groupFile; } - else if ( groupType == "Groups" ) - { - ngroup = m_uiForm.leNoGroups->text(); - nspec = "( " +ndet+ " ) / " +ngroup; - } - else if ( groupType == "All" ) + else if(groupType == "Groups") { - return "All"; - } - else if ( groupType == "Individual" ) - { - return "Individual"; - } + QString groupWS = "__Grouping"; - groupFile = m_uiForm.cbInst->itemData(m_uiForm.cbInst->currentIndex()).toString().toLower(); - groupFile += "_" + m_uiForm.cbAnalyser->currentText() + m_uiForm.cbReflection->currentText(); - groupFile += "_" + groupType + ".map"; + IAlgorithm_sptr groupingAlg = AlgorithmManager::Instance().create("CreateGroupingWorkspace"); + groupingAlg->initialize(); - QString pyInput = - "import IndirectEnergyConversion as ind\n" - "mapfile = ind.createMappingFile('"+groupFile+"', %1, %2, %3)\n" - "print mapfile\n"; - pyInput = pyInput.arg(ngroup); - pyInput = pyInput.arg(nspec); - pyInput = pyInput.arg(m_uiForm.leSpectraMin->text()); + groupingAlg->setProperty("FixedGroupCount", m_uiForm.leNoGroups->text().toInt()); + groupingAlg->setProperty("InstrumentName", m_uiForm.cbInst->currentText().toStdString()); + groupingAlg->setProperty("ComponentName", m_uiForm.cbAnalyser->currentText().toStdString()); + groupingAlg->setProperty("OutputWorkspace", groupWS.toStdString()); - QString pyOutput = m_pythonRunner.runPythonCode(pyInput).trimmed(); + m_batchAlgoRunner->addAlgorithm(groupingAlg); - return pyOutput; + return groupWS; + } + else + { + // Catch All and Individual + return groupType; + } } /** - * This function creates the Python script necessary to set the variables used for saving data - * in the main convert_to_energy script. - * @return python code as a string + * Converts the checkbox selection to a comma delimited list of save formats for the + * InelasticIndirectReduction algorithm. + * + * @return A vector of save formats */ - QString IndirectConvertToEnergy::savePyCode() + std::vector IndirectConvertToEnergy::getSaveFormats() { - QStringList fileFormats; - QString fileFormatList; + std::vector fileFormats; if ( m_uiForm.save_ckNexus->isChecked() ) - fileFormats << "nxs"; + fileFormats.push_back("nxs"); if ( m_uiForm.save_ckSPE->isChecked() ) - fileFormats << "spe"; + fileFormats.push_back("spe"); if ( m_uiForm.save_ckNxSPE->isChecked() ) - fileFormats << "nxspe"; + fileFormats.push_back("nxspe"); if ( m_uiForm.save_ckAscii->isChecked() ) - fileFormats << "ascii"; + fileFormats.push_back("ascii"); if ( m_uiForm.save_ckAclimax->isChecked() ) - fileFormats << "aclimax"; + fileFormats.push_back("aclimax"); + if ( m_uiForm.save_ckDaveGrp->isChecked() ) + fileFormats.push_back("davegrp"); - if ( fileFormats.size() != 0 ) - fileFormatList = "'" + fileFormats.join("', '") + "'"; - else - fileFormatList = ""; - - return fileFormatList; + return fileFormats; } /** @@ -719,68 +561,109 @@ namespace CustomInterfaces */ void IndirectConvertToEnergy::plotRaw() { - if ( m_uiForm.ind_runFiles->isValid() ) + using namespace Mantid::API; + using MantidQt::API::BatchAlgorithmRunner; + + if(!m_uiForm.ind_runFiles->isValid()) { - bool ok; - QString spectraRange = QInputDialog::getText(0, "Insert Spectra Ranges", "Range: ", QLineEdit::Normal, m_uiForm.leSpectraMin->text() +"-"+ m_uiForm.leSpectraMax->text(), &ok); + emit showMessageBox("You must select a run file."); + return; + } - if ( !ok || spectraRange.isEmpty() ) - { - return; - } - QStringList specList = spectraRange.split("-"); + bool ok; + QString spectraRange = QInputDialog::getText(0, "Insert Spectra Ranges", "Range: ", QLineEdit::Normal, m_uiForm.leSpectraMin->text() +"-"+ m_uiForm.leSpectraMax->text(), &ok); - QString rawFile = m_uiForm.ind_runFiles->getFirstFilename(); - if ( (specList.size() > 2) || ( specList.size() < 1) ) - { - emit showMessageBox("Invalid input. Must be of form -"); - return; - } - if ( specList.size() == 1 ) - { - specList.append(specList[0]); - } + if(!ok || spectraRange.isEmpty()) + return; - QString bgrange; + QStringList specList = spectraRange.split("-"); + if(specList.size() != 2) + { + emit showMessageBox("Invalid input. Must be of form -"); + return; + } - if ( m_bgRemoval ) - { - QPair range = m_backgroundDialog->getRange(); - bgrange = "[ " + QString::number(range.first) + "," + QString::number(range.second) + " ]"; - } - else - { - bgrange = "[-1, -1]"; - } + std::vector detectorRange; + detectorRange.push_back(specList[0].toInt()); - QString pyInput = - "from mantid.simpleapi import CalculateFlatBackground,GroupDetectors,Load\n" - "from mantidplot import plotSpectrum\n" - "import os.path as op\n" - "file = r'" + rawFile + "'\n" - "name = op.splitext( op.split(file)[1] )[0]\n" - "bgrange = " + bgrange + "\n" - "Load(Filename=file, OutputWorkspace=name, SpectrumMin="+specList[0]+", SpectrumMax="+specList[1]+")\n" - "if ( bgrange != [-1, -1] ):\n" - " #Remove background\n" - " CalculateFlatBackground(InputWorkspace=name, OutputWorkspace=name+'_bg', StartX=bgrange[0], EndX=bgrange[1], Mode='Mean')\n" - " GroupDetectors(InputWorkspace=name+'_bg', OutputWorkspace=name+'_grp', DetectorList=range("+specList[0]+","+specList[1]+"+1))\n" - " GroupDetectors(InputWorkspace=name, OutputWorkspace=name+'_grp_raw', DetectorList=range("+specList[0]+","+specList[1]+"+1))\n" - "else: # Just group detectors as they are\n" - " GroupDetectors(InputWorkspace=name, OutputWorkspace=name+'_grp', DetectorList=range("+specList[0]+","+specList[1]+"+1))\n" - "graph = plotSpectrum(name+'_grp', 0)\n"; - - QString pyOutput = m_pythonRunner.runPythonCode(pyInput).trimmed(); - - if ( pyOutput != "" ) - { - emit showMessageBox(pyOutput); - } + if(specList.size() == 1) + detectorRange.push_back(specList[0].toInt() + 1); + else + detectorRange.push_back(specList[1].toInt() + 1); + + QString rawFile = m_uiForm.ind_runFiles->getFirstFilename(); + QFileInfo rawFileInfo(rawFile); + std::string name = rawFileInfo.baseName().toStdString(); + + IAlgorithm_sptr loadAlg = AlgorithmManager::Instance().create("Load"); + loadAlg->initialize(); + loadAlg->setProperty("Filename", rawFile.toStdString()); + loadAlg->setProperty("OutputWorkspace", name); + loadAlg->setProperty("SpectrumMin", specList[0].toStdString()); + loadAlg->setProperty("SpectrumMax", specList[1].toStdString()); + m_batchAlgoRunner->addAlgorithm(loadAlg); + + BatchAlgorithmRunner::AlgorithmRuntimeProps inputFromLoad; + inputFromLoad["InputWorkspace"] = name; + + if(m_bgRemoval) + { + QPair range = m_backgroundDialog->getRange(); + + IAlgorithm_sptr calcBackAlg = AlgorithmManager::Instance().create("CalculateFlatBackground"); + calcBackAlg->initialize(); + calcBackAlg->setProperty("OutputWorkspace", name + "_bg"); + calcBackAlg->setProperty("Mode", "Mean"); + calcBackAlg->setProperty("StartX", range.first); + calcBackAlg->setProperty("EndX", range.second); + m_batchAlgoRunner->addAlgorithm(calcBackAlg, inputFromLoad); + + BatchAlgorithmRunner::AlgorithmRuntimeProps inputFromCalcBG; + inputFromCalcBG["InputWorkspace"] = name + "_bg"; + + IAlgorithm_sptr groupAlg = AlgorithmManager::Instance().create("GroupDetectors"); + groupAlg->initialize(); + groupAlg->setProperty("OutputWorkspace", name + "_grp"); + groupAlg->setProperty("DetectorList", detectorRange); + m_batchAlgoRunner->addAlgorithm(groupAlg, inputFromCalcBG); + + IAlgorithm_sptr rawGroupAlg = AlgorithmManager::Instance().create("GroupDetectors"); + rawGroupAlg->initialize(); + rawGroupAlg->setProperty("OutputWorkspace", name + "_grp_raw"); + rawGroupAlg->setProperty("DetectorList", detectorRange); + m_batchAlgoRunner->addAlgorithm(rawGroupAlg, inputFromLoad); } else { - emit showMessageBox("You must select a run file."); + IAlgorithm_sptr rawGroupAlg = AlgorithmManager::Instance().create("GroupDetectors"); + rawGroupAlg->initialize(); + rawGroupAlg->setProperty("OutputWorkspace", name + "_grp"); + rawGroupAlg->setProperty("DetectorList", detectorRange); + m_batchAlgoRunner->addAlgorithm(rawGroupAlg, inputFromLoad); } + + connect(m_batchAlgoRunner, SIGNAL(batchComplete(bool)), this, SLOT(plotRawComplete(bool))); + m_batchAlgoRunner->executeBatchAsync(); + } + + /** + * Handles plotting the result of Plot Raw + * + * @param error Indicates if the algorithm chain failed + */ + void IndirectConvertToEnergy::plotRawComplete(bool error) + { + disconnect(m_batchAlgoRunner, SIGNAL(batchComplete(bool)), this, SLOT(plotRawComplete(bool))); + + if(error) + return; + + QString rawFile = m_uiForm.ind_runFiles->getFirstFilename(); + QFileInfo rawFileInfo(rawFile); + std::string name = rawFileInfo.baseName().toStdString(); + + std::string pyInput = "from mantidplot import plotSpectrum\nplotSpectrum('" + name + "_grp', 0)\n"; + m_pythonRunner.runPythonCode(QString::fromStdString(pyInput)); } void IndirectConvertToEnergy::useCalib(bool state) @@ -795,14 +678,10 @@ namespace CustomInterfaces */ void IndirectConvertToEnergy::calibFileChanged(const QString & calib) { - if ( calib.isEmpty() ) - { + if(calib.isEmpty()) m_uiForm.ckUseCalib->setChecked(false); - } else - { m_uiForm.ckUseCalib->setChecked(true); - } } /** @@ -810,8 +689,7 @@ namespace CustomInterfaces */ void IndirectConvertToEnergy::pbRunEditing() { - m_uiForm.pbRun->setEnabled(false); - m_uiForm.pbRun->setText("Editing..."); + emit updateRunButton(false, "Editing...", "Run numbers are curently being edited."); } /** @@ -819,7 +697,7 @@ namespace CustomInterfaces */ void IndirectConvertToEnergy::pbRunFinding() { - m_uiForm.pbRun->setText("Finding files..."); + emit updateRunButton(false, "Finding files...", "Searchig for data files for the run numbers entered..."); m_uiForm.ind_runFiles->setEnabled(false); } @@ -830,13 +708,13 @@ namespace CustomInterfaces { if(!m_uiForm.ind_runFiles->isValid()) { - m_uiForm.pbRun->setText("Invalid Run"); + emit updateRunButton(false, "Invalid Run(s)", "Cannot find data files for some of the run numbers enetered."); } else { - m_uiForm.pbRun->setText("Run"); - m_uiForm.pbRun->setEnabled(true); + emit updateRunButton(); } + m_uiForm.ind_runFiles->setEnabled(true); } diff --git a/Code/Mantid/MantidQt/CustomInterfaces/src/IndirectDataReduction.cpp b/Code/Mantid/MantidQt/CustomInterfaces/src/IndirectDataReduction.cpp index 4f2fe9195e69..2c51d24b3275 100644 --- a/Code/Mantid/MantidQt/CustomInterfaces/src/IndirectDataReduction.cpp +++ b/Code/Mantid/MantidQt/CustomInterfaces/src/IndirectDataReduction.cpp @@ -13,6 +13,7 @@ #include "MantidQtCustomInterfaces/IndirectDiagnostics.h" #include "MantidQtCustomInterfaces/IndirectMoments.h" #include "MantidQtCustomInterfaces/IndirectSqw.h" +#include "MantidQtCustomInterfaces/IndirectSymmetrise.h" #include "MantidQtCustomInterfaces/IndirectTransmission.h" #include @@ -20,6 +21,7 @@ #include #include + //Add this class to the list of specialised dialogs in this namespace namespace MantidQt { @@ -29,16 +31,18 @@ namespace MantidQt } } + namespace { Mantid::Kernel::Logger g_log("IndirectDataReduction"); } + +using namespace Mantid::API; +using namespace Mantid::Geometry; using namespace MantidQt::CustomInterfaces; using namespace MantidQt; -//---------------------- -// Public member functions -//---------------------- + /** * Default constructor for class. Initialises interface pointers to NULL values. @@ -46,26 +50,28 @@ using namespace MantidQt; */ IndirectDataReduction::IndirectDataReduction(QWidget *parent) : UserSubWindow(parent), - m_curInterfaceSetup(""), + m_instrument(""), m_settingsGroup("CustomInterfaces/IndirectDataReduction"), m_algRunner(new MantidQt::API::AlgorithmRunner(this)), m_changeObserver(*this, &IndirectDataReduction::handleDirectoryChange) { - //Signals to report load instrument algo result + // Signals to report load instrument algo result connect(m_algRunner, SIGNAL(algorithmComplete(bool)), this, SLOT(instrumentLoadingDone(bool))); } + /** * Destructor */ IndirectDataReduction::~IndirectDataReduction() { - //Make sure no algos are sunning after the window has been closed + // Make sure no algos are running after the window has been closed m_algRunner->cancelRunningAlgorithm(); saveSettings(); } + /** * On user clicking the "help" button on the interface, directs their request to the relevant * interface's helpClicked() function. @@ -74,22 +80,28 @@ void IndirectDataReduction::helpClicked() { QString tabName = m_uiForm.tabWidget->tabText( m_uiForm.tabWidget->currentIndex()); + QString url = "http://www.mantidproject.org/Indirect:"; + if ( tabName == "Energy Transfer" ) url += "EnergyTransfer"; else if ( tabName == "Calibration" ) url += "Calibration"; else if ( tabName == "Diagnostics" ) url += "Diagnostics"; + else if (tabName == "Symmetrise") + url += "Symmetrise"; else if ( tabName == "S(Q, w)" ) url += "SofQW"; else if (tabName == "Transmission") url += "Transmission"; else if (tabName == "Moments") url += "Moments"; + QDesktopServices::openUrl(QUrl(url)); } + /** * This is the function called when the "Run" button is clicked. It will call the relevent function * in the subclass. @@ -97,74 +109,61 @@ void IndirectDataReduction::helpClicked() void IndirectDataReduction::runClicked() { QString tabName = m_uiForm.tabWidget->tabText(m_uiForm.tabWidget->currentIndex()); - if ( tabName == "Energy Transfer" ) - m_tab_convert_to_energy->runTab(); - else if ( tabName == "Calibration" ) - m_tab_calibration->runTab(); - else if ( tabName == "Diagnostics" ) - m_tab_diagnostics->runTab(); - else if ( tabName == "S(Q, w)" ) - m_tab_sqw->runTab(); - else if (tabName == "Transmission") - m_tab_trans->runTab(); - else if(tabName == "Moments") - m_tab_moments->runTab(); + m_tabs[tabName]->runTab(); } + /** - * Sets up Qt UI file and connects signals, slots. + * Sets up Qt UI file and connects signals, slots. */ void IndirectDataReduction::initLayout() { m_uiForm.setupUi(this); - m_tab_convert_to_energy = new IndirectConvertToEnergy(m_uiForm, this); - m_tab_sqw = new IndirectSqw(m_uiForm, this); - m_tab_diagnostics = new IndirectDiagnostics(m_uiForm, this); - m_tab_calibration = new IndirectCalibration(m_uiForm, this); - m_tab_trans = new IndirectTransmission(m_uiForm, this); - m_tab_moments = new IndirectMoments(m_uiForm, this); - - // Assume we get a incompatiable instrument to start with - m_uiForm.pbRun->setEnabled(false); - - // Signal / Slot Connections Set Up Here - - // signal/slot connections to respond to changes in instrument selection combo boxes - connect(m_uiForm.cbInst, SIGNAL(instrumentSelectionChanged(const QString&)), this, SLOT(userSelectInstrument(const QString&))); - - // connect "?" (Help) Button + // Do not allow running until setup and instrument laoding are done + updateRunButton(false, "Loading UI", "Initialising user interface components..."); + + if(m_instrument == "") + instrumentSelected(m_uiForm.cbInst->currentText()); + + // Create the tabs + m_tabs["Energy Transfer"] = new IndirectConvertToEnergy(m_uiForm, this); + m_tabs["Calibration"] = new IndirectCalibration(m_uiForm, this); + m_tabs["Diagnostics"] = new IndirectDiagnostics(m_uiForm, this); + m_tabs["Transmission"] = new IndirectTransmission(m_uiForm, this); + m_tabs["Symmetrise"] = new IndirectSymmetrise(m_uiForm, this); + m_tabs["S(Q, w)"] = new IndirectSqw(m_uiForm, this); + m_tabs["Moments"] = new IndirectMoments(m_uiForm, this); + + // Handle the instrument being changed + connect(m_uiForm.cbInst, SIGNAL(instrumentSelectionChanged(const QString&)), this, SLOT(instrumentSelected(const QString&))); + // Handle the analyser being changed + connect(m_uiForm.cbAnalyser, SIGNAL(currentIndexChanged(int)), this, SLOT(analyserSelected(int))); + // Handle the reflection being changed + connect(m_uiForm.cbReflection, SIGNAL(currentIndexChanged(int)), this, SLOT(instrumentSetupChanged())); + + // Connect "?" (Help) Button connect(m_uiForm.pbHelp, SIGNAL(clicked()), this, SLOT(helpClicked())); - // connect the "Run" button + // Connect the "Run" button connect(m_uiForm.pbRun, SIGNAL(clicked()), this, SLOT(runClicked())); - // connect the "Manage User Directories" Button + // Connect the "Manage User Directories" Button connect(m_uiForm.pbManageDirectories, SIGNAL(clicked()), this, SLOT(openDirectoryDialog())); - // ignals for tabs running Python - connect(m_tab_convert_to_energy, SIGNAL(runAsPythonScript(const QString&, bool)), this, SIGNAL(runAsPythonScript(const QString&, bool))); - connect(m_tab_sqw, SIGNAL(runAsPythonScript(const QString&, bool)), this, SIGNAL(runAsPythonScript(const QString&, bool))); - connect(m_tab_calibration, SIGNAL(runAsPythonScript(const QString&, bool)), this, SIGNAL(runAsPythonScript(const QString&, bool))); - connect(m_tab_diagnostics, SIGNAL(runAsPythonScript(const QString&, bool)), this, SIGNAL(runAsPythonScript(const QString&, bool))); - connect(m_tab_trans, SIGNAL(runAsPythonScript(const QString&, bool)), this, SIGNAL(runAsPythonScript(const QString&, bool))); - connect(m_tab_moments, SIGNAL(runAsPythonScript(const QString&, bool)), this, SIGNAL(runAsPythonScript(const QString&, bool))); - - // ignals for tabs showing mesage boxes - connect(m_tab_convert_to_energy, SIGNAL(showMessageBox(const QString&)), this, SLOT(showMessageBox(const QString&))); - connect(m_tab_sqw, SIGNAL(showMessageBox(const QString&)), this, SLOT(showMessageBox(const QString&))); - connect(m_tab_calibration, SIGNAL(showMessageBox(const QString&)), this, SLOT(showMessageBox(const QString&))); - connect(m_tab_diagnostics, SIGNAL(showMessageBox(const QString&)), this, SLOT(showMessageBox(const QString&))); - connect(m_tab_trans, SIGNAL(showMessageBox(const QString&)), this, SLOT(showMessageBox(const QString&))); - connect(m_tab_moments, SIGNAL(showMessageBox(const QString&)), this, SLOT(showMessageBox(const QString&))); - - // Run any tab setup code - m_tab_convert_to_energy->setupTab(); - m_tab_sqw->setupTab(); - m_tab_diagnostics->setupTab(); - m_tab_calibration->setupTab(); - m_tab_trans->setupTab(); - m_tab_moments->setupTab(); + // Reset the Run button state when the tab is changed + connect(m_uiForm.tabWidget, SIGNAL(currentChanged(int)), this, SLOT(updateRunButton())); + + // Connect tab signals and run any setup code + for(auto it = m_tabs.begin(); it != m_tabs.end(); ++it) + { + connect(it->second, SIGNAL(runAsPythonScript(const QString&, bool)), this, SIGNAL(runAsPythonScript(const QString&, bool))); + connect(it->second, SIGNAL(showMessageBox(const QString&)), this, SLOT(showMessageBox(const QString&))); + connect(it->second, SIGNAL(updateRunButton(bool, QString, QString)), this, SLOT(updateRunButton(bool, QString, QString))); + connect(this, SIGNAL(newInstrumentConfiguration()), it->second, SIGNAL(newInstrumentConfiguration())), + it->second->setupTab(); + } } + /** * This function is ran after initLayout(), and runPythonCode is unavailable before this function * has run (because of the setup of the base class). For this reason, "setup" functions that require @@ -174,89 +173,138 @@ void IndirectDataReduction::initLocalPython() { // select starting instrument readSettings(); - - if ( m_curInterfaceSetup == "" ) - { - userSelectInstrument(m_uiForm.cbInst->currentText()); - } } + /** - * Read settings from the persistent store + * Called when any of the instrument configuration options are changed. + * + * Used to notify tabs that rely on the instrument config when the config changes. */ -void IndirectDataReduction::readSettings() +void IndirectDataReduction::instrumentSetupChanged() { - QSettings settings; - settings.beginGroup(m_settingsGroup); - QString instrName = settings.value("instrument-name", "").toString(); - settings.endGroup(); + QString instrumentName = m_uiForm.cbInst->currentText(); + QString analyser = m_uiForm.cbAnalyser->currentText(); + QString reflection = m_uiForm.cbReflection->currentText(); - setDefaultInstrument(instrName); + if(instrumentName != "" && analyser != "" && reflection != "") + { + loadInstrumentIfNotExist(instrumentName.toStdString(), analyser.toStdString(), reflection.toStdString()); + emit newInstrumentConfiguration(); + } } + /** - * Save settings to a persistent storage + * Loads an empty instrument into a workspace (__empty_INST) unless the workspace already exists. + * + * If an analyser and reflection are supplied then the corresponding IPF is also loaded. + * + * @param instrumentName Name of the instrument to load + * @param analyser Analyser being used (optional) + * @param reflection Relection being used (optional) + * @returns Pointer to instrument workspace */ -void IndirectDataReduction::saveSettings() +Mantid::API::MatrixWorkspace_sptr IndirectDataReduction::loadInstrumentIfNotExist(std::string instrumentName, + std::string analyser, std::string reflection) { - QSettings settings; - settings.beginGroup(m_settingsGroup); - QString instrName; + std::string instWorkspaceName = "__empty_" + instrumentName; + std::string idfDirectory = Mantid::Kernel::ConfigService::Instance().getString("instrumentDefinition.directory"); - instrName = m_uiForm.cbInst->currentText(); + // If the workspace does not exist in ADS then load an empty instrument + if(!AnalysisDataService::Instance().doesExist(instWorkspaceName)) + { + std::string parameterFilename = idfDirectory + instrumentName + "_Definition.xml"; + IAlgorithm_sptr loadAlg = AlgorithmManager::Instance().create("LoadEmptyInstrument"); + loadAlg->initialize(); + loadAlg->setProperty("Filename", parameterFilename); + loadAlg->setProperty("OutputWorkspace", instWorkspaceName); + loadAlg->execute(); + } - settings.setValue("instrument-name", instrName); - settings.endGroup(); + // Load the IPF if given an analyser and reflection + if(!analyser.empty() && !reflection.empty()) + { + std::string ipfFilename = idfDirectory + instrumentName + "_" + analyser + "_" + reflection + "_Parameters.xml"; + IAlgorithm_sptr loadParamAlg = AlgorithmManager::Instance().create("LoadParameterFile"); + loadParamAlg->initialize(); + loadParamAlg->setProperty("Filename", ipfFilename); + loadParamAlg->setProperty("Workspace", instWorkspaceName); + loadParamAlg->execute(); + } + + // Get the workspace, which should exist now + MatrixWorkspace_sptr instWorkspace = AnalysisDataService::Instance().retrieveWS(instWorkspaceName); + + return instWorkspace; } + /** - * Sets up the initial instrument for the interface. This value is taken from the users' - * settings in the menu View -> Preferences -> Mantid -> Instrument - * @param name :: The name of the default instrument + * Gets the operation modes for the current instrument as defined in it's parameter file. + * + * @returns A list of analysers and a vector of reflections that can be used with each */ -void IndirectDataReduction::setDefaultInstrument(const QString & name) +std::vector > > IndirectDataReduction::getInstrumentModes() { - if( name.isEmpty() ) return; + std::vector > > modes; + MatrixWorkspace_sptr instWorkspace = loadInstrumentIfNotExist(m_instrument.toStdString()); + Instrument_const_sptr instrument = instWorkspace->getInstrument(); - int index = m_uiForm.cbInst->findText(name); - if( index >= 0 ) + std::vector analysers; + boost::split(analysers, instrument->getStringParameter("analysers")[0], boost::is_any_of(",")); + + for(auto it = analysers.begin(); it != analysers.end(); ++it) { - m_uiForm.cbInst->setCurrentIndex(index); + std::string analyser = *it; + std::string ipfReflections = instrument->getStringParameter("refl-" + analyser)[0]; + + std::vector reflections; + boost::split(reflections, ipfReflections, boost::is_any_of(","), boost::token_compress_on); + + std::pair > data(analyser, reflections); + modes.push_back(data); } + + return modes; } + /** - * This function: 1. loads the instrument and gets the value of deltaE-mode parameter - * 2. Based on this value, makes the necessary changes to the form setup (direct or indirect). - * @param name :: name of the instrument from the QComboBox + * Updated the list of analysers based on the current instrument. */ -void IndirectDataReduction::instrumentSelectChanged(const QString& name) +void IndirectDataReduction::updateAnalyserList() { - QString defFile = (Mantid::API::ExperimentInfo::getInstrumentFilename(name.toStdString())).c_str(); - if((defFile == "") || !m_uiForm.cbInst->isVisible()) - { - g_log.error("Instument loading failed!"); - m_uiForm.cbInst->setEnabled(true); - m_uiForm.pbRun->setEnabled(true); - return; - } + auto instModes = getInstrumentModes(); - QString outWS = "__empty_" + m_uiForm.cbInst->currentText(); + m_uiForm.cbAnalyser->clear(); - m_curInterfaceSetup = name; + for(auto modesIt = instModes.begin(); modesIt != instModes.end(); ++modesIt) + { + QString analyser = QString::fromStdString(modesIt->first); + std::vector reflections = modesIt->second; - //Load the empty instrument into the workspace __empty_[name] - //This used to be done in Python - Mantid::API::IAlgorithm_sptr instLoader = Mantid::API::AlgorithmManager::Instance().create("LoadEmptyInstrument", -1); - instLoader->initialize(); - instLoader->setProperty("Filename", defFile.toStdString()); - instLoader->setProperty("OutputWorkspace", outWS.toStdString()); + if(analyser != "diffraction") // Do not put diffraction into the analyser list + { + if(reflections.size() > 0) + { + QStringList reflectionsList; + for(auto reflIt = reflections.begin(); reflIt != reflections.end(); ++reflIt) + reflectionsList.push_back(QString::fromStdString(*reflIt)); + QVariant data = QVariant(reflectionsList); + m_uiForm.cbAnalyser->addItem(analyser, data); + } + else + { + m_uiForm.cbAnalyser->addItem(analyser); + } + } + } - //Ensure no other algorithm is running - m_algRunner->cancelRunningAlgorithm(); - m_algRunner->startAlgorithm(instLoader); + analyserSelected(m_uiForm.cbAnalyser->currentIndex()); } + /** * Tasks to be carried out after an empty instument has finished loading */ @@ -267,127 +315,112 @@ void IndirectDataReduction::instrumentLoadingDone(bool error) { g_log.error("Instument loading failed! (this can be caused by having both direct and indirect interfaces open)"); m_uiForm.cbInst->setEnabled(true); - m_uiForm.pbRun->setEnabled(true); + updateRunButton(false, "No Instrument", "No instrument is currently loaded."); return; } - performInstSpecific(); - setIDFValues(curInstPrefix); - - m_uiForm.pbRun->setEnabled(true); + updateAnalyserList(); + updateRunButton(); m_uiForm.cbInst->setEnabled(true); } + /** - * If the instrument selection has changed, calls instrumentSelectChanged - * @param prefix :: instrument name from QComboBox object + * Handled loading thebase instrument when it is selected form the instrument combo box. + * + * @param instName Instrument name from QComboBox object */ -void IndirectDataReduction::userSelectInstrument(const QString& prefix) +void IndirectDataReduction::instrumentSelected(const QString& instName) { - if ( prefix != m_curInterfaceSetup ) + if(instName != m_instrument) { // Remove the old empty instrument workspace if it is there - std::string ws_name = "__empty_" + m_curInterfaceSetup.toStdString(); + std::string wsName = "__empty_" + m_instrument.toStdString(); Mantid::API::AnalysisDataServiceImpl& dataStore = Mantid::API::AnalysisDataService::Instance(); - if( dataStore.doesExist(ws_name) ) - { - dataStore.remove(ws_name); - } + if(dataStore.doesExist(wsName)) + dataStore.remove(wsName); - m_uiForm.pbRun->setEnabled(false); + updateRunButton(false, "Loading Inst.", "Loading the selected instrument..."); m_uiForm.cbInst->setEnabled(false); - instrumentSelectChanged(prefix); - } -} + loadInstrumentIfNotExist(instName.toStdString()); + m_instrument = instName; -void IndirectDataReduction::openDirectoryDialog() -{ - MantidQt::API::ManageUserDirectories *ad = new MantidQt::API::ManageUserDirectories(this); - ad->show(); - ad->setFocus(); + //TODO + instrumentLoadingDone(false); + } } -/** -* This function holds any steps that must be performed on the selection of an instrument, -* for example loading values from the Instrument Definition File (IDF). -* @param prefix :: The selected instruments prefix in Mantid. -*/ -void IndirectDataReduction::setIDFValues(const QString & prefix) -{ - dynamic_cast(m_tab_convert_to_energy)->setIDFValues(prefix); -} /** -* This function holds any steps that must be performed on the layout that are specific -* to the currently selected instrument. -*/ -void IndirectDataReduction::performInstSpecific() + * Updates the list of reflections in the reflection combo box when the analyser is changed. + * + * @param index Index of analyser in combo box + */ +void IndirectDataReduction::analyserSelected(int index) { - setInstSpecificWidget("cm-1-convert-choice", m_uiForm.ckCm1Units, QCheckBox::Off); - setInstSpecificWidget("save-aclimax-choice", m_uiForm.save_ckAclimax, QCheckBox::Off); -} + // Populate Reflection combobox with correct values for Analyser selected. + m_uiForm.cbReflection->clear(); -/** -* This function either shows or hides the given QCheckBox, based on the named property -* inside the instrument param file. When hidden, the default state will be used to -* reset to the "unused" state of the checkbox. -* -* @param parameterName :: The name of the property to look for inside the current inst param file. -* @param checkBox :: The checkbox to set the state of, and to either hide or show based on the current inst. -* @param defaultState :: The state to which the checkbox will be set upon hiding it. -*/ -void IndirectDataReduction::setInstSpecificWidget(const std::string & parameterName, QCheckBox * checkBox, QCheckBox::ToggleState defaultState) -{ - // Get access to instrument specific parameters via the loaded empty workspace. - std::string instName = m_uiForm.cbInst->currentText().toStdString(); - Mantid::API::MatrixWorkspace_sptr input = boost::dynamic_pointer_cast(Mantid::API::AnalysisDataService::Instance().retrieve("__empty_" + instName)); - if(input == NULL) + QVariant currentData = m_uiForm.cbAnalyser->itemData(index); + if ( currentData == QVariant::Invalid ) + { + m_uiForm.lbReflection->setEnabled(false); + m_uiForm.cbReflection->setEnabled(false); return; - - Mantid::Geometry::Instrument_const_sptr instr = input->getInstrument(); - - // See if the instrument params file requests that the checkbox be shown to the user. - std::vector showParams = instr->getStringParameter(parameterName); - - std::string show = ""; - if(!showParams.empty()) - show = showParams[0]; - - if(show == "Show") - checkBox->setHidden(false); + } else { - checkBox->setHidden(true); - checkBox->setState(defaultState); + m_uiForm.lbReflection->setEnabled(true); + m_uiForm.cbReflection->setEnabled(true); + QStringList reflections = currentData.toStringList(); + for ( int i = 0; i < reflections.count(); i++ ) + { + m_uiForm.cbReflection->addItem(reflections[i]); + } } + + emit instrumentSetupChanged(); } + +/** + * Remove the Poco observer on the config service when the interfaces is closed. + * + * @param close CLose event (unused) + */ void IndirectDataReduction::closeEvent(QCloseEvent* close) { - (void) close; + UNUSED_ARG(close); Mantid::Kernel::ConfigService::Instance().removeObserver(m_changeObserver); } + +/** + * Reloads settings if the default sata search or save directories have been changed. + */ void IndirectDataReduction::handleDirectoryChange(Mantid::Kernel::ConfigValChangeNotification_ptr pNf) { std::string key = pNf->key(); - if ( key == "datasearch.directories" || key == "defaultsave.directory" ) - { - loadSettings(); - } + if(key == "datasearch.directories" || key == "defaultsave.directory") + readSettings(); } -void IndirectDataReduction::loadSettings() -{ - // set values of m_dataDir and m_saveDir + +/** + * Read Qt settings for the interface. + */ +void IndirectDataReduction::readSettings() +{ + // Set values of m_dataDir and m_saveDir m_dataDir = QString::fromStdString(Mantid::Kernel::ConfigService::Instance().getString("datasearch.directories")); - m_dataDir.replace(" ",""); + m_dataDir.replace(" ", ""); if(m_dataDir.length() > 0) m_dataDir = m_dataDir.split(";", QString::SkipEmptyParts)[0]; m_saveDir = QString::fromStdString(Mantid::Kernel::ConfigService::Instance().getString("defaultsave.directory")); - + QSettings settings; + // Load settings for MWRunFile widgets settings.beginGroup(m_settingsGroup + "DataFiles"); settings.setValue("last_directory", m_dataDir); @@ -400,21 +433,74 @@ void IndirectDataReduction::loadSettings() settings.setValue("last_directory", m_saveDir); m_uiForm.ind_calibFile->readSettings(settings.group()); m_uiForm.ind_mapFile->readSettings(settings.group()); - m_uiForm.slice_calibFile->readSettings(settings.group()); + m_uiForm.slice_dsCalibFile->readSettings(settings.group()); m_uiForm.moment_dsInput->readSettings(settings.group()); - m_uiForm.transInputFile->readSettings(settings.group()); - m_uiForm.transCanFile->readSettings(settings.group()); m_uiForm.sqw_dsSampleInput->readSettings(settings.group()); settings.endGroup(); + + // Load the last used instrument + settings.beginGroup(m_settingsGroup); + QString instName = settings.value("instrument-name", "").toString(); + settings.endGroup(); + + if(instName.isEmpty()) + return; + + int index = m_uiForm.cbInst->findText(instName); + if(index >= 0) + m_uiForm.cbInst->setCurrentIndex(index); +} + + +/** + * Save settings to a persistent storage. + */ +void IndirectDataReduction::saveSettings() +{ + QSettings settings; + settings.beginGroup(m_settingsGroup); + QString instrName; + + instrName = m_uiForm.cbInst->currentText(); + + settings.setValue("instrument-name", instrName); + settings.endGroup(); +} + + +/** + * Handles showing the manage directory dialog box. + */ +void IndirectDataReduction::openDirectoryDialog() +{ + MantidQt::API::ManageUserDirectories *ad = new MantidQt::API::ManageUserDirectories(this); + ad->show(); + ad->setFocus(); } + /** * Slot to wrap the protected showInformationBox method defined * in UserSubWindow and provide access to composed tabs. - * - * @param message :: The message to display in the message box + * + * @param message The message to display in the message box */ void IndirectDataReduction::showMessageBox(const QString& message) { showInformationBox(message); } + + +/** + * Slot to allow setting the state of the Run button. + * + * @param enabled If the button is clickable + * @param message Message shown on the button + * @param tooltip Tooltip shown when hovering over button + */ +void IndirectDataReduction::updateRunButton(bool enabled, QString message, QString tooltip) +{ + m_uiForm.pbRun->setEnabled(enabled); + m_uiForm.pbRun->setText(message); + m_uiForm.pbRun->setToolTip(tooltip); +} diff --git a/Code/Mantid/MantidQt/CustomInterfaces/src/IndirectDataReductionTab.cpp b/Code/Mantid/MantidQt/CustomInterfaces/src/IndirectDataReductionTab.cpp index bcb3456cb015..c079ecba2bdc 100644 --- a/Code/Mantid/MantidQt/CustomInterfaces/src/IndirectDataReductionTab.cpp +++ b/Code/Mantid/MantidQt/CustomInterfaces/src/IndirectDataReductionTab.cpp @@ -1,7 +1,11 @@ #include "MantidQtCustomInterfaces/IndirectDataReductionTab.h" +#include "MantidAPI/AlgorithmManager.h" #include "MantidKernel/Logger.h" +using namespace Mantid::API; +using namespace Mantid::Geometry; + namespace { Mantid::Kernel::Logger g_log("IndirectDataReductionTab"); @@ -14,25 +18,10 @@ namespace CustomInterfaces //---------------------------------------------------------------------------------------------- /** Constructor */ - IndirectDataReductionTab::IndirectDataReductionTab(Ui::IndirectDataReduction& uiForm, QObject* parent) : QObject(parent), - m_plots(), m_curves(), m_rangeSelectors(), - m_properties(), - m_dblManager(new QtDoublePropertyManager()), m_blnManager(new QtBoolPropertyManager()), m_grpManager(new QtGroupPropertyManager()), - m_dblEdFac(new DoubleEditorFactory()), + IndirectDataReductionTab::IndirectDataReductionTab(Ui::IndirectDataReduction& uiForm, QObject* parent) : IndirectTab(parent), m_uiForm(uiForm) { - m_parentWidget = dynamic_cast(parent); - - m_algRunner = new MantidQt::API::AlgorithmRunner(m_parentWidget); - m_valInt = new QIntValidator(m_parentWidget); - m_valDbl = new QDoubleValidator(m_parentWidget); - m_valPosDbl = new QDoubleValidator(m_parentWidget); - - const double tolerance = 0.00001; - m_valPosDbl->setBottom(tolerance); - - QObject::connect(m_algRunner, SIGNAL(algorithmComplete(bool)), this, SLOT(algorithmFinished(bool))); - connect(&m_pythonRunner, SIGNAL(runAsPythonScript(const QString&, bool)), this, SIGNAL(runAsPythonScript(const QString&, bool))); + connect(m_batchAlgoRunner, SIGNAL(batchComplete(bool)), this, SLOT(tabExecutionComplete(bool))); } //---------------------------------------------------------------------------------------------- @@ -41,11 +30,13 @@ namespace CustomInterfaces IndirectDataReductionTab::~IndirectDataReductionTab() { } - + void IndirectDataReductionTab::runTab() { if(validate()) { + m_tabRunning = true; + emit updateRunButton(false, "Running...", "Running data reduction..."); run(); } else @@ -54,266 +45,237 @@ namespace CustomInterfaces } } - void IndirectDataReductionTab::setupTab() - { - setup(); - } - - void IndirectDataReductionTab::validateTab() + /** + * Slot used to update the run button when an algorithm that was strted by the Run button complete. + * + * @param error Unused + */ + void IndirectDataReductionTab::tabExecutionComplete(bool error) { - validate(); + UNUSED_ARG(error); + if(m_tabRunning) + { + m_tabRunning = false; + emit updateRunButton(); + } } /** - * Run the load algorithm with the supplied filename and spectrum range - * - * @param filename :: The name of the file to load - * @param outputName :: The name of the output workspace - * @param specMin :: Lower spectra bound - * @param specMax :: Upper spectra bound - * @return If the algorithm was successful + * Loads an empty instrument into a workspace (__empty_INST) unless the workspace already exists. + * + * If an analyser and reflection are supplied then the corresponding IPF is also loaded. + * + * @param instrumentName Name of the instrument to load + * @param analyser Analyser being used (optional) + * @param reflection Relection being used (optional) + * @returns Pointer to instrument workspace */ - bool IndirectDataReductionTab::loadFile(const QString& filename, const QString& outputName, - const int specMin, const int specMax) + Mantid::API::MatrixWorkspace_sptr IndirectDataReductionTab::loadInstrumentIfNotExist(std::string instrumentName, + std::string analyser, std::string reflection) { - using namespace Mantid::API; - - Algorithm_sptr load = AlgorithmManager::Instance().createUnmanaged("Load", -1); - load->initialize(); + IndirectDataReduction* parentIDR = dynamic_cast(m_parentWidget); - load->setProperty("Filename", filename.toStdString()); - load->setProperty("OutputWorkspace", outputName.toStdString()); + if(parentIDR == NULL) + throw std::runtime_error("IndirectDataReductionTab must be a child of IndirectDataReduction"); - if(specMin != -1) - load->setProperty("SpectrumMin", specMin); - - if(specMax != -1) - load->setProperty("SpectrumMax", specMax); - - load->execute(); - - //If reloading fails we're out of options - return load->isExecuted(); + return parentIDR->loadInstrumentIfNotExist(instrumentName, analyser, reflection); } /** - * Gets details for the current indtrument configuration defined in Convert To Energy tab + * Gets details for the current instrument configuration defined in Convert To Energy tab. * - * @return :: Map of information ID to value + * @return Map of information ID to value */ std::map IndirectDataReductionTab::getInstrumentDetails() { std::map instDetails; - - QString pyInput = - "from IndirectEnergyConversion import getReflectionDetails\n" - "instrument = '" + m_uiForm.cbInst->currentText() + "'\n" - "analyser = '" + m_uiForm.cbAnalyser->currentText() + "'\n" - "reflection = '" + m_uiForm.cbReflection->currentText() + "'\n" - "print getReflectionDetails(instrument, analyser, reflection)\n"; - QString pyOutput = m_pythonRunner.runPythonCode(pyInput).trimmed(); + // Get instrument configuration + std::string instrumentName = m_uiForm.cbInst->currentText().toStdString(); + std::string analyser = m_uiForm.cbAnalyser->currentText().toStdString(); + std::string reflection = m_uiForm.cbReflection->currentText().toStdString(); + + instDetails["instrument"] = QString::fromStdString(instrumentName); + instDetails["analyser"] = QString::fromStdString(analyser); + instDetails["reflection"] = QString::fromStdString(reflection); + + // List of values to get from IPF + std::vector ipfElements; + ipfElements.push_back("analysis-type"); + ipfElements.push_back("spectra-min"); + ipfElements.push_back("spectra-max"); + ipfElements.push_back("efixed-val"); + ipfElements.push_back("peak-start"); + ipfElements.push_back("peak-end"); + ipfElements.push_back("back-start"); + ipfElements.push_back("back-end"); + ipfElements.push_back("rebin-default"); + + // Get the instrument workspace + MatrixWorkspace_sptr instWorkspace = loadInstrumentIfNotExist(instrumentName, analyser, reflection); + + // In the IRIS IPF there is no fmica component + if(instrumentName == "IRIS" && analyser == "fmica") + analyser = "mica"; + + // Get the instrument + auto instrument = instWorkspace->getInstrument(); + if(instrument == NULL) + return instDetails; + + // Get the analyser component + auto component = instrument->getComponentByName(analyser); + + // For each parameter we want to get + for(auto it = ipfElements.begin(); it != ipfElements.end(); ++it) + { + try + { + std::string key = *it; - QStringList values = pyOutput.split("\n", QString::SkipEmptyParts); + QString value = getInstrumentParameterFrom(instrument, key); - if(values.count() > 3) - { - instDetails["AnalysisType"] = values[0]; - instDetails["SpectraMin"] = values[1]; - instDetails["SpectraMax"] = values[2]; + if(value.isEmpty() && component != NULL) + QString value = getInstrumentParameterFrom(component, key); - if(values.count() >= 8) - { - instDetails["EFixed"] = values[3]; - instDetails["PeakMin"] = values[4]; - instDetails["PeakMax"] = values[5]; - instDetails["BackMin"] = values[6]; - instDetails["BackMax"] = values[7]; + instDetails[QString::fromStdString(key)] = value; } - - if(values.count() >= 9) + // In the case that the parameter does not exist + catch(Mantid::Kernel::Exception::NotFoundError &nfe) { - instDetails["RebinString"] = values[8]; + UNUSED_ARG(nfe); + g_log.warning() << "Could not find parameter " << *it << " in instrument " << instrumentName << std::endl; } } return instDetails; } - /** - * Gets the range of the curve plotted in the mini plot - * - * @param curveID :: The string index of the curve in the m_curves map - * @return A pair containing the maximum and minimum points of the curve - */ - std::pair IndirectDataReductionTab::getCurveRange(const QString& curveID) - { - size_t npts = m_curves[curveID]->data().size(); - - if( npts < 2 ) - throw std::invalid_argument("Too few points on data curve to determine range."); - - return std::make_pair(m_curves[curveID]->data().x(0), m_curves[curveID]->data().x(npts-1)); - } - - /** - * Set the range of an axis on a miniplot - * - * @param plotID :: Index of plot in m_plots map - * @param axis :: ID of axis to set range of - * @param range :: Pair of double values specifying range - */ - void IndirectDataReductionTab::setAxisRange(const QString& plotID, QwtPlot::Axis axis, - std::pair range) - { - m_plots[plotID]->setAxisScale(axis, range.first, range.second); - } - - /** - * Sets the X axis of a plot to match the range of x values on a curve - * - * @param plotID :: Index of plot in m_plots map - * @param curveID :: Index of curve in m_curves map - */ - void IndirectDataReductionTab::setXAxisToCurve(const QString& plotID, const QString& curveID) - { - auto range = getCurveRange(curveID); - setAxisRange(plotID, QwtPlot::xBottom, range); - } - - /** - * Plot a workspace to the miniplot given a workspace name and - * a specturm index. - * - * This method uses the analysis data service to retrieve the workspace. - * - * @param workspace :: The name of the workspace - * @param index :: The spectrum index of the workspace - * @param plotID :: String index of the plot in the m_plots map - * @param curveID :: String index of the curve in the m_curves map, defaults to plot ID - */ - void IndirectDataReductionTab::plotMiniPlot(const QString& workspace, size_t index, - const QString& plotID, const QString& curveID) + QString IndirectDataReductionTab::getInstrumentParameterFrom(Mantid::Geometry::IComponent_const_sptr comp, std::string param) { - using namespace Mantid::API; - auto ws = AnalysisDataService::Instance().retrieveWS(workspace.toStdString()); - plotMiniPlot(ws, index, plotID, curveID); - } + QString value; - /** - * Replot a given mini plot - * - * @param plotID :: ID of plot in m_plots map - */ - void IndirectDataReductionTab::replot(const QString& plotID) - { - m_plots[plotID]->replot(); - } + if(!comp->hasParameter(param)) + return ""; - /** - * Plot a workspace to the miniplot given a workspace pointer and - * a specturm index. - * - * @param workspace :: Pointer to the workspace - * @param wsIndex :: The spectrum index of the workspace - * @param plotID :: String index of the plot in the m_plots map - * @param curveID :: String index of the curve in the m_curves map, defaults to plot ID - */ - void IndirectDataReductionTab::plotMiniPlot(const Mantid::API::MatrixWorkspace_const_sptr & workspace, size_t wsIndex, - const QString& plotID, const QString& curveID) - { - using Mantid::MantidVec; - - QString cID = curveID; - if(cID == "") - cID = plotID; - - //check if we can plot - if( wsIndex >= workspace->getNumberHistograms() || workspace->readX(0).size() < 2 ) - return; + // Determine it's type and call the corresponding get function + std::string paramType = comp->getParameterType(param); - QwtWorkspaceSpectrumData wsData(*workspace, static_cast(wsIndex), false); + if(paramType == "string") + value = QString::fromStdString(comp->getStringParameter(param)[0]); - if ( m_curves[cID] != NULL ) - { - m_curves[cID]->attach(0); - delete m_curves[cID]; - m_curves[cID] = NULL; - } + if(paramType == "double") + value = QString::number(comp->getNumberParameter(param)[0]); - size_t nhist = workspace->getNumberHistograms(); - if ( wsIndex >= nhist ) - { - emit showMessageBox("Error: Workspace index out of range."); - } - else - { - m_curves[cID] = new QwtPlotCurve(); - m_curves[cID]->setData(wsData); - m_curves[cID]->attach(m_plots[plotID]); - - m_plots[plotID]->replot(); - } - } - - /** - * 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 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 IndirectDataReductionTab::setPlotRange(const QString& rsID, QtProperty* min, QtProperty* max, - const std::pair& 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); - } - - /** - * Set the position of the guides on the mini plot - * - * @param rsID :: The string index of the range selector in the map m_rangeSelectors - * @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 IndirectDataReductionTab::setMiniPlotGuides(const QString& rsID, QtProperty* lower, QtProperty* upper, - const std::pair& 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); + return value; } /** - * Runs an algorithm async + * Gets default peak and background ranges for an instrument in time of flight. * - * @param algorithm :: The algorithm to be run - */ - void IndirectDataReductionTab::runAlgorithm(const Mantid::API::IAlgorithm_sptr algorithm) - { - algorithm->setRethrows(true); - m_algRunner->startAlgorithm(algorithm); - } - - /** - * Handles getting the results of an algorithm running async + * @param instName Name of instrument + * @param analyser Analyser component + * @param reflection Reflection used * - * @param error :: True if execution failed, false otherwise + * @returns A map of range ID to value */ - void IndirectDataReductionTab::algorithmFinished(bool error) + std::map IndirectDataReductionTab::getRangesFromInstrument( + QString instName, QString analyser, QString reflection) { - if(error) - { - emit showMessageBox("Error running SofQWMoments. \nSee results log for details."); - } + // Get any unset parameters + if(instName.isEmpty()) + instName = m_uiForm.cbInst->currentText(); + if(analyser.isEmpty()) + analyser = m_uiForm.cbAnalyser->currentText(); + if(reflection.isEmpty()) + reflection = m_uiForm.cbReflection->currentText(); + + std::map ranges; + + // Get the instrument + auto instWs = loadInstrumentIfNotExist(instName.toStdString(), analyser.toStdString(), reflection.toStdString()); + auto inst = instWs->getInstrument(); + + // Get the analyser component + auto comp = inst->getComponentByName(analyser.toStdString()); + if(!comp) + return ranges; + + // Get the resolution of the analyser + auto resParams = comp->getNumberParameter("resolution", true); + if(resParams.size() < 1) + return ranges; + double resolution = resParams[0]; + + std::vector x; + x.push_back(-6 * resolution); + x.push_back(-5 * resolution); + x.push_back(-2 * resolution); + x.push_back(0); + x.push_back(2 * resolution); + std::vector y; + y.push_back(1); + y.push_back(2); + y.push_back(3); + y.push_back(4); + std::vector e(4, 0); + + IAlgorithm_sptr createWsAlg = AlgorithmManager::Instance().create("CreateWorkspace"); + createWsAlg->initialize(); + createWsAlg->setProperty("OutputWorkspace", "__energy"); + createWsAlg->setProperty("DataX", x); + createWsAlg->setProperty("DataY", y); + createWsAlg->setProperty("DataE", e); + createWsAlg->setProperty("Nspec", 1); + createWsAlg->setProperty("UnitX", "DeltaE"); + createWsAlg->execute(); + + IAlgorithm_sptr convertHistAlg = AlgorithmManager::Instance().create("ConvertToHistogram"); + convertHistAlg->initialize(); + convertHistAlg->setProperty("InputWorkspace", "__energy"); + convertHistAlg->setProperty("OutputWorkspace", "__energy"); + convertHistAlg->execute(); + + IAlgorithm_sptr loadInstAlg = AlgorithmManager::Instance().create("LoadInstrument"); + loadInstAlg->initialize(); + loadInstAlg->setProperty("Workspace", "__energy"); + loadInstAlg->setProperty("InstrumentName", instName.toStdString()); + loadInstAlg->execute(); + + QString ipfFilename = instName + "_" + analyser + "_" + reflection + "_Parameters.xml"; + + IAlgorithm_sptr loadParamAlg = AlgorithmManager::Instance().create("LoadParameterFile"); + loadParamAlg->initialize(); + loadParamAlg->setProperty("Workspace", "__energy"); + loadParamAlg->setProperty("Filename", ipfFilename.toStdString()); + loadParamAlg->execute(); + + auto energyWs = AnalysisDataService::Instance().retrieveWS("__energy"); + double efixed = energyWs->getInstrument()->getNumberParameter("efixed-val")[0]; + + auto spectrum = energyWs->getSpectrum(0); + spectrum->setSpectrumNo(3); + spectrum->clearDetectorIDs(); + spectrum->addDetectorID(3); + + IAlgorithm_sptr convUnitsAlg = AlgorithmManager::Instance().create("ConvertUnits"); + convUnitsAlg->initialize(); + convUnitsAlg->setProperty("InputWorkspace", "__energy"); + convUnitsAlg->setProperty("OutputWorkspace", "__tof"); + convUnitsAlg->setProperty("Target", "TOF"); + convUnitsAlg->setProperty("EMode", "Indirect"); + convUnitsAlg->setProperty("EFixed", efixed); + convUnitsAlg->execute(); + + auto tofWs = AnalysisDataService::Instance().retrieveWS("__tof"); + + std::vector tofData = tofWs->readX(0); + ranges["peak-start-tof"] = tofData[0]; + ranges["peak-end-tof"] = tofData[2]; + ranges["back-start-tof"] = tofData[3]; + ranges["back-end-tof"] = tofData[4]; + + return ranges; } } // namespace CustomInterfaces diff --git a/Code/Mantid/MantidQt/CustomInterfaces/src/IndirectDiagnostics.cpp b/Code/Mantid/MantidQt/CustomInterfaces/src/IndirectDiagnostics.cpp index aba874ca7cf7..e1ac3785e73f 100644 --- a/Code/Mantid/MantidQt/CustomInterfaces/src/IndirectDiagnostics.cpp +++ b/Code/Mantid/MantidQt/CustomInterfaces/src/IndirectDiagnostics.cpp @@ -6,6 +6,8 @@ #include +using namespace Mantid::API; + namespace { Mantid::Kernel::Logger g_log("IndirectDiagnostics"); @@ -19,7 +21,7 @@ namespace CustomInterfaces /** Constructor */ IndirectDiagnostics::IndirectDiagnostics(Ui::IndirectDataReduction& uiForm, QWidget * parent) : - IndirectDataReductionTab(uiForm, parent) + IndirectDataReductionTab(uiForm, parent), m_lastDiagFilename("") { // Property Tree m_propTrees["SlicePropTree"] = new QtTreePropertyBrowser(); @@ -63,7 +65,6 @@ namespace CustomInterfaces // Slice plot m_plots["SlicePlot"] = new QwtPlot(m_parentWidget); - m_curves["SlicePlot"] = new QwtPlotCurve(); m_rangeSelectors["SlicePeak"] = new MantidWidgets::RangeSelector(m_plots["SlicePlot"]); m_rangeSelectors["SliceBackground"] = new MantidWidgets::RangeSelector(m_plots["SlicePlot"]); @@ -79,107 +80,116 @@ namespace CustomInterfaces // Refresh the plot window m_plots["SlicePlot"]->replot(); + // Preview plot + m_plots["SlicePreviewPlot"] = new QwtPlot(m_parentWidget); + m_plots["SlicePreviewPlot"]->setAxisFont(QwtPlot::xBottom, parent->font()); + m_plots["SlicePreviewPlot"]->setAxisFont(QwtPlot::yLeft, parent->font()); + m_plots["SlicePreviewPlot"]->setCanvasBackground(Qt::white); + m_uiForm.slice_plotPreview->addWidget(m_plots["SlicePreviewPlot"]); + m_plots["SlicePreviewPlot"]->replot(); + // SIGNAL/SLOT CONNECTIONS - /* connect(m_rangeSelectors["SlicePeak"], SIGNAL(rangeChanged(double, double)), m_rangeSelectors["SliceBackground"], SLOT(setRange(double, double))); */ + + // Update instrument information when a new instrument config is selected + connect(this, SIGNAL(newInstrumentConfiguration()), this, SLOT(setDefaultInstDetails())); // Update properties when a range selector is changed - connect(m_rangeSelectors["SlicePeak"], SIGNAL(minValueChanged(double)), this, SLOT(sliceMinChanged(double))); - connect(m_rangeSelectors["SlicePeak"], SIGNAL(maxValueChanged(double)), this, SLOT(sliceMaxChanged(double))); - connect(m_rangeSelectors["SliceBackground"], SIGNAL(minValueChanged(double)), this, SLOT(sliceMinChanged(double))); - connect(m_rangeSelectors["SliceBackground"], SIGNAL(maxValueChanged(double)), this, SLOT(sliceMaxChanged(double))); - // Update range seelctors when a property 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))); + + // Update range selctors when a property is changed connect(m_dblManager, SIGNAL(valueChanged(QtProperty*, double)), this, SLOT(sliceUpdateRS(QtProperty*, double))); // Enable/disable second range options when checkbox is toggled connect(m_blnManager, SIGNAL(valueChanged(QtProperty*, bool)), this, SLOT(sliceTwoRanges(QtProperty*, bool))); - // Plot slice miniplot when file has finished loading - connect(m_uiForm.slice_inputFile, SIGNAL(filesFound()), this, SLOT(slicePlotRaw())); - // Plot slice miniplot when user clicks Plot Raw - connect(m_uiForm.slice_pbPlotRaw, SIGNAL(clicked()), this, SLOT(slicePlotRaw())); // Enables/disables calibration file selection when user toggles Use Calibratin File checkbox connect(m_uiForm.slice_ckUseCalib, SIGNAL(toggled(bool)), this, SLOT(sliceCalib(bool))); + // Plot slice miniplot when file has finished loading + connect(m_uiForm.slice_inputFile, SIGNAL(filesFound()), this, SLOT(slicePlotRaw())); + // Shows message on run buton when user is inputting a run number + connect(m_uiForm.slice_inputFile, SIGNAL(fileTextChanged(const QString &)), this, SLOT(pbRunEditing())); + // Shows message on run button when Mantid is finding the file for a given run number + connect(m_uiForm.slice_inputFile, SIGNAL(findingFiles()), this, SLOT(pbRunFinding())); + // Reverts run button back to normal when file finding has finished + connect(m_uiForm.slice_inputFile, SIGNAL(fileFindingFinished()), this, SLOT(pbRunFinished())); + + // Update preview plot when slice algorithm completes + connect(m_batchAlgoRunner, SIGNAL(batchComplete(bool)), this, SLOT(sliceAlgDone(bool))); + // Set default UI state sliceTwoRanges(0, false); + m_uiForm.slice_ckUseCalib->setChecked(false); + sliceCalib(false); } - + //---------------------------------------------------------------------------------------------- /** Destructor */ IndirectDiagnostics::~IndirectDiagnostics() { } - + void IndirectDiagnostics::setup() { } void IndirectDiagnostics::run() { - QString pyInput = - "from IndirectEnergyConversion import slice\n" - "tofRange = [" + QString::number(m_dblManager->value(m_properties["PeakStart"])) + "," - + QString::number(m_dblManager->value(m_properties["PeakEnd"])); - if ( m_blnManager->value(m_properties["UseTwoRanges"]) ) - { - pyInput += - "," + QString::number(m_dblManager->value(m_properties["BackgroundStart"])) + "," - + QString::number(m_dblManager->value(m_properties["BackgroundEnd"])) + "]\n"; - } - else - { - pyInput += "]\n"; - } - if ( m_uiForm.slice_ckUseCalib->isChecked() ) - { - pyInput += - "calib = r'" + m_uiForm.slice_calibFile->getFirstFilename() + "'\n"; - } - else - { - pyInput += - "calib = ''\n"; - } + QString suffix = "_" + m_uiForm.cbAnalyser->currentText() + m_uiForm.cbReflection->currentText() + "_slice"; QString filenames = m_uiForm.slice_inputFile->getFilenames().join("', r'"); - QString suffix = m_uiForm.cbAnalyser->currentText() + m_uiForm.cbReflection->currentText(); - pyInput += - "rawfile = [r'" + filenames + "']\n" - "spectra = ["+ QString::number(m_dblManager->value(m_properties["SpecMin"])) + "," + QString::number(m_dblManager->value(m_properties["SpecMax"])) +"]\n" - "suffix = '" + suffix + "'\n"; - - if(m_uiForm.slice_ckVerbose->isChecked()) - pyInput += "verbose = True\n"; - else - pyInput += "verbose = False\n"; - if(m_uiForm.slice_ckPlot->isChecked()) - pyInput += "plot = True\n"; - else - pyInput += "plot = False\n"; + std::vector spectraRange; + spectraRange.push_back(static_cast(m_dblManager->value(m_properties["SpecMin"]))); + spectraRange.push_back(static_cast(m_dblManager->value(m_properties["SpecMax"]))); - if(m_uiForm.slice_ckSave->isChecked()) - pyInput += "save = True\n"; - else - pyInput += "save = False\n"; + std::vector peakRange; + peakRange.push_back(m_dblManager->value(m_properties["PeakStart"])); + peakRange.push_back(m_dblManager->value(m_properties["PeakEnd"])); + + IAlgorithm_sptr sliceAlg = AlgorithmManager::Instance().create("TimeSlice"); + sliceAlg->initialize(); + + sliceAlg->setProperty("InputFiles", filenames.toStdString()); + sliceAlg->setProperty("SpectraRange", spectraRange); + sliceAlg->setProperty("PeakRange", peakRange); + sliceAlg->setProperty("Verbose", m_uiForm.slice_ckVerbose->isChecked()); + sliceAlg->setProperty("Plot", m_uiForm.slice_ckPlot->isChecked()); + sliceAlg->setProperty("Save", m_uiForm.slice_ckSave->isChecked()); + sliceAlg->setProperty("OutputNameSuffix", suffix.toStdString()); + + if(m_uiForm.slice_ckUseCalib->isChecked()) + { + QString calibWsName = m_uiForm.slice_dsCalibFile->getCurrentDataName(); + sliceAlg->setProperty("CalibrationWorkspace", calibWsName.toStdString()); + } - pyInput += - "slice(rawfile, calib, tofRange, spectra, suffix, Save=save, Verbose=verbose, Plot=plot)"; + if(m_blnManager->value(m_properties["UseTwoRanges"])) + { + std::vector backgroundRange; + backgroundRange.push_back(m_dblManager->value(m_properties["BackgroundStart"])); + backgroundRange.push_back(m_dblManager->value(m_properties["BackgroundEnd"])); + sliceAlg->setProperty("BackgroundRange", backgroundRange); + } - QString pyOutput = m_pythonRunner.runPythonCode(pyInput).trimmed(); + runAlgorithm(sliceAlg); } bool IndirectDiagnostics::validate() { UserInputValidator uiv; + // Check raw input uiv.checkMWRunFilesIsValid("Input", m_uiForm.slice_inputFile); - if( m_uiForm.slice_ckUseCalib->isChecked() ) + if(m_uiForm.slice_ckUseCalib->isChecked()) uiv.checkMWRunFilesIsValid("Calibration", m_uiForm.slice_inputFile); + // Check peak range auto rangeOne = std::make_pair(m_dblManager->value(m_properties["PeakStart"]), m_dblManager->value(m_properties["PeakEnd"])); uiv.checkValidRange("Range One", rangeOne); + // Check background range bool useTwoRanges = m_blnManager->value(m_properties["UseTwoRanges"]); - if( useTwoRanges ) + if(useTwoRanges) { auto rangeTwo = std::make_pair(m_dblManager->value(m_properties["BackgroundStart"]), m_dblManager->value(m_properties["BackgroundEnd"])); uiv.checkValidRange("Range Two", rangeTwo); @@ -187,19 +197,21 @@ namespace CustomInterfaces uiv.checkRangesDontOverlap(rangeOne, rangeTwo); } - auto specRange = std::make_pair(m_dblManager->value(m_properties["SpecMin"]), m_dblManager->value(m_properties["SpecMax"])); + // Check spectra range + auto specRange = std::make_pair(m_dblManager->value(m_properties["SpecMin"]), m_dblManager->value(m_properties["SpecMax"]) + 1); uiv.checkValidRange("Spectra Range", specRange); QString error = uiv.generateErrorMessage(); + bool isError = error != ""; - if(error != "") + if(isError) g_log.warning(error.toStdString()); - return (error == ""); + return !isError; } /** - * Sets default spectra, peak and background ranges + * Sets default spectra, peak and background ranges. */ void IndirectDiagnostics::setDefaultInstDetails() { @@ -207,16 +219,16 @@ namespace CustomInterfaces std::map instDetails = getInstrumentDetails(); //Set spectra range - m_dblManager->setValue(m_properties["SpecMin"], instDetails["SpectraMin"].toDouble()); - m_dblManager->setValue(m_properties["SpecMax"], instDetails["SpectraMax"].toDouble()); + m_dblManager->setValue(m_properties["SpecMin"], instDetails["spectra-min"].toDouble()); + m_dblManager->setValue(m_properties["SpecMax"], instDetails["spectra-max"].toDouble()); //Set peak and background ranges if(instDetails.size() >= 8) { setMiniPlotGuides("SlicePeak", m_properties["PeakStart"], m_properties["PeakEnd"], - std::pair(instDetails["PeakMin"].toDouble(), instDetails["PeakMax"].toDouble())); - setMiniPlotGuides("SliceBackground", m_properties["BackStart"], m_properties["BackEnd"], - std::pair(instDetails["BackMin"].toDouble(), instDetails["BackMax"].toDouble())); + std::pair(instDetails["peak-start"].toDouble(), instDetails["peak-end"].toDouble())); + setMiniPlotGuides("SliceBackground", m_properties["BackgroundStart"], m_properties["BackgroundEnd"], + std::pair(instDetails["back-start"].toDouble(), instDetails["back-end"].toDouble())); } } @@ -225,17 +237,28 @@ namespace CustomInterfaces */ void IndirectDiagnostics::slicePlotRaw() { - using namespace Mantid::API; + QString filename = m_uiForm.slice_inputFile->getFirstFilename(); + + // Only update if we have a different file + if(filename == m_lastDiagFilename) + return; + + m_lastDiagFilename = filename; + + disconnect(m_dblManager, SIGNAL(valueChanged(QtProperty*, double)), this, SLOT(updatePreviewPlot())); + disconnect(m_blnManager, SIGNAL(valueChanged(QtProperty*, bool)), this, SLOT(updatePreviewPlot())); setDefaultInstDetails(); if ( m_uiForm.slice_inputFile->isValid() ) { - QString filename = m_uiForm.slice_inputFile->getFirstFilename(); QFileInfo fi(filename); QString wsname = fi.baseName(); - if(!loadFile(filename, wsname, m_uiForm.leSpectraMin->text().toInt(), m_uiForm.leSpectraMax->text().toInt())) + int specMin = static_cast(m_dblManager->value(m_properties["SpecMin"])); + int specMax = static_cast(m_dblManager->value(m_properties["SpecMax"])); + + if(!loadFile(filename, wsname, specMin, specMax)) { emit showMessageBox("Unable to load file.\nCheck whether your file exists and matches the selected instrument in the EnergyTransfer tab."); return; @@ -259,6 +282,11 @@ namespace CustomInterfaces { emit showMessageBox("Selected input files are invalid."); } + + connect(m_dblManager, SIGNAL(valueChanged(QtProperty*, double)), this, SLOT(updatePreviewPlot())); + connect(m_blnManager, SIGNAL(valueChanged(QtProperty*, bool)), this, SLOT(updatePreviewPlot())); + + updatePreviewPlot(); } /** @@ -278,52 +306,143 @@ namespace CustomInterfaces */ void IndirectDiagnostics::sliceCalib(bool state) { - m_uiForm.slice_calibFile->setEnabled(state); - m_uiForm.slice_calibFile->isOptional(!state); + m_uiForm.slice_dsCalibFile->setEnabled(state); + } + + void IndirectDiagnostics::rangeSelectorDropped(double min, double max) + { + MantidWidgets::RangeSelector* from = qobject_cast(sender()); + + if(from == m_rangeSelectors["SlicePeak"]) + { + m_dblManager->setValue(m_properties["PeakStart"], min); + m_dblManager->setValue(m_properties["PeakEnd"], max); + } + else if(from == m_rangeSelectors["SliceBackground"]) + { + m_dblManager->setValue(m_properties["BackgroundStart"], min); + m_dblManager->setValue(m_properties["BackgroundEnd"], max); + } } /** - * Handles the value of a range selector minimum value being changed + * Update the value of a range selector given a QtProperty * - * @param val :: New minimum value + * @param prop :: Pointer to the QtProperty + * @param val :: New value of the range selector */ - void IndirectDiagnostics::sliceMinChanged(double val) + void IndirectDiagnostics::sliceUpdateRS(QtProperty* prop, double val) { - MantidWidgets::RangeSelector* from = qobject_cast(sender()); + 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); + } + + /** + * Runs the slice algorithm with preview properties. + */ + void IndirectDiagnostics::updatePreviewPlot() + { + QString suffix = "_" + m_uiForm.cbAnalyser->currentText() + m_uiForm.cbReflection->currentText() + "_slice"; + QString filenames = m_uiForm.slice_inputFile->getFilenames().join("', r'"); + + std::vector spectraRange; + spectraRange.push_back(static_cast(m_dblManager->value(m_properties["SpecMin"]))); + spectraRange.push_back(static_cast(m_dblManager->value(m_properties["SpecMax"]))); - if ( from == m_rangeSelectors["SlicePeak"] ) - m_dblManager->setValue(m_properties["PeakStart"], val); - else if ( from == m_rangeSelectors["SliceBackground"] ) - m_dblManager->setValue(m_properties["BackgroundStart"], val); + std::vector peakRange; + peakRange.push_back(m_dblManager->value(m_properties["PeakStart"])); + peakRange.push_back(m_dblManager->value(m_properties["PeakEnd"])); + + IAlgorithm_sptr sliceAlg = AlgorithmManager::Instance().create("TimeSlice"); + sliceAlg->initialize(); + + sliceAlg->setProperty("InputFiles", filenames.toStdString()); + sliceAlg->setProperty("SpectraRange", spectraRange); + sliceAlg->setProperty("PeakRange", peakRange); + sliceAlg->setProperty("Verbose", m_uiForm.slice_ckVerbose->isChecked()); + sliceAlg->setProperty("Plot", false); + sliceAlg->setProperty("Save", false); + sliceAlg->setProperty("OutputNameSuffix", suffix.toStdString()); + + if(m_uiForm.slice_ckUseCalib->isChecked()) + { + QString calibWsName = m_uiForm.slice_dsCalibFile->getCurrentDataName(); + sliceAlg->setProperty("CalibrationWorkspace", calibWsName.toStdString()); + } + + if(m_blnManager->value(m_properties["UseTwoRanges"])) + { + std::vector backgroundRange; + backgroundRange.push_back(m_dblManager->value(m_properties["BackgroundStart"])); + backgroundRange.push_back(m_dblManager->value(m_properties["BackgroundEnd"])); + sliceAlg->setProperty("BackgroundRange", backgroundRange); + } + + // Stop the algorithm conflicting with it's self if it is already running + if(m_batchAlgoRunner->queueLength() == 0) + runAlgorithm(sliceAlg); } /** - * Handles the value of a range selector maximum value being changed + * Updates the preview plot when the algorithm is complete. * - * @param val :: New maximum value + * @param error True if the algorithm was stopped due to error, false otherwise */ - void IndirectDiagnostics::sliceMaxChanged(double val) + void IndirectDiagnostics::sliceAlgDone(bool error) { - MantidWidgets::RangeSelector* from = qobject_cast(sender()); + if(error) + return; + + QStringList filenames = m_uiForm.slice_inputFile->getFilenames(); + if(filenames.size() < 1) + return; - if ( from == m_rangeSelectors["SlicePeak"] ) - m_dblManager->setValue(m_properties["PeakEnd"], val); - else if ( from == m_rangeSelectors["SliceBackground"] ) - m_dblManager->setValue(m_properties["BackgroundEnd"], val); + QString filename = filenames[0].toLower(); + QFileInfo rawFileInfo(filename); + QString wsName = rawFileInfo.baseName() + "_" + m_uiForm.cbAnalyser->currentText() + m_uiForm.cbReflection->currentText() + "_slice"; + + // Plot result spectrum + plotMiniPlot(wsName, 0, "SlicePreviewPlot", "SlicePreviewCurve"); + + // Set X range to data range + setXAxisToCurve("SlicePreviewPlot", "SlicePreviewCurve"); + m_plots["SlicePreviewPlot"]->replot(); } /** - * Update the value of a range selector given a QtProperty - * - * @param prop :: Pointer to the QtProperty - * @param val :: New value of the range selector + * Called when a user starts to type / edit the runs to load. */ - void IndirectDiagnostics::sliceUpdateRS(QtProperty* prop, double val) + void IndirectDiagnostics::pbRunEditing() + { + emit updateRunButton(false, "Editing...", "Run numbers are curently being edited."); + } + + /** + * Called when the FileFinder starts finding the files. + */ + void IndirectDiagnostics::pbRunFinding() { - 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); + emit updateRunButton(false, "Finding files...", "Searchig for data files for the run numbers entered..."); + m_uiForm.slice_inputFile->setEnabled(false); + } + + /** + * Called when the FileFinder has finished finding the files. + */ + void IndirectDiagnostics::pbRunFinished() + { + if(!m_uiForm.slice_inputFile->isValid()) + { + emit updateRunButton(false, "Invalid Run(s)", "Cannot find data files for some of the run numbers enetered."); + } + else + { + emit updateRunButton(); + } + + m_uiForm.slice_inputFile->setEnabled(true); } } // namespace CustomInterfaces diff --git a/Code/Mantid/MantidQt/CustomInterfaces/src/IndirectDiffractionReduction.cpp b/Code/Mantid/MantidQt/CustomInterfaces/src/IndirectDiffractionReduction.cpp index 45009aa65346..e3c9a1c5a406 100644 --- a/Code/Mantid/MantidQt/CustomInterfaces/src/IndirectDiffractionReduction.cpp +++ b/Code/Mantid/MantidQt/CustomInterfaces/src/IndirectDiffractionReduction.cpp @@ -4,12 +4,16 @@ #include "MantidQtCustomInterfaces/IndirectDiffractionReduction.h" #include "MantidQtAPI/ManageUserDirectories.h" +#include "MantidAPI/AlgorithmManager.h" #include "MantidKernel/Logger.h" #include "MantidKernel/MultiFileNameParser.h" #include #include +using namespace Mantid::API; +using namespace Mantid::Geometry; + //Add this class to the list of specialised dialogs in this namespace namespace MantidQt { @@ -30,15 +34,22 @@ namespace // anon DECLARE_SUBWINDOW(IndirectDiffractionReduction); +using namespace Mantid::API; using namespace MantidQt::CustomInterfaces; +using MantidQt::API::BatchAlgorithmRunner; + //---------------------- // Public member functions //---------------------- ///Constructor IndirectDiffractionReduction::IndirectDiffractionReduction(QWidget *parent) : - UserSubWindow(parent), m_valInt(NULL), m_valDbl(NULL), m_settingsGroup("CustomInterfaces/DEMON") + UserSubWindow(parent), m_valInt(NULL), m_valDbl(NULL), + m_settingsGroup("CustomInterfaces/DEMON"), + m_batchAlgoRunner(new BatchAlgorithmRunner(parent)) { + // Handles completion of the diffraction algorithm chain + connect(m_batchAlgoRunner, SIGNAL(batchComplete(bool)), this, SLOT(plotResults(bool))); } ///Destructor @@ -47,208 +58,330 @@ IndirectDiffractionReduction::~IndirectDiffractionReduction() saveSettings(); } +/** + * Runs a diffraction reduction when the user clieks Run. + */ void IndirectDiffractionReduction::demonRun() { - if ( !validateDemon() ) - { - showInformationBox("Invalid invalid. Incorrect entries marked with red star."); - return; - } - - QString instName=m_uiForm.cbInst->currentText(); + QString instName = m_uiForm.cbInst->currentText(); QString mode = m_uiForm.cbReflection->currentText(); - if ( instName != "OSIRIS" || mode == "diffspec" ) - { - // MSGDiffractionReduction - QString pfile = instName + "_diffraction_" + mode + "_Parameters.xml"; - QString pyInput = - "from IndirectDiffractionReduction import MSGDiffractionReducer\n" - "reducer = MSGDiffractionReducer()\n" - "reducer.set_instrument_name('" + instName + "')\n" - "reducer.set_detector_range("+m_uiForm.set_leSpecMin->text()+"-1, " +m_uiForm.set_leSpecMax->text()+"-1)\n" - "reducer.set_parameter_file('" + pfile + "')\n" - "files = [r'" + m_uiForm.dem_rawFiles->getFilenames().join("',r'") + "']\n" - "for file in files:\n" - " reducer.append_data_file(file)\n"; - // Fix Vesuvio to FoilOut for now - if(instName == "VESUVIO") - pyInput += "reducer.append_load_option('Mode','FoilOut')\n"; - - if ( m_uiForm.dem_ckSumFiles->isChecked() ) - { - pyInput += "reducer.set_sum_files(True)\n"; - } - pyInput += "formats = []\n"; - if ( m_uiForm.ckGSS->isChecked() ) pyInput += "formats.append('gss')\n"; - if ( m_uiForm.ckNexus->isChecked() ) pyInput += "formats.append('nxs')\n"; - if ( m_uiForm.ckAscii->isChecked() ) pyInput += "formats.append('ascii')\n"; - - QString rebin = m_uiForm.leRebinStart->text() + "," + m_uiForm.leRebinWidth->text() - + "," + m_uiForm.leRebinEnd->text(); - if ( rebin != ",," ) - { - pyInput += "reducer.set_rebin_string('" + rebin +"')\n"; - } - - pyInput += "reducer.set_save_formats(formats)\n"; - pyInput += - "reducer.reduce()\n"; - - if ( m_uiForm.cbPlotType->currentText() == "Spectra" ) + if(instName == "OSIRIS" && mode == "diffonly") + { + if(!m_uiForm.dem_rawFiles->isValid() || !validateVanCal()) { - pyInput += "wslist = reducer.get_result_workspaces()\n" - "from mantidplot import *\n" - "plotSpectrum(wslist, 0)\n"; + showInformationBox("Invalid input.\nIncorrect entries marked with red star."); + return; } - QString pyOutput = runPythonCode(pyInput).trimmed(); + runOSIRISdiffonlyReduction(); } else { - // Get the files names from MWRunFiles widget, and convert them from Qt forms into stl equivalents. - QStringList fileNames = m_uiForm.dem_rawFiles->getFilenames(); - std::vector stlFileNames; - stlFileNames.reserve(fileNames.size()); - std::transform(fileNames.begin(),fileNames.end(),std::back_inserter(stlFileNames), toStdString); - - // Use the file names to suggest a workspace name to use. Report to logger and stop if unable to parse correctly. - QString drangeWsName; - QString tofWsName; - try + if(!m_uiForm.dem_rawFiles->isValid() || !validateRebin()) { - QString nameBase = QString::fromStdString(Mantid::Kernel::MultiFileNameParsing::suggestWorkspaceName(stlFileNames)); - tofWsName = "'" + nameBase + "_tof'"; - drangeWsName = "'" + nameBase + "_dRange'"; - } - catch(std::runtime_error & re) - { - g_log.error(re.what()); + showInformationBox("Invalid input.\nIncorrect entries marked with red star."); return; } - QString pyInput = - "from mantid.simpleapi import *\n" - "OSIRISDiffractionReduction(" - "Sample=r'" + m_uiForm.dem_rawFiles->getFilenames().join(", ") + "', " - "Vanadium=r'" + m_uiForm.dem_vanadiumFile->getFilenames().join(", ") + "', " - "CalFile=r'" + m_uiForm.dem_calFile->getFirstFilename() + "', " - "OutputWorkspace=" + drangeWsName + ")\n"; - - pyInput += "ConvertUnits(InputWorkspace=" + drangeWsName + ", OutputWorkspace=" + tofWsName + ", Target='TOF')\n"; - - if ( m_uiForm.ckGSS->isChecked() ) - { - pyInput += "SaveGSS(InputWorkspace=" + tofWsName + ", Filename=" + tofWsName + " + '.gss')\n"; - } + runGenericReduction(instName, mode); + } +} + +/** + * Handles plotting result spectra from algorithm chains. + * + * @param error True if the chain was stopped due to error + */ +void IndirectDiffractionReduction::plotResults(bool error) +{ + // Nothing can be plotted + if(error) + { + showInformationBox("Error running diffraction reduction.\nSee Results Log for details."); + return; + } - if ( m_uiForm.ckNexus->isChecked() ) - pyInput += "SaveNexusProcessed(InputWorkspace=" + drangeWsName + ", Filename=" + drangeWsName + "+'.nxs')\n"; + QString instName = m_uiForm.cbInst->currentText(); + QString mode = m_uiForm.cbReflection->currentText(); - if ( m_uiForm.ckAscii->isChecked() ) - pyInput += "SaveAscii(InputWorkspace=" + drangeWsName + ", Filename=" + drangeWsName + " +'.dat')\n"; + QString plotType = m_uiForm.cbPlotType->currentText(); - if ( m_uiForm.cbPlotType->currentText() == "Spectra" ) - { - pyInput += "from mantidplot import *\n" - "plotSpectrum(" + drangeWsName + ", 0)\n" - "plotSpectrum(" + tofWsName + ", 0)\n"; - } + QString pyInput = "from mantidplot import plotSpectrum, plot2D\n"; + + if(plotType == "Spectra" || plotType == "Both") + { + for(auto it = m_plotWorkspaces.begin(); it != m_plotWorkspaces.end(); ++it) + pyInput += "plotSpectrum('" + *it + "', 0)\n"; + } - QString pyOutput = runPythonCode(pyInput).trimmed(); + if(plotType == "Contour" || plotType == "Both") + { + for(auto it = m_plotWorkspaces.begin(); it != m_plotWorkspaces.end(); ++it) + pyInput += "plot2D('" + *it + "')\n"; } + + runPythonCode(pyInput); } -void IndirectDiffractionReduction::instrumentSelected(int) +/** + * Runs a diffraction reduction for any instrument in any mode. + * + * @param instName Name of the instrument + * @param mode Mode instrument is operating in (diffspec/diffonly) + */ +void IndirectDiffractionReduction::runGenericReduction(QString instName, QString mode) { - if ( ! m_uiForm.cbInst->isVisible() ) + // Get rebin string + QString rebinStart = m_uiForm.leRebinStart->text(); + QString rebinWidth = m_uiForm.leRebinWidth->text(); + QString rebinEnd = m_uiForm.leRebinEnd->text(); + + QString rebin = ""; + if(!rebinStart.isEmpty() && !rebinWidth.isEmpty() && !rebinEnd.isEmpty()) + rebin = rebinStart + "," + rebinWidth + "," + rebinEnd; + + bool individualGrouping = m_uiForm.ckIndividualGrouping->isChecked(); + + // Get detector range + std::vector detRange; + detRange.push_back(m_uiForm.set_leSpecMin->text().toLong()); + detRange.push_back(m_uiForm.set_leSpecMax->text().toLong()); + + // Get MSGDiffractionReduction algorithm instance + IAlgorithm_sptr msgDiffReduction = AlgorithmManager::Instance().create("MSGDiffractionReduction"); + msgDiffReduction->initialize(); + + // Get save formats + std::vector saveFormats; + if(m_uiForm.ckGSS->isChecked()) saveFormats.push_back("gss"); + if(m_uiForm.ckNexus->isChecked()) saveFormats.push_back("nxs"); + if(m_uiForm.ckAscii->isChecked()) saveFormats.push_back("ascii"); + + // Set algorithm properties + msgDiffReduction->setProperty("Instrument", instName.toStdString()); + msgDiffReduction->setProperty("Mode", mode.toStdString()); + msgDiffReduction->setProperty("SumFiles", m_uiForm.dem_ckSumFiles->isChecked()); + msgDiffReduction->setProperty("InputFiles", m_uiForm.dem_rawFiles->getFilenames().join(",").toStdString()); + msgDiffReduction->setProperty("DetectorRange", detRange); + msgDiffReduction->setProperty("RebinParam", rebin.toStdString()); + msgDiffReduction->setProperty("IndividualGrouping", individualGrouping); + msgDiffReduction->setProperty("SaveFormats", saveFormats); + msgDiffReduction->setProperty("OutputWorkspaceGroup", "IndirectDiffraction_Workspaces"); + + m_batchAlgoRunner->addAlgorithm(msgDiffReduction); + + m_plotWorkspaces.clear(); + m_plotWorkspaces.push_back("IndirectDiffraction_Workspaces"); + + m_batchAlgoRunner->executeBatchAsync(); +} + +/** + * Runs a diffraction reduction for OSIRIS operating in diffonly mode using the OSIRISDiffractionReduction algorithm. + */ +void IndirectDiffractionReduction::runOSIRISdiffonlyReduction() +{ + // Get the files names from MWRunFiles widget, and convert them from Qt forms into stl equivalents. + QStringList fileNames = m_uiForm.dem_rawFiles->getFilenames(); + std::vector stlFileNames; + stlFileNames.reserve(fileNames.size()); + std::transform(fileNames.begin(),fileNames.end(),std::back_inserter(stlFileNames), toStdString); + + // Use the file names to suggest a workspace name to use. Report to logger and stop if unable to parse correctly. + QString drangeWsName; + QString tofWsName; + try + { + QString nameBase = QString::fromStdString(Mantid::Kernel::MultiFileNameParsing::suggestWorkspaceName(stlFileNames)); + tofWsName = "'" + nameBase + "_tof'"; + drangeWsName = "'" + nameBase + "_dRange'"; + } + catch(std::runtime_error & re) { - // If the interface is not shown, do not go looking for parameter files, etc. + g_log.error(re.what()); return; } - m_uiForm.cbReflection->blockSignals(true); - m_uiForm.cbReflection->clear(); + IAlgorithm_sptr osirisDiffReduction = AlgorithmManager::Instance().create("OSIRISDiffractionReduction"); + osirisDiffReduction->initialize(); + osirisDiffReduction->setProperty("Sample", m_uiForm.dem_rawFiles->getFilenames().join(",").toStdString()); + osirisDiffReduction->setProperty("Vanadium", m_uiForm.dem_vanadiumFile->getFilenames().join(",").toStdString()); + osirisDiffReduction->setProperty("CalFile", m_uiForm.dem_calFile->getFirstFilename().toStdString()); + osirisDiffReduction->setProperty("OutputWorkspace", drangeWsName.toStdString()); + m_batchAlgoRunner->addAlgorithm(osirisDiffReduction); - QString pyInput = - "from IndirectEnergyConversion import getInstrumentDetails\n" - "print getInstrumentDetails('" + m_uiForm.cbInst->currentText() + "')\n"; + BatchAlgorithmRunner::AlgorithmRuntimeProps inputFromReductionProps; + inputFromReductionProps["InputWorkspace"] = drangeWsName.toStdString(); - QString pyOutput = runPythonCode(pyInput).trimmed(); + IAlgorithm_sptr convertUnits = AlgorithmManager::Instance().create("ConvertUnits"); + convertUnits->initialize(); + convertUnits->setProperty("OutputWorkspace", tofWsName.toStdString()); + convertUnits->setProperty("Target", "TOF"); + m_batchAlgoRunner->addAlgorithm(convertUnits, inputFromReductionProps); - if(pyOutput.length() > 0) - { - QStringList analysers = pyOutput.split("\n", QString::SkipEmptyParts); + BatchAlgorithmRunner::AlgorithmRuntimeProps inputFromConvUnitsProps; + inputFromConvUnitsProps["InputWorkspace"] = tofWsName.toStdString(); - for (int i = 0; i< analysers.count(); i++ ) - { - QStringList analyser = analysers[i].split("-", QString::SkipEmptyParts); - if ( analyser[0] == "diffraction" && analyser.count() > 1) - { - QStringList reflections = analyser[1].split(",", QString::SkipEmptyParts); - for ( int j = 0; j < reflections.count(); j++ ) - { - m_uiForm.cbReflection->addItem(reflections[j]); - } - } - } + if ( m_uiForm.ckGSS->isChecked() ) + { + QString gssFilename = tofWsName + ".gss"; + IAlgorithm_sptr saveGSS = AlgorithmManager::Instance().create("SaveGSS"); + saveGSS->initialize(); + saveGSS->setProperty("Filename", gssFilename.toStdString()); + m_batchAlgoRunner->addAlgorithm(saveGSS, inputFromConvUnitsProps); } - reflectionSelected(m_uiForm.cbReflection->currentIndex()); - m_uiForm.cbReflection->blockSignals(false); + if ( m_uiForm.ckNexus->isChecked() ) + { + QString nexusFilename = drangeWsName + ".nxs"; + IAlgorithm_sptr saveNexus = AlgorithmManager::Instance().create("SaveNexusProcessed"); + saveNexus->initialize(); + saveNexus->setProperty("Filename", nexusFilename.toStdString()); + m_batchAlgoRunner->addAlgorithm(saveNexus, inputFromReductionProps); + } - // Disable summing file options for OSIRIS. - if ( m_uiForm.cbInst->currentText() != "OSIRIS" ) - m_uiForm.dem_ckSumFiles->setEnabled(true); - else + if ( m_uiForm.ckAscii->isChecked() ) { - m_uiForm.dem_ckSumFiles->setChecked(true); - m_uiForm.dem_ckSumFiles->setEnabled(false); + QString asciiFilename = drangeWsName + ".dat"; + IAlgorithm_sptr saveASCII = AlgorithmManager::Instance().create("SaveAscii"); + saveASCII->initialize(); + saveASCII->setProperty("Filename", asciiFilename.toStdString()); + m_batchAlgoRunner->addAlgorithm(saveASCII, inputFromReductionProps); } + m_plotWorkspaces.clear(); + m_plotWorkspaces.push_back(tofWsName); + m_plotWorkspaces.push_back(drangeWsName); + + m_batchAlgoRunner->executeBatchAsync(); } -void IndirectDiffractionReduction::reflectionSelected(int) +/** + * Loads an empty instrument and returns a pointer to the workspace. + * + * Optionally loads an IPF if a reflection was provided. + * + * @param instrumentName Name of an inelastic indiretc instrument (IRIS, OSIRIN, TOSCA, VESUVIO) + * @param reflection Reflection mode to load parameters for (diffspec or diffonly) + */ +MatrixWorkspace_sptr IndirectDiffractionReduction::loadInstrument(std::string instrumentName, std::string reflection) { - QString pyInput = - "from IndirectEnergyConversion import getReflectionDetails\n" - "instrument = '" + m_uiForm.cbInst->currentText() + "'\n" - "reflection = '" + m_uiForm.cbReflection->currentText() + "'\n" - "print getReflectionDetails(instrument, 'diffraction', reflection)\n"; + std::string instWorkspaceName = "__empty_" + instrumentName; + std::string idfPath = Mantid::Kernel::ConfigService::Instance().getString("instrumentDefinition.directory"); + + if(!AnalysisDataService::Instance().doesExist(instWorkspaceName)) + { + std::string parameterFilename = idfPath + instrumentName + "_Definition.xml"; + IAlgorithm_sptr loadAlg = AlgorithmManager::Instance().create("LoadEmptyInstrument"); + loadAlg->initialize(); + loadAlg->setProperty("Filename", parameterFilename); + loadAlg->setProperty("OutputWorkspace", instWorkspaceName); + loadAlg->execute(); + } - QString pyOutput = runPythonCode(pyInput).trimmed(); - QStringList values = pyOutput.split("\n", QString::SkipEmptyParts); + MatrixWorkspace_sptr instWorkspace = AnalysisDataService::Instance().retrieveWS(instWorkspaceName); - if ( values.count() < 3 ) + // Load parameter file if a reflection was given + if(!reflection.empty()) { - showInformationBox("Could not gather necessary data from parameter file."); - return; + std::string ipfFilename = idfPath + instrumentName + "_diffraction_" + reflection + "_Parameters.xml"; + IAlgorithm_sptr loadParamAlg = AlgorithmManager::Instance().create("LoadParameterFile"); + loadParamAlg->initialize(); + loadParamAlg->setProperty("Filename", ipfFilename); + loadParamAlg->setProperty("Workspace", instWorkspaceName); + loadParamAlg->execute(); } - else + + return instWorkspace; +} + +/** + * Handles loading an instrument and reflections when an instruiment is selected form the drop down. + */ +void IndirectDiffractionReduction::instrumentSelected(int) +{ + // If the interface is not shown, do not go looking for parameter files, etc. + if(!m_uiForm.cbInst->isVisible()) + return; + + std::string instrumentName = m_uiForm.cbInst->currentText().toStdString(); + MatrixWorkspace_sptr instWorkspace = loadInstrument(instrumentName); + Instrument_const_sptr instrument = instWorkspace->getInstrument(); + + std::vector analysers; + boost::split(analysers, instrument->getStringParameter("refl-diffraction")[0], boost::is_any_of(",")); + + m_uiForm.cbReflection->blockSignals(true); + m_uiForm.cbReflection->clear(); + + for(auto it = analysers.begin(); it != analysers.end(); ++it) { - QString analysisType = values[0]; - m_uiForm.set_leSpecMin->setText(values[1]); - m_uiForm.set_leSpecMax->setText(values[2]); + std::string reflection = *it; + m_uiForm.cbReflection->addItem(QString::fromStdString(reflection)); } + reflectionSelected(m_uiForm.cbReflection->currentIndex()); + m_uiForm.cbReflection->blockSignals(false); +} + +/** + * Handles setting default spectra range when a reflection is slected from the drop down. + */ +void IndirectDiffractionReduction::reflectionSelected(int) +{ + std::string instrumentName = m_uiForm.cbInst->currentText().toStdString(); + std::string reflection = m_uiForm.cbReflection->currentText().toStdString(); + MatrixWorkspace_sptr instWorkspace = loadInstrument(instrumentName, reflection); + Instrument_const_sptr instrument = instWorkspace->getInstrument(); + + // Get default spectra range + double specMin = instrument->getNumberParameter("spectra-min")[0]; + double specMax = instrument->getNumberParameter("spectra-max")[0]; + + m_uiForm.set_leSpecMin->setText(QString::number(specMin)); + m_uiForm.set_leSpecMax->setText(QString::number(specMax)); + // Determine whether we need vanadium input - pyInput = "from IndirectDiffractionReduction import getStringProperty\n" - "print getStringProperty('__empty_" + m_uiForm.cbInst->currentText() + "', 'Workflow.Diffraction.Correction')\n"; + std::vector correctionVector = instrument->getStringParameter("Workflow.Diffraction.Correction"); + bool vanadiumNeeded = false; + if(correctionVector.size() > 0) + vanadiumNeeded = (correctionVector[0] == "Vanadium"); - pyOutput = runPythonCode(pyInput).trimmed(); + if(vanadiumNeeded) + m_uiForm.swVanadium->setCurrentIndex(0); + else + m_uiForm.swVanadium->setCurrentIndex(1); - if ( pyOutput == "Vanadium" ) + // Hide options that the current instrument config cannot process + if(instrumentName == "OSIRIS" && reflection == "diffonly") { - m_uiForm.swVanadium->setCurrentIndex(0); + // Disable individual grouping + m_uiForm.ckIndividualGrouping->setToolTip("OSIRIS cannot group detectors individually in diffonly mode"); + m_uiForm.ckIndividualGrouping->setEnabled(false); + m_uiForm.ckIndividualGrouping->setChecked(false); + + // Disable sum files + m_uiForm.dem_ckSumFiles->setToolTip("OSIRIS cannot sum files in diffonly mode"); + m_uiForm.dem_ckSumFiles->setEnabled(false); + m_uiForm.dem_ckSumFiles->setChecked(false); } else { - m_uiForm.swVanadium->setCurrentIndex(1); - } - + // Re-enable sum files + m_uiForm.dem_ckSumFiles->setToolTip(""); + m_uiForm.dem_ckSumFiles->setEnabled(true); + m_uiForm.dem_ckSumFiles->setChecked(true); + // Re-enable individual grouping + m_uiForm.ckIndividualGrouping->setToolTip(""); + m_uiForm.ckIndividualGrouping->setEnabled(true); + } } +/** + * Handles opening the directory manager window. + */ void IndirectDiffractionReduction::openDirectoryDialog() { MantidQt::API::ManageUserDirectories *ad = new MantidQt::API::ManageUserDirectories(this); @@ -256,12 +389,18 @@ void IndirectDiffractionReduction::openDirectoryDialog() ad->setFocus(); } +/** + * Handles the user clicking the help button. + */ void IndirectDiffractionReduction::help() { QString url = "http://www.mantidproject.org/Indirect_Diffraction_Reduction"; QDesktopServices::openUrl(QUrl(url)); } +/** + * Sets up UI components and Qt signal/slot connections. + */ void IndirectDiffractionReduction::initLayout() { m_uiForm.setupUi(this); @@ -272,7 +411,12 @@ void IndirectDiffractionReduction::initLayout() connect(m_uiForm.cbInst, SIGNAL(currentIndexChanged(int)), this, SLOT(instrumentSelected(int))); connect(m_uiForm.cbReflection, SIGNAL(currentIndexChanged(int)), this, SLOT(reflectionSelected(int))); - + + // Update run button based on state of raw files field + connect(m_uiForm.dem_rawFiles, SIGNAL(fileTextChanged(const QString &)), this, SLOT(runFilesChanged())); + connect(m_uiForm.dem_rawFiles, SIGNAL(findingFiles()), this, SLOT(runFilesFinding())); + connect(m_uiForm.dem_rawFiles, SIGNAL(fileFindingFinished()), this, SLOT(runFilesFound())); + m_valInt = new QIntValidator(this); m_valDbl = new QDoubleValidator(this); @@ -283,9 +427,13 @@ void IndirectDiffractionReduction::initLayout() m_uiForm.leRebinWidth->setValidator(m_valDbl); m_uiForm.leRebinEnd->setValidator(m_valDbl); + // Update the list of plot options when individual grouping is toggled + connect(m_uiForm.ckIndividualGrouping, SIGNAL(stateChanged(int)), this, SLOT(individualGroupingToggled(int))); + loadSettings(); - validateDemon(); + // Update invalid rebinning markers + validateRebin(); } void IndirectDiffractionReduction::initLocalPython() @@ -305,7 +453,6 @@ void IndirectDiffractionReduction::loadSettings() m_uiForm.dem_calFile->setUserInput(settings.value("last_cal_file").toString()); m_uiForm.dem_vanadiumFile->setUserInput(settings.value("last_van_files").toString()); settings.endGroup(); - } void IndirectDiffractionReduction::saveSettings() @@ -318,18 +465,20 @@ void IndirectDiffractionReduction::saveSettings() settings.endGroup(); } -bool IndirectDiffractionReduction::validateDemon() +/** + * Validates the rebinning fields and updates invalid markers. + * + * @returns True if reinning options are valid, flase otherwise + */ +bool IndirectDiffractionReduction::validateRebin() { - bool rawValid = true; - if ( ! m_uiForm.dem_rawFiles->isValid() ) { rawValid = false; } - QString rebStartTxt = m_uiForm.leRebinStart->text(); QString rebStepTxt = m_uiForm.leRebinWidth->text(); QString rebEndTxt = m_uiForm.leRebinEnd->text(); bool rebinValid = true; // Need all or none - if(rebStartTxt.isEmpty() && rebStepTxt.isEmpty() && rebEndTxt.isEmpty() ) + if(rebStartTxt.isEmpty() && rebStepTxt.isEmpty() && rebEndTxt.isEmpty()) { rebinValid = true; m_uiForm.valRebinStart->setText(""); @@ -354,7 +503,7 @@ bool IndirectDiffractionReduction::validateDemon() CHECK_VALID(rebStepTxt,m_uiForm.valRebinWidth); CHECK_VALID(rebEndTxt,m_uiForm.valRebinEnd); - if(rebinValid && rebStartTxt.toDouble() > rebEndTxt.toDouble()) + if(rebinValid && rebStartTxt.toDouble() >= rebEndTxt.toDouble()) { rebinValid = false; m_uiForm.valRebinStart->setText("*"); @@ -362,7 +511,92 @@ bool IndirectDiffractionReduction::validateDemon() } } - return rawValid && rebinValid; + return rebinValid; +} + +/** + * Checks to see if the vanadium and cal file fields are valid. + * + * @returns True fo vanadium and calibration files are valid, false otherwise + */ +bool IndirectDiffractionReduction::validateVanCal() +{ + if(!m_uiForm.dem_calFile->isValid()) + return false; + + if(!m_uiForm.dem_vanadiumFile->isValid()) + return false; + + return true; +} + +/** + * Disables and shows message on run button indicating that run files have benn changed. + */ +void IndirectDiffractionReduction::runFilesChanged() +{ + m_uiForm.pbRun->setEnabled(false); + m_uiForm.pbRun->setText("Editing..."); +} + +/** + * Disables and shows message on run button to indicate searching for data files. + */ +void IndirectDiffractionReduction::runFilesFinding() +{ + m_uiForm.pbRun->setEnabled(false); + m_uiForm.pbRun->setText("Finding files..."); +} + +/** + * Updates run button with result of file search. + */ +void IndirectDiffractionReduction::runFilesFound() +{ + bool valid = m_uiForm.dem_rawFiles->isValid(); + m_uiForm.pbRun->setEnabled(valid); + + if(valid) + m_uiForm.pbRun->setText("Run"); + else + m_uiForm.pbRun->setText("Invalid Run"); + + // Disable sum files if only one file is given + int fileCount = m_uiForm.dem_rawFiles->getFilenames().size(); + if(fileCount < 2) + m_uiForm.dem_ckSumFiles->setChecked(false); +} + +/** + * Handles the user toggling the individual grouping check box. + * + * @param state The selection state of the check box + */ +void IndirectDiffractionReduction::individualGroupingToggled(int state) +{ + int itemCount = m_uiForm.cbPlotType->count(); + + switch(state) + { + case Qt::Unchecked: + if(itemCount == 4) + { + m_uiForm.cbPlotType->removeItem(3); + m_uiForm.cbPlotType->removeItem(2); + } + break; + + case Qt::Checked: + if(itemCount == 2) + { + m_uiForm.cbPlotType->insertItem(2, "Contour"); + m_uiForm.cbPlotType->insertItem(3, "Both"); + } + break; + + default: + return; + } } } diff --git a/Code/Mantid/MantidQt/CustomInterfaces/src/IndirectLoadAscii.cpp b/Code/Mantid/MantidQt/CustomInterfaces/src/IndirectLoadAscii.cpp index 412607ea0214..3eb42924b140 100644 --- a/Code/Mantid/MantidQt/CustomInterfaces/src/IndirectLoadAscii.cpp +++ b/Code/Mantid/MantidQt/CustomInterfaces/src/IndirectLoadAscii.cpp @@ -1,7 +1,7 @@ #include "MantidKernel/ConfigService.h" #include "MantidQtAPI/ManageUserDirectories.h" #include "MantidQtCustomInterfaces/IndirectLoadAscii.h" -#include "MantidQtCustomInterfaces/IndirectNeutron.h" +#include "MantidQtCustomInterfaces/IndirectLoadILL.h" #include #include @@ -31,7 +31,7 @@ void IndirectLoadAscii::initLayout() Mantid::Kernel::ConfigService::Instance().addObserver(m_changeObserver); //insert each tab into the interface on creation - m_loadAsciiTabs.insert(std::make_pair(NEUTRON, new IndirectNeutron(m_uiForm.IndirectLoadAsciiTabs->widget(NEUTRON)))); + m_loadAsciiTabs.insert(std::make_pair(LOAD_ILL, new IndirectLoadILL(m_uiForm.IndirectLoadAsciiTabs->widget(LOAD_ILL)))); //Connect each tab to the actions available in this GUI std::map::iterator iter; diff --git a/Code/Mantid/MantidQt/CustomInterfaces/src/IndirectNeutron.cpp b/Code/Mantid/MantidQt/CustomInterfaces/src/IndirectLoadILL.cpp similarity index 94% rename from Code/Mantid/MantidQt/CustomInterfaces/src/IndirectNeutron.cpp rename to Code/Mantid/MantidQt/CustomInterfaces/src/IndirectLoadILL.cpp index e276f699acf7..a6247ec41bdd 100644 --- a/Code/Mantid/MantidQt/CustomInterfaces/src/IndirectNeutron.cpp +++ b/Code/Mantid/MantidQt/CustomInterfaces/src/IndirectLoadILL.cpp @@ -3,7 +3,7 @@ #include "MantidAPI/MatrixWorkspace.h" #include "MantidKernel/ConfigService.h" #include "MantidKernel/FacilityInfo.h" -#include "MantidQtCustomInterfaces/IndirectNeutron.h" +#include "MantidQtCustomInterfaces/IndirectLoadILL.h" #include #include @@ -12,7 +12,7 @@ namespace MantidQt { namespace CustomInterfaces { - IndirectNeutron::IndirectNeutron(QWidget * parent) : + IndirectLoadILL::IndirectLoadILL(QWidget * parent) : IndirectLoadAsciiTab(parent) { m_uiForm.setupUi(parent); @@ -31,7 +31,7 @@ namespace MantidQt * * @return :: Whether the form was valid */ - bool IndirectNeutron::validate() + bool IndirectLoadILL::validate() { QString filename = m_uiForm.mwRun->getFirstFilename(); QFileInfo finfo(filename); @@ -48,9 +48,9 @@ namespace MantidQt /** * Collect the settings on the GUI and build a python - * script that runs IndirectNeutron + * script that runs IndirectLoadILL */ - void IndirectNeutron::run() + void IndirectLoadILL::run() { QString verbose("False"); QString plot("False"); @@ -123,7 +123,7 @@ namespace MantidQt * * @param settings :: The settings to loading into the interface */ - void IndirectNeutron::loadSettings(const QSettings& settings) + void IndirectLoadILL::loadSettings(const QSettings& settings) { m_uiForm.mwRun->readSettings(settings.group()); } @@ -133,7 +133,7 @@ namespace MantidQt * * @param instrument :: The name of the instrument */ - void IndirectNeutron::instrumentChanged(const QString& instrument) + void IndirectLoadILL::instrumentChanged(const QString& instrument) { using namespace Mantid::API; @@ -195,7 +195,7 @@ namespace MantidQt * @param instrument :: The name of the instrument * @return Pointer to the instrument */ - Mantid::Geometry::Instrument_const_sptr IndirectNeutron::getInstrument(const QString& instrument) + Mantid::Geometry::Instrument_const_sptr IndirectLoadILL::getInstrument(const QString& instrument) { using namespace Mantid::API; @@ -236,7 +236,7 @@ namespace MantidQt * * @param analyser :: The name of the analyser */ - void IndirectNeutron::analyserChanged(const QString& analyser) + void IndirectLoadILL::analyserChanged(const QString& analyser) { using namespace Mantid::API; @@ -253,7 +253,7 @@ namespace MantidQt * * Assumes that names have the form \_\.\ */ - void IndirectNeutron::handleFilesFound() + void IndirectLoadILL::handleFilesFound() { //get first part of basename QString filename = m_uiForm.mwRun->getFirstFilename(); diff --git a/Code/Mantid/MantidQt/CustomInterfaces/src/IndirectMolDyn.cpp b/Code/Mantid/MantidQt/CustomInterfaces/src/IndirectMolDyn.cpp index ceb7311b9242..bc89ad7aa716 100644 --- a/Code/Mantid/MantidQt/CustomInterfaces/src/IndirectMolDyn.cpp +++ b/Code/Mantid/MantidQt/CustomInterfaces/src/IndirectMolDyn.cpp @@ -3,85 +3,98 @@ #include #include +using namespace Mantid::API; + namespace MantidQt { - namespace CustomInterfaces - { - IndirectMolDyn::IndirectMolDyn(QWidget * parent) : - IndirectSimulationTab(parent) - { - m_uiForm.setupUi(parent); - } - - /** - * Validate the form to check the program can be run - * - * @return :: Whether the form was valid - */ - bool IndirectMolDyn::validate() - { - QString filename = m_uiForm.mwRun->getFirstFilename(); - QFileInfo finfo(filename); - QString ext = finfo.extension().toLower(); - - if(ext != "dat" && ext != "cdl") - { - emit showMessageBox("File is not of expected type:\n File type must be .dat or .cdl"); - return false; - } - - return true; - } - - /** - * Collect the settings on the GUI and build a python - * script that runs IndirectMolDyn - */ - void IndirectMolDyn::run() - { - QString verbose("False"); - QString plot("False"); - QString save("False"); - - QString filename = m_uiForm.mwRun->getFirstFilename(); - QFileInfo finfo(filename); - QString ext = finfo.extension().toLower(); - - QString funcNames = m_uiForm.leFunctionNames->text(); - - //output options - if(m_uiForm.chkVerbose->isChecked()){ verbose = "True"; } - if(m_uiForm.chkSave->isChecked()){ save ="True"; } - plot = m_uiForm.cbPlot->currentText(); - - - QString pyInput = - "from IndirectMolDyn import "; - - QString pyFunc(""); - if(ext == "dat") - { - pyFunc = "MolDynText"; - pyInput += pyFunc + "\n" + pyFunc + "('"+filename+"',"+verbose+",'"+plot+"',"+save+")"; - } - else if (ext == "cdl") - { - pyFunc = "MolDynImport"; - pyInput += pyFunc + "\n" + pyFunc + "('"+filename+"','"+funcNames+"',"+verbose+",'"+plot+"',"+save+")"; - } - - runPythonScript(pyInput); - } - - /** - * Set the data selectors to use the default save directory - * when browsing for input files. - * - * @param settings :: The settings to loading into the interface - */ - void IndirectMolDyn::loadSettings(const QSettings& settings) - { - m_uiForm.mwRun->readSettings(settings.group()); - } - } // namespace CustomInterfaces + namespace CustomInterfaces + { + IndirectMolDyn::IndirectMolDyn(QWidget * parent) : + IndirectSimulationTab(parent) + { + m_uiForm.setupUi(parent); + + connect(m_uiForm.ckCropEnergy, SIGNAL(toggled(bool)), m_uiForm.dspMaxEnergy, SLOT(setEnabled(bool))); + connect(m_uiForm.ckResolution, SIGNAL(toggled(bool)), m_uiForm.dsResolution, SLOT(setEnabled(bool))); + } + + void IndirectMolDyn::setup() + { + } + + /** + * Validate the form to check the program can be run + * + * @return :: Whether the form was valid + */ + bool IndirectMolDyn::validate() + { + QString filename = m_uiForm.mwRun->getFirstFilename(); + QFileInfo finfo(filename); + QString ext = finfo.extension().toLower(); + + if(ext != "dat" && ext != "cdl") + { + emit showMessageBox("File is not of expected type.\n File type must be .dat or .cdl"); + return false; + } + + QString functions = m_uiForm.leFunctionNames->text(); + if(ext == "cdl" && functions.isEmpty()) + { + emit showMessageBox("Must specify at least one function when loading CDL file."); + return false; + } + + if(m_uiForm.ckResolution->isChecked() && !m_uiForm.dsResolution->isValid()) + { + emit showMessageBox("Invalid resolution file."); + return false; + } + + return true; + } + + /** + * Collect the settings on the GUI and run the MolDyn algorithm. + */ + void IndirectMolDyn::run() + { + // Get filename and base filename (for naming output workspace group) + QString filename = m_uiForm.mwRun->getFirstFilename(); + QFileInfo fi(filename); + QString baseName = fi.baseName(); + + // Setup algorithm + IAlgorithm_sptr molDynAlg = AlgorithmManager::Instance().create("MolDyn"); + molDynAlg->setProperty("Filename", filename.toStdString()); + molDynAlg->setProperty("Functions", m_uiForm.leFunctionNames->text().toStdString()); + molDynAlg->setProperty("Verbose", m_uiForm.ckVerbose->isChecked()); + molDynAlg->setProperty("Save", m_uiForm.ckSave->isChecked()); + molDynAlg->setProperty("Plot", m_uiForm.cbPlot->currentText().toStdString()); + molDynAlg->setProperty("OutputWorkspace", baseName.toStdString()); + + // Set energy crop option + if(m_uiForm.ckCropEnergy->isChecked()) + molDynAlg->setProperty("MaxEnergy", QString::number(m_uiForm.dspMaxEnergy->value()).toStdString()); + + // Set instrument resolution option + if(m_uiForm.ckResolution->isChecked()) + molDynAlg->setProperty("Resolution", m_uiForm.dsResolution->getCurrentDataName().toStdString()); + + runAlgorithm(molDynAlg); + } + + /** + * Set the data selectors to use the default save directory + * when browsing for input files. + * + * @param settings :: The settings to loading into the interface + */ + void IndirectMolDyn::loadSettings(const QSettings& settings) + { + m_uiForm.mwRun->readSettings(settings.group()); + } + + } // namespace CustomInterfaces } // namespace MantidQt diff --git a/Code/Mantid/MantidQt/CustomInterfaces/src/IndirectMoments.cpp b/Code/Mantid/MantidQt/CustomInterfaces/src/IndirectMoments.cpp index 36fd92e82a31..1a4cd24779dc 100644 --- a/Code/Mantid/MantidQt/CustomInterfaces/src/IndirectMoments.cpp +++ b/Code/Mantid/MantidQt/CustomInterfaces/src/IndirectMoments.cpp @@ -5,6 +5,8 @@ #include #include +using namespace Mantid::API; + namespace MantidQt { namespace CustomInterfaces @@ -17,22 +19,34 @@ namespace CustomInterfaces { const unsigned int NUM_DECIMALS = 6; + // RAW PLOT m_plots["MomentsPlot"] = new QwtPlot(m_parentWidget); - m_curves["MomentsPlotCurve"] = new QwtPlotCurve(); + /* m_curves["MomentsPlotCurve"] = new QwtPlotCurve(); */ m_rangeSelectors["MomentsRangeSelector"] = new MantidWidgets::RangeSelector(m_plots["MomentsPlot"]); - m_propTrees["MomentsPropTree"] = new QtTreePropertyBrowser(); - - m_propTrees["MomentsPropTree"]->setFactoryForManager(m_dblManager, m_dblEdFac); m_rangeSelectors["MomentsRangeSelector"]->setInfoOnly(false); - // initilise plot + // Initilise plot m_plots["MomentsPlot"]->setCanvasBackground(Qt::white); m_plots["MomentsPlot"]->setAxisFont(QwtPlot::xBottom, parent->font()); m_plots["MomentsPlot"]->setAxisFont(QwtPlot::yLeft, parent->font()); - //add the plot to the ui form + // Add plot to UI m_uiForm.moment_plotSpace->addWidget(m_plots["MomentsPlot"]); - //add the properties browser to the ui form + + // PREVIEW PLOT + m_plots["MomentsPreviewPlot"] = new QwtPlot(m_parentWidget); + + // Initilise plot + m_plots["MomentsPreviewPlot"]->setCanvasBackground(Qt::white); + m_plots["MomentsPreviewPlot"]->setAxisFont(QwtPlot::xBottom, parent->font()); + m_plots["MomentsPreviewPlot"]->setAxisFont(QwtPlot::yLeft, parent->font()); + + // Add plot to UI + m_uiForm.moment_plotPreview->addWidget(m_plots["MomentsPreviewPlot"]); + + // PROPERTY TREE + m_propTrees["MomentsPropTree"] = new QtTreePropertyBrowser(); + m_propTrees["MomentsPropTree"]->setFactoryForManager(m_dblManager, m_dblEdFac); m_uiForm.moment_treeSpace->addWidget(m_propTrees["MomentsPropTree"]); m_properties["EMin"] = m_dblManager->addProperty("EMin"); m_properties["EMax"] = m_dblManager->addProperty("EMax"); @@ -49,10 +63,12 @@ namespace CustomInterfaces connect(m_uiForm.moment_ckScale, SIGNAL(toggled(bool)), m_uiForm.moment_leScale, SLOT(setEnabled(bool))); connect(m_uiForm.moment_ckScale, SIGNAL(toggled(bool)), m_uiForm.moment_validScale, SLOT(setVisible(bool))); - connect(m_rangeSelectors["MomentsRangeSelector"], SIGNAL(minValueChanged(double)), this, SLOT(minValueChanged(double))); - connect(m_rangeSelectors["MomentsRangeSelector"], SIGNAL(maxValueChanged(double)), this, SLOT(maxValueChanged(double))); + connect(m_rangeSelectors["MomentsRangeSelector"], 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 + connect(m_batchAlgoRunner, SIGNAL(batchComplete(bool)), this, SLOT(momentsAlgComplete(bool))); + m_uiForm.moment_validScale->setStyleSheet("QLabel { color : #aa0000; }"); } @@ -69,9 +85,8 @@ namespace CustomInterfaces void IndirectMoments::run() { - using namespace Mantid::API; QString workspaceName = m_uiForm.moment_dsInput->getCurrentDataName(); - QString outputName = workspaceName.left(workspaceName.length()-4); + QString outputName = workspaceName.left(workspaceName.length() - 4); QString scaleString = m_uiForm.moment_leScale->text(); double scale = 1.0; double eMin = m_dblManager->value(m_properties["EMin"]); @@ -81,10 +96,10 @@ namespace CustomInterfaces bool verbose = m_uiForm.moment_ckVerbose->isChecked(); bool save = m_uiForm.moment_ckSave->isChecked(); - if (!scaleString.isEmpty()) - { + if(!scaleString.isEmpty()) scale = scaleString.toDouble(); - } + + std::string outputWorkspaceName = outputName.toStdString() + "_Moments"; IAlgorithm_sptr momentsAlg = AlgorithmManager::Instance().create("SofQWMoments", -1); momentsAlg->initialize(); @@ -95,7 +110,7 @@ namespace CustomInterfaces momentsAlg->setProperty("Plot", plot); momentsAlg->setProperty("Verbose", verbose); momentsAlg->setProperty("Save", save); - momentsAlg->setProperty("OutputWorkspace", outputName.toStdString() + "_Moments"); + momentsAlg->setProperty("OutputWorkspace", outputWorkspaceName); //execute algorithm on seperate thread runAlgorithm(momentsAlg); @@ -103,15 +118,12 @@ namespace CustomInterfaces bool IndirectMoments::validate() { - using namespace Mantid::API; UserInputValidator uiv; uiv.checkDataSelectorIsValid("Sample input", m_uiForm.moment_dsInput); if (m_uiForm.moment_ckScale->isChecked()) - { uiv.checkFieldIsValid("A valid scale must be supplied.\n", m_uiForm.moment_leScale, m_uiForm.moment_validScale); - } QString msg = uiv.generateErrorMessage(); if (!msg.isEmpty()) @@ -125,35 +137,36 @@ namespace CustomInterfaces void IndirectMoments::handleSampleInputReady(const QString& filename) { + disconnect(m_dblManager, SIGNAL(valueChanged(QtProperty*, double)), this, SLOT(updateProperties(QtProperty*, double))); + plotMiniPlot(filename, 0, "MomentsPlot", "MomentsPlotCurve"); std::pair range = getCurveRange("MomentsPlotCurve"); setMiniPlotGuides("MomentsRangeSelector", m_properties["EMin"], m_properties["EMax"], range); setPlotRange("MomentsRangeSelector", m_properties["EMin"], m_properties["EMax"], range); - } - /** - * Updates the property manager when the lower guide is moved on the mini plot - * - * @param min :: The new value of the lower guide - */ - void IndirectMoments::minValueChanged(double min) - { - m_dblManager->setValue(m_properties["EMin"], min); + connect(m_dblManager, SIGNAL(valueChanged(QtProperty*, double)), this, SLOT(updateProperties(QtProperty*, double))); + + // Update the results preview plot + updatePreviewPlot(); } /** - * Updates the property manager when the upper guide is moved on the mini plot + * Updates the property manager when the range selector is moved. * + * @param min :: The new value of the lower guide * @param max :: The new value of the upper guide */ - void IndirectMoments::maxValueChanged(double max) + void IndirectMoments::rangeChanged(double min, double max) { + m_dblManager->setValue(m_properties["EMin"], min); m_dblManager->setValue(m_properties["EMax"], max); } - /** + /** * Handles when properties in the property manager are updated. * + * Performs validation and uodated preview plot. + * * @param prop :: The property being updated * @param val :: The new value for the property */ @@ -183,6 +196,80 @@ namespace CustomInterfaces m_rangeSelectors["MomentsRangeSelector"]->setMaximum(val); } } + + updatePreviewPlot(); + } + + /** + * Runs the moments algorithm with preview properties. + */ + void IndirectMoments::updatePreviewPlot(QString workspaceName) + { + if(workspaceName.isEmpty()) + workspaceName = m_uiForm.moment_dsInput->getCurrentDataName(); + + QString outputName = workspaceName.left(workspaceName.length() - 4); + QString scaleString = m_uiForm.moment_leScale->text(); + double scale = 1.0; + double eMin = m_dblManager->value(m_properties["EMin"]); + double eMax = m_dblManager->value(m_properties["EMax"]); + + bool verbose = m_uiForm.moment_ckVerbose->isChecked(); + + if(!scaleString.isEmpty()) + scale = scaleString.toDouble(); + + std::string outputWorkspaceName = outputName.toStdString() + "_Moments"; + + IAlgorithm_sptr momentsAlg = AlgorithmManager::Instance().create("SofQWMoments"); + momentsAlg->initialize(); + momentsAlg->setProperty("Sample", workspaceName.toStdString()); + momentsAlg->setProperty("Scale", scale); + momentsAlg->setProperty("EnergyMin", eMin); + momentsAlg->setProperty("EnergyMax", eMax); + momentsAlg->setProperty("Plot", false); + momentsAlg->setProperty("Verbose", verbose); + momentsAlg->setProperty("Save", false); + momentsAlg->setProperty("OutputWorkspace", outputWorkspaceName); + + // Make sure there are no other algorithms in the queue. + // It seems to be possible to have the selctionChangedLazy signal fire multiple times + // if the renage selector is moved in a certain way. + if(m_batchAlgoRunner->queueLength() == 0) + runAlgorithm(momentsAlg); + } + + /** + * Handles plotting the preview plot when the algorithm finishes. + * + * @param error True if the algorithm exited due to error, false otherwise + */ + void IndirectMoments::momentsAlgComplete(bool error) + { + if(error) + return; + + QString workspaceName = m_uiForm.moment_dsInput->getCurrentDataName(); + QString outputName = workspaceName.left(workspaceName.length() - 4); + std::string outputWorkspaceName = outputName.toStdString() + "_Moments"; + + WorkspaceGroup_sptr resultWsGroup = AnalysisDataService::Instance().retrieveWS(outputWorkspaceName); + std::vector resultWsNames = resultWsGroup->getNames(); + + if(resultWsNames.size() < 4) + return; + + // Plot each spectrum + plotMiniPlot(QString::fromStdString(resultWsNames[0]), 0, "MomentsPreviewPlot", "Moments_M0"); + plotMiniPlot(QString::fromStdString(resultWsNames[2]), 0, "MomentsPreviewPlot", "Moments_M2"); + plotMiniPlot(QString::fromStdString(resultWsNames[3]), 0, "MomentsPreviewPlot", "Moments_M4"); + + // Colour plots as close to plot output as possible + m_curves["Moments_M0"]->setPen(QColor(Qt::green)); + m_curves["Moments_M2"]->setPen(QColor(Qt::black)); + m_curves["Moments_M4"]->setPen(QColor(Qt::red)); + + m_plots["MomentsPreviewPlot"]->replot(); } } // namespace CustomInterfaces diff --git a/Code/Mantid/MantidQt/CustomInterfaces/src/IndirectSassena.cpp b/Code/Mantid/MantidQt/CustomInterfaces/src/IndirectSassena.cpp new file mode 100644 index 000000000000..457718358c6e --- /dev/null +++ b/Code/Mantid/MantidQt/CustomInterfaces/src/IndirectSassena.cpp @@ -0,0 +1,108 @@ +#include "MantidQtCustomInterfaces/IndirectSassena.h" + +#include +#include + +namespace MantidQt +{ + namespace CustomInterfaces + { + IndirectSassena::IndirectSassena(QWidget * parent) : + IndirectSimulationTab(parent) + { + m_uiForm.setupUi(parent); + connect(m_batchAlgoRunner, SIGNAL(batchComplete(bool)), this, SLOT(handleAlgorithmFinish(bool))); + } + + void IndirectSassena::setup() + { + } + + /** + * Validate the form to check the program can be run. + * + * @return Whether the form was valid + */ + bool IndirectSassena::validate() + { + // There is very little to actually be invalid here + // that was not already done via restrictions on input + return true; + } + + /** + * Configures and executes the LoadSassena algorithm. + */ + void IndirectSassena::run() + { + using namespace Mantid::API; + using MantidQt::API::BatchAlgorithmRunner; + + QString inputFileName = m_uiForm.mwInputFile->getFirstFilename(); + QFileInfo inputFileInfo(inputFileName); + m_outWsName = inputFileInfo.baseName(); + bool save = m_uiForm.chkSave->isChecked(); + + // If the workspace group already exists then remove it + if(AnalysisDataService::Instance().doesExist(m_outWsName.toStdString())) + AnalysisDataService::Instance().deepRemoveGroup(m_outWsName.toStdString()); + + IAlgorithm_sptr sassenaAlg = AlgorithmManager::Instance().create("LoadSassena"); + sassenaAlg->initialize(); + + sassenaAlg->setProperty("Filename", inputFileName.toStdString()); + sassenaAlg->setProperty("SortByQVectors", m_uiForm.cbSortQ->isChecked()); + sassenaAlg->setProperty("TimeUnit", m_uiForm.sbTimeUnit->value()); + sassenaAlg->setProperty("OutputWorkspace", m_outWsName.toStdString()); + + m_batchAlgoRunner->addAlgorithm(sassenaAlg); + + BatchAlgorithmRunner::AlgorithmRuntimeProps inputFromSassenaAlg; + inputFromSassenaAlg["InputWorkspace"] = m_outWsName.toStdString(); + + if(save) + { + QString saveFilename = m_outWsName + ".nxs"; + + IAlgorithm_sptr saveAlg = AlgorithmManager::Instance().create("SaveNexus"); + saveAlg->initialize(); + + saveAlg->setProperty("Filename", saveFilename.toStdString()); + + m_batchAlgoRunner->addAlgorithm(saveAlg, inputFromSassenaAlg); + } + + m_batchAlgoRunner->executeBatchAsync(); + } + + /** + * Handles completion of the algorithm batch. + * + * @param error If the batch was stopped due to error + */ + void IndirectSassena::handleAlgorithmFinish(bool error) + { + bool plot = m_uiForm.chkPlot->isChecked(); + + // Nothing to do if the algorithm failed or we do not want to plot + if(error || !plot) + return; + + // Plot the output workspace group + QString pyInput = "plotSpectrum('" + m_outWsName + "', 0)\n"; + emit runAsPythonScript(pyInput); + } + + /** + * Set the data selectors to use the default save directory + * when browsing for input files. + * + * @param settings :: The settings to loading into the interface + */ + void IndirectSassena::loadSettings(const QSettings& settings) + { + m_uiForm.mwInputFile->readSettings(settings.group()); + } + + } // namespace CustomInterfaces +} // namespace MantidQt diff --git a/Code/Mantid/MantidQt/CustomInterfaces/src/IndirectSimulation.cpp b/Code/Mantid/MantidQt/CustomInterfaces/src/IndirectSimulation.cpp index 9a62239a5252..649cdfa022b9 100644 --- a/Code/Mantid/MantidQt/CustomInterfaces/src/IndirectSimulation.cpp +++ b/Code/Mantid/MantidQt/CustomInterfaces/src/IndirectSimulation.cpp @@ -2,11 +2,12 @@ #include "MantidQtAPI/ManageUserDirectories.h" #include "MantidQtCustomInterfaces/IndirectSimulation.h" #include "MantidQtCustomInterfaces/IndirectMolDyn.h" +#include "MantidQtCustomInterfaces/IndirectSassena.h" #include #include -//Add this class to the list of specialised dialogs in this namespace +// Add this class to the list of specialised dialogs in this namespace namespace MantidQt { namespace CustomInterfaces @@ -20,30 +21,34 @@ using namespace MantidQt::CustomInterfaces; IndirectSimulation::IndirectSimulation(QWidget *parent) : UserSubWindow(parent), m_changeObserver(*this, &IndirectSimulation::handleDirectoryChange) { +} +IndirectSimulation::~IndirectSimulation() +{ } void IndirectSimulation::initLayout() { m_uiForm.setupUi(this); - + // Connect Poco Notification Observer Mantid::Kernel::ConfigService::Instance().addObserver(m_changeObserver); - //insert each tab into the interface on creation - m_loadAsciiTabs.insert(std::make_pair(MOLDYN, new IndirectMolDyn(m_uiForm.IndirectSimulationTabs->widget(MOLDYN)))); + // Insert each tab into the interface on creation + m_simulationTabs.insert(std::make_pair(MOLDYN, new IndirectMolDyn(m_uiForm.IndirectSimulationTabs->widget(MOLDYN)))); + m_simulationTabs.insert(std::make_pair(SASSENA, new IndirectSassena(m_uiForm.IndirectSimulationTabs->widget(SASSENA)))); - //Connect each tab to the actions available in this GUI + // Connect each tab to the actions available in this GUI std::map::iterator iter; - for (iter = m_loadAsciiTabs.begin(); iter != m_loadAsciiTabs.end(); ++iter) + for (iter = m_simulationTabs.begin(); iter != m_simulationTabs.end(); ++iter) { - connect(iter->second, SIGNAL(executePythonScript(const QString&, bool)), this, SIGNAL(runAsPythonScript(const QString&, bool))); + connect(iter->second, SIGNAL(runAsPythonScript(const QString&, bool)), this, SIGNAL(runAsPythonScript(const QString&, bool))); connect(iter->second, SIGNAL(showMessageBox(const QString&)), this, SLOT(showMessageBox(const QString&))); } loadSettings(); - //Connect statements for the buttons shared between all tabs on the Indirect Bayes interface + // Connect statements for the buttons shared between all tabs on the Indirect Bayes interface connect(m_uiForm.pbRun, SIGNAL(clicked()), this, SLOT(runClicked())); connect(m_uiForm.pbHelp, SIGNAL(clicked()), this, SLOT(helpClicked())); connect(m_uiForm.pbManageDirs, SIGNAL(clicked()), this, SLOT(manageUserDirectories())); @@ -88,7 +93,7 @@ void IndirectSimulation::loadSettings() settings.setValue("last_directory", saveDir); std::map::iterator iter; - for (iter = m_loadAsciiTabs.begin(); iter != m_loadAsciiTabs.end(); ++iter) + for (iter = m_simulationTabs.begin(); iter != m_simulationTabs.end(); ++iter) { iter->second->loadSettings(settings); } @@ -96,22 +101,17 @@ void IndirectSimulation::loadSettings() settings.endGroup(); } - /** * Slot to run the underlying algorithm code based on the currently selected * tab. - * + * * This method checks the tabs validate method is passing before calling * the run method. */ void IndirectSimulation::runClicked() { int tabIndex = m_uiForm.IndirectSimulationTabs->currentIndex(); - - if(m_loadAsciiTabs[tabIndex]->validate()) - { - m_loadAsciiTabs[tabIndex]->run(); - } + m_simulationTabs[tabIndex]->runTab(); } /** @@ -121,7 +121,7 @@ void IndirectSimulation::runClicked() void IndirectSimulation::helpClicked() { int tabIndex = m_uiForm.IndirectSimulationTabs->currentIndex(); - QString url = m_loadAsciiTabs[tabIndex]->tabHelpURL(); + QString url = m_simulationTabs[tabIndex]->tabHelpURL(); QDesktopServices::openUrl(QUrl(url)); } @@ -139,14 +139,10 @@ void IndirectSimulation::manageUserDirectories() /** * Slot to wrap the protected showInformationBox method defined * in UserSubWindow and provide access to composed tabs. - * + * * @param message :: The message to display in the message box */ void IndirectSimulation::showMessageBox(const QString& message) { showInformationBox(message); } - -IndirectSimulation::~IndirectSimulation() -{ -} diff --git a/Code/Mantid/MantidQt/CustomInterfaces/src/IndirectSimulationTab.cpp b/Code/Mantid/MantidQt/CustomInterfaces/src/IndirectSimulationTab.cpp index ea5956931ece..47d7cef49b87 100644 --- a/Code/Mantid/MantidQt/CustomInterfaces/src/IndirectSimulationTab.cpp +++ b/Code/Mantid/MantidQt/CustomInterfaces/src/IndirectSimulationTab.cpp @@ -1,6 +1,8 @@ #include "MantidQtAPI/UserSubWindow.h" #include "MantidQtCustomInterfaces/IndirectSimulationTab.h" +using namespace Mantid::API; + namespace MantidQt { namespace CustomInterfaces @@ -9,9 +11,8 @@ namespace MantidQt //---------------------------------------------------------------------------------------------- /** Constructor */ - IndirectSimulationTab::IndirectSimulationTab(QWidget * parent) : QWidget(parent) + IndirectSimulationTab::IndirectSimulationTab(QWidget * parent) : IndirectTab(parent) { - } //---------------------------------------------------------------------------------------------- @@ -23,23 +24,13 @@ namespace MantidQt /** * Method to build a URL to the appropriate page on the wiki for this tab. - * + * * @return The URL to the wiki page */ QString IndirectSimulationTab::tabHelpURL() - { + { return "http://www.mantidproject.org/IndirectSimualtion:" + help(); } - /** - * Emits a signal to run a python script using the method in the parent - * UserSubWindow - * - * @param pyInput :: A string of python code to execute - */ - void IndirectSimulationTab::runPythonScript(const QString& pyInput) - { - emit executePythonScript(pyInput, false); - } } } // namespace MantidQt diff --git a/Code/Mantid/MantidQt/CustomInterfaces/src/IndirectSqw.cpp b/Code/Mantid/MantidQt/CustomInterfaces/src/IndirectSqw.cpp index c736b1a73397..22f772470c3b 100644 --- a/Code/Mantid/MantidQt/CustomInterfaces/src/IndirectSqw.cpp +++ b/Code/Mantid/MantidQt/CustomInterfaces/src/IndirectSqw.cpp @@ -4,6 +4,9 @@ #include +using namespace Mantid::API; +using MantidQt::API::BatchAlgorithmRunner; + namespace MantidQt { namespace CustomInterfaces @@ -14,184 +17,254 @@ namespace CustomInterfaces IndirectSqw::IndirectSqw(Ui::IndirectDataReduction& uiForm, QWidget * parent) : IndirectDataReductionTab(uiForm, parent) { - connect(m_uiForm.sqw_ckRebinE, SIGNAL(toggled(bool)), this, SLOT(sOfQwRebinE(bool))); - connect(m_uiForm.sqw_dsSampleInput, SIGNAL(loadClicked()), this, SLOT(sOfQwPlotInput())); - m_uiForm.sqw_leELow->setValidator(m_valDbl); m_uiForm.sqw_leEWidth->setValidator(m_valDbl); m_uiForm.sqw_leEHigh->setValidator(m_valDbl); m_uiForm.sqw_leQLow->setValidator(m_valDbl); m_uiForm.sqw_leQWidth->setValidator(m_valDbl); m_uiForm.sqw_leQHigh->setValidator(m_valDbl); + + connect(m_uiForm.sqw_ckRebinE, SIGNAL(toggled(bool)), this, SLOT(energyRebinToggle(bool))); + connect(m_uiForm.sqw_dsSampleInput, SIGNAL(loadClicked()), this, SLOT(plotContour())); + + connect(m_batchAlgoRunner, SIGNAL(batchComplete(bool)), this, SLOT(sqwAlgDone(bool))); } - + //---------------------------------------------------------------------------------------------- /** Destructor */ IndirectSqw::~IndirectSqw() { } - + void IndirectSqw::setup() { } - void IndirectSqw::run() + bool IndirectSqw::validate() { - QString rebinString = m_uiForm.sqw_leQLow->text() + "," + m_uiForm.sqw_leQWidth->text() + - "," + m_uiForm.sqw_leQHigh->text(); - - QString wsname; - if(m_uiForm.sqw_dsSampleInput->isFileSelectorVisible()) - { - // Load Nexus file into workspace - QString filename = m_uiForm.sqw_dsSampleInput->getFullFilePath(); - QFileInfo fi(filename); - wsname = fi.baseName(); - - if(!loadFile(filename, wsname)) - { - emit showMessageBox("Could not load Nexus file"); - } - } - else - { - // Get the workspace - wsname = m_uiForm.sqw_dsSampleInput->getCurrentDataName(); - } - - QString pyInput = "from mantid.simpleapi import *\n"; + bool valid = true; - // Create output name before rebinning - pyInput += "sqwInput = '" + wsname + "'\n"; - pyInput += "sqwOutput = sqwInput[:-3] + 'sqw'\n"; + UserInputValidator uiv; + uiv.checkDataSelectorIsValid("Sample", m_uiForm.sqw_dsSampleInput); + QString error = uiv.generateErrorMessage(); - if ( m_uiForm.sqw_ckRebinE->isChecked() ) + if(!error.isEmpty()) { - QString eRebinString = m_uiForm.sqw_leELow->text() + "," + m_uiForm.sqw_leEWidth->text() + - "," + m_uiForm.sqw_leEHigh->text(); - - pyInput += "Rebin(InputWorkspace=sqwInput, OutputWorkspace=sqwInput+'_r', Params='" + eRebinString + "')\n" - "sqwInput += '_r'\n"; + valid = false; + emit showMessageBox(error); } - pyInput += - "efixed = " + m_uiForm.leEfixed->text() + "\n" - "rebin = '" + rebinString + "'\n"; + if(m_uiForm.sqw_ckRebinE->isChecked() && !validateEnergyRebin()) + valid = false; - QString rebinType = m_uiForm.sqw_cbRebinType->currentText(); - if(rebinType == "Centre (SofQW)") - pyInput += "SofQW(InputWorkspace=sqwInput, OutputWorkspace=sqwOutput, QAxisBinning=rebin, EMode='Indirect', EFixed=efixed)\n"; - else if(rebinType == "Parallelepiped (SofQW2)") - pyInput += "SofQW2(InputWorkspace=sqwInput, OutputWorkspace=sqwOutput, QAxisBinning=rebin, EMode='Indirect', EFixed=efixed)\n"; - else if(rebinType == "Parallelepiped/Fractional Area (SofQW3)") - pyInput += "SofQW3(InputWorkspace=sqwInput, OutputWorkspace=sqwOutput, QAxisBinning=rebin, EMode='Indirect', EFixed=efixed)\n"; + if(!validateQRebin()) + valid = false; - pyInput += "AddSampleLog(Workspace=sqwOutput, LogName='rebin_type', LogType='String', LogText='"+rebinType+"')\n"; + return valid; + } - if ( m_uiForm.sqw_ckSave->isChecked() ) - { - pyInput += "SaveNexus(InputWorkspace=sqwOutput, Filename=sqwOutput+'.nxs')\n"; + /** + * Validates the Q rebinning parameters. + * + * @returns If the rebinning is valid + */ + bool IndirectSqw::validateQRebin() + { + bool valid = true; - if (m_uiForm.sqw_ckVerbose->isChecked()) - { - pyInput += "logger.notice(\"Resolution file saved to default save directory.\")\n"; - } + if ( m_uiForm.sqw_leQLow->text() == "" ) + { + valid = false; + m_uiForm.sqw_valQLow->setText("*"); + } + else + { + m_uiForm.sqw_valQLow->setText(" "); } - if ( m_uiForm.sqw_cbPlotType->currentText() == "Contour" ) + if ( m_uiForm.sqw_leQWidth->text() == "" ) { - pyInput += "importMatrixWorkspace(sqwOutput).plotGraph2D()\n"; + valid = false; + m_uiForm.sqw_valQWidth->setText("*"); + } + else + { + m_uiForm.sqw_valQWidth->setText(" "); } - else if ( m_uiForm.sqw_cbPlotType->currentText() == "Spectra" ) + if ( m_uiForm.sqw_leQHigh->text() == "" ) { - pyInput += - "nspec = mtd[sqwOutput].getNumberHistograms()\n" - "plotSpectrum(sqwOutput, range(0, nspec))\n"; + valid = false; + m_uiForm.sqw_valQHigh->setText("*"); + } + else + { + m_uiForm.sqw_valQHigh->setText(" "); } - QString pyOutput = m_pythonRunner.runPythonCode(pyInput).trimmed(); + return valid; } - bool IndirectSqw::validate() + /** + * Validates the energy rebinning parameters. + * + * @returns If the rebinning is valid + */ + bool IndirectSqw::validateEnergyRebin() { bool valid = true; - UserInputValidator uiv; - uiv.checkDataSelectorIsValid("Sample", m_uiForm.sqw_dsSampleInput); - QString error = uiv.generateErrorMessage(); - - if (!error.isEmpty()) + if ( m_uiForm.sqw_leELow->text() == "" ) { valid = false; - emit showMessageBox(error); + m_uiForm.sqw_valELow->setText("*"); } - - if ( m_uiForm.sqw_ckRebinE->isChecked() ) + else { - if ( m_uiForm.sqw_leELow->text() == "" ) - { - valid = false; - m_uiForm.sqw_valELow->setText("*"); - } - else - { - m_uiForm.sqw_valELow->setText(" "); - } - - if ( m_uiForm.sqw_leEWidth->text() == "" ) - { - valid = false; - m_uiForm.sqw_valEWidth->setText("*"); - } - else - { - m_uiForm.sqw_valEWidth->setText(" "); - } - - if ( m_uiForm.sqw_leEHigh->text() == "" ) - { - valid = false; - m_uiForm.sqw_valEHigh->setText("*"); - } - else - { - m_uiForm.sqw_valEHigh->setText(" "); - } + m_uiForm.sqw_valELow->setText(" "); } - if ( m_uiForm.sqw_leQLow->text() == "" ) + if ( m_uiForm.sqw_leEWidth->text() == "" ) { valid = false; - m_uiForm.sqw_valQLow->setText("*"); + m_uiForm.sqw_valEWidth->setText("*"); } else { - m_uiForm.sqw_valQLow->setText(" "); + m_uiForm.sqw_valEWidth->setText(" "); } - if ( m_uiForm.sqw_leQWidth->text() == "" ) + if ( m_uiForm.sqw_leEHigh->text() == "" ) { valid = false; - m_uiForm.sqw_valQWidth->setText("*"); + m_uiForm.sqw_valEHigh->setText("*"); } else { - m_uiForm.sqw_valQWidth->setText(" "); + m_uiForm.sqw_valEHigh->setText(" "); } - if ( m_uiForm.sqw_leQHigh->text() == "" ) + return valid; + } + + void IndirectSqw::run() + { + QString sampleWsName = m_uiForm.sqw_dsSampleInput->getCurrentDataName(); + QString sqwWsName = sampleWsName.left(sampleWsName.length() - 4) + "_sqw"; + QString eRebinWsName = sampleWsName.left(sampleWsName.length() - 4) + "_r"; + + QString rebinString = m_uiForm.sqw_leQLow->text() + "," + m_uiForm.sqw_leQWidth->text() + + "," + m_uiForm.sqw_leQHigh->text(); + + // Rebin in energy + bool rebinInEnergy = m_uiForm.sqw_ckRebinE->isChecked(); + if(rebinInEnergy) { - valid = false; - m_uiForm.sqw_valQHigh->setText("*"); + QString eRebinString = m_uiForm.sqw_leELow->text() + "," + m_uiForm.sqw_leEWidth->text() + + "," + m_uiForm.sqw_leEHigh->text(); + + IAlgorithm_sptr energyRebinAlg = AlgorithmManager::Instance().create("Rebin"); + energyRebinAlg->initialize(); + + energyRebinAlg->setProperty("InputWorkspace", sampleWsName.toStdString()); + energyRebinAlg->setProperty("OutputWorkspace", eRebinWsName.toStdString()); + energyRebinAlg->setProperty("Params", eRebinString.toStdString()); + + m_batchAlgoRunner->addAlgorithm(energyRebinAlg); } + + // Get correct S(Q, w) algorithm + QString eFixed = getInstrumentDetails()["efixed-val"]; + + IAlgorithm_sptr sqwAlg; + QString rebinType = m_uiForm.sqw_cbRebinType->currentText(); + + if(rebinType == "Centre (SofQW)") + sqwAlg = AlgorithmManager::Instance().create("SofQW"); + else if(rebinType == "Parallelepiped (SofQW2)") + sqwAlg = AlgorithmManager::Instance().create("SofQW2"); + else if(rebinType == "Parallelepiped/Fractional Area (SofQW3)") + sqwAlg = AlgorithmManager::Instance().create("SofQW3"); + + // S(Q, w) algorithm + sqwAlg->initialize(); + + BatchAlgorithmRunner::AlgorithmRuntimeProps sqwInputProps; + if(rebinInEnergy) + sqwInputProps["InputWorkspace"] = eRebinWsName.toStdString(); else + sqwInputProps["InputWorkspace"] = sampleWsName.toStdString(); + + sqwAlg->setProperty("OutputWorkspace", sqwWsName.toStdString()); + sqwAlg->setProperty("QAxisBinning", rebinString.toStdString()); + sqwAlg->setProperty("EMode", "Indirect"); + sqwAlg->setProperty("EFixed", eFixed.toStdString()); + + m_batchAlgoRunner->addAlgorithm(sqwAlg, sqwInputProps); + + // Add sample log for S(Q, w) algorithm used + IAlgorithm_sptr sampleLogAlg = AlgorithmManager::Instance().create("AddSampleLog"); + sampleLogAlg->initialize(); + + sampleLogAlg->setProperty("LogName", "rebin_type"); + sampleLogAlg->setProperty("LogType", "String"); + sampleLogAlg->setProperty("LogText", rebinType.toStdString()); + + BatchAlgorithmRunner::AlgorithmRuntimeProps inputToAddSampleLogProps; + inputToAddSampleLogProps["Workspace"] = sqwWsName.toStdString(); + + m_batchAlgoRunner->addAlgorithm(sampleLogAlg, inputToAddSampleLogProps); + + // Save S(Q, w) workspace + if(m_uiForm.sqw_ckSave->isChecked()) { - m_uiForm.sqw_valQHigh->setText(" "); + QString saveFilename = sqwWsName + ".nxs"; + + IAlgorithm_sptr saveNexusAlg = AlgorithmManager::Instance().create("SaveNexus"); + saveNexusAlg->initialize(); + + saveNexusAlg->setProperty("Filename", saveFilename.toStdString()); + + BatchAlgorithmRunner::AlgorithmRuntimeProps inputToSaveNexusProps; + inputToSaveNexusProps["InputWorkspace"] = sqwWsName.toStdString(); + + m_batchAlgoRunner->addAlgorithm(saveNexusAlg, inputToSaveNexusProps); } - return valid; + m_batchAlgoRunner->executeBatch(); + } + + /** + * Handles plotting the S(Q, w) workspace when the algorithm chain is finished. + * + * @param error If the algorithm chain failed + */ + void IndirectSqw::sqwAlgDone(bool error) + { + if(error) + return; + + // Get the workspace name + QString sampleWsName = m_uiForm.sqw_dsSampleInput->getCurrentDataName(); + QString sqwWsName = sampleWsName.left(sampleWsName.length() - 4) + "_sqw"; + + QString pyInput = "sqw_ws = '" + sqwWsName + "'\n"; + QString plotType = m_uiForm.sqw_cbPlotType->currentText(); + + if(plotType == "Contour") + { + pyInput += "plot2D(sqw_ws)\n"; + } + + else if(plotType == "Spectra") + { + pyInput += + "n_spec = mtd[sqw_ws].getNumberHistograms()\n" + "plotSpectrum(sqw_ws, range(0, n_spec))\n"; + } + + m_pythonRunner.runPythonCode(pyInput).trimmed(); } /** @@ -199,11 +272,14 @@ namespace CustomInterfaces * * @param state :: True to enable RiE UI, false to disable */ - void IndirectSqw::sOfQwRebinE(bool state) + void IndirectSqw::energyRebinToggle(bool state) { QString val; - if ( state ) val = "*"; - else val = " "; + if(state) + val = "*"; + else + val = " "; + m_uiForm.sqw_leELow->setEnabled(state); m_uiForm.sqw_leEWidth->setEnabled(state); m_uiForm.sqw_leEHigh->setEnabled(state); @@ -223,32 +299,26 @@ namespace CustomInterfaces * * Creates a colour 2D plot of the data */ - void IndirectSqw::sOfQwPlotInput() + void IndirectSqw::plotContour() { - QString pyInput = "from mantid.simpleapi import *\n" - "from mantidplot import *\n"; - - if (m_uiForm.sqw_dsSampleInput->isValid()) + if(m_uiForm.sqw_dsSampleInput->isValid()) { - if(m_uiForm.sqw_dsSampleInput->isFileSelectorVisible()) - { - //Load file into workspacwe - pyInput += "filename = r'" + m_uiForm.sqw_dsSampleInput->getFullFilePath() + "'\n" - "(dir, file) = os.path.split(filename)\n" - "(sqwInput, ext) = os.path.splitext(file)\n" - "LoadNexus(Filename=filename, OutputWorkspace=sqwInput)\n"; - } - else - { - //Use existing workspace - pyInput += "sqwInput = '" + m_uiForm.sqw_dsSampleInput->getCurrentDataName() + "'\n"; - } - - pyInput += "ConvertSpectrumAxis(InputWorkspace=sqwInput, OutputWorkspace=sqwInput[:-4]+'_rqw', Target='ElasticQ', EMode='Indirect')\n" - "ws = importMatrixWorkspace(sqwInput[:-4]+'_rqw')\n" - "ws.plotGraph2D()\n"; - - QString pyOutput = m_pythonRunner.runPythonCode(pyInput).trimmed(); + QString sampleWsName = m_uiForm.sqw_dsSampleInput->getCurrentDataName(); + + QString convertedWsName = sampleWsName.left(sampleWsName.length() - 4) + "_rqw"; + + IAlgorithm_sptr convertSpecAlg = AlgorithmManager::Instance().create("ConvertSpectrumAxis"); + convertSpecAlg->initialize(); + + convertSpecAlg->setProperty("InputWorkspace", sampleWsName.toStdString()); + convertSpecAlg->setProperty("OutputWorkspace", convertedWsName.toStdString()); + convertSpecAlg->setProperty("Target", "ElasticQ"); + convertSpecAlg->setProperty("EMode", "Indirect"); + + convertSpecAlg->execute(); + + QString pyInput = "plot2D('" + convertedWsName + "')\n"; + m_pythonRunner.runPythonCode(pyInput).trimmed(); } else { diff --git a/Code/Mantid/MantidQt/CustomInterfaces/src/IndirectSymmetrise.cpp b/Code/Mantid/MantidQt/CustomInterfaces/src/IndirectSymmetrise.cpp new file mode 100644 index 000000000000..6caef16805e2 --- /dev/null +++ b/Code/Mantid/MantidQt/CustomInterfaces/src/IndirectSymmetrise.cpp @@ -0,0 +1,520 @@ +#include "MantidQtCustomInterfaces/IndirectSymmetrise.h" + +#include "MantidAPI/MatrixWorkspace.h" +#include "MantidAPI/ITableWorkspace.h" +#include "MantidKernel/Logger.h" +#include "MantidQtCustomInterfaces/UserInputValidator.h" + +#include + +namespace +{ + Mantid::Kernel::Logger g_log("IndirectSymmetrise"); +} + +using namespace Mantid::API; + +namespace MantidQt +{ +namespace CustomInterfaces +{ + //---------------------------------------------------------------------------------------------- + /** Constructor + */ + IndirectSymmetrise::IndirectSymmetrise(Ui::IndirectDataReduction& uiForm, QWidget * parent) : + IndirectDataReductionTab(uiForm, parent) + { + int numDecimals = 6; + + // Property Trees + m_propTrees["SymmPropTree"] = new QtTreePropertyBrowser(); + m_uiForm.symm_properties->addWidget(m_propTrees["SymmPropTree"]); + + m_propTrees["SymmPVPropTree"] = new QtTreePropertyBrowser(); + m_uiForm.symm_previewProperties->addWidget(m_propTrees["SymmPVPropTree"]); + + // Editor Factories + DoubleEditorFactory *doubleEditorFactory = new DoubleEditorFactory(); + m_propTrees["SymmPropTree"]->setFactoryForManager(m_dblManager, doubleEditorFactory); + + // Raw Properties + m_properties["EMin"] = m_dblManager->addProperty("EMin"); + m_dblManager->setDecimals(m_properties["EMin"], numDecimals); + m_propTrees["SymmPropTree"]->addProperty(m_properties["EMin"]); + m_properties["EMax"] = m_dblManager->addProperty("EMax"); + m_dblManager->setDecimals(m_properties["EMax"], numDecimals); + m_propTrees["SymmPropTree"]->addProperty(m_properties["EMax"]); + + QtProperty* rawPlotProps = m_grpManager->addProperty("Raw Plot"); + m_propTrees["SymmPropTree"]->addProperty(rawPlotProps); + + m_properties["PreviewSpec"] = m_dblManager->addProperty("Spectrum No"); + m_dblManager->setDecimals(m_properties["PreviewSpec"], 0); + rawPlotProps->addSubProperty(m_properties["PreviewSpec"]); + + m_properties["PreviewRange"] = m_dblManager->addProperty("X Range"); + rawPlotProps->addSubProperty(m_properties["PreviewRange"]); + + // Preview Properties + // Mainly used for display rather than getting user input + m_properties["NegativeYValue"] = m_dblManager->addProperty("Negative Y"); + m_dblManager->setDecimals(m_properties["NegativeYValue"], numDecimals); + m_propTrees["SymmPVPropTree"]->addProperty(m_properties["NegativeYValue"]); + + m_properties["PositiveYValue"] = m_dblManager->addProperty("Positive Y"); + m_dblManager->setDecimals(m_properties["PositiveYValue"], numDecimals); + m_propTrees["SymmPVPropTree"]->addProperty(m_properties["PositiveYValue"]); + + m_properties["DeltaY"] = m_dblManager->addProperty("Delta Y"); + m_dblManager->setDecimals(m_properties["DeltaY"], numDecimals); + m_propTrees["SymmPVPropTree"]->addProperty(m_properties["DeltaY"]); + + // Raw plot + m_plots["SymmRawPlot"] = new QwtPlot(m_parentWidget); + m_plots["SymmRawPlot"]->setAxisFont(QwtPlot::xBottom, parent->font()); + m_plots["SymmRawPlot"]->setAxisFont(QwtPlot::yLeft, parent->font()); + m_plots["SymmRawPlot"]->setCanvasBackground(Qt::white); + m_uiForm.symm_plot->addWidget(m_plots["SymmRawPlot"]); + + // Indicators for Y value at each EMin position + m_rangeSelectors["NegativeEMinYPos"] = new MantidWidgets::RangeSelector(m_plots["SymmRawPlot"], + MantidWidgets::RangeSelector::YSINGLE, true, true); + m_rangeSelectors["PositiveEMinYPos"] = new MantidWidgets::RangeSelector(m_plots["SymmRawPlot"], + 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); + + // Indicator for centre of symmetry (x=0) + m_rangeSelectors["CentreMark_Raw"] = new MantidWidgets::RangeSelector(m_plots["SymmRawPlot"], + MantidWidgets::RangeSelector::XSINGLE, true, true); + m_rangeSelectors["CentreMark_Raw"]->setColour(Qt::cyan); + m_rangeSelectors["CentreMark_Raw"]->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_plots["SymmRawPlot"]); + m_rangeSelectors["PositiveE_Raw"] = new MantidWidgets::RangeSelector(m_plots["SymmRawPlot"]); + + m_rangeSelectors["NegativeE_Raw"]->setColour(Qt::darkGreen); + m_rangeSelectors["PositiveE_Raw"]->setColour(Qt::darkGreen); + + // Preview plot + m_plots["SymmPreviewPlot"] = new QwtPlot(m_parentWidget); + m_plots["SymmPreviewPlot"]->setAxisFont(QwtPlot::xBottom, parent->font()); + m_plots["SymmPreviewPlot"]->setAxisFont(QwtPlot::yLeft, parent->font()); + m_plots["SymmPreviewPlot"]->setCanvasBackground(Qt::white); + m_uiForm.symm_previewPlot->addWidget(m_plots["SymmPreviewPlot"]); + + // Indicators for negative and positive X range values on X axis + m_rangeSelectors["NegativeE_PV"] = new MantidWidgets::RangeSelector(m_plots["SymmPreviewPlot"], + MantidWidgets::RangeSelector::XMINMAX, true, true); + m_rangeSelectors["PositiveE_PV"] = new MantidWidgets::RangeSelector(m_plots["SymmPreviewPlot"], + MantidWidgets::RangeSelector::XMINMAX, true, true); + + m_rangeSelectors["NegativeE_PV"]->setColour(Qt::darkGreen); + m_rangeSelectors["PositiveE_PV"]->setColour(Qt::darkGreen); + + // Indicator for centre of symmetry (x=0) + m_rangeSelectors["CentreMark_PV"] = new MantidWidgets::RangeSelector(m_plots["SymmPreviewPlot"], + MantidWidgets::RangeSelector::XSINGLE, true, true); + m_rangeSelectors["CentreMark_PV"]->setColour(Qt::cyan); + m_rangeSelectors["CentreMark_PV"]->setMinimum(0.0); + + // Refresh the plot windows + m_plots["SymmRawPlot"]->replot(); + m_plots["SymmPreviewPlot"]->replot(); + + // SIGNAL/SLOT CONNECTIONS + // Validate the E range when it is changed + connect(m_dblManager, SIGNAL(valueChanged(QtProperty*, double)), this, SLOT(verifyERange(QtProperty*, double))); + // Plot a new spectrum when the user changes the value of the preview spectrum + connect(m_dblManager, SIGNAL(valueChanged(QtProperty*, double)), this, SLOT(replotNewSpectrum(QtProperty*, double))); + // Plot miniplot when file has finished loading + connect(m_uiForm.symm_dsInput, SIGNAL(dataReady(const QString&)), this, SLOT(plotRawInput(const QString&))); + // Preview symmetrise + connect(m_uiForm.symm_previewButton, 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))); + + // Set default X range values + m_dblManager->setValue(m_properties["EMin"], 0.1); + m_dblManager->setValue(m_properties["EMax"], 0.5); + + // Set default x axis range + std::pair defaultRange(-1.0, 1.0); + setAxisRange("SymmRawPlot", QwtPlot::xBottom, defaultRange); + setAxisRange("SymmPreviewPlot", QwtPlot::xBottom, defaultRange); + } + + //---------------------------------------------------------------------------------------------- + /** Destructor + */ + IndirectSymmetrise::~IndirectSymmetrise() + { + } + + void IndirectSymmetrise::setup() + { + } + + bool IndirectSymmetrise::validate() + { + // Check for a valid input file + if(!m_uiForm.symm_dsInput->isValid()) + return false; + + // EMin and EMax must be positive + if(m_dblManager->value(m_properties["EMin"]) <= 0.0) + return false; + if(m_dblManager->value(m_properties["EMax"]) <= 0.0) + return false; + + return true; + } + + void IndirectSymmetrise::run() + { + QString workspaceName = m_uiForm.symm_dsInput->getCurrentDataName(); + QString outputWorkspaceName = workspaceName.left(workspaceName.length() - 4) + "_sym" + workspaceName.right(4); + + bool plot = m_uiForm.symm_ckPlot->isChecked(); + bool verbose = m_uiForm.symm_ckVerbose->isChecked(); + bool save = m_uiForm.symm_ckSave->isChecked(); + + double e_min = m_dblManager->value(m_properties["EMin"]); + double e_max = m_dblManager->value(m_properties["EMax"]); + + IAlgorithm_sptr symmetriseAlg = AlgorithmManager::Instance().create("Symmetrise", -1); + symmetriseAlg->initialize(); + symmetriseAlg->setProperty("Sample", workspaceName.toStdString()); + symmetriseAlg->setProperty("XMin", e_min); + symmetriseAlg->setProperty("XMax", e_max); + symmetriseAlg->setProperty("Plot", plot); + symmetriseAlg->setProperty("Verbose", verbose); + symmetriseAlg->setProperty("Save", save); + symmetriseAlg->setProperty("OutputWorkspace", outputWorkspaceName.toStdString()); + + // Execute algorithm on seperate thread + runAlgorithm(symmetriseAlg); + } + + /** + * Plots a new workspace in the mini plot when it is loaded form the data selector. + * + * @param workspaceName Name of the workspace that has been laoded + */ + void IndirectSymmetrise::plotRawInput(const QString &workspaceName) + { + // Set the preview spectrum number to the first spectrum in the workspace + MatrixWorkspace_sptr sampleWS = AnalysisDataService::Instance().retrieveWS(workspaceName.toStdString()); + int minSpectrumRange = sampleWS->getSpectrum(0)->getSpectrumNo(); + m_dblManager->setValue(m_properties["PreviewSpec"], static_cast(minSpectrumRange)); + + updateMiniPlots(); + + // Set the preview range to the maximum absolute X value + auto axisRange = getCurveRange("SymmRawPlot"); + double symmRange = std::max(fabs(axisRange.first), fabs(axisRange.second)); + g_log.information() << "Symmetrise x axis range +/- " << symmRange << std::endl; + m_dblManager->setValue(m_properties["PreviewRange"], symmRange); + + // Set valid range for range selectors + m_rangeSelectors["NegativeE_Raw"]->setRange(-symmRange, 0); + m_rangeSelectors["PositiveE_Raw"]->setRange(0, symmRange); + + // Set some default (and valid) values for E range + m_dblManager->setValue(m_properties["EMax"], axisRange.second); + m_dblManager->setValue(m_properties["EMin"], axisRange.second/10); + + updateMiniPlots(); + } + + /** + * Updates the mini plots. + */ + void IndirectSymmetrise::updateMiniPlots() + { + if(!m_uiForm.symm_dsInput->isValid()) + return; + + QString workspaceName = m_uiForm.symm_dsInput->getCurrentDataName(); + int spectrumNumber = static_cast(m_dblManager->value(m_properties["PreviewSpec"])); + + Mantid::API::MatrixWorkspace_sptr input = boost::dynamic_pointer_cast( + Mantid::API::AnalysisDataService::Instance().retrieve(workspaceName.toStdString())); + + // Set the X axis range based on the range specified by the user + std::pairrange; + range.first = -m_dblManager->value(m_properties["PreviewRange"]); + range.second = m_dblManager->value(m_properties["PreviewRange"]); + setAxisRange("SymmRawPlot", QwtPlot::xBottom, range); + + // Plot the spectrum chosen by the user + size_t spectrumIndex = input->getIndexFromSpectrumNumber(spectrumNumber); + plotMiniPlot(input, spectrumIndex, "SymmRawPlot"); + + // Match X axis range on preview plot + setAxisRange("SymmPreviewPlot", QwtPlot::xBottom, range); + m_plots["SymmPreviewPlot"]->replot(); + } + + /** + * Redraws mini plots when user changes previw range or spectrum. + * + * @param prop QtProperty that was changed + * @param value Value it was changed to + */ + void IndirectSymmetrise::replotNewSpectrum(QtProperty *prop, double value) + { + // Validate the preview range + if(prop == m_properties["PreviewRange"]) + { + // If preview range was set negative then set it to the absolute value of the value it was set to + if(value < 0) + { + m_dblManager->setValue(m_properties["PreviewRange"], fabs(value)); + return; + } + } + + // Validate the preview spectra + if(prop == m_properties["PreviewSpec"]) + { + // Get the range of possible spectra numbers + QString workspaceName = m_uiForm.symm_dsInput->getCurrentDataName(); + MatrixWorkspace_sptr sampleWS = AnalysisDataService::Instance().retrieveWS(workspaceName.toStdString()); + int minSpectrumRange = sampleWS->getSpectrum(0)->getSpectrumNo(); + int maxSpectrumRange = sampleWS->getSpectrum(sampleWS->getNumberHistograms()-1)->getSpectrumNo(); + + // If entered value is lower then set spectra number to lowest valid value + if(value < minSpectrumRange) + { + m_dblManager->setValue(m_properties["PreviewSpec"], minSpectrumRange); + return; + } + + // If entered value is higer then set spectra number to highest valid value + if(value > maxSpectrumRange) + { + m_dblManager->setValue(m_properties["PreviewSpec"], maxSpectrumRange); + return; + } + } + + // If we get this far then properties are valid so update mini plots + if((prop == m_properties["PreviewSpec"]) || (prop == m_properties["PreviewRange"])) + updateMiniPlots(); + } + + /** + * Verifies that the E Range is valid. + * + * @param prop QtProperty changed + * @param value Value it was changed to (unused) + */ + void IndirectSymmetrise::verifyERange(QtProperty *prop, double value) + { + UNUSED_ARG(value); + + double eMin = m_dblManager->value(m_properties["EMin"]); + double eMax = m_dblManager->value(m_properties["EMax"]); + + if(prop == m_properties["EMin"]) + { + // If the value of EMin is negative try negating it to get a valid range + if(eMin < 0) + { + eMin = -eMin; + m_dblManager->setValue(m_properties["EMin"], eMin); + return; + } + + // If range is still invalid reset EMin to half EMax + if(eMin > eMax) + { + m_dblManager->setValue(m_properties["EMin"], eMax/2); + return; + } + } + else if(prop == m_properties["EMax"]) + { + // If the value of EMax is negative try negating it to get a valid range + if(eMax < 0) + { + eMax = -eMax; + m_dblManager->setValue(m_properties["EMax"], eMax); + return; + } + + // If range is invalid reset EMax to double EMin + if(eMin > eMax) + { + m_dblManager->setValue(m_properties["EMax"], eMin*2); + return; + } + } + + // If we get this far then the E range is valid + // Update the range selectors with the new values. + updateRangeSelectors(prop, value); + } + + /** + * Handles a request to preview the symmetrise. + * + * Runs Symmetrise on the current spectrum and plots in preview mini plot. + * + * @see IndirectSymmetrise::previewAlgDone() + */ + void IndirectSymmetrise::preview() + { + // Handle algorithm completion signal + connect(m_batchAlgoRunner, SIGNAL(batchComplete(bool)), this, SLOT(previewAlgDone(bool))); + + // Do nothing if no data has been laoded + QString workspaceName = m_uiForm.symm_dsInput->getCurrentDataName(); + if(workspaceName.isEmpty()) + return; + + bool verbose = m_uiForm.symm_ckVerbose->isChecked(); + double e_min = m_dblManager->value(m_properties["EMin"]); + double e_max = m_dblManager->value(m_properties["EMax"]); + long spectrumNumber = static_cast(m_dblManager->value(m_properties["PreviewSpec"])); + std::vector spectraRange(2, spectrumNumber); + + // Run the algorithm on the preview spectrum only + IAlgorithm_sptr symmetriseAlg = AlgorithmManager::Instance().create("Symmetrise", -1); + symmetriseAlg->initialize(); + symmetriseAlg->setProperty("Sample", workspaceName.toStdString()); + symmetriseAlg->setProperty("XMin", e_min); + symmetriseAlg->setProperty("XMax", e_max); + symmetriseAlg->setProperty("Plot", false); + symmetriseAlg->setProperty("Verbose", verbose); + symmetriseAlg->setProperty("Save", false); + symmetriseAlg->setProperty("SpectraRange", spectraRange); + symmetriseAlg->setProperty("OutputWorkspace", "__Symmetrise_temp"); + symmetriseAlg->setProperty("OutputPropertiesTable", "__SymmetriseProps_temp"); + + runAlgorithm(symmetriseAlg); + } + + /** + * Handles completion of the preview algorithm. + * + * @param error If the algorithm failed + */ + void IndirectSymmetrise::previewAlgDone(bool error) + { + if(error) + return; + + QString workspaceName = m_uiForm.symm_dsInput->getCurrentDataName(); + int spectrumNumber = static_cast(m_dblManager->value(m_properties["PreviewSpec"])); + + MatrixWorkspace_sptr sampleWS = AnalysisDataService::Instance().retrieveWS(workspaceName.toStdString()); + ITableWorkspace_sptr propsTable = AnalysisDataService::Instance().retrieveWS("__SymmetriseProps_temp"); + MatrixWorkspace_sptr symmWS = AnalysisDataService::Instance().retrieveWS("__Symmetrise_temp"); + + // Get the index of XCut on each side of zero + int negativeIndex = propsTable->getColumn("NegativeXMinIndex")->cell(0); + int positiveIndex = propsTable->getColumn("PositiveXMinIndex")->cell(0); + + // Get the Y values for each XCut and the difference between them + double negativeY = sampleWS->dataY(0)[negativeIndex]; + double positiveY = sampleWS->dataY(0)[positiveIndex]; + double deltaY = fabs(negativeY - positiveY); + + // Show values in property tree + m_dblManager->setValue(m_properties["NegativeYValue"], negativeY); + m_dblManager->setValue(m_properties["PositiveYValue"], positiveY); + m_dblManager->setValue(m_properties["DeltaY"], deltaY); + + // Set indicator positions + m_rangeSelectors["NegativeEMinYPos"]->setMinimum(negativeY); + m_rangeSelectors["PositiveEMinYPos"]->setMinimum(positiveY); + + // Plot preview plot + size_t spectrumIndex = symmWS->getIndexFromSpectrumNumber(spectrumNumber); + plotMiniPlot("__Symmetrise_temp", spectrumIndex, "SymmPreviewPlot"); + + // Don't want this to trigger when the algorithm is run for all spectra + disconnect(m_batchAlgoRunner, SIGNAL(batchComplete(bool)), this, SLOT(previewAlgDone(bool))); + } + + /** + * Updates position of XCut range selectors when used changed value of XCut. + * + * @param prop QtProperty changed + * @param value Value it was changed to (unused) + */ + void IndirectSymmetrise::updateRangeSelectors(QtProperty *prop, double value) + { + value = fabs(value); + + if(prop == m_properties["EMin"]) + { + m_rangeSelectors["NegativeE_Raw"]->setMaximum(-value); + m_rangeSelectors["PositiveE_Raw"]->setMinimum(value); + + m_rangeSelectors["NegativeE_PV"]->setMinimum(-value); + m_rangeSelectors["PositiveE_PV"]->setMinimum(value); + } + + if(prop == m_properties["EMax"]) + { + m_rangeSelectors["NegativeE_Raw"]->setMinimum(-value); + m_rangeSelectors["PositiveE_Raw"]->setMaximum(value); + + m_rangeSelectors["NegativeE_PV"]->setMaximum(-value); + m_rangeSelectors["PositiveE_PV"]->setMaximum(value); + } + } + + /** + * Handles the X minimum value being changed from a range selector. + * + * @param value New range selector value + */ + void IndirectSymmetrise::xRangeMinChanged(double value) + { + MantidWidgets::RangeSelector *from = qobject_cast(sender()); + + if(from == m_rangeSelectors["PositiveE_Raw"]) + { + m_dblManager->setValue(m_properties["EMin"], std::abs(value)); + } + else if(from == m_rangeSelectors["NegativeE_Raw"]) + { + m_dblManager->setValue(m_properties["EMax"], std::abs(value)); + } + } + + /** + * Handles the X maximum value being changed from a range selector. + * + * @param value New range selector value + */ + void IndirectSymmetrise::xRangeMaxChanged(double value) + { + MantidWidgets::RangeSelector *from = qobject_cast(sender()); + + if(from == m_rangeSelectors["PositiveE_Raw"]) + { + m_dblManager->setValue(m_properties["EMax"], std::abs(value)); + } + else if(from == m_rangeSelectors["NegativeE_Raw"]) + { + m_dblManager->setValue(m_properties["EMin"], std::abs(value)); + } + } + +} // namespace CustomInterfaces +} // namespace Mantid diff --git a/Code/Mantid/MantidQt/CustomInterfaces/src/IndirectTab.cpp b/Code/Mantid/MantidQt/CustomInterfaces/src/IndirectTab.cpp new file mode 100644 index 000000000000..037feb9d98df --- /dev/null +++ b/Code/Mantid/MantidQt/CustomInterfaces/src/IndirectTab.cpp @@ -0,0 +1,279 @@ +#include "MantidQtCustomInterfaces/IndirectTab.h" + +#include "MantidAPI/AlgorithmManager.h" +#include "MantidKernel/Logger.h" + +using namespace Mantid::API; +using namespace Mantid::Geometry; + +namespace +{ + Mantid::Kernel::Logger g_log("IndirectTab"); +} + +namespace MantidQt +{ +namespace CustomInterfaces +{ + //---------------------------------------------------------------------------------------------- + /** Constructor + */ + IndirectTab::IndirectTab(QObject* parent) : QObject(parent), + m_plots(), m_curves(), m_rangeSelectors(), + m_properties(), + m_dblManager(new QtDoublePropertyManager()), m_blnManager(new QtBoolPropertyManager()), m_grpManager(new QtGroupPropertyManager()), + m_dblEdFac(new DoubleEditorFactory()) + { + m_parentWidget = dynamic_cast(parent); + + m_batchAlgoRunner = new MantidQt::API::BatchAlgorithmRunner(m_parentWidget); + m_valInt = new QIntValidator(m_parentWidget); + m_valDbl = new QDoubleValidator(m_parentWidget); + m_valPosDbl = new QDoubleValidator(m_parentWidget); + + const double tolerance = 0.00001; + m_valPosDbl->setBottom(tolerance); + + connect(m_batchAlgoRunner, SIGNAL(batchComplete(bool)), this, SLOT(algorithmFinished(bool))); + connect(&m_pythonRunner, SIGNAL(runAsPythonScript(const QString&, bool)), this, SIGNAL(runAsPythonScript(const QString&, bool))); + } + + //---------------------------------------------------------------------------------------------- + /** Destructor + */ + IndirectTab::~IndirectTab() + { + } + + void IndirectTab::runTab() + { + if(validate()) + run(); + else + g_log.warning("Failed to validate indirect tab input!"); + } + + void IndirectTab::setupTab() + { + setup(); + } + + bool IndirectTab::validateTab() + { + return validate(); + } + + /** + * Run the load algorithm with the supplied filename and spectrum range + * + * @param filename :: The name of the file to load + * @param outputName :: The name of the output workspace + * @param specMin :: Lower spectra bound + * @param specMax :: Upper spectra bound + * @return If the algorithm was successful + */ + bool IndirectTab::loadFile(const QString& filename, const QString& outputName, + const int specMin, const int specMax) + { + Algorithm_sptr load = AlgorithmManager::Instance().createUnmanaged("Load", -1); + load->initialize(); + + load->setProperty("Filename", filename.toStdString()); + load->setProperty("OutputWorkspace", outputName.toStdString()); + + if(specMin != -1) + load->setProperty("SpectrumMin", specMin); + + if(specMax != -1) + load->setProperty("SpectrumMax", specMax); + + load->execute(); + + //If reloading fails we're out of options + return load->isExecuted(); + } + + /** + * Gets the range of the curve plotted in the mini plot + * + * @param curveID :: The string index of the curve in the m_curves map + * @return A pair containing the maximum and minimum points of the curve + */ + std::pair IndirectTab::getCurveRange(const QString& curveID) + { + size_t npts = m_curves[curveID]->data().size(); + + if( npts < 2 ) + throw std::invalid_argument("Too few points on data curve to determine range."); + + return std::make_pair(m_curves[curveID]->data().x(0), m_curves[curveID]->data().x(npts-1)); + } + + /** + * Set the range of an axis on a miniplot + * + * @param plotID :: Index of plot in m_plots map + * @param axis :: ID of axis to set range of + * @param range :: Pair of double values specifying range + */ + void IndirectTab::setAxisRange(const QString& plotID, QwtPlot::Axis axis, + std::pair range) + { + m_plots[plotID]->setAxisScale(axis, range.first, range.second); + } + + /** + * Sets the X axis of a plot to match the range of x values on a curve + * + * @param plotID :: Index of plot in m_plots map + * @param curveID :: Index of curve in m_curves map + */ + void IndirectTab::setXAxisToCurve(const QString& plotID, const QString& curveID) + { + auto range = getCurveRange(curveID); + setAxisRange(plotID, QwtPlot::xBottom, range); + } + + /** + * Plot a workspace to the miniplot given a workspace name and + * a specturm index. + * + * This method uses the analysis data service to retrieve the workspace. + * + * @param workspace :: The name of the workspace + * @param index :: The spectrum index of the workspace + * @param plotID :: String index of the plot in the m_plots map + * @param curveID :: String index of the curve in the m_curves map, defaults to plot ID + */ + void IndirectTab::plotMiniPlot(const QString& workspace, size_t index, + const QString& plotID, const QString& curveID) + { + auto ws = AnalysisDataService::Instance().retrieveWS(workspace.toStdString()); + plotMiniPlot(ws, index, plotID, curveID); + } + + /** + * Replot a given mini plot + * + * @param plotID :: ID of plot in m_plots map + */ + void IndirectTab::replot(const QString& plotID) + { + m_plots[plotID]->replot(); + } + + /** + * Plot a workspace to the miniplot given a workspace pointer and + * a specturm index. + * + * @param workspace :: Pointer to the workspace + * @param wsIndex :: The spectrum index of the workspace + * @param plotID :: String index of the plot in the m_plots map + * @param curveID :: String index of the curve in the m_curves map, defaults to plot ID + */ + void IndirectTab::plotMiniPlot(const Mantid::API::MatrixWorkspace_const_sptr & workspace, size_t wsIndex, + const QString& plotID, const QString& curveID) + { + using Mantid::MantidVec; + + QString cID = curveID; + if(cID == "") + cID = plotID; + + //check if we can plot + if( wsIndex >= workspace->getNumberHistograms() || workspace->readX(0).size() < 2 ) + return; + + QwtWorkspaceSpectrumData wsData(*workspace, static_cast(wsIndex), false); + + if ( m_curves[cID] != NULL ) + { + m_curves[cID]->attach(0); + delete m_curves[cID]; + m_curves[cID] = NULL; + } + + size_t nhist = workspace->getNumberHistograms(); + if ( wsIndex >= nhist ) + { + emit showMessageBox("Error: Workspace index out of range."); + } + else + { + m_curves[cID] = new QwtPlotCurve(); + m_curves[cID]->setData(wsData); + m_curves[cID]->attach(m_plots[plotID]); + + m_plots[plotID]->replot(); + } + } + + /** + * 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 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::setPlotRange(const QString& rsID, QtProperty* min, QtProperty* max, + const std::pair& 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); + } + + /** + * Set the position of the guides on the mini plot + * + * @param rsID :: The string index of the range selector in the map m_rangeSelectors + * @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::setMiniPlotGuides(const QString& rsID, QtProperty* lower, QtProperty* upper, + const std::pair& 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); + } + + /** + * Runs an algorithm async + * + * @param algorithm :: The algorithm to be run + */ + void IndirectTab::runAlgorithm(const Mantid::API::IAlgorithm_sptr algorithm) + { + algorithm->setRethrows(true); + + // There should never really be unexecuted algorithms in the queue, but it is worth warning in case of possible weirdness + size_t batchQueueLength = m_batchAlgoRunner->queueLength(); + if(batchQueueLength > 0) + g_log.warning() << "Batch queue already contains " << batchQueueLength << " algorithms!" << std::endl; + + m_batchAlgoRunner->addAlgorithm(algorithm); + m_batchAlgoRunner->executeBatchAsync(); + } + + /** + * Handles getting the results of an algorithm running async + * + * @param error :: True if execution failed, false otherwise + */ + void IndirectTab::algorithmFinished(bool error) + { + if(error) + { + emit showMessageBox("Error running algorithm. \nSee results log for details."); + } + } + +} // namespace CustomInterfaces +} // namespace Mantid diff --git a/Code/Mantid/MantidQt/CustomInterfaces/src/IndirectTransmission.cpp b/Code/Mantid/MantidQt/CustomInterfaces/src/IndirectTransmission.cpp index 2bd6e87b540b..a5b21b3d5360 100644 --- a/Code/Mantid/MantidQt/CustomInterfaces/src/IndirectTransmission.cpp +++ b/Code/Mantid/MantidQt/CustomInterfaces/src/IndirectTransmission.cpp @@ -2,6 +2,8 @@ #include +using namespace Mantid::API; + namespace MantidQt { namespace CustomInterfaces @@ -13,87 +15,122 @@ namespace CustomInterfaces IndirectTransmission::IndirectTransmission(Ui::IndirectDataReduction& uiForm, QWidget * parent) : IndirectDataReductionTab(uiForm, parent) { + // Preview plot + m_plots["PreviewPlot"] = new QwtPlot(m_parentWidget); + m_plots["PreviewPlot"]->setAxisFont(QwtPlot::xBottom, parent->font()); + m_plots["PreviewPlot"]->setAxisFont(QwtPlot::yLeft, parent->font()); + m_plots["PreviewPlot"]->setCanvasBackground(Qt::white); + m_uiForm.trans_plotPreview->addWidget(m_plots["PreviewPlot"]); + + // Update the preview plot when the algorithm is complete + connect(m_batchAlgoRunner, SIGNAL(batchComplete(bool)), this, SLOT(transAlgDone(bool))); + connect(m_uiForm.trans_dsSampleInput, SIGNAL(dataReady(QString)), this, SLOT(dataLoaded())); + connect(m_uiForm.trans_dsCanInput, SIGNAL(dataReady(QString)), this, SLOT(dataLoaded())); } - + //---------------------------------------------------------------------------------------------- /** Destructor */ IndirectTransmission::~IndirectTransmission() { - } - + void IndirectTransmission::setup() { } void IndirectTransmission::run() { - QString sampleNo = m_uiForm.transInputFile->getFirstFilename(); - QString canNo = m_uiForm.transCanFile->getFirstFilename(); - - QFileInfo finfo(sampleNo); - QString inst = finfo.baseName(); - - //flags for various algorithm options - QString verbose("False"); - QString save("False"); - QString plot("False"); - - if(m_uiForm.trans_ckVerbose->isChecked()) - { - verbose = "True"; - } - - if(m_uiForm.trans_ckSave->isChecked()) - { - save = "True"; - } - - if(m_uiForm.trans_ckPlot->isChecked()) - { - plot = "True"; - } - - QString pyInput = - "from IndirectEnergyConversion import IndirectTrans \n" - "IndirectTrans('"+inst+"','"+sampleNo+"','"+canNo+"'," - "Verbose="+verbose+"," - "Plot="+plot+"," - "Save="+save+"" - ")\n"; - - emit runAsPythonScript(pyInput, true); + QString sampleWsName = m_uiForm.trans_dsSampleInput->getCurrentDataName(); + QString canWsName = m_uiForm.trans_dsCanInput->getCurrentDataName(); + QString outWsName = sampleWsName + "_trans"; + + IAlgorithm_sptr transAlg = AlgorithmManager::Instance().create("IndirectTransmissionMonitor", -1); + transAlg->initialize(); + + transAlg->setProperty("SampleWorkspace", sampleWsName.toStdString()); + transAlg->setProperty("CanWorkspace", canWsName.toStdString()); + transAlg->setProperty("OutputWorkspace", outWsName.toStdString()); + + transAlg->setProperty("Verbose", m_uiForm.trans_ckVerbose->isChecked()); + transAlg->setProperty("Plot", m_uiForm.trans_ckPlot->isChecked()); + transAlg->setProperty("Save", m_uiForm.trans_ckSave->isChecked()); + + runAlgorithm(transAlg); } bool IndirectTransmission::validate() { + // Check if we have an appropriate instrument QString currentInst = m_uiForm.cbInst->currentText(); - - //Check if we have an appropriate instrument if(currentInst != "IRIS" && currentInst != "OSIRIS") - { return false; - } - //Check that the user has entered some file names - if(m_uiForm.transInputFile->isEmpty() - || m_uiForm.transCanFile->isEmpty()) - { + // Check for an invalid sample input + if(!m_uiForm.trans_dsSampleInput->isValid()) return false; - } - - //Check if we have a file problem - QString errorInputFile = m_uiForm.transInputFile->getFileProblem(); - QString errorCanFile = m_uiForm.transCanFile->getFileProblem(); - if(!errorInputFile.isEmpty() || !errorCanFile.isEmpty()) - { + // Check for an invalid can input + if(!m_uiForm.trans_dsCanInput->isValid()) return false; - } return true; } + void IndirectTransmission::dataLoaded() + { + if(validate()) + previewPlot(); + } + + void IndirectTransmission::previewPlot() + { + QString sampleWsName = m_uiForm.trans_dsSampleInput->getCurrentDataName(); + QString canWsName = m_uiForm.trans_dsCanInput->getCurrentDataName(); + QString outWsName = sampleWsName + "_trans"; + + IAlgorithm_sptr transAlg = AlgorithmManager::Instance().create("IndirectTransmissionMonitor", -1); + transAlg->initialize(); + + transAlg->setProperty("SampleWorkspace", sampleWsName.toStdString()); + transAlg->setProperty("CanWorkspace", canWsName.toStdString()); + transAlg->setProperty("OutputWorkspace", outWsName.toStdString()); + + transAlg->setProperty("Verbose", m_uiForm.trans_ckVerbose->isChecked()); + transAlg->setProperty("Plot", false); + transAlg->setProperty("Save", false); + + runAlgorithm(transAlg); + } + + void IndirectTransmission::transAlgDone(bool error) + { + if(error) + return; + + QString sampleWsName = m_uiForm.trans_dsSampleInput->getCurrentDataName(); + QString outWsName = sampleWsName + "_trans"; + + WorkspaceGroup_sptr resultWsGroup = AnalysisDataService::Instance().retrieveWS(outWsName.toStdString()); + std::vector resultWsNames = resultWsGroup->getNames(); + + if(resultWsNames.size() < 3) + return; + + // Plot each spectrum + plotMiniPlot(QString::fromStdString(resultWsNames[0]), 0, "PreviewPlot", "SamCurve"); + plotMiniPlot(QString::fromStdString(resultWsNames[1]), 0, "PreviewPlot", "CanCurve"); + plotMiniPlot(QString::fromStdString(resultWsNames[2]), 0, "PreviewPlot", "TransCurve"); + + // Colour plots as per plot option + m_curves["SamCurve"]->setPen(QColor(Qt::red)); + m_curves["CanCurve"]->setPen(QColor(Qt::black)); + m_curves["TransCurve"]->setPen(QColor(Qt::green)); + + // Set X range to data range + setXAxisToCurve("PreviewPlot", "TransCurve"); + m_plots["PreviewPlot"]->replot(); + } + } // namespace CustomInterfaces } // namespace Mantid diff --git a/Code/Mantid/MantidQt/CustomInterfaces/src/JumpFit.cpp b/Code/Mantid/MantidQt/CustomInterfaces/src/JumpFit.cpp index d6492b4c0293..5f50250b1995 100644 --- a/Code/Mantid/MantidQt/CustomInterfaces/src/JumpFit.cpp +++ b/Code/Mantid/MantidQt/CustomInterfaces/src/JumpFit.cpp @@ -1,3 +1,4 @@ +#include "MantidAPI/AlgorithmManager.h" #include "MantidAPI/Run.h" #include "MantidAPI/TextAxis.h" #include "MantidQtCustomInterfaces/JumpFit.h" @@ -6,23 +7,34 @@ #include #include +using namespace Mantid::API; + namespace MantidQt { namespace CustomInterfaces { - JumpFit::JumpFit(QWidget * parent) : + JumpFit::JumpFit(QWidget * parent) : IndirectBayesTab(parent) { m_uiForm.setupUi(parent); - //add the plot to the ui form - m_uiForm.plotSpace->addWidget(m_plot); - //add the properties browser to the ui form + // Create the plot + m_plots["JumpFitPlot"] = new QwtPlot(m_parentWidget); + m_plots["JumpFitPlot"]->setCanvasBackground(Qt::white); + m_plots["JumpFitPlot"]->setAxisFont(QwtPlot::xBottom, parent->font()); + m_plots["JumpFitPlot"]->setAxisFont(QwtPlot::yLeft, parent->font()); + m_uiForm.plotSpace->addWidget(m_plots["JumpFitPlot"]); + + // Create range selector + m_rangeSelectors["JumpFitQ"] = new MantidWidgets::RangeSelector(m_plots["JumpFitPlot"]); + connect(m_rangeSelectors["JumpFitQ"], SIGNAL(selectionChangedLazy(double, double)), this, SLOT(qRangeChanged(double, double))); + + // Add the properties browser to the ui form m_uiForm.treeSpace->addWidget(m_propTree); m_properties["QMin"] = m_dblManager->addProperty("QMin"); m_properties["QMax"] = m_dblManager->addProperty("QMax"); - + m_dblManager->setDecimals(m_properties["QMin"], NUM_DECIMALS); m_dblManager->setDecimals(m_properties["QMax"], NUM_DECIMALS); @@ -35,11 +47,18 @@ namespace MantidQt connect(m_uiForm.dsSample, SIGNAL(dataReady(const QString&)), this, SLOT(handleSampleInputReady(const QString&))); // Connect width selector to handler method connect(m_uiForm.cbWidth, SIGNAL(currentIndexChanged(const QString&)), this, SLOT(handleWidthChange(const QString&))); + + // Connect algorithm runner to completion handler function + connect(m_batchAlgoRunner, SIGNAL(batchComplete(bool)), this, SLOT(fitAlgDone(bool))); } + void JumpFit::setup() + { + } + /** * Validate the form to check the program can be run - * + * * @return :: Whether the form was valid */ bool JumpFit::validate() @@ -48,7 +67,7 @@ namespace MantidQt uiv.checkDataSelectorIsValid("Sample", m_uiForm.dsSample); //this workspace doesn't have any valid widths - if(spectraList.size() == 0) + if(m_spectraList.size() == 0) { uiv.addErrorMessage("Input workspace doesn't appear to contain any width data."); } @@ -67,58 +86,118 @@ namespace MantidQt * Collect the settings on the GUI and build a python * script that runs JumpFit */ - void JumpFit::run() + void JumpFit::run() { - QString verbose("False"); - QString plot("False"); - QString save("False"); - - QString sample = m_uiForm.dsSample->getCurrentDataName(); + bool verbose = m_uiForm.chkVerbose->isChecked(); + bool save = m_uiForm.chkSave->isChecked(); + bool plot = m_uiForm.chkPlot->isChecked(); + + runImpl(verbose, plot, save); + } - //fit function to use - QString fitFunction("CE"); + /** + * Runs the JumpFit algorithm with preview parameters to update the preview plot. + */ + void JumpFit::runPreviewAlgorithm() + { + runImpl(); + } + + /** + * Runs algorithm. + * + * @param verbose Enable/disable verbose option + * @param plot Enable/disable plotting + * @param save Enable/disable saving + */ + void JumpFit::runImpl(bool verbose, bool plot, bool save) + { + // Do noting with invalid data + if(!m_uiForm.dsSample->isValid()) + return; + + // Fit function to use + QString fitFunction("ChudleyElliot"); switch(m_uiForm.cbFunction->currentIndex()) { case 0: - fitFunction = "CE"; // Use Chudley-Elliott + fitFunction = "ChudleyElliot"; break; case 1: fitFunction = "HallRoss"; break; case 2: - fitFunction = "Fick"; + fitFunction = "FickDiffusion"; break; case 3: - fitFunction = "Teixeira"; + fitFunction = "TeixeiraWater"; break; } + // Loaded workspace name + QString sample = m_uiForm.dsSample->getCurrentDataName(); + auto ws = Mantid::API::AnalysisDataService::Instance().retrieve(sample.toStdString()); + std::string widthText = m_uiForm.cbWidth->currentText().toStdString(); - int width = spectraList[widthText]; - QString widthTxt = boost::lexical_cast(width).c_str(); + long width = m_spectraList[widthText]; - // Cropping values - QString QMin = m_properties["QMin"]->valueText(); - QString QMax = m_properties["QMax"]->valueText(); + fitAlg = AlgorithmManager::Instance().create("JumpFit"); + fitAlg->initialize(); - //output options - if(m_uiForm.chkVerbose->isChecked()) { verbose = "True"; } - if(m_uiForm.chkSave->isChecked()) { save = "True"; } - if(m_uiForm.chkPlot->isChecked()) { plot = "True"; } + fitAlg->setProperty("InputWorkspace", ws); + fitAlg->setProperty("Function", fitFunction.toStdString()); - QString pyInput = - "from IndirectJumpFit import JumpRun\n"; + fitAlg->setProperty("Width", width); + fitAlg->setProperty("QMin", m_dblManager->value(m_properties["QMin"])); + fitAlg->setProperty("QMax", m_dblManager->value(m_properties["QMax"])); - pyInput += "JumpRun('"+sample+"','"+fitFunction+"',"+widthTxt+","+QMin+","+QMax+"," - "Save="+save+", Plot="+plot+", Verbose="+verbose+")\n"; + fitAlg->setProperty("Verbose", verbose); + fitAlg->setProperty("Plot", plot); + fitAlg->setProperty("Save", save); - runPythonScript(pyInput); - } + if(m_batchAlgoRunner->queueLength() < 1) + runAlgorithm(fitAlg); + } + + /** + * Handles the JumpFit algorithm finishing, used to plot fit in miniplot. + * + * @param error True if the algorithm failed, false otherwise + */ + void JumpFit::fitAlgDone(bool error) + { + // Ignore errors + if(error) + return; + + std::string outWsName = fitAlg->getPropertyValue("Output") + "_Workspace"; + MatrixWorkspace_sptr outputWorkspace = AnalysisDataService::Instance().retrieveWS(outWsName); + TextAxis* axis = dynamic_cast(outputWorkspace->getAxis(1)); + + for(unsigned int histIndex = 0; histIndex < outputWorkspace->getNumberHistograms(); histIndex++) + { + QString specName = QString::fromStdString(axis->label(histIndex)); + + if(specName == "Calc") + { + plotMiniPlot(outputWorkspace, histIndex, "JumpFitPlot", specName); + m_curves[specName]->setPen(QColor(Qt::red)); + } + + if(specName == "Diff") + { + plotMiniPlot(outputWorkspace, histIndex, "JumpFitPlot", specName); + m_curves[specName]->setPen(QColor(Qt::green)); + } + } + + replot("JumpFitPlot"); + } /** * Set the data selectors to use the default save directory * when browsing for input files. - * + * * @param settings :: The current settings */ void JumpFit::loadSettings(const QSettings& settings) @@ -129,61 +208,78 @@ namespace MantidQt /** * Plots the loaded file to the miniplot and sets the guides * and the range - * + * * @param filename :: The name of the workspace to plot */ void JumpFit::handleSampleInputReady(const QString& filename) { + // Disable things that run the preview algorithm + disconnect(m_dblManager, SIGNAL(valueChanged(QtProperty*, double)), this, SLOT(runPreviewAlgorithm())); + disconnect(m_uiForm.cbFunction, SIGNAL(currentIndexChanged(const QString&)), this, SLOT(runPreviewAlgorithm())); + disconnect(m_uiForm.cbWidth, SIGNAL(currentIndexChanged(const QString&)), this, SLOT(runPreviewAlgorithm())); + + // Scale to convert to HWHM + IAlgorithm_sptr scaleAlg = AlgorithmManager::Instance().create("Scale"); + scaleAlg->initialize(); + scaleAlg->setProperty("InputWorkspace", filename.toStdString()); + scaleAlg->setProperty("OutputWorkspace", filename.toStdString()); + scaleAlg->setProperty("Factor", 0.5); + scaleAlg->execute(); auto ws = Mantid::API::AnalysisDataService::Instance().retrieve(filename.toStdString()); auto mws = boost::dynamic_pointer_cast(ws); findAllWidths(mws); - - if(spectraList.size() > 0) + + if(m_spectraList.size() > 0) { m_uiForm.cbWidth->setEnabled(true); std::string currentWidth = m_uiForm.cbWidth->currentText().toStdString(); - plotMiniPlot(filename, spectraList[currentWidth]); + plotMiniPlot(filename, m_spectraList[currentWidth], "JumpFitPlot", "RawPlotCurve"); + std::pair res; - std::pair range = getCurveRange(); + std::pair range = getCurveRange("RawPlotCurve"); - //Use the values from the instrument parameter file if we can + // Use the values from the instrument parameter file if we can if(getInstrumentResolution(filename, res)) - { - setMiniPlotGuides(m_properties["QMin"], m_properties["QMax"], res); - } + setMiniPlotGuides("JumpFitQ", m_properties["QMin"], m_properties["QMax"], res); else - { - setMiniPlotGuides(m_properties["QMin"], m_properties["QMax"], range); - } + setMiniPlotGuides("JumpFitQ", m_properties["QMin"], m_properties["QMax"], range); - setPlotRange(m_properties["QMin"], m_properties["QMax"], range); + setPlotRange("JumpFitQ", m_properties["QMin"], m_properties["QMax"], range); } else { m_uiForm.cbWidth->setEnabled(false); emit showMessageBox("Workspace doesn't appear to contain any width data"); } + + // Update preview plot + runPreviewAlgorithm(); + + // Re-enable things that run the preview algorithm + connect(m_dblManager, SIGNAL(valueChanged(QtProperty*, double)), this, SLOT(runPreviewAlgorithm())); + connect(m_uiForm.cbFunction, SIGNAL(currentIndexChanged(const QString&)), this, SLOT(runPreviewAlgorithm())); + connect(m_uiForm.cbWidth, SIGNAL(currentIndexChanged(const QString&)), this, SLOT(runPreviewAlgorithm())); } /** - * Find all of the spectra in the workspace that have width data - * + * Find all of the spectra in the workspace that have width data + * * @param ws :: The workspace to search */ void JumpFit::findAllWidths(Mantid::API::MatrixWorkspace_const_sptr ws) { m_uiForm.cbWidth->clear(); - spectraList.clear(); + m_spectraList.clear(); for (size_t i = 0; i < ws->getNumberHistograms(); ++i) { auto axis = dynamic_cast(ws->getAxis(1)); std::string title = axis->label(i); - //check if the axis labels indicate this spectrum is width data + //check if the axis labels indicate this spectrum is width data size_t qLinesWidthIndex = title.find(".Width"); size_t convFitWidthIndex = title.find(".FWHM"); @@ -195,7 +291,7 @@ namespace MantidQt { std::string cbItemName = ""; size_t substrIndex = 0; - + if (qLinesWidth) { substrIndex = qLinesWidthIndex; @@ -206,9 +302,9 @@ namespace MantidQt } cbItemName = title.substr(0, substrIndex); - spectraList[cbItemName] = static_cast(i); + m_spectraList[cbItemName] = static_cast(i); m_uiForm.cbWidth->addItem(QString(cbItemName.c_str())); - + //display widths f1.f1, f2.f1 and f2.f2 if (m_uiForm.cbWidth->count() == 3) { @@ -220,7 +316,7 @@ namespace MantidQt /** * Plots the loaded file to the miniplot when the selected spectrum changes - * + * * @param text :: The name spectrum index to plot */ void JumpFit::handleWidthChange(const QString& text) @@ -228,33 +324,25 @@ namespace MantidQt QString sampleName = m_uiForm.dsSample->getCurrentDataName(); QString samplePath = m_uiForm.dsSample->getFullFilePath(); - if(!sampleName.isEmpty() && spectraList.size() > 0) + if(!sampleName.isEmpty() && m_spectraList.size() > 0) { if(validate()) { - plotMiniPlot(sampleName, spectraList[text.toStdString()]); + plotMiniPlot(sampleName, m_spectraList[text.toStdString()], "JumpFitPlot", "RawPlotCurve"); } } } /** - * Updates the property manager when the lower guide is moved on the mini plot + * Updates the property manager when the range selector is moved on the mini plot. * * @param min :: The new value of the lower guide - */ - void JumpFit::minValueChanged(double min) - { - m_dblManager->setValue(m_properties["QMin"], min); - } - - /** - * Updates the property manager when the upper guide is moved on the mini plot - * * @param max :: The new value of the upper guide */ - void JumpFit::maxValueChanged(double max) + void JumpFit::qRangeChanged(double min, double max) { - m_dblManager->setValue(m_properties["QMax"], max); + m_dblManager->setValue(m_properties["QMin"], min); + m_dblManager->setValue(m_properties["QMax"], max); } /** @@ -267,11 +355,11 @@ namespace MantidQt { if(prop == m_properties["QMin"]) { - updateLowerGuide(m_properties["QMin"], m_properties["QMax"], val); + updateLowerGuide(m_rangeSelectors["JumpFitQ"], m_properties["QMin"], m_properties["QMax"], val); } else if (prop == m_properties["QMax"]) { - updateUpperGuide(m_properties["QMin"], m_properties["QMax"], val); + updateUpperGuide(m_rangeSelectors["JumpFitQ"], m_properties["QMin"], m_properties["QMax"], val); } } } // namespace CustomInterfaces diff --git a/Code/Mantid/MantidQt/CustomInterfaces/src/MSDFit.cpp b/Code/Mantid/MantidQt/CustomInterfaces/src/MSDFit.cpp index 9d0f589b4912..226cd5965c33 100644 --- a/Code/Mantid/MantidQt/CustomInterfaces/src/MSDFit.cpp +++ b/Code/Mantid/MantidQt/CustomInterfaces/src/MSDFit.cpp @@ -168,13 +168,13 @@ namespace IDA auto ws = Mantid::API::AnalysisDataService::Instance().retrieveWS(wsname.toStdString()); int nHist = static_cast(ws->getNumberHistograms()); - QString plotSpec =uiForm().msd_lePlotSpectrum->text(); + QString plotSpec = uiForm().msd_lePlotSpectrum->text(); QString specMin = uiForm().msd_leSpectraMin->text(); QString specMax = uiForm().msd_leSpectraMax->text(); int wsIndex = 0; int minIndex = 0; - int maxIndex = nHist-1; + int maxIndex = nHist - 1; if (currentWsName == wsname) { @@ -213,7 +213,7 @@ namespace IDA uiForm().msd_leSpectraMax->setText(QString::number(maxIndex)); uiForm().msd_lePlotSpectrum->setText(QString::number(wsIndex)); - m_intVal->setRange(0, nHist-1); + m_intVal->setRange(0, maxIndex); //delete reference to fitting. if (m_msdFitCurve != NULL) diff --git a/Code/Mantid/MantidQt/CustomInterfaces/src/Muon/MuonAnalysis.cpp b/Code/Mantid/MantidQt/CustomInterfaces/src/Muon/MuonAnalysis.cpp index 024a53d8898f..dc2156083ef3 100644 --- a/Code/Mantid/MantidQt/CustomInterfaces/src/Muon/MuonAnalysis.cpp +++ b/Code/Mantid/MantidQt/CustomInterfaces/src/Muon/MuonAnalysis.cpp @@ -12,7 +12,6 @@ #include "MantidGeometry/IComponent.h" #include "MantidGeometry/IDetector.h" #include "MantidGeometry/Instrument/DetectorGroup.h" -#include "MantidGeometry/Instrument/XMLlogfile.h" #include "MantidKernel/ConfigService.h" #include "MantidKernel/Exception.h" #include "MantidKernel/Exception.h" diff --git a/Code/Mantid/MantidQt/CustomInterfaces/src/QReflTableModel.cpp b/Code/Mantid/MantidQt/CustomInterfaces/src/QReflTableModel.cpp index 1352779a3641..a56ca43d1083 100644 --- a/Code/Mantid/MantidQt/CustomInterfaces/src/QReflTableModel.cpp +++ b/Code/Mantid/MantidQt/CustomInterfaces/src/QReflTableModel.cpp @@ -10,12 +10,13 @@ namespace MantidQt const QString QReflTableModel::RUNS = "Run(s)"; const QString QReflTableModel::ANGLE = "Angle"; - const QString QReflTableModel::TRANSMISSION = "Transmission"; - const QString QReflTableModel::QMIN = "q_min"; - const QString QReflTableModel::QMAX = "q_max"; - const QString QReflTableModel::DQQ = "dq/q"; + const QString QReflTableModel::TRANSMISSION = "Transmission Run(s)"; + const QString QReflTableModel::QMIN = "Q min"; + const QString QReflTableModel::QMAX = "Q max"; + const QString QReflTableModel::DQQ = "dQ/Q"; const QString QReflTableModel::SCALE = "Scale"; const QString QReflTableModel::GROUP = "Group"; + const QString QReflTableModel::OPTIONS = "Options"; const int QReflTableModel::COL_RUNS(0); const int QReflTableModel::COL_ANGLE(1); @@ -25,6 +26,7 @@ namespace MantidQt const int QReflTableModel::COL_DQQ(5); const int QReflTableModel::COL_SCALE(6); const int QReflTableModel::COL_GROUP(7); + const int QReflTableModel::COL_OPTIONS(8); //---------------------------------------------------------------------------------------------- /** Constructor @@ -40,6 +42,7 @@ namespace MantidQt m_columnNameMap.insert(std::make_pair(COL_DQQ, DQQ)); m_columnNameMap.insert(std::make_pair(COL_SCALE, SCALE)); m_columnNameMap.insert(std::make_pair(COL_GROUP, GROUP)); + m_columnNameMap.insert(std::make_pair(COL_OPTIONS, OPTIONS)); } //---------------------------------------------------------------------------------------------- @@ -56,7 +59,7 @@ namespace MantidQt void QReflTableModel::invalidateDataCache(const int row) const { //If the row is in the cache, invalidate the cache. - if(row == m_dataCachePeakIndex) + if(row == m_dataCachePeakIndex || row == -1) m_dataCachePeakIndex = -1; } @@ -80,8 +83,9 @@ namespace MantidQt m_dataCache.push_back(QString::fromStdString(tableRow.cell(COL_QMIN))); m_dataCache.push_back(QString::fromStdString(tableRow.cell(COL_QMAX))); m_dataCache.push_back(QString::fromStdString(tableRow.cell(COL_DQQ))); - m_dataCache.push_back(QString::fromStdString(tableRow.cell(COL_SCALE))); + m_dataCache.push_back(QString::number(tableRow.cell(COL_SCALE))); m_dataCache.push_back(QString::number(tableRow.cell(COL_GROUP))); + m_dataCache.push_back(QString::fromStdString(tableRow.cell(COL_OPTIONS))); m_dataCachePeakIndex = row; } @@ -131,11 +135,14 @@ namespace MantidQt */ QVariant QReflTableModel::data(const QModelIndex &index, int role) const { - if (role == Qt::TextAlignmentRole) + if(role == Qt::TextAlignmentRole) { - return Qt::AlignRight; + if(index.column() == COL_OPTIONS) + return Qt::AlignLeft; + else + return Qt::AlignRight; } - else if( role != Qt::DisplayRole && role != Qt::EditRole) + else if(role != Qt::DisplayRole && role != Qt::EditRole) { return QVariant(); } @@ -163,13 +170,14 @@ namespace MantidQt const int colNumber = index.column(); const int rowNumber = index.row(); - if (colNumber == COL_GROUP) - { - m_tWS->Int(rowNumber, COL_GROUP) = str.toInt(); - } - else + switch(colNumber) { - m_tWS->String(rowNumber, colNumber) = str.toStdString(); + case COL_GROUP: + m_tWS->Int(rowNumber, COL_GROUP) = str.toInt(); break; + case COL_SCALE: + m_tWS->Double(rowNumber, COL_SCALE) = str.toDouble(); break; + default: + m_tWS->String(rowNumber, colNumber) = str.toStdString(); break; } invalidateDataCache(rowNumber); @@ -189,17 +197,97 @@ namespace MantidQt */ QVariant QReflTableModel::headerData(int section, Qt::Orientation orientation, int role) const { - if (role != Qt::DisplayRole) - return QVariant(); - - if (orientation == Qt::Horizontal) + if(role == Qt::WhatsThisRole && orientation == Qt::Horizontal) { - return findColumnName(section); + switch(section) + { + case COL_RUNS: + return QString( + "Sample runs to be processed.
" + "required
" + "Runs may be given as run numbers or workspace names. " + "Multiple runs may be added together by separating them with a '+'. " + "

Example: 1234+1235+1236" + ); + case COL_ANGLE: + return QString( + "Angle used during the run.
" + "optional
" + "Unit: degrees
" + "If left blank, this is set to the last value for 'THETA' in the run's sample log. " + "If multiple runs were given in the Run(s) column, the first listed run's sample log will be used. " + "

Example: 0.7" + ); + case COL_TRANSMISSION: + return QString( + "Transmission run(s) to use to normalise the sample runs.
" + "optional
" + "To specify two transmission runs, separate them with a comma. " + "If left blank, the sample runs will be normalised by monitor only." + "

Example: 1234,12345" + ); + case COL_QMIN: + return QString( + "Minimum value of Q to be used
" + "optional
" + "Unit: Å-1
" + "Data with a value of Q lower than this will be discarded. " + "If left blank, this is set to the lowest Q value found. " + "This is useful for discarding noisy data. " + "

Example: 0.1" + ); + case COL_QMAX: + return QString( + "Maximum value of Q to be used
" + "optional
" + "Unit: Å-1
" + "Data with a value of Q higher than this will be discarded. " + "If left blank, this is set to the highest Q value found. " + "This is useful for discarding noisy data. " + "

Example: 0.9" + ); + case COL_DQQ: + return QString( + "Resolution used when rebinning
" + "optional
" + "If left blank, this is calculated for you using the CalculateResolution algorithm. " + "

Example: 0.9" + ); + case COL_SCALE: + return QString( + "Scaling factor
" + "required
" + "The created IvsQ workspaces will be Scaled by 1/i where i is the value of this column." + "

Example: 1" + ); + case COL_GROUP: + return QString( + "Grouping for stitching
" + "required
" + "The value of this column determines which other rows this row's output will be stitched with. " + "All rows with the same group number are stitched together. " + ); + case COL_OPTIONS: + return QString( + "Override ReflectometryReductionOneAuto properties
" + "optional
" + "This column allows you to override the properties used when executing ReflectometryReductionOneAuto. " + "Options are given as key=value pairs, separated by commas. " + "Values containing commas must be quoted." + "

Example: StrictSpectrumChecking=0, RegionOfDirectBeam=\"0,2\", Params=\"1,2,3\"" + ); + default: + return QVariant(); + } } - else if (orientation == Qt::Vertical) + else if(role == Qt::DisplayRole) { - return QString::number(section + 1); + if(orientation == Qt::Horizontal) + return findColumnName(section); + if(orientation == Qt::Vertical) + return QString::number(section + 1); } + return QVariant(); } @@ -213,5 +301,51 @@ namespace MantidQt return Qt::ItemIsEnabled | Qt::ItemIsSelectable | Qt::ItemIsEditable; } + /** + Insert the given number of rows at the specified position + @param row : The row to insert before + @param count : The number of rows to insert + @param parent : The parent index + */ + bool QReflTableModel::insertRows(int row, int count, const QModelIndex& parent) + { + if(count < 1) + return true; + + if(row < 0) + return false; + + beginInsertRows(parent, row, row + count - 1); + for(int i = 0; i < count; ++i) + m_tWS->insertRow(row + i); + endInsertRows(); + + invalidateDataCache(-1); + return true; + } + + /** + Remove the given number of rows from the specified position + @param row : The row index to remove from + @param count : The number of rows to remove + @param parent : The parent index + */ + bool QReflTableModel::removeRows(int row, int count, const QModelIndex& parent) + { + if(count < 1) + return true; + + if(row < 0) + return false; + + beginRemoveRows(parent, row, row + count - 1); + for(int i = 0; i < count; ++i) + m_tWS->removeRow(row); + endRemoveRows(); + + invalidateDataCache(-1); + return true; + } + } // namespace CustomInterfaces } // namespace Mantid diff --git a/Code/Mantid/MantidQt/CustomInterfaces/src/QtReflMainView.cpp b/Code/Mantid/MantidQt/CustomInterfaces/src/QtReflMainView.cpp index da5087459d2d..ffb8bd3b27bc 100644 --- a/Code/Mantid/MantidQt/CustomInterfaces/src/QtReflMainView.cpp +++ b/Code/Mantid/MantidQt/CustomInterfaces/src/QtReflMainView.cpp @@ -1,10 +1,9 @@ #include "MantidQtCustomInterfaces/QtReflMainView.h" #include "MantidQtCustomInterfaces/QReflTableModel.h" -#include "MantidQtCustomInterfaces/ReflNullMainViewPresenter.h" #include "MantidQtCustomInterfaces/ReflMainViewPresenter.h" -#include "MantidQtCustomInterfaces/ReflBlankMainViewPresenter.h" -#include "MantidQtCustomInterfaces/ReflLoadedMainViewPresenter.h" +#include "MantidQtMantidWidgets/HintingLineEditFactory.h" #include "MantidAPI/ITableWorkspace.h" +#include "MantidKernel/ConfigService.h" #include #include @@ -19,7 +18,7 @@ namespace MantidQt //---------------------------------------------------------------------------------------------- /** Constructor */ - QtReflMainView::QtReflMainView(QWidget *parent) : UserSubWindow(parent), m_presenter(new ReflNullMainViewPresenter()) + QtReflMainView::QtReflMainView(QWidget *parent) : UserSubWindow(parent), m_openMap(new QSignalMapper(this)) { } @@ -36,29 +35,27 @@ namespace MantidQt void QtReflMainView::initLayout() { ui.setupUi(this); - ui.workspaceSelector->refresh(); + + ui.buttonProcess->setDefaultAction(ui.actionProcess); + ui.buttonTransfer->setDefaultAction(ui.actionTransfer); + + //Create a whats this button + ui.rowToolBar->addAction(QWhatsThis::createAction(this)); //Expand the process runs column at the expense of the search column ui.splitterTables->setStretchFactor(0, 0); ui.splitterTables->setStretchFactor(1, 1); - connect(ui.workspaceSelector,SIGNAL(activated(QString)),this,SLOT(setModel(QString))); - connect(ui.buttonSave, SIGNAL(clicked()),this, SLOT(saveButton())); - connect(ui.buttonSaveAs, SIGNAL(clicked()),this, SLOT(saveAsButton())); - connect(ui.buttonNew, SIGNAL(clicked()),this, SLOT(setNew())); - connect(ui.buttonAddRow, SIGNAL(clicked()),this, SLOT(addRowButton())); - connect(ui.buttonDeleteRow, SIGNAL(clicked()),this, SLOT(deleteRowButton())); - connect(ui.buttonProcess, SIGNAL(clicked()),this, SLOT(processButton())); - setNew(); - } + //Allow rows and columns to be reordered + ui.viewTable->verticalHeader()->setMovable(true); + ui.viewTable->horizontalHeader()->setMovable(true); - /** - This slot loads a blank table and changes to a BlankMainView presenter - */ - void QtReflMainView::setNew() - { - boost::scoped_ptr newPtr(new ReflBlankMainViewPresenter(this)); - m_presenter.swap(newPtr); + //Custom context menu for table + connect(ui.viewTable, SIGNAL(customContextMenuRequested(const QPoint&)), this, SLOT(showContextMenu(const QPoint&))); + connect(ui.tableSearchResults, SIGNAL(customContextMenuRequested(const QPoint&)), this, SLOT(showSearchContextMenu(const QPoint&))); + + //Finally, create a presenter to do the thinking for us + m_presenter = boost::shared_ptr(new ReflMainViewPresenter(this)); } /** @@ -67,59 +64,251 @@ namespace MantidQt */ void QtReflMainView::setModel(QString name) { - boost::scoped_ptr newPtr(new ReflLoadedMainViewPresenter(name.toStdString(), this)); - m_presenter.swap(newPtr); - m_presenter->notify(NoFlags); + m_toOpen = name.toStdString(); + m_presenter->notify(IReflPresenter::OpenTableFlag); } /** Set a new model in the tableview @param model : the model to be attached to the tableview */ - void QtReflMainView::showTable(ITableWorkspace_sptr model) + void QtReflMainView::showTable(QReflTableModel_sptr model) { - ui.viewTable->setModel(new QReflTableModel(model)); + m_model = model; + //So we can notify the presenter when the user updates the table + connect(m_model.get(), SIGNAL(dataChanged(const QModelIndex&, const QModelIndex&)), this, SLOT(tableUpdated(const QModelIndex&, const QModelIndex&))); + ui.viewTable->setModel(m_model.get()); ui.viewTable->resizeColumnsToContents(); } + /** + Set a new model for search results + @param model : the model to be attached to the search results + */ + void QtReflMainView::showSearch(ReflSearchModel_sptr model) + { + m_searchModel = model; + ui.tableSearchResults->setModel(m_searchModel.get()); + ui.tableSearchResults->resizeColumnsToContents(); + } + + /** + Set the list of tables the user is offered to open + @param tables : the names of the tables in the ADS + */ + void QtReflMainView::setTableList(const std::set& tables) + { + ui.menuOpenTable->clear(); + + for(auto it = tables.begin(); it != tables.end(); ++it) + { + QAction* openTable = ui.menuOpenTable->addAction(QString::fromStdString(*it)); + openTable->setIcon(QIcon("://worksheet.png")); + + //Map this action to the table name + m_openMap->setMapping(openTable, QString::fromStdString(*it)); + + connect(openTable, SIGNAL(triggered()), m_openMap, SLOT(map())); + connect(m_openMap, SIGNAL(mapped(QString)), this, SLOT(setModel(QString))); + } + } + /** This slot notifies the presenter that the "save" button has been pressed */ - void QtReflMainView::saveButton() + void QtReflMainView::on_actionSaveTable_triggered() { - m_presenter->notify(SaveFlag); + m_presenter->notify(IReflPresenter::SaveFlag); } /** This slot notifies the presenter that the "save as" button has been pressed */ - void QtReflMainView::saveAsButton() + void QtReflMainView::on_actionSaveTableAs_triggered() + { + m_presenter->notify(IReflPresenter::SaveAsFlag); + } + + /** + This slot notifies the presenter that the "append row" button has been pressed + */ + void QtReflMainView::on_actionAppendRow_triggered() { - m_presenter->notify(SaveAsFlag); + m_presenter->notify(IReflPresenter::AppendRowFlag); } /** - This slot notifies the presenter that the "add row" button has been pressed + This slot notifies the presenter that the "prepend row" button has been pressed */ - void QtReflMainView::addRowButton() + void QtReflMainView::on_actionPrependRow_triggered() { - m_presenter->notify(AddRowFlag); + m_presenter->notify(IReflPresenter::PrependRowFlag); } /** This slot notifies the presenter that the "delete" button has been pressed */ - void QtReflMainView::deleteRowButton() + void QtReflMainView::on_actionDeleteRow_triggered() { - m_presenter->notify(DeleteRowFlag); + m_presenter->notify(IReflPresenter::DeleteRowFlag); } /** This slot notifies the presenter that the "process" button has been pressed */ - void QtReflMainView::processButton() + void QtReflMainView::on_actionProcess_triggered() + { + m_presenter->notify(IReflPresenter::ProcessFlag); + } + + /** + This slot notifies the presenter that the "group rows" button has been pressed + */ + void QtReflMainView::on_actionGroupRows_triggered() + { + m_presenter->notify(IReflPresenter::GroupRowsFlag); + } + + /** + This slot notifies the presenter that the "clear selected" button has been pressed + */ + void QtReflMainView::on_actionClearSelected_triggered() + { + m_presenter->notify(IReflPresenter::ClearSelectedFlag); + } + + /** + This slot notifies the presenter that the "copy selection" button has been pressed + */ + void QtReflMainView::on_actionCopySelected_triggered() + { + m_presenter->notify(IReflPresenter::CopySelectedFlag); + } + + /** + This slot notifies the presenter that the "cut selection" button has been pressed + */ + void QtReflMainView::on_actionCutSelected_triggered() + { + m_presenter->notify(IReflPresenter::CutSelectedFlag); + } + + /** + This slot notifies the presenter that the "paste selection" button has been pressed + */ + void QtReflMainView::on_actionPasteSelected_triggered() + { + m_presenter->notify(IReflPresenter::PasteSelectedFlag); + } + + /** + This slot notifies the presenter that the "new table" button has been pressed + */ + void QtReflMainView::on_actionNewTable_triggered() + { + m_presenter->notify(IReflPresenter::NewTableFlag); + } + + /** + This slot notifies the presenter that the "expand selection" button has been pressed + */ + void QtReflMainView::on_actionExpandSelection_triggered() + { + m_presenter->notify(IReflPresenter::ExpandSelectionFlag); + } + + /** + This slot notifies the presenter that the "options..." button has been pressed + */ + void QtReflMainView::on_actionOptionsDialog_triggered() + { + m_presenter->notify(IReflPresenter::OptionsDialogFlag); + } + + /** + This slot notifies the presenter that the "search" button has been pressed + */ + void QtReflMainView::on_actionSearch_triggered() + { + m_presenter->notify(IReflPresenter::SearchFlag); + } + + /** + This slot notifies the presenter that the "transfer" button has been pressed + */ + void QtReflMainView::on_actionTransfer_triggered() + { + m_presenter->notify(IReflPresenter::TransferFlag); + } + + /** + This slot notifies the presenter that the "export table" button has been pressed + */ + void QtReflMainView::on_actionExportTable_triggered() + { + m_presenter->notify(IReflPresenter::ExportTableFlag); + } + + /** + This slot notifies the presenter that the "import table" button has been pressed + */ + void QtReflMainView::on_actionImportTable_triggered() + { + m_presenter->notify(IReflPresenter::ImportTableFlag); + } + + /** + This slot notifies the presenter that the table has been updated/changed by the user + */ + void QtReflMainView::tableUpdated(const QModelIndex& topLeft, const QModelIndex& bottomRight) + { + Q_UNUSED(topLeft); + Q_UNUSED(bottomRight); + m_presenter->notify(IReflPresenter::TableUpdatedFlag); + } + + /** + This slot is triggered when the user right clicks on the table + @param pos : The position of the right click within the table + */ + void QtReflMainView::showContextMenu(const QPoint& pos) { - m_presenter->notify(ProcessFlag); + //If the user didn't right-click on anything, don't show a context menu. + if(!ui.viewTable->indexAt(pos).isValid()) + return; + + //parent widget takes ownership of QMenu + QMenu* menu = new QMenu(this); + menu->addAction(ui.actionProcess); + menu->addAction(ui.actionExpandSelection); + menu->addSeparator(); + menu->addAction(ui.actionPrependRow); + menu->addAction(ui.actionAppendRow); + menu->addSeparator(); + menu->addAction(ui.actionGroupRows); + menu->addAction(ui.actionCopySelected); + menu->addAction(ui.actionCutSelected); + menu->addAction(ui.actionPasteSelected); + menu->addAction(ui.actionClearSelected); + menu->addSeparator(); + menu->addAction(ui.actionDeleteRow); + + menu->popup(ui.viewTable->viewport()->mapToGlobal(pos)); + } + + /** + This slot is triggered when the user right clicks on the search results table + @param pos : The position of the right click within the table + */ + void QtReflMainView::showSearchContextMenu(const QPoint& pos) + { + if(!ui.tableSearchResults->indexAt(pos).isValid()) + return; + + //parent widget takes ownership of QMenu + QMenu* menu = new QMenu(this); + menu->addAction(ui.actionTransfer); + menu->popup(ui.tableSearchResults->viewport()->mapToGlobal(pos)); } /** @@ -184,20 +373,177 @@ namespace MantidQt return ""; } + /** + Show the user the dialog for an algorithm + */ + void QtReflMainView::showAlgorithmDialog(const std::string& algorithm) + { + std::stringstream pythonSrc; + pythonSrc << "try:\n"; + pythonSrc << " " << algorithm << "Dialog()\n"; + pythonSrc << "except:\n"; + pythonSrc << " pass\n"; + runPythonCode(QString::fromStdString(pythonSrc.str())); + } + + /** + Set the range of the progress bar + @param min : The minimum value of the bar + @param max : The maxmimum value of the bar + */ + void QtReflMainView::setProgressRange(int min, int max) + { + ui.progressBar->setRange(min, max); + } + + /** + Set the status of the progress bar + @param progress : The current value of the bar + */ + void QtReflMainView::setProgress(int progress) + { + ui.progressBar->setValue(progress); + } + + /** + Set which rows are selected + @param rows : The set of rows to select + */ + void QtReflMainView::setSelection(const std::set& rows) + { + ui.viewTable->clearSelection(); + auto selectionModel = ui.viewTable->selectionModel(); + + for(auto row = rows.begin(); row != rows.end(); ++row) + selectionModel->select(ui.viewTable->model()->index((*row), 0), QItemSelectionModel::Select | QItemSelectionModel::Rows); + } + + /** + Set the list of available instruments to search and process for + @param instruments : The list of instruments available + @param defaultInstrument : The instrument to have selected by default + */ + void QtReflMainView::setInstrumentList(const std::vector& instruments, const std::string& defaultInstrument) + { + ui.comboSearchInstrument->clear(); + ui.comboProcessInstrument->clear(); + + for(auto it = instruments.begin(); it != instruments.end(); ++it) + { + QString instrument = QString::fromStdString(*it); + ui.comboSearchInstrument->addItem(instrument); + ui.comboProcessInstrument->addItem(instrument); + } + + int index = ui.comboSearchInstrument->findData(QString::fromStdString(defaultInstrument), Qt::DisplayRole); + ui.comboSearchInstrument->setCurrentIndex(index); + ui.comboProcessInstrument->setCurrentIndex(index); + } + + /** + Set the strategy used for generating hints for the autocompletion in the options column. + @param hintStrategy The hinting strategy to use + */ + void QtReflMainView::setOptionsHintStrategy(HintStrategy* hintStrategy) + { + ui.viewTable->setItemDelegateForColumn(ReflMainViewPresenter::COL_OPTIONS, new HintingLineEditFactory(hintStrategy)); + } + + /** + Sets the contents of the system's clipboard + @param text The contents of the clipboard + */ + void QtReflMainView::setClipboard(const std::string& text) + { + QApplication::clipboard()->setText(QString::fromStdString(text)); + } + + /** + Get the selected instrument for searching + @returns the selected instrument to search for + */ + std::string QtReflMainView::getSearchInstrument() const + { + return ui.comboSearchInstrument->currentText().toStdString(); + } + + /** + Get the selected instrument for processing + @returns the selected instrument to process with + */ + std::string QtReflMainView::getProcessInstrument() const + { + return ui.comboProcessInstrument->currentText().toStdString(); + } + /** Get the indices of the highlighted rows - @returns a vector of unsigned ints contianing the highlighted row numbers + @returns a set of ints containing the highlighted row numbers */ - std::vector QtReflMainView::getSelectedRowIndexes() const + std::set QtReflMainView::getSelectedRows() const { - auto selectedRows = ui.viewTable->selectionModel()->selectedRows(); - //auto selectedType = ui.viewTable->selectionModel()->; - std::vector rowIndexes; - for (auto idx = selectedRows.begin(); idx != selectedRows.end(); ++idx) + std::set rows; + auto selectionModel = ui.viewTable->selectionModel(); + if(selectionModel) { - rowIndexes.push_back(idx->row()); + auto selectedRows = selectionModel->selectedRows(); + for(auto it = selectedRows.begin(); it != selectedRows.end(); ++it) + rows.insert(it->row()); } - return rowIndexes; + return rows; + } + + /** + Get the indices of the highlighted search result rows + @returns a set of ints containing the selected row numbers + */ + std::set QtReflMainView::getSelectedSearchRows() const + { + std::set rows; + auto selectionModel = ui.tableSearchResults->selectionModel(); + if(selectionModel) + { + auto selectedRows = selectionModel->selectedRows(); + for(auto it = selectedRows.begin(); it != selectedRows.end(); ++it) + rows.insert(it->row()); + } + return rows; + } + + /** + Get the name of the workspace that the user wishes to open as a table + @returns The name of the workspace to open + */ + std::string QtReflMainView::getWorkspaceToOpen() const + { + return m_toOpen; + } + + /** + Get a pointer to the presenter that's currently controlling this view. + @returns A pointer to the presenter + */ + boost::shared_ptr QtReflMainView::getPresenter() const + { + return m_presenter; + } + + /** + Gets the contents of the system's clipboard + @returns The contents of the clipboard + */ + std::string QtReflMainView::getClipboard() const + { + return QApplication::clipboard()->text().toStdString(); + } + + /** + Get the string the user wants to search for. + @returns The search string + */ + std::string QtReflMainView::getSearchString() const + { + return ui.textSearch->text().toStdString(); } } // namespace CustomInterfaces diff --git a/Code/Mantid/MantidQt/CustomInterfaces/src/QtReflOptionsDialog.cpp b/Code/Mantid/MantidQt/CustomInterfaces/src/QtReflOptionsDialog.cpp new file mode 100644 index 000000000000..501c461d1e06 --- /dev/null +++ b/Code/Mantid/MantidQt/CustomInterfaces/src/QtReflOptionsDialog.cpp @@ -0,0 +1,107 @@ +#include "MantidQtCustomInterfaces/QtReflOptionsDialog.h" +#include "MantidQtCustomInterfaces/QtReflMainView.h" + +namespace MantidQt +{ + namespace CustomInterfaces + { + /** Constructor */ + QtReflOptionsDialog::QtReflOptionsDialog(ReflMainView* view, boost::shared_ptr presenter) : + QDialog(dynamic_cast(view)), + m_presenter(presenter) + { + initLayout(); + initBindings(); + loadOptions(); + } + + /** Destructor */ + QtReflOptionsDialog::~QtReflOptionsDialog() + { + } + + /** Initialise the ui */ + void QtReflOptionsDialog::initLayout() + { + ui.setupUi(this); + connect(ui.buttonBox->button(QDialogButtonBox::Ok), SIGNAL(clicked()), this, SLOT(saveOptions())); + } + + /** Bind options to their widgets */ + void QtReflOptionsDialog::initBindings() + { + m_bindings.clear(); + + //Check all the widgets for the "reflOptionName" property. + //If it exists, bind the named option to that widget. + QList widgets = findChildren(); + for(auto it = widgets.begin(); it != widgets.end(); ++it) + { + QVariant binding = (*it)->property("reflOptionName"); + if(binding.isValid()) + m_bindings[binding.toString().toStdString()] = (*it)->objectName(); + } + } + + /** This slot saves the currently configured options to the presenter */ + void QtReflOptionsDialog::saveOptions() + { + std::map options = m_presenter->options(); + + //Iterate through all our bound widgets, pushing their value into the options map + for(auto it = m_bindings.begin(); it != m_bindings.end(); ++it) + { + QString widgetName = it->second; + if(widgetName.isEmpty()) + continue; + + QCheckBox* checkbox = findChild(widgetName); + if(checkbox) + { + options[it->first] = checkbox->isChecked(); + continue; + } + + QSpinBox* spinbox = findChild(widgetName); + if(spinbox) + { + options[it->first] = spinbox->value(); + continue; + } + } + + //Update the presenter's options + m_presenter->setOptions(options); + } + + /** This slot sets the ui to match the presenter's options */ + void QtReflOptionsDialog::loadOptions() + { + std::map options = m_presenter->options(); + + //Set the values from the options + for(auto it = options.begin(); it != options.end(); ++it) + { + QString widgetName = m_bindings[it->first]; + if(widgetName.isEmpty()) + continue; + + QCheckBox* checkbox = findChild(widgetName); + if(checkbox) + { + checkbox->setChecked(it->second.toBool()); + continue; + } + + QSpinBox* spinbox = findChild(widgetName); + if(spinbox) + { + spinbox->setValue(it->second.toInt()); + continue; + } + } + } + + } //CustomInterfaces +} //MantidQt + diff --git a/Code/Mantid/MantidQt/CustomInterfaces/src/Quasi.cpp b/Code/Mantid/MantidQt/CustomInterfaces/src/Quasi.cpp index f8384fb0cec5..f66a6cd58f53 100644 --- a/Code/Mantid/MantidQt/CustomInterfaces/src/Quasi.cpp +++ b/Code/Mantid/MantidQt/CustomInterfaces/src/Quasi.cpp @@ -1,3 +1,4 @@ +#include "MantidAPI/TextAxis.h" #include "MantidQtCustomInterfaces/Quasi.h" #include "MantidQtCustomInterfaces/UserInputValidator.h" @@ -10,10 +11,19 @@ namespace MantidQt { m_uiForm.setupUi(parent); - //add the plot to the ui form - m_uiForm.plotSpace->addWidget(m_plot); + // Create the plot + m_plots["QuasiPlot"] = new QwtPlot(m_parentWidget); + m_plots["QuasiPlot"]->setCanvasBackground(Qt::white); + m_plots["QuasiPlot"]->setAxisFont(QwtPlot::xBottom, parent->font()); + m_plots["QuasiPlot"]->setAxisFont(QwtPlot::yLeft, parent->font()); + m_uiForm.plotSpace->addWidget(m_plots["QuasiPlot"]); - //add the properties browser to the ui form + // Create range selector + m_rangeSelectors["QuasiERange"] = new MantidWidgets::RangeSelector(m_plots["QuasiPlot"]); + connect(m_rangeSelectors["QuasiERange"], SIGNAL(minValueChanged(double)), this, SLOT(minValueChanged(double))); + connect(m_rangeSelectors["QuasiERange"], SIGNAL(maxValueChanged(double)), this, SLOT(maxValueChanged(double))); + + // Add the properties browser to the UI form m_uiForm.treeSpace->addWidget(m_propTree); m_properties["EMin"] = m_dblManager->addProperty("EMin"); @@ -61,6 +71,10 @@ namespace MantidQt m_uiForm.mwFixWidthDat->readSettings(settings.group()); } + void Quasi::setup() + { + } + /** * Validate the form to check the program can be run * @@ -101,6 +115,8 @@ namespace MantidQt */ void Quasi::run() { + using namespace Mantid::API; + // Using 1/0 instead of True/False for compatibility with underlying Fortran code // in some places QString verbose("False"); @@ -120,6 +136,9 @@ namespace MantidQt QString sampleName = m_uiForm.dsSample->getCurrentDataName(); QString resName = m_uiForm.dsResolution->getCurrentDataName(); + // Should be either "red", "sqw" or "res" + QString resType = resName.right(3); + QString program = m_uiForm.cbProgram->currentText(); if(program == "Lorentzians") @@ -151,7 +170,7 @@ namespace MantidQt QString fitOps = "[" + elasticPeak + ", '" + background + "', " + fixedWidth + ", " + useResNorm + "]"; - //Collect input from the properties browser + // Collect input from the properties browser QString eMin = m_properties["EMin"]->valueText(); QString eMax = m_properties["EMax"]->valueText(); QString eRange = "[" + eMin + "," + eMax + "]"; @@ -160,7 +179,7 @@ namespace MantidQt QString resBins = m_properties["ResBinning"]->valueText(); QString nBins = "[" + sampleBins + "," + resBins + "]"; - //Output options + // Output options if(m_uiForm.chkVerbose->isChecked()) { verbose = "True"; } if(m_uiForm.chkSave->isChecked()) { save = "True"; } QString plot = m_uiForm.cbPlot->currentText(); @@ -170,6 +189,39 @@ namespace MantidQt " Save="+save+", Plot='"+plot+"', Verbose="+verbose+")\n"; runPythonScript(pyInput); + + // Get the correct workspace name based on the type of resolution file + if(program == "QL") + { + if(resType == "res") + program += "r"; + else + program += "d"; + } + + // Update mini plot + QString outWsName = sampleName.left(sampleName.size() - 3) + program + "_Workspace_0"; + MatrixWorkspace_sptr outputWorkspace = AnalysisDataService::Instance().retrieveWS(outWsName.toStdString()); + TextAxis* axis = dynamic_cast(outputWorkspace->getAxis(1)); + + for(size_t histIndex = 0; histIndex < outputWorkspace->getNumberHistograms(); histIndex++) + { + QString specName = QString::fromStdString(axis->label(histIndex)); + + if(specName.contains("fit")) + { + plotMiniPlot(outputWorkspace, histIndex, "QuasiPlot", specName); + m_curves[specName]->setPen(QColor(Qt::red)); + } + + if(specName.contains("diff")) + { + plotMiniPlot(outputWorkspace, histIndex, "QuasiPlot", specName); + m_curves[specName]->setPen(QColor(Qt::green)); + } + } + + replot("QuasiPlot"); } /** @@ -180,10 +232,10 @@ namespace MantidQt */ void Quasi::handleSampleInputReady(const QString& filename) { - plotMiniPlot(filename, 0); - std::pair range = getCurveRange(); - setMiniPlotGuides(m_properties["EMin"], m_properties["EMax"], range); - setPlotRange(m_properties["EMin"], m_properties["EMax"], range); + plotMiniPlot(filename, 0, "QuasiPlot", "RawPlotCurve"); + std::pair range = getCurveRange("RawPlotCurve"); + setMiniPlotGuides("QuasiERange", m_properties["EMin"], m_properties["EMax"], range); + setPlotRange("QuasiERange", m_properties["EMin"], m_properties["EMax"], range); } /** @@ -216,11 +268,11 @@ namespace MantidQt { if(prop == m_properties["EMin"]) { - updateLowerGuide(m_properties["EMin"], m_properties["EMax"], val); + updateLowerGuide(m_rangeSelectors["QuasiERange"], m_properties["EMin"], m_properties["EMax"], val); } else if (prop == m_properties["EMax"]) { - updateUpperGuide(m_properties["EMin"], m_properties["EMax"], val); + updateUpperGuide(m_rangeSelectors["QuasiERange"], m_properties["EMin"], m_properties["EMax"], val); } } diff --git a/Code/Mantid/MantidQt/CustomInterfaces/src/ReflBlankMainViewPresenter.cpp b/Code/Mantid/MantidQt/CustomInterfaces/src/ReflBlankMainViewPresenter.cpp deleted file mode 100644 index 34c1cf1bf47b..000000000000 --- a/Code/Mantid/MantidQt/CustomInterfaces/src/ReflBlankMainViewPresenter.cpp +++ /dev/null @@ -1,83 +0,0 @@ -#include "MantidQtCustomInterfaces/ReflBlankMainViewPresenter.h" -#include "MantidAPI/WorkspaceFactory.h" -#include "MantidAPI/TableRow.h" -using namespace Mantid::API; -namespace -{ - ITableWorkspace_sptr createWorkspace() - { - ITableWorkspace_sptr ws = WorkspaceFactory::Instance().createTable(); - auto colRuns = ws->addColumn("str","Run(s)"); - auto colTheta = ws->addColumn("str","ThetaIn"); - auto colTrans = ws->addColumn("str","TransRun(s)"); - auto colQmin = ws->addColumn("str","Qmin"); - auto colQmax = ws->addColumn("str","Qmax"); - auto colDqq = ws->addColumn("str","dq/q"); - auto colScale = ws->addColumn("str","Scale"); - auto colStitch = ws->addColumn("int","StitchGroup"); - - colRuns->setPlotType(0); - colTheta->setPlotType(0); - colTrans->setPlotType(0); - colQmin->setPlotType(0); - colQmax->setPlotType(0); - colDqq->setPlotType(0); - colScale->setPlotType(0); - colStitch->setPlotType(0); - - TableRow row = ws->appendRow(); - return ws; - } -} - -namespace MantidQt -{ - namespace CustomInterfaces - { - - - //---------------------------------------------------------------------------------------------- - /** Constructor - */ - ReflBlankMainViewPresenter::ReflBlankMainViewPresenter(ReflMainView* view): ReflMainViewPresenter(view) - { - m_model = createWorkspace(); - load(); - } - - //---------------------------------------------------------------------------------------------- - /** Destructor - */ - ReflBlankMainViewPresenter::~ReflBlankMainViewPresenter() - { - } - - /** - Press changes to a previously saved-to item in the ADS, or ask for a name if never given one - */ - void ReflBlankMainViewPresenter::save() - { - if (m_cache_name != "") - { - AnalysisDataService::Instance().addOrReplace(m_cache_name, boost::shared_ptr(m_model->clone())); - } - else - { - saveAs(); - } - } - - /** - Press changes to a new item in the ADS - */ - void ReflBlankMainViewPresenter::saveAs() - { - std::string userString = m_view->askUserString("Save As", "Enter a workspace name:", "Workspace"); - if(!userString.empty()) - { - m_cache_name = userString; - save(); - } - } - } // namespace CustomInterfaces -} // namespace Mantid diff --git a/Code/Mantid/MantidQt/CustomInterfaces/src/ReflCatalogSearcher.cpp b/Code/Mantid/MantidQt/CustomInterfaces/src/ReflCatalogSearcher.cpp new file mode 100644 index 000000000000..b2600f66bb04 --- /dev/null +++ b/Code/Mantid/MantidQt/CustomInterfaces/src/ReflCatalogSearcher.cpp @@ -0,0 +1,69 @@ +#include "MantidQtCustomInterfaces/ReflCatalogSearcher.h" + +#include "MantidAPI/AlgorithmManager.h" +#include "MantidAPI/CatalogManager.h" + +using namespace Mantid::API; + +namespace MantidQt +{ + namespace CustomInterfaces + { + ITableWorkspace_sptr ReflCatalogSearcher::search(const std::string& text, const std::string& instrument) + { + auto sessions = CatalogManager::Instance().getActiveSessions(); + if(sessions.empty()) + throw std::runtime_error("You are not logged into any catalogs."); + + const std::string sessionId = sessions.front()->getSessionId(); + + auto algSearch = AlgorithmManager::Instance().create("CatalogGetDataFiles"); + algSearch->initialize(); + algSearch->setChild(true); + algSearch->setLogging(false); + algSearch->setProperty("Session", sessionId); + algSearch->setProperty("InvestigationId", text); + algSearch->setProperty("OutputWorkspace", "_ReflSearchResults"); + algSearch->execute(); + ITableWorkspace_sptr results = algSearch->getProperty("OutputWorkspace"); + + //Now, tidy up the data + std::set toRemove; + for(size_t i = 0; i < results->rowCount(); ++i) + { + std::string& run = results->String(i,0); + + //Too short to be more than ".raw" + if(run.size() < 5) + { + toRemove.insert(i); + } + //If this isn't the right instrument, remove it + else if(run.substr(0, instrument.size()) != instrument) + { + toRemove.insert(i); + } + //If it's not a raw file, remove it + else if(run.substr(run.size() - 4, 4) != ".raw") + { + toRemove.insert(i); + } + + //It's a valid run, so let's trim the instrument prefix and ".raw" suffix + run = run.substr(instrument.size(), run.size() - (instrument.size() + 4)); + + //Let's also get rid of any leading zeros + size_t numZeros = 0; + while(run[numZeros] == '0') + numZeros++; + run = run.substr(numZeros, run.size() - numZeros); + } + + //Sets are sorted so if we go from back to front we won't trip over ourselves + for(auto row = toRemove.rbegin(); row != toRemove.rend(); ++row) + results->removeRow(*row); + + return results; + } + } +} diff --git a/Code/Mantid/MantidQt/CustomInterfaces/src/ReflLegacyTransferStrategy.cpp b/Code/Mantid/MantidQt/CustomInterfaces/src/ReflLegacyTransferStrategy.cpp new file mode 100644 index 000000000000..58247c202622 --- /dev/null +++ b/Code/Mantid/MantidQt/CustomInterfaces/src/ReflLegacyTransferStrategy.cpp @@ -0,0 +1,78 @@ +#include "MantidQtCustomInterfaces/ReflLegacyTransferStrategy.h" + +#include +#include +#include + +namespace MantidQt +{ + namespace CustomInterfaces + { + std::vector > ReflLegacyTransferStrategy::transferRuns(const std::map& runRows) + { + /* + * If the descriptions are the same except for theta: same group, different rows. + * If the descriptions are the same including theta: same row with runs separated by '+' + * We always prefill theta if we can. + */ + + //maps descriptions to runs. Multiple runs are joined with '+' + std::map runsByDesc; + //Counter used to feed fresh group ids + int nextGroupId = 0; + //maps a description to a group. If descriptions only differ by theta, they'll share a group + std::map groupsByDesc; + //maps descriptions to the value of theta they contain + std::map thetaByDesc; + + //Iterate over the input and build the maps + for(auto rowIt = runRows.begin(); rowIt != runRows.end(); ++rowIt) + { + const std::string run = rowIt->first; + const std::string desc = rowIt->second; + std::string cleanDesc = desc; + + //See if theta is in the description + static boost::regex regexTheta("(?|th[:=](?[0-9.]+)|in (?[0-9.]+) theta)"); + boost::smatch matches; + if(boost::regex_search(desc, matches, regexTheta)) + { + //We have theta. Let's get a clean description + size_t matchOffset = matches.position("theta"); + const std::string theta = matches["theta"].str(); + const std::string descPreTheta = desc.substr(0, matchOffset); + const std::string descPostTheta = desc.substr(matchOffset + theta.length(), std::string::npos); + cleanDesc = descPreTheta + "?" + descPostTheta; + thetaByDesc[desc] = theta; + } + + //map the description to the run, making sure to join with a + if one already exists + const std::string prevRun = runsByDesc[desc]; + if(prevRun.empty()) + runsByDesc[desc] = run; + else + runsByDesc[desc] = prevRun + "+" + run; + + //If there isn't a group for this description (ignoring differences in theta) yet, make one + if(groupsByDesc[cleanDesc].empty()) + groupsByDesc[cleanDesc] = boost::lexical_cast(nextGroupId++); + + //Assign this description to the group it belongs to + groupsByDesc[desc] = groupsByDesc[cleanDesc]; + } + + //All the data we need is now properly organised, so we can quickly throw out the rows needed + std::vector > output; + for(auto run = runsByDesc.begin(); run != runsByDesc.end(); ++run) + { + std::map row; + row["runs"] = run->second; + row["theta"] = thetaByDesc[run->first]; + row["group"] = groupsByDesc[run->first]; + output.push_back(row); + } + std::sort(output.begin(), output.end()); + return output; + } + } +} diff --git a/Code/Mantid/MantidQt/CustomInterfaces/src/ReflLoadedMainViewPresenter.cpp b/Code/Mantid/MantidQt/CustomInterfaces/src/ReflLoadedMainViewPresenter.cpp deleted file mode 100644 index 642b846194c5..000000000000 --- a/Code/Mantid/MantidQt/CustomInterfaces/src/ReflLoadedMainViewPresenter.cpp +++ /dev/null @@ -1,102 +0,0 @@ -#include "MantidQtCustomInterfaces/ReflLoadedMainViewPresenter.h" -#include "MantidAPI/ITableWorkspace.h" -#include "MantidAPI/WorkspaceFactory.h" -#include "MantidQtCustomInterfaces/ReflMainView.h" -using namespace Mantid::API; -namespace -{ - void hasValidModel(ITableWorkspace_sptr model) - { - if(model->columnCount() != 8) - throw std::runtime_error("Selected table has the incorrect number of columns (8) to be used as a reflectometry table."); - - try - { - model->String(0,0); - model->String(0,1); - model->String(0,2); - model->String(0,3); - model->String(0,4); - model->String(0,5); - model->String(0,6); - model->Int(0,7); - } - catch(const std::runtime_error&) - { - throw std::runtime_error("Selected table does not meet the specifications to become a model for this interface."); - } - } -} -namespace MantidQt -{ - namespace CustomInterfaces - { - - - //---------------------------------------------------------------------------------------------- - /** Constructor - */ - - ReflLoadedMainViewPresenter::ReflLoadedMainViewPresenter(ITableWorkspace_sptr model, ReflMainView* view): - ReflMainViewPresenter(boost::shared_ptr(model->clone()), view) - { - if (model->name() != "") - { - m_cache_name = model->name(); - } - else - { - throw std::runtime_error("Supplied model workspace must have a name"); - } - m_cache = model; - hasValidModel(m_model); - load(); - } - - ReflLoadedMainViewPresenter::ReflLoadedMainViewPresenter(std::string model, ReflMainView* view): - ReflMainViewPresenter(boost::shared_ptr(AnalysisDataService::Instance().retrieveWS(model)->clone()), view) - { - m_cache = AnalysisDataService::Instance().retrieveWS(model); - if (m_cache->name() != "") - { - m_cache_name = m_cache->name(); - } - else - { - throw std::runtime_error("Supplied model workspace must have a name"); - } - hasValidModel(m_model); - load(); - } - - //---------------------------------------------------------------------------------------------- - /** Destructor - */ - ReflLoadedMainViewPresenter::~ReflLoadedMainViewPresenter() - { - - } - - /** - Press changes to the same item in the ADS - */ - void ReflLoadedMainViewPresenter::save() - { - AnalysisDataService::Instance().addOrReplace(m_cache_name,boost::shared_ptr(m_model->clone())); - } - - /** - Press changes to a new item in the ADS - */ - void ReflLoadedMainViewPresenter::saveAs() - { - std::string userString = m_view->askUserString("Save As", "Enter a workspace name:", "Workspace"); - if(!userString.empty()) - { - m_cache_name = userString; - save(); - } - } - - } // namespace CustomInterfaces -} // namespace Mantid diff --git a/Code/Mantid/MantidQt/CustomInterfaces/src/ReflMainView.cpp b/Code/Mantid/MantidQt/CustomInterfaces/src/ReflMainView.cpp deleted file mode 100644 index 88019bdf982a..000000000000 --- a/Code/Mantid/MantidQt/CustomInterfaces/src/ReflMainView.cpp +++ /dev/null @@ -1,17 +0,0 @@ -#include "MantidQtCustomInterfaces/ReflMainView.h" -#include "MantidAPI/ITableWorkspace.h" - -namespace MantidQt -{ - namespace CustomInterfaces - { - - ReflMainView::ReflMainView() - { - } - - ReflMainView::~ReflMainView() - { - } - } -} diff --git a/Code/Mantid/MantidQt/CustomInterfaces/src/ReflMainViewPresenter.cpp b/Code/Mantid/MantidQt/CustomInterfaces/src/ReflMainViewPresenter.cpp index be4f0ee82f0f..800fec7e18d2 100644 --- a/Code/Mantid/MantidQt/CustomInterfaces/src/ReflMainViewPresenter.cpp +++ b/Code/Mantid/MantidQt/CustomInterfaces/src/ReflMainViewPresenter.cpp @@ -1,33 +1,262 @@ #include "MantidQtCustomInterfaces/ReflMainViewPresenter.h" +#include "MantidAPI/AlgorithmManager.h" #include "MantidAPI/ITableWorkspace.h" +#include "MantidAPI/TableRow.h" +#include "MantidGeometry/Instrument/ParameterMap.h" +#include "MantidKernel/Strings.h" +#include "MantidKernel/TimeSeriesProperty.h" +#include "MantidKernel/Utils.h" +#include "MantidQtCustomInterfaces/ReflCatalogSearcher.h" +#include "MantidQtCustomInterfaces/ReflLegacyTransferStrategy.h" #include "MantidQtCustomInterfaces/ReflMainView.h" -#include "MantidAPI/AlgorithmManager.h" +#include "MantidQtCustomInterfaces/ReflSearchModel.h" +#include "MantidQtCustomInterfaces/QReflTableModel.h" +#include "MantidQtCustomInterfaces/QtReflOptionsDialog.h" +#include "MantidQtMantidWidgets/AlgorithmHintStrategy.h" + +#include +#include + +#include + using namespace Mantid::API; +using namespace Mantid::Geometry; +using namespace Mantid::Kernel; +using namespace MantidQt::MantidWidgets; + +namespace +{ + const QString ReflSettingsGroup = "Mantid/CustomInterfaces/ISISReflectometry"; + + void validateModel(ITableWorkspace_sptr model) + { + if(!model) + throw std::runtime_error("Null pointer"); + + if(model->columnCount() != 9) + throw std::runtime_error("Selected table has the incorrect number of columns (9) to be used as a reflectometry table."); + + try + { + model->String(0,0); + model->String(0,1); + model->String(0,2); + model->String(0,3); + model->String(0,4); + model->String(0,5); + model->Double(0,6); + model->Int(0,7); + model->String(0,8); + } + catch(const std::runtime_error&) + { + throw std::runtime_error("Selected table does not meet the specifications to become a model for this interface."); + } + } + + bool isValidModel(Workspace_sptr model) + { + try + { + validateModel(boost::dynamic_pointer_cast(model)); + } + catch(...) + { + return false; + } + return true; + } + + ITableWorkspace_sptr createWorkspace() + { + ITableWorkspace_sptr ws = WorkspaceFactory::Instance().createTable(); + auto colRuns = ws->addColumn("str","Run(s)"); + auto colTheta = ws->addColumn("str","ThetaIn"); + auto colTrans = ws->addColumn("str","TransRun(s)"); + auto colQmin = ws->addColumn("str","Qmin"); + auto colQmax = ws->addColumn("str","Qmax"); + auto colDqq = ws->addColumn("str","dq/q"); + auto colScale = ws->addColumn("double","Scale"); + auto colStitch = ws->addColumn("int","StitchGroup"); + auto colOptions = ws->addColumn("str","Options"); + + colRuns->setPlotType(0); + colTheta->setPlotType(0); + colTrans->setPlotType(0); + colQmin->setPlotType(0); + colQmax->setPlotType(0); + colDqq->setPlotType(0); + colScale->setPlotType(0); + colStitch->setPlotType(0); + colOptions->setPlotType(0); + + return ws; + } + + ITableWorkspace_sptr createDefaultWorkspace() + { + //Create a blank workspace with one line and set the scale column to 1 + auto ws = createWorkspace(); + ws->appendRow(); + ws->Double(0, MantidQt::CustomInterfaces::ReflMainViewPresenter::COL_SCALE) = 1.0; + return ws; + } +} namespace MantidQt { namespace CustomInterfaces { + ReflMainViewPresenter::ReflMainViewPresenter(ReflMainView* view, boost::shared_ptr searcher): + m_view(view), + m_tableDirty(false), + m_searcher(searcher), + m_transferStrategy(new ReflLegacyTransferStrategy()), + m_addObserver(*this, &ReflMainViewPresenter::handleAddEvent), + m_remObserver(*this, &ReflMainViewPresenter::handleRemEvent), + m_clearObserver(*this, &ReflMainViewPresenter::handleClearEvent), + m_renameObserver(*this, &ReflMainViewPresenter::handleRenameEvent), + m_replaceObserver(*this, &ReflMainViewPresenter::handleReplaceEvent) + { + //Initialise options + initOptions(); + + //Set up the instrument selectors + std::vector instruments; + instruments.push_back("INTER"); + instruments.push_back("SURF"); + instruments.push_back("CRISP"); + instruments.push_back("POLREF"); + + //If the user's configured default instrument is in this list, set it as the default, otherwise use INTER + const std::string defaultInst = Mantid::Kernel::ConfigService::Instance().getString("default.instrument"); + if(std::find(instruments.begin(), instruments.end(), defaultInst) != instruments.end()) + m_view->setInstrumentList(instruments, defaultInst); + else + m_view->setInstrumentList(instruments, "INTER"); + + //Populate an initial list of valid tables to open, and subscribe to the ADS to keep it up to date + Mantid::API::AnalysisDataServiceImpl& ads = Mantid::API::AnalysisDataService::Instance(); - const int ReflMainViewPresenter::COL_RUNS(0); - const int ReflMainViewPresenter::COL_ANGLE(1); - const int ReflMainViewPresenter::COL_TRANSMISSION(2); - const int ReflMainViewPresenter::COL_QMIN(3); - const int ReflMainViewPresenter::COL_QMAX(4); - const int ReflMainViewPresenter::COL_DQQ(5); - const int ReflMainViewPresenter::COL_SCALE(6); - const int ReflMainViewPresenter::COL_GROUP(7); + std::set items; + items = ads.getObjectNames(); + for(auto it = items.begin(); it != items.end(); ++it ) + { + const std::string name = *it; + Workspace_sptr ws = ads.retrieve(name); - ReflMainViewPresenter::ReflMainViewPresenter(ReflMainView* view): m_view(view) + if(isValidModel(ws)) + m_workspaceList.insert(name); + } + + ads.notificationCenter.addObserver(m_addObserver); + ads.notificationCenter.addObserver(m_remObserver); + ads.notificationCenter.addObserver(m_renameObserver); + ads.notificationCenter.addObserver(m_clearObserver); + ads.notificationCenter.addObserver(m_replaceObserver); + + m_view->setTableList(m_workspaceList); + + //Provide autocompletion hints for the options column. We use the algorithm's properties minus + //those we blacklist. We blacklist any useless properties or ones we're handling that the user + //should'nt touch. + IAlgorithm_sptr alg = AlgorithmManager::Instance().create("ReflectometryReductionOneAuto"); + std::set blacklist; + blacklist.insert("ThetaIn"); + blacklist.insert("ThetaOut"); + blacklist.insert("InputWorkspace"); + blacklist.insert("OutputWorkspace"); + blacklist.insert("OutputWorkspaceWavelength"); + blacklist.insert("FirstTransmissionRun"); + blacklist.insert("SecondTransmissionRun"); + m_view->setOptionsHintStrategy(new AlgorithmHintStrategy(alg, blacklist)); + + //If we don't have a searcher yet, use ReflCatalogSearcher + if(!m_searcher) + m_searcher.reset(new ReflCatalogSearcher()); + + //Start with a blank table + newTable(); + } + + ReflMainViewPresenter::~ReflMainViewPresenter() { + Mantid::API::AnalysisDataServiceImpl& ads = Mantid::API::AnalysisDataService::Instance(); + ads.notificationCenter.removeObserver(m_addObserver); + ads.notificationCenter.removeObserver(m_remObserver); + ads.notificationCenter.removeObserver(m_clearObserver); + ads.notificationCenter.removeObserver(m_renameObserver); + ads.notificationCenter.removeObserver(m_replaceObserver); } - ReflMainViewPresenter::ReflMainViewPresenter(ITableWorkspace_sptr model, ReflMainView* view): m_model(model), m_view(view) + /** + * Finds the first unused group id + */ + int ReflMainViewPresenter::getUnusedGroup(std::set ignoredRows) const { + std::set usedGroups; + + //Scan through all the rows, working out which group ids are used + for(int idx = 0; idx < m_model->rowCount(); ++idx) + { + if(ignoredRows.find(idx) != ignoredRows.end()) + continue; + + //This is an unselected row. Add it to the list of used group ids + usedGroups.insert(m_model->data(m_model->index(idx, COL_GROUP)).toInt()); + } + + int groupId = 0; + + //While the group id is one of the used ones, increment it by 1 + while(usedGroups.find(groupId) != usedGroups.end()) + groupId++; + + return groupId; } - ReflMainViewPresenter::~ReflMainViewPresenter() + /** + Parses a string in the format `a = 1,b=2, c = "1,2,3,4", d = 5.0, e='a,b,c'` into a map of key/value pairs + @param str The input string + @throws std::runtime_error on an invalid input string + */ + std::map ReflMainViewPresenter::parseKeyValueString(const std::string& str) { + //Tokenise, using '\' as an escape character, ',' as a delimiter and " and ' as quote characters + boost::tokenizer > tok(str, boost::escaped_list_separator("\\", ",", "\"'")); + + std::map kvp; + + for(auto it = tok.begin(); it != tok.end(); ++it) + { + std::vector valVec; + boost::split(valVec, *it, boost::is_any_of("=")); + + if(valVec.size() > 1) + { + //We split on all '='s. The first delimits the key, the rest are assumed to be part of the value + std::string key = valVec[0]; + //Drop the key from the values vector + valVec.erase(valVec.begin()); + //Join the remaining sections, + std::string value = boost::algorithm::join(valVec, "="); + + //Remove any unwanted whitespace + boost::trim(key); + boost::trim(value); + + if(key.empty() || value.empty()) + throw std::runtime_error("Invalid key value pair, '" + *it + "'"); + + + kvp[key] = value; + } + else + { + throw std::runtime_error("Invalid key value pair, '" + *it + "'"); + } + } + return kvp; } /** @@ -41,145 +270,459 @@ namespace MantidQt return; } - std::vector rows = m_view->getSelectedRowIndexes(); - if(rows.size() == 0) + std::set rows = m_view->getSelectedRows(); + if(rows.empty()) { - //Does the user want to abort? - if(!m_view->askUserYesNo("This will process all rows in the table. Continue?","Process all rows?")) - return; + if(m_options["WarnProcessAll"].toBool()) + { + //Does the user want to abort? + if(!m_view->askUserYesNo("This will process all rows in the table. Continue?","Process all rows?")) + return; + } //They want to process all rows, so populate rows with every index in the model - for(size_t idx = 0; idx < m_model->rowCount(); ++idx) - rows.push_back(idx); + for(int idx = 0; idx < m_model->rowCount(); ++idx) + rows.insert(idx); } - try + //Map group numbers to the set of rows in that group we want to process + std::map > groups; + for(auto it = rows.begin(); it != rows.end(); ++it) + groups[m_model->data(m_model->index(*it, COL_GROUP)).toInt()].insert(*it); + + //Check each group and warn if we're only partially processing it + for(auto gIt = groups.begin(); gIt != groups.end(); ++gIt) { - //TODO: Handle groups and stitch them together accordingly - for(auto it = rows.begin(); it != rows.end(); ++it) - processRow(*it); + const int& groupId = gIt->first; + const std::set& groupRows = gIt->second; + //Are we only partially processing a group? + if(groupRows.size() < numRowsInGroup(gIt->first) && m_options["WarnProcessPartialGroup"].toBool()) + { + std::stringstream err; + err << "You have only selected " << groupRows.size() << " of the "; + err << numRowsInGroup(groupId) << " rows in group " << groupId << "."; + err << " Are you sure you want to continue?"; + if(!m_view->askUserYesNo(err.str(), "Continue Processing?")) + return; + } } - catch(std::exception& ex) + + //Validate the rows + for(auto it = rows.begin(); it != rows.end(); ++it) { - m_view->giveUserCritical("Error encountered while processing: \n" + std::string(ex.what()),"Error"); + try + { + validateRow(*it); + autofillRow(*it); + } + catch(std::exception& ex) + { + const std::string rowNo = Mantid::Kernel::Strings::toString(*it + 1); + m_view->giveUserCritical("Error found in row " + rowNo + ":\n" + ex.what(), "Error"); + return; + } + } + + int progress = 0; + //Each group and each row within count as a progress step. + const int maxProgress = (int)(rows.size() + groups.size()); + m_view->setProgressRange(progress, maxProgress); + m_view->setProgress(progress); + + for(auto gIt = groups.begin(); gIt != groups.end(); ++gIt) + { + const std::set groupRows = gIt->second; + + //Reduce each row + for(auto rIt = groupRows.begin(); rIt != groupRows.end(); ++rIt) + { + try + { + reduceRow(*rIt); + m_view->setProgress(++progress); + } + catch(std::exception& ex) + { + const std::string rowNo = Mantid::Kernel::Strings::toString(*rIt + 1); + const std::string message = "Error encountered while processing row " + rowNo + ":\n"; + m_view->giveUserCritical(message + ex.what(), "Error"); + m_view->setProgress(0); + return; + } + } + + try + { + stitchRows(groupRows); + m_view->setProgress(++progress); + } + catch(std::exception& ex) + { + const std::string groupNo = Mantid::Kernel::Strings::toString(gIt->first); + const std::string message = "Error encountered while stitching group " + groupNo + ":\n"; + m_view->giveUserCritical(message + ex.what(), "Error"); + m_view->setProgress(0); + return; + } } } /** - Process a specific Row - @param rowNo : The row in the model to process + Validate a row. + If a row passes validation, it is ready to be autofilled, but + not necessarily ready for processing. + @param rowNo : The row in the model to validate + @throws std::invalid_argument if the row fails validation */ - void ReflMainViewPresenter::processRow(size_t rowNo) + void ReflMainViewPresenter::validateRow(int rowNo) const { - const std::string run = m_model->String(rowNo, COL_RUNS); - const std::string transStr = m_model->String(rowNo, COL_TRANSMISSION); - const std::string transWSName = makeTransWSName(transStr); + if(rowNo >= m_model->rowCount()) + throw std::invalid_argument("Invalid row"); - double dqq = 0; - double theta = 0; - double qmin = 0; - double qmax = 0; + if(m_model->data(m_model->index(rowNo, COL_RUNS)).toString().isEmpty()) + throw std::invalid_argument("Run column may not be empty."); + } - const bool dqqGiven = !m_model->String(rowNo, COL_DQQ ).empty(); - const bool thetaGiven = !m_model->String(rowNo, COL_ANGLE).empty(); - const bool qminGiven = !m_model->String(rowNo, COL_QMIN ).empty(); - const bool qmaxGiven = !m_model->String(rowNo, COL_QMAX ).empty(); + /** + Autofill a row + @param rowNo : The row in the model to autofill + @throws std::runtime_error if the row could not be auto-filled + */ + void ReflMainViewPresenter::autofillRow(int rowNo) + { + if(rowNo >= m_model->rowCount()) + throw std::runtime_error("Invalid row"); - if(dqqGiven) - Mantid::Kernel::Strings::convert(m_model->String(rowNo, COL_DQQ), dqq); + const std::string runStr = m_model->data(m_model->index(rowNo, COL_RUNS)).toString().toStdString(); + MatrixWorkspace_sptr run = boost::dynamic_pointer_cast(loadRun(runStr, m_view->getProcessInstrument())); - if(thetaGiven) - Mantid::Kernel::Strings::convert(m_model->String(rowNo, COL_ANGLE), theta); + //Fetch two theta from the log if needed + if(m_model->data(m_model->index(rowNo, COL_ANGLE)).toString().isEmpty()) + { + Property* logData = NULL; + + //First try TwoTheta + try + { + logData = run->mutableRun().getLogData("Theta"); + } + catch(std::exception&) + { + throw std::runtime_error("Value for two theta could not be found in log."); + } + + auto logPWV = dynamic_cast*>(logData); + auto logTSP = dynamic_cast*>(logData); + + double thetaVal; + if(logPWV) + thetaVal = *logPWV; + else if(logTSP && logTSP->realSize() > 0) + thetaVal = logTSP->lastValue(); + else + throw std::runtime_error("Value for two theta could not be found in log."); + + //Update the model + if(m_options["RoundAngle"].toBool()) + thetaVal = Utils::roundToDP(thetaVal, m_options["RoundAnglePrecision"].toInt()); + + m_model->setData(m_model->index(rowNo, COL_ANGLE), thetaVal); + m_tableDirty = true; + } + + //If we need to calculate the resolution, do. + if(m_model->data(m_model->index(rowNo, COL_DQQ)).toString().isEmpty()) + { + IAlgorithm_sptr calcResAlg = AlgorithmManager::Instance().create("CalculateResolution"); + calcResAlg->setProperty("Workspace", run); + calcResAlg->setProperty("TwoTheta", m_model->data(m_model->index(rowNo, COL_ANGLE)).toString().toStdString()); + calcResAlg->execute(); + + //Update the model + double dqqVal = calcResAlg->getProperty("Resolution"); + + if(m_options["RoundDQQ"].toBool()) + dqqVal = Utils::roundToDP(dqqVal, m_options["RoundDQQPrecision"].toInt()); + + m_model->setData(m_model->index(rowNo, COL_DQQ), dqqVal); + m_tableDirty = true; + } + } + + /** + Extracts the run number of a workspace + @param ws : The workspace to fetch the run number from + @returns The run number of the workspace + */ + std::string ReflMainViewPresenter::getRunNumber(const Workspace_sptr& ws) + { + //If we can, use the run number from the workspace's sample log + MatrixWorkspace_sptr mws = boost::dynamic_pointer_cast(ws); + if(mws) + { + try + { + const Property* runProperty = mws->mutableRun().getLogData("run_number"); + auto runNumber = dynamic_cast*>(runProperty); + if(runNumber) + return *runNumber; + } + catch(Mantid::Kernel::Exception::NotFoundError&) + { + //We'll just fall back to looking at the workspace's name + } + } + + //Okay, let's see what we can get from the workspace's name + const std::string wsName = ws->name(); - if(qminGiven) - Mantid::Kernel::Strings::convert(m_model->String(rowNo, COL_QMIN), qmin); + //Matches TOF_13460 -> 13460 + boost::regex outputRegex("(TOF|IvsQ|IvsLam)_([0-9]+)"); - if(qmaxGiven) - Mantid::Kernel::Strings::convert(m_model->String(rowNo, COL_QMAX), qmax); + //Matches INTER13460 -> 13460 + boost::regex instrumentRegex("[a-zA-Z]{3,}([0-9]{3,})"); - //Load the run + boost::smatch matches; + if(boost::regex_match(wsName, matches, outputRegex)) + { + return matches[2].str(); + } + else if(boost::regex_match(wsName, matches, instrumentRegex)) + { + return matches[1].str(); + } + + //Resort to using the workspace name + return wsName; + } + + /** + Loads a run from disk or fetches it from the AnalysisDataService + @param run : The name of the run + @param instrument : The instrument the run belongs to + @throws std::runtime_error if the run could not be loaded + @returns a shared pointer to the workspace + */ + Workspace_sptr ReflMainViewPresenter::loadRun(const std::string& run, const std::string& instrument = "") + { + //First, let's see if the run given is the name of a workspace in the ADS + if(AnalysisDataService::Instance().doesExist(run)) + return AnalysisDataService::Instance().retrieveWS(run); + + //Is the run string is numeric + if(boost::regex_match(run, boost::regex("\\d+"))) + { + std::string wsName; + + //Look "TOF_" in the ADS + wsName = "TOF_" + run; + if(AnalysisDataService::Instance().doesExist(wsName)) + return AnalysisDataService::Instance().retrieveWS(wsName); + + //Look for "" in the ADS + wsName = instrument + run; + if(AnalysisDataService::Instance().doesExist(wsName)) + return AnalysisDataService::Instance().retrieveWS(wsName); + } + + //We'll just have to load it ourselves + const std::string filename = instrument + run; IAlgorithm_sptr algLoadRun = AlgorithmManager::Instance().create("Load"); algLoadRun->initialize(); - algLoadRun->setChild(true); - algLoadRun->setProperty("Filename", run); - algLoadRun->setProperty("OutputWorkspace", run + "_TOF"); + algLoadRun->setProperty("Filename", filename); + algLoadRun->setProperty("OutputWorkspace", "TOF_" + run); algLoadRun->execute(); if(!algLoadRun->isExecuted()) - throw std::runtime_error("Could not open run: " + run); + throw std::runtime_error("Could not open " + filename); - Workspace_sptr runWS = algLoadRun->getProperty("OutputWorkspace"); + return AnalysisDataService::Instance().retrieveWS("TOF_" + run); + } + + /** + Reduce a row + @param rowNo : The row in the model to reduce + @throws std::runtime_error if reduction fails + */ + void ReflMainViewPresenter::reduceRow(int rowNo) + { + const std::string run = m_model->data(m_model->index(rowNo, COL_RUNS)).toString().toStdString(); + const std::string transStr = m_model->data(m_model->index(rowNo, COL_TRANSMISSION)).toString().toStdString(); + const std::string options = m_model->data(m_model->index(rowNo, COL_OPTIONS)).toString().toStdString(); + + double theta = 0; + + const bool thetaGiven = !m_model->data(m_model->index(rowNo, COL_ANGLE)).toString().isEmpty(); + + if(thetaGiven) + theta = m_model->data(m_model->index(rowNo, COL_ANGLE)).toDouble(); + + Workspace_sptr runWS = loadRun(run, m_view->getProcessInstrument()); + const std::string runNo = getRunNumber(runWS); - //If the transmission workspace already exists, re-use it. MatrixWorkspace_sptr transWS; - if(AnalysisDataService::Instance().doesExist(transWSName)) - transWS = AnalysisDataService::Instance().retrieveWS(transWSName); - else + if(!transStr.empty()) transWS = makeTransWS(transStr); IAlgorithm_sptr algReflOne = AlgorithmManager::Instance().create("ReflectometryReductionOneAuto"); algReflOne->initialize(); - algReflOne->setChild(true); - algReflOne->setProperty("InputWorkspace", runWS); - algReflOne->setProperty("FirstTransmissionRun", transWS); - algReflOne->setProperty("OutputWorkspace", run + "_IvsQ"); - algReflOne->setProperty("OutputWorkspaceWaveLength", run + "_IvsLam"); + algReflOne->setProperty("InputWorkspace", runWS->name()); + if(transWS) + algReflOne->setProperty("FirstTransmissionRun", transWS->name()); + algReflOne->setProperty("OutputWorkspace", "IvsQ_" + runNo); + algReflOne->setProperty("OutputWorkspaceWaveLength", "IvsLam_" + runNo); algReflOne->setProperty("ThetaIn", theta); + + //Parse and set any user-specified options + auto optionsMap = parseKeyValueString(options); + for(auto kvp = optionsMap.begin(); kvp != optionsMap.end(); ++kvp) + { + try + { + algReflOne->setProperty(kvp->first, kvp->second); + } + catch(Mantid::Kernel::Exception::NotFoundError&) + { + throw std::runtime_error("Invalid property in options column: " + kvp->first); + } + } + algReflOne->execute(); if(!algReflOne->isExecuted()) throw std::runtime_error("Failed to run ReflectometryReductionOneAuto."); - MatrixWorkspace_sptr runWSQ = algReflOne->getProperty("OutputWorkspace"); - MatrixWorkspace_sptr runWSLam = algReflOne->getProperty("OutputWorkspaceWaveLength"); + const double scale = m_model->data(m_model->index(rowNo, COL_SCALE)).toDouble(); + if(scale != 1.0) + { + IAlgorithm_sptr algScale = AlgorithmManager::Instance().create("Scale"); + algScale->initialize(); + algScale->setProperty("InputWorkspace", "IvsQ_" + runNo); + algScale->setProperty("OutputWorkspace", "IvsQ_" + runNo); + algScale->setProperty("Factor", 1.0 / scale); + algScale->execute(); - std::vector built_params; - built_params.push_back(qmin); - built_params.push_back(-dqq); - built_params.push_back(qmax); + if(!algScale->isExecuted()) + throw std::runtime_error("Failed to run Scale algorithm"); + } - IAlgorithm_sptr algRebinQ = AlgorithmManager::Instance().create("Rebin"); - algRebinQ->initialize(); - algRebinQ->setChild(true); - algRebinQ->setProperty("InputWorkspace", runWSQ); - algRebinQ->setProperty("Params", built_params); - algRebinQ->setProperty("OutputWorkspace", run + "_IvsQ_binned"); - algRebinQ->execute(); + //Reduction has completed. Put Qmin and Qmax into the table if needed, for stitching. + if(m_model->data(m_model->index(rowNo, COL_QMIN)).toString().isEmpty() || m_model->data(m_model->index(rowNo, COL_QMAX)).toString().isEmpty()) + { + MatrixWorkspace_sptr ws = AnalysisDataService::Instance().retrieveWS("IvsQ_" + runNo); + std::vector qrange = calcQRange(ws, theta); - IAlgorithm_sptr algRebinLam = AlgorithmManager::Instance().create("Rebin"); - algRebinLam->initialize(); - algRebinLam->setChild(true); - algRebinLam->setProperty("InputWorkspace", runWSLam); - algRebinLam->setProperty("Params", built_params); - algRebinLam->setProperty("OutputWorkspace", run + "_IvsLam_binned"); - algRebinLam->execute(); + if(m_model->data(m_model->index(rowNo, COL_QMIN)).toString().isEmpty()) + m_model->setData(m_model->index(rowNo, COL_QMIN), qrange[0]); - MatrixWorkspace_sptr runWSQBin = algRebinQ->getProperty("OutputWorkspace"); - MatrixWorkspace_sptr runWSLamBin = algRebinLam->getProperty("OutputWorkspace"); + if(m_model->data(m_model->index(rowNo, COL_QMAX)).toString().isEmpty()) + m_model->setData(m_model->index(rowNo, COL_QMAX), qrange[1]); - //Finally, place the resulting workspaces into the ADS. - AnalysisDataService::Instance().addOrReplace(run + "_TOF", runWS); + m_tableDirty = true; + } + } - AnalysisDataService::Instance().addOrReplace(run + "_IvsQ", runWSQ); - AnalysisDataService::Instance().addOrReplace(run + "_IvsLam", runWSLam); + /** + Calculates the minimum and maximum values for Q + @param ws : The workspace to fetch the instrument values from + @param theta : The value of two theta to use in calculations + */ + std::vector ReflMainViewPresenter::calcQRange(MatrixWorkspace_sptr ws, double theta) + { + double lmin, lmax; + try + { + const Instrument_const_sptr instrument = ws->getInstrument(); + lmin = instrument->getNumberParameter("LambdaMin")[0]; + lmax = instrument->getNumberParameter("LambdaMax")[0]; + } + catch(std::exception&) + { + throw std::runtime_error("LambdaMin/LambdaMax instrument parameters are required to calculate qmin/qmax"); + } - AnalysisDataService::Instance().addOrReplace(run + "_IvsQ_binned", runWSQBin); - AnalysisDataService::Instance().addOrReplace(run + "_IvsLam_binned", runWSLamBin); + double qmin = 4 * M_PI / lmax * sin(theta * M_PI / 180.0); + double qmax = 4 * M_PI / lmin * sin(theta * M_PI / 180.0); - AnalysisDataService::Instance().addOrReplace(transWSName, transWS); + if(m_options["RoundQMin"].toBool()) + qmin = Utils::roundToDP(qmin, m_options["RoundQMinPrecision"].toInt()); + + if(m_options["RoundQMax"].toBool()) + qmax = Utils::roundToDP(qmax, m_options["RoundQMaxPrecision"].toInt()); + + std::vector ret; + ret.push_back(qmin); + ret.push_back(qmax); + return ret; } /** - Converts a transmission workspace input string into its ADS name - @param transString : the comma separated transmission run numbers to use - @returns the ADS name the transmission run should be stored as + Stitches the workspaces created by the given rows together. + @param rows : the list of rows */ - std::string ReflMainViewPresenter::makeTransWSName(const std::string& transString) + void ReflMainViewPresenter::stitchRows(std::set rows) { - std::vector transVec; - boost::split(transVec, transString, boost::is_any_of(",")); - return "TRANS_" + transVec[0] + (transVec.size() > 1 ? "_" + transVec[1] : ""); + //If we can get away with doing nothing, do. + if(rows.size() < 2) + return; + + //Properties for Stitch1DMany + std::vector workspaceNames; + std::vector runs; + + std::vector params; + std::vector startOverlaps; + std::vector endOverlaps; + + //Go through each row and prepare the properties + for(auto rowIt = rows.begin(); rowIt != rows.end(); ++rowIt) + { + const std::string runStr = m_model->data(m_model->index(*rowIt, COL_RUNS)).toString().toStdString(); + const double qmin = m_model->data(m_model->index(*rowIt, COL_QMIN)).toDouble(); + const double qmax = m_model->data(m_model->index(*rowIt, COL_QMAX)).toDouble(); + + Workspace_sptr runWS = loadRun(runStr); + if(runWS) + { + const std::string runNo = getRunNumber(runWS); + if(AnalysisDataService::Instance().doesExist("IvsQ_" + runNo)) + { + runs.push_back(runNo); + workspaceNames.push_back("IvsQ_" + runNo); + } + } + + startOverlaps.push_back(qmin); + endOverlaps.push_back(qmax); + } + + double dqq = m_model->data(m_model->index(*(rows.begin()), COL_DQQ)).toDouble(); + + //params are qmin, -dqq, qmax for the final output + params.push_back(*std::min_element(startOverlaps.begin(), startOverlaps.end())); + params.push_back(-dqq); + params.push_back(*std::max_element(endOverlaps.begin(), endOverlaps.end())); + + //startOverlaps and endOverlaps need to be slightly offset from each other + //See usage examples of Stitch1DMany to see why we discard first qmin and last qmax + startOverlaps.erase(startOverlaps.begin()); + endOverlaps.pop_back(); + + std::string outputWSName = "IvsQ_" + boost::algorithm::join(runs, "_"); + + IAlgorithm_sptr algStitch = AlgorithmManager::Instance().create("Stitch1DMany"); + algStitch->initialize(); + algStitch->setProperty("InputWorkspaces", workspaceNames); + algStitch->setProperty("OutputWorkspace", outputWSName); + algStitch->setProperty("Params", params); + algStitch->setProperty("StartOverlaps", startOverlaps); + algStitch->setProperty("EndOverlaps", endOverlaps); + + algStitch->execute(); + + if(!algStitch->isExecuted()) + throw std::runtime_error("Failed to run Stitch1DMany on IvsQ workspaces."); } /** @@ -202,36 +745,25 @@ namespace MantidQt throw std::runtime_error("Failed to parse the transmission run list."); for(auto it = transVec.begin(); it != transVec.end(); ++it) - { - IAlgorithm_sptr algLoadTrans = AlgorithmManager::Instance().create("Load"); - algLoadTrans->initialize(); - algLoadTrans->setChild(true); - algLoadTrans->setProperty("Filename", *it); - algLoadTrans->setProperty("OutputWorkspace", "TRANS_" + *it); + transWSVec.push_back(loadRun(*it, m_view->getProcessInstrument())); - if(!algLoadTrans->isInitialized()) - break; - - algLoadTrans->execute(); - - if(!algLoadTrans->isExecuted()) - break; - - transWSVec.push_back(algLoadTrans->getProperty("OutputWorkspace")); - } - - if(transWSVec.size() != transVec.size()) - throw std::runtime_error("Failed to load one or more transmission runs. Check the run number and Mantid's data directories are correct."); + //If the transmission workspace is already in the ADS, re-use it + std::string lastName = "TRANS_" + boost::algorithm::join(transVec, "_"); + if(AnalysisDataService::Instance().doesExist(lastName)) + return AnalysisDataService::Instance().retrieveWS(lastName); //We have the runs, so we can create a TransWS IAlgorithm_sptr algCreateTrans = AlgorithmManager::Instance().create("CreateTransmissionWorkspaceAuto"); algCreateTrans->initialize(); - algCreateTrans->setChild(true); - algCreateTrans->setProperty("FirstTransmissionRun", boost::dynamic_pointer_cast(transWSVec[0])); + algCreateTrans->setProperty("FirstTransmissionRun", transWSVec[0]->name()); + if(transWSVec.size() > 1) + algCreateTrans->setProperty("SecondTransmissionRun", transWSVec[1]->name()); + + std::string wsName = "TRANS_" + getRunNumber(transWSVec[0]); if(transWSVec.size() > 1) - algCreateTrans->setProperty("SecondTransmissionRun", boost::dynamic_pointer_cast(transWSVec[1])); + wsName += "_" + getRunNumber(transWSVec[1]); - algCreateTrans->setProperty("OutputWorkspace", makeTransWSName(transString)); + algCreateTrans->setProperty("OutputWorkspace", wsName); if(!algCreateTrans->isInitialized()) throw std::runtime_error("Could not initialize CreateTransmissionWorkspaceAuto"); @@ -241,31 +773,48 @@ namespace MantidQt if(!algCreateTrans->isExecuted()) throw std::runtime_error("CreateTransmissionWorkspaceAuto failed to execute"); - return algCreateTrans->getProperty("OutputWorkspace"); + return AnalysisDataService::Instance().retrieveWS(wsName); } /** - Add row(s) to the model + Inserts a new row in the specified location + @param index The index to insert the new row before */ - void ReflMainViewPresenter::addRow() + void ReflMainViewPresenter::insertRow(int index) { - std::vector rows = m_view->getSelectedRowIndexes(); - if (rows.size() == 0) - { - m_model->appendRow(); - } + const int groupId = getUnusedGroup(); + if(!m_model->insertRow(index)) + return; + //Set the default scale to 1.0 + m_model->setData(m_model->index(index, COL_SCALE), 1.0); + //Set the group id of the new row + m_model->setData(m_model->index(index, COL_GROUP), groupId); + } + + /** + Insert a row after the last selected row + */ + void ReflMainViewPresenter::appendRow() + { + std::set rows = m_view->getSelectedRows(); + if(rows.empty()) + insertRow(m_model->rowCount()); else - { - //as selections have to be contigous, then all that needs to be done is add - //a number of rows at the highest index equal to the size of the returned vector - std::sort (rows.begin(), rows.end()); - for (size_t idx = rows.size(); 0 < idx; --idx) - { - m_model->insertRow(rows.at(0)); - } - } + insertRow(*rows.rbegin() + 1); + m_tableDirty = true; + } - m_view->showTable(m_model); + /** + Insert a row before the first selected row + */ + void ReflMainViewPresenter::prependRow() + { + std::set rows = m_view->getSelectedRows(); + if(rows.empty()) + insertRow(0); + else + insertRow(*rows.begin()); + m_tableDirty = true; } /** @@ -273,38 +822,458 @@ namespace MantidQt */ void ReflMainViewPresenter::deleteRow() { - std::vector rows = m_view->getSelectedRowIndexes(); - std::sort(rows.begin(), rows.end()); - for(size_t idx = rows.size(); 0 < idx; --idx) - m_model->removeRow(rows.at(0)); + std::set rows = m_view->getSelectedRows(); + for(auto row = rows.rbegin(); row != rows.rend(); ++row) + m_model->removeRow(*row); - m_view->showTable(m_model); + m_tableDirty = true; + } + + /** + Group rows together + */ + void ReflMainViewPresenter::groupRows() + { + const std::set rows = m_view->getSelectedRows(); + //Find the first unused group id, ignoring the selected rows + const int groupId = getUnusedGroup(rows); + + //Now we just have to set the group id on the selected rows + for(auto it = rows.begin(); it != rows.end(); ++it) + m_model->setData(m_model->index(*it, COL_GROUP), groupId); + + m_tableDirty = true; } /** Used by the view to tell the presenter something has changed */ - void ReflMainViewPresenter::notify(int flag) + void ReflMainViewPresenter::notify(IReflPresenter::Flag flag) { switch(flag) { - case ReflMainView::SaveAsFlag: saveAs(); break; - case ReflMainView::SaveFlag: save(); break; - case ReflMainView::AddRowFlag: addRow(); break; - case ReflMainView::DeleteRowFlag: deleteRow(); break; - case ReflMainView::ProcessFlag: process(); break; - - case ReflMainView::NoFlags: return; + case IReflPresenter::SaveAsFlag: saveTableAs(); break; + case IReflPresenter::SaveFlag: saveTable(); break; + case IReflPresenter::AppendRowFlag: appendRow(); break; + case IReflPresenter::PrependRowFlag: prependRow(); break; + case IReflPresenter::DeleteRowFlag: deleteRow(); break; + case IReflPresenter::ProcessFlag: process(); break; + case IReflPresenter::GroupRowsFlag: groupRows(); break; + case IReflPresenter::OpenTableFlag: openTable(); break; + case IReflPresenter::NewTableFlag: newTable(); break; + case IReflPresenter::TableUpdatedFlag: m_tableDirty = true; break; + case IReflPresenter::ExpandSelectionFlag: expandSelection(); break; + case IReflPresenter::OptionsDialogFlag: showOptionsDialog(); break; + case IReflPresenter::ClearSelectedFlag: clearSelected(); break; + case IReflPresenter::CopySelectedFlag: copySelected(); break; + case IReflPresenter::CutSelectedFlag: cutSelected(); break; + case IReflPresenter::PasteSelectedFlag: pasteSelected(); break; + case IReflPresenter::SearchFlag: search(); break; + case IReflPresenter::TransferFlag: transfer(); break; + case IReflPresenter::ImportTableFlag: importTable(); break; + case IReflPresenter::ExportTableFlag: exportTable(); break; } //Not having a 'default' case is deliberate. gcc issues a warning if there's a flag we aren't handling. } /** - Load the model into the table + Press changes to the same item in the ADS */ - void ReflMainViewPresenter::load() + void ReflMainViewPresenter::saveTable() { + if(!m_wsName.empty()) + { + AnalysisDataService::Instance().addOrReplace(m_wsName,boost::shared_ptr(m_ws->clone())); + m_tableDirty = false; + } + else + { + saveTableAs(); + } + } + + /** + Press changes to a new item in the ADS + */ + void ReflMainViewPresenter::saveTableAs() + { + const std::string userString = m_view->askUserString("Save As", "Enter a workspace name:", "Workspace"); + if(!userString.empty()) + { + m_wsName = userString; + saveTable(); + } + } + + /** + Start a new, untitled table + */ + void ReflMainViewPresenter::newTable() + { + if(m_tableDirty && m_options["WarnDiscardChanges"].toBool()) + if(!m_view->askUserYesNo("Your current table has unsaved changes. Are you sure you want to discard them?","Start New Table?")) + return; + + m_ws = createDefaultWorkspace(); + m_model.reset(new QReflTableModel(m_ws)); + m_wsName.clear(); m_view->showTable(m_model); + + m_tableDirty = false; + } + + /** + Open a table from the ADS + */ + void ReflMainViewPresenter::openTable() + { + if(m_tableDirty && m_options["WarnDiscardChanges"].toBool()) + if(!m_view->askUserYesNo("Your current table has unsaved changes. Are you sure you want to discard them?","Open Table?")) + return; + + auto& ads = AnalysisDataService::Instance(); + const std::string toOpen = m_view->getWorkspaceToOpen(); + + if(toOpen.empty()) + return; + + if(!ads.isValid(toOpen).empty()) + { + m_view->giveUserCritical("Could not open workspace: " + toOpen, "Error"); + return; + } + + ITableWorkspace_sptr origTable = AnalysisDataService::Instance().retrieveWS(toOpen); + + //We create a clone of the table for live editing. The original is not updated unless we explicitly save. + ITableWorkspace_sptr newTable = boost::shared_ptr(origTable->clone()); + try + { + validateModel(newTable); + m_ws = newTable; + m_model.reset(new QReflTableModel(m_ws)); + m_wsName = toOpen; + m_view->showTable(m_model); + m_tableDirty = false; + } + catch(std::runtime_error& e) + { + m_view->giveUserCritical("Could not open workspace: " + std::string(e.what()), "Error"); + } + } + + /** + Import a table from TBL file + */ + void ReflMainViewPresenter::importTable() + { + m_view->showAlgorithmDialog("LoadReflTBL"); + } + + /** + Export a table to TBL file + */ + void ReflMainViewPresenter::exportTable() + { + m_view->showAlgorithmDialog("SaveReflTBL"); + } + + /** + Handle ADS add events + */ + void ReflMainViewPresenter::handleAddEvent(Mantid::API::WorkspaceAddNotification_ptr pNf) + { + const std::string name = pNf->objectName(); + + if(Mantid::API::AnalysisDataService::Instance().isHiddenDataServiceObject(name)) + return; + + if(!isValidModel(pNf->object())) + return; + + m_workspaceList.insert(name); + m_view->setTableList(m_workspaceList); + } + + /** + Handle ADS remove events + */ + void ReflMainViewPresenter::handleRemEvent(Mantid::API::WorkspacePostDeleteNotification_ptr pNf) + { + const std::string name = pNf->objectName(); + m_workspaceList.erase(name); + m_view->setTableList(m_workspaceList); + } + + /** + Handle ADS clear events + */ + void ReflMainViewPresenter::handleClearEvent(Mantid::API::ClearADSNotification_ptr) + { + m_workspaceList.clear(); + m_view->setTableList(m_workspaceList); + } + + /** + Handle ADS rename events + */ + void ReflMainViewPresenter::handleRenameEvent(Mantid::API::WorkspaceRenameNotification_ptr pNf) + { + //If we have this workspace, rename it + const std::string name = pNf->objectName(); + const std::string newName = pNf->newObjectName(); + + if(m_workspaceList.find(name) == m_workspaceList.end()) + return; + + m_workspaceList.erase(name); + m_workspaceList.insert(newName); + m_view->setTableList(m_workspaceList); + } + + /** + Handle ADS replace events + */ + void ReflMainViewPresenter::handleReplaceEvent(Mantid::API::WorkspaceAfterReplaceNotification_ptr pNf) + { + const std::string name = pNf->objectName(); + //Erase it + m_workspaceList.erase(name); + + //If it's a table workspace, bring it back + if(isValidModel(pNf->object())) + m_workspaceList.insert(name); + + m_view->setTableList(m_workspaceList); + } + + /** Returns how many rows there are in a given group + @param groupId : The id of the group to count the rows of + @returns The number of rows in the group + */ + size_t ReflMainViewPresenter::numRowsInGroup(int groupId) const + { + size_t count = 0; + for(int i = 0; i < m_model->rowCount(); ++i) + if(m_model->data(m_model->index(i, COL_GROUP)).toInt() == groupId) + count++; + return count; + } + + /** Expands the current selection to all the rows in the selected groups */ + void ReflMainViewPresenter::expandSelection() + { + std::set groupIds; + + std::set rows = m_view->getSelectedRows(); + for(auto row = rows.begin(); row != rows.end(); ++row) + groupIds.insert(m_model->data(m_model->index(*row, COL_GROUP)).toInt()); + + std::set selection; + + for(int i = 0; i < m_model->rowCount(); ++i) + if(groupIds.find(m_model->data(m_model->index(i, COL_GROUP)).toInt()) != groupIds.end()) + selection.insert(i); + + m_view->setSelection(selection); + } + + /** Clear the currently selected rows */ + void ReflMainViewPresenter::clearSelected() + { + std::set rows = m_view->getSelectedRows(); + std::set ignore; + for(auto row = rows.begin(); row != rows.end(); ++row) + { + ignore.clear(); + ignore.insert(*row); + + m_model->setData(m_model->index(*row, COL_RUNS), ""); + m_model->setData(m_model->index(*row, COL_ANGLE), ""); + m_model->setData(m_model->index(*row, COL_TRANSMISSION), ""); + m_model->setData(m_model->index(*row, COL_QMIN), ""); + m_model->setData(m_model->index(*row, COL_QMAX), ""); + m_model->setData(m_model->index(*row, COL_SCALE), 1.0); + m_model->setData(m_model->index(*row, COL_DQQ), ""); + m_model->setData(m_model->index(*row, COL_GROUP), getUnusedGroup(ignore)); + m_model->setData(m_model->index(*row, COL_OPTIONS), ""); + } + m_tableDirty = true; + } + + /** Copy the currently selected rows to the clipboard */ + void ReflMainViewPresenter::copySelected() + { + std::vector lines; + + std::set rows = m_view->getSelectedRows(); + for(auto rowIt = rows.begin(); rowIt != rows.end(); ++rowIt) + { + std::vector line; + for(int col = COL_RUNS; col <= COL_OPTIONS; ++col) + line.push_back(m_model->data(m_model->index(*rowIt, col)).toString().toStdString()); + lines.push_back(boost::algorithm::join(line, "\t")); + } + + m_view->setClipboard(boost::algorithm::join(lines, "\n")); + } + + /** Copy currently selected rows to the clipboard, and then delete them. */ + void ReflMainViewPresenter::cutSelected() + { + copySelected(); + deleteRow(); + } + + /** Paste the contents of the clipboard into the currently selected rows, or append new rows */ + void ReflMainViewPresenter::pasteSelected() + { + const std::string text = m_view->getClipboard(); + std::vector lines; + boost::split(lines, text, boost::is_any_of("\n")); + + //If we have rows selected, we'll overwrite them. If not, we'll append new rows to write to. + std::set rows = m_view->getSelectedRows(); + if(rows.empty()) + { + //Add as many new rows as required + for(size_t i = 0; i < lines.size(); ++i) + { + int index = m_model->rowCount(); + insertRow(index); + rows.insert(index); + } + } + + //Iterate over rows and lines simultaneously, stopping when we reach the end of either + auto rowIt = rows.begin(); + auto lineIt = lines.begin(); + for(; rowIt != rows.end() && lineIt != lines.end(); rowIt++, lineIt++) + { + std::vector values; + boost::split(values, *lineIt, boost::is_any_of("\t")); + + //Paste as many columns as we can from this line + for(int col = COL_RUNS; col <= COL_OPTIONS && col < static_cast(values.size()); ++col) + m_model->setData(m_model->index(*rowIt, col), QString::fromStdString(values[col])); + } + } + + /** Searches for runs that can be used */ + void ReflMainViewPresenter::search() + { + const std::string searchString = m_view->getSearchString(); + const std::string searchInstr = m_view->getSearchInstrument(); + + //Don't bother searching if they're not searching for anything + if(searchString.empty()) + return; + + try + { + auto results = m_searcher->search(searchString, searchInstr); + m_searchModel = ReflSearchModel_sptr(new ReflSearchModel(results)); + m_view->showSearch(m_searchModel); + } + catch(std::runtime_error& e) + { + m_view->giveUserCritical("Error running search:\n" + std::string(e.what()), "Search Failed"); + } + } + + /** Transfers the selected runs in the search results to the processing table */ + void ReflMainViewPresenter::transfer() + { + //Build the input for the transfer strategy + std::map runs; + auto selectedRows = m_view->getSelectedSearchRows(); + for(auto rowIt = selectedRows.begin(); rowIt != selectedRows.end(); ++rowIt) + { + const int row = *rowIt; + const std::string run = m_searchModel->data(m_searchModel->index(row, 0)).toString().toStdString(); + const std::string description = m_searchModel->data(m_searchModel->index(row, 1)).toString().toStdString(); + runs[run] = description; + } + + auto newRows = m_transferStrategy->transferRuns(runs); + + std::map groups; + for(auto rowIt = newRows.begin(); rowIt != newRows.end(); ++rowIt) + { + auto& row = *rowIt; + + if(groups.count(row["group"]) == 0) + groups[row["group"]] = getUnusedGroup(); + + const int rowIndex = m_model->rowCount(); + m_model->insertRow(rowIndex); + m_model->setData(m_model->index(rowIndex, COL_RUNS), QString::fromStdString(row["runs"])); + m_model->setData(m_model->index(rowIndex, COL_ANGLE), QString::fromStdString(row["theta"])); + m_model->setData(m_model->index(rowIndex, COL_SCALE), 1.0); + m_model->setData(m_model->index(rowIndex, COL_GROUP), groups[row["group"]]); + } + } + + /** Shows the Refl Options dialog */ + void ReflMainViewPresenter::showOptionsDialog() + { + auto options = new QtReflOptionsDialog(m_view, m_view->getPresenter()); + //By default the dialog is only destroyed when ReflMainView is and so they'll stack up. + //This way, they'll be deallocated as soon as they've been closed. + options->setAttribute(Qt::WA_DeleteOnClose, true); + options->exec(); + } + + /** Gets the options used by the presenter + @returns The options used by the presenter + */ + const std::map& ReflMainViewPresenter::options() const + { + return m_options; + } + + /** Sets the options used by the presenter + @param options : The new options for the presenter to use + */ + void ReflMainViewPresenter::setOptions(const std::map& options) + { + //Overwrite the given options + for(auto it = options.begin(); it != options.end(); ++it) + m_options[it->first] = it->second; + + //Save any changes to disk + QSettings settings; + settings.beginGroup(ReflSettingsGroup); + for(auto it = m_options.begin(); it != m_options.end(); ++it) + settings.setValue(QString::fromStdString(it->first), it->second); + settings.endGroup(); + } + + /** Load options from disk if possible, or set to defaults */ + void ReflMainViewPresenter::initOptions() + { + m_options.clear(); + + //Set defaults + m_options["WarnProcessAll"] = true; + m_options["WarnDiscardChanges"] = true; + m_options["WarnProcessPartialGroup"] = true; + m_options["RoundAngle"] = false; + m_options["RoundQMin"] = false; + m_options["RoundQMax"] = false; + m_options["RoundDQQ"] = false; + m_options["RoundAnglePrecision"] = 3; + m_options["RoundQMinPrecision"] = 3; + m_options["RoundQMaxPrecision"] = 3; + m_options["RoundDQQPrecision"] = 3; + + //Load saved values from disk + QSettings settings; + settings.beginGroup(ReflSettingsGroup); + QStringList keys = settings.childKeys(); + for(auto it = keys.begin(); it != keys.end(); ++it) + m_options[it->toStdString()] = settings.value(*it); + settings.endGroup(); } } } diff --git a/Code/Mantid/MantidQt/CustomInterfaces/src/ReflNullMainViewPresenter.cpp b/Code/Mantid/MantidQt/CustomInterfaces/src/ReflNullMainViewPresenter.cpp deleted file mode 100644 index 2af3afc4169d..000000000000 --- a/Code/Mantid/MantidQt/CustomInterfaces/src/ReflNullMainViewPresenter.cpp +++ /dev/null @@ -1,19 +0,0 @@ -#include "MantidQtCustomInterfaces/ReflNullMainViewPresenter.h" -#include "MantidAPI/ITableWorkspace.h" -#include "MantidQtCustomInterfaces/ReflMainView.h" - -namespace MantidQt -{ - namespace CustomInterfaces - { - void ReflNullMainViewPresenter::notify(int flag) - { - (void)flag; - throw std::runtime_error("Cannot notify a null presenter"); - } - - ReflNullMainViewPresenter::~ReflNullMainViewPresenter() - { - } - } -} diff --git a/Code/Mantid/MantidQt/CustomInterfaces/src/ReflSearchModel.cpp b/Code/Mantid/MantidQt/CustomInterfaces/src/ReflSearchModel.cpp new file mode 100644 index 000000000000..c95413cbb8fd --- /dev/null +++ b/Code/Mantid/MantidQt/CustomInterfaces/src/ReflSearchModel.cpp @@ -0,0 +1,116 @@ +#include "MantidQtCustomInterfaces/ReflSearchModel.h" +#include "MantidAPI/ITableWorkspace.h" +#include "MantidAPI/TableRow.h" + +namespace MantidQt +{ + namespace CustomInterfaces + { + using namespace Mantid::API; + + //---------------------------------------------------------------------------------------------- + /** Constructor + @param tableWorkspace : The table workspace to copy data from + */ + ReflSearchModel::ReflSearchModel(ITableWorkspace_sptr tableWorkspace) + { + //Copy the data from the input table workspace + for(size_t i = 0; i < tableWorkspace->rowCount(); ++i) + { + const std::string run = tableWorkspace->String(i,0); + const std::string description = tableWorkspace->String(i,6); + m_runs.push_back(run); + m_descriptions[run] = description; + } + + //By sorting the vector of runs, we sort the entire table + std::sort(m_runs.begin(), m_runs.end()); + } + + //---------------------------------------------------------------------------------------------- + /** Destructor + */ + ReflSearchModel::~ReflSearchModel() + { + } + + /** + @return the row count. + */ + int ReflSearchModel::rowCount(const QModelIndex &) const + { + return static_cast(m_runs.size()); + } + + /** + @return the number of columns in the model. + */ + int ReflSearchModel::columnCount(const QModelIndex &) const + { + return 2; + } + + /** + Overrident data method, allows consuming view to extract data for an index and role. + @param index : For which to extract the data + @param role : Role mode + */ + QVariant ReflSearchModel::data(const QModelIndex &index, int role) const + { + if(role != Qt::DisplayRole) + return QVariant(); + + const int colNumber = index.column(); + const int rowNumber = index.row(); + + if(rowNumber < 0 || rowNumber >= static_cast(m_runs.size())) + return QVariant(); + + const std::string run = m_runs[rowNumber]; + + if(colNumber == 0) + return QString::fromStdString(run); + + if(colNumber == 1) + return QString::fromStdString(m_descriptions.find(run)->second); + + return QVariant(); + } + + /** + Get the heading for a given section, orientation and role. + @param section : Column index + @param orientation : Heading orientation + @param role : Role mode of table. + @return HeaderData. + */ + QVariant ReflSearchModel::headerData(int section, Qt::Orientation orientation, int role) const + { + if(role != Qt::DisplayRole) + return QVariant(); + + if(orientation == Qt::Horizontal) + { + switch(section) + { + case 0: return "Run"; + case 1: return "Description"; + default: return ""; + } + } + return QVariant(); + } + + /** + Provide flags on an index by index basis + @param index: To generate a flag for. + */ + Qt::ItemFlags ReflSearchModel::flags(const QModelIndex &index) const + { + if(!index.isValid()) + return 0; + else + return Qt::ItemIsEnabled | Qt::ItemIsSelectable; + } + } // namespace CustomInterfaces +} // namespace Mantid diff --git a/Code/Mantid/MantidQt/CustomInterfaces/src/ResNorm.cpp b/Code/Mantid/MantidQt/CustomInterfaces/src/ResNorm.cpp index 5ab1d38bd4f2..7665cb062e51 100644 --- a/Code/Mantid/MantidQt/CustomInterfaces/src/ResNorm.cpp +++ b/Code/Mantid/MantidQt/CustomInterfaces/src/ResNorm.cpp @@ -10,10 +10,21 @@ namespace MantidQt { m_uiForm.setupUi(parent); - //add the plot to the ui form - m_uiForm.plotSpace->addWidget(m_plot); - //add the properties browser to the ui form + // Create the plot + m_plots["ResNormPlot"] = new QwtPlot(m_parentWidget); + m_plots["ResNormPlot"]->setCanvasBackground(Qt::white); + m_plots["ResNormPlot"]->setAxisFont(QwtPlot::xBottom, parent->font()); + m_plots["ResNormPlot"]->setAxisFont(QwtPlot::yLeft, parent->font()); + m_uiForm.plotSpace->addWidget(m_plots["ResNormPlot"]); + + // Create range selector + m_rangeSelectors["ResNormERange"] = new MantidWidgets::RangeSelector(m_plots["ResNormPlot"]); + connect(m_rangeSelectors["ResNormERange"], SIGNAL(minValueChanged(double)), this, SLOT(minValueChanged(double))); + connect(m_rangeSelectors["ResNormERange"], SIGNAL(maxValueChanged(double)), this, SLOT(maxValueChanged(double))); + + // Add the properties browser to the ui form m_uiForm.treeSpace->addWidget(m_propTree); + m_properties["EMin"] = m_dblManager->addProperty("EMin"); m_properties["EMax"] = m_dblManager->addProperty("EMax"); m_properties["VanBinning"] = m_dblManager->addProperty("Van Binning"); @@ -34,6 +45,10 @@ namespace MantidQt connect(m_uiForm.dsVanadium, SIGNAL(dataReady(const QString&)), this, SLOT(handleVanadiumInputReady(const QString&))); } + void ResNorm::setup() + { + } + /** * Validate the form to check the program can be run * @@ -110,9 +125,9 @@ namespace MantidQt */ void ResNorm::handleVanadiumInputReady(const QString& filename) { - plotMiniPlot(filename, 0); + plotMiniPlot(filename, 0, "ResNormPlot", "RawPlotCurve"); std::pair res; - std::pair range = getCurveRange(); + std::pair range = getCurveRange("RawPlotCurve"); //Use the values from the instrument parameter file if we can if(getInstrumentResolution(filename, res)) @@ -121,14 +136,14 @@ namespace MantidQt res.first = res.first * 10; res.second = res.second * 10; - setMiniPlotGuides(m_properties["EMin"], m_properties["EMax"], res); + setMiniPlotGuides("ResNormERange", m_properties["EMin"], m_properties["EMax"], res); } else { - setMiniPlotGuides(m_properties["EMin"], m_properties["EMax"], range); + setMiniPlotGuides("ResNormERange", m_properties["EMin"], m_properties["EMax"], range); } - setPlotRange(m_properties["EMin"], m_properties["EMax"], range); + setPlotRange("ResNormERange", m_properties["EMin"], m_properties["EMax"], range); } /** @@ -161,11 +176,11 @@ namespace MantidQt { if(prop == m_properties["EMin"]) { - updateLowerGuide(m_properties["EMin"], m_properties["EMax"], val); + updateLowerGuide(m_rangeSelectors["ResNormERange"], m_properties["EMin"], m_properties["EMax"], val); } else if (prop == m_properties["EMax"]) { - updateUpperGuide(m_properties["EMin"], m_properties["EMax"], val); + updateUpperGuide(m_rangeSelectors["ResNormERange"], m_properties["EMin"], m_properties["EMax"], val); } } } // namespace CustomInterfaces diff --git a/Code/Mantid/MantidQt/CustomInterfaces/src/Stretch.cpp b/Code/Mantid/MantidQt/CustomInterfaces/src/Stretch.cpp index e75822650e92..83f8217d2830 100644 --- a/Code/Mantid/MantidQt/CustomInterfaces/src/Stretch.cpp +++ b/Code/Mantid/MantidQt/CustomInterfaces/src/Stretch.cpp @@ -1,6 +1,11 @@ #include "MantidQtCustomInterfaces/Stretch.h" #include "MantidQtCustomInterfaces/UserInputValidator.h" +namespace +{ + Mantid::Kernel::Logger g_log("Stretch"); +} + namespace MantidQt { namespace CustomInterfaces @@ -10,9 +15,19 @@ namespace MantidQt { m_uiForm.setupUi(parent); - //add the plot to the ui form - m_uiForm.plotSpace->addWidget(m_plot); - //add the properties browser to the ui form + // Create the plot + m_plots["StretchPlot"] = new QwtPlot(m_parentWidget); + m_plots["StretchPlot"]->setCanvasBackground(Qt::white); + m_plots["StretchPlot"]->setAxisFont(QwtPlot::xBottom, parent->font()); + m_plots["StretchPlot"]->setAxisFont(QwtPlot::yLeft, parent->font()); + m_uiForm.plotSpace->addWidget(m_plots["StretchPlot"]); + + // Create range selector + m_rangeSelectors["StretchERange"] = new MantidWidgets::RangeSelector(m_plots["StretchPlot"]); + connect(m_rangeSelectors["StretchERange"], SIGNAL(minValueChanged(double)), this, SLOT(minValueChanged(double))); + connect(m_rangeSelectors["StretchERange"], SIGNAL(maxValueChanged(double)), this, SLOT(maxValueChanged(double))); + + // Add the properties browser to the ui form m_uiForm.treeSpace->addWidget(m_propTree); m_properties["EMin"] = m_dblManager->addProperty("EMin"); @@ -48,6 +63,10 @@ namespace MantidQt connect(m_uiForm.chkSequentialFit, SIGNAL(toggled(bool)), m_uiForm.cbPlot, SLOT(setEnabled(bool))); } + void Stretch::setup() + { + } + /** * Validate the form to check the program can be run * @@ -75,6 +94,8 @@ namespace MantidQt */ void Stretch::run() { + using namespace Mantid::API; + QString save("False"); QString verbose("False"); @@ -138,10 +159,10 @@ namespace MantidQt */ void Stretch::handleSampleInputReady(const QString& filename) { - plotMiniPlot(filename, 0); - std::pair range = getCurveRange(); - setMiniPlotGuides(m_properties["EMin"], m_properties["EMax"], range); - setPlotRange(m_properties["EMin"], m_properties["EMax"], range); + plotMiniPlot(filename, 0, "StretchPlot", "RawPlotCurve"); + std::pair range = getCurveRange("RawPlotCurve"); + setMiniPlotGuides("StretchERange", m_properties["EMin"], m_properties["EMax"], range); + setPlotRange("StretchERange", m_properties["EMin"], m_properties["EMax"], range); } /** @@ -174,11 +195,11 @@ namespace MantidQt { if(prop == m_properties["EMin"]) { - updateLowerGuide(m_properties["EMin"], m_properties["EMax"], val); + updateLowerGuide(m_rangeSelectors["StretchERange"], m_properties["EMin"], m_properties["EMax"], val); } else if (prop == m_properties["EMax"]) { - updateUpperGuide(m_properties["EMin"], m_properties["EMax"], val); + updateUpperGuide(m_rangeSelectors["StretchERange"], m_properties["EMin"], m_properties["EMax"], val); } } diff --git a/Code/Mantid/MantidQt/CustomInterfaces/test/ReflBlankMainViewPresenterTest.h b/Code/Mantid/MantidQt/CustomInterfaces/test/ReflBlankMainViewPresenterTest.h deleted file mode 100644 index f567f699ec8b..000000000000 --- a/Code/Mantid/MantidQt/CustomInterfaces/test/ReflBlankMainViewPresenterTest.h +++ /dev/null @@ -1,340 +0,0 @@ -#ifndef MANTID_CUSTOMINTERFACES_REFLBLANKMAINVIEWPRESENTERTEST_H_ -#define MANTID_CUSTOMINTERFACES_REFLBLANKMAINVIEWPRESENTERTEST_H_ - -#include -#include -#include -#include -#include "MantidDataObjects/TableWorkspace.h" -#include "MantidAPI/ITableWorkspace.h" -#include "MantidQtCustomInterfaces/ReflMainView.h" -#include "MantidAPI/FrameworkManager.h" -#include "MantidAPI/TableRow.h" -#include "MantidQtCustomInterfaces/ReflBlankMainViewPresenter.h" - -#include "ReflMainViewMockObjects.h" - -using namespace MantidQt::CustomInterfaces; -using namespace Mantid::API; -using namespace testing; - -class ReflBlankMainViewPresenterTest : 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 ReflBlankMainViewPresenterTest *createSuite() { return new ReflBlankMainViewPresenterTest(); } - static void destroySuite( ReflBlankMainViewPresenterTest *suite ) { delete suite; } - - void testConstruction() - { - ConstructView constructView; - EXPECT_CALL(constructView, showTable(_)).Times(1); - ReflBlankMainViewPresenter presenter(&constructView); - TS_ASSERT(Mock::VerifyAndClearExpectations(&constructView)); - } - - void testEditSave() - { - FakeView fakeView; - EXPECT_CALL(fakeView, askUserString(_,_,"Workspace")) - .Times(1) - .WillRepeatedly(Return("Workspace")); - ReflBlankMainViewPresenter presenter(&fakeView); - presenter.notify(SaveFlag); - ITableWorkspace_sptr ws = AnalysisDataService::Instance().retrieveWS("Workspace"); - TS_ASSERT_EQUALS(ws->rowCount(), 5); - TS_ASSERT_EQUALS(ws->String(1,0), "13460"); - TS_ASSERT_EQUALS(ws->Int(1,7), 3); - TS_ASSERT(Mock::VerifyAndClearExpectations(&fakeView)); - AnalysisDataService::Instance().remove("Workspace"); - } - - void testSaveAs() - { - MockView mockView; - EXPECT_CALL(mockView, askUserString(_,_,"Workspace")) - .Times(2) - .WillOnce(Return("")) - .WillRepeatedly(Return("Workspace")); - ReflBlankMainViewPresenter presenter(&mockView); - presenter.notify(SaveFlag); - presenter.notify(SaveFlag); - TS_ASSERT(Mock::VerifyAndClearExpectations(&mockView)); - TS_ASSERT(AnalysisDataService::Instance().doesExist("Workspace")); - AnalysisDataService::Instance().remove("Workspace"); - } - - void testSaveProcess() - { - MockView mockView; - EXPECT_CALL(mockView, askUserString(_,_,"Workspace")) - .Times(2) - .WillOnce(Return("")) - .WillRepeatedly(Return("Workspace")); - ReflBlankMainViewPresenter presenter(&mockView); - presenter.notify(SaveAsFlag); - presenter.notify(SaveAsFlag); - presenter.notify(SaveFlag); - TS_ASSERT(Mock::VerifyAndClearExpectations(&mockView)); - TS_ASSERT(AnalysisDataService::Instance().doesExist("Workspace")); - AnalysisDataService::Instance().remove("Workspace"); - } - - void testAddRow() - { - std::vector rowlist = std::vector(); - AddDelProcView mockView; - EXPECT_CALL(mockView, askUserString(_,_,"Workspace")) - .Times(1) - .WillRepeatedly(Return("Workspace")); - EXPECT_CALL(mockView, getSelectedRowIndexes()) - .Times(2) - .WillRepeatedly(Return(rowlist)); - ReflBlankMainViewPresenter presenter(&mockView); - mockView.addDataForTest(); - presenter.notify(AddRowFlag); - presenter.notify(AddRowFlag); - presenter.notify(SaveFlag); - ITableWorkspace_sptr ws = AnalysisDataService::Instance().retrieveWS("Workspace"); - TS_ASSERT_EQUALS(ws->rowCount(), 6); - TS_ASSERT_EQUALS(ws->String(1,0), "13462"); - TS_ASSERT_EQUALS(ws->Int(1,7), 3); - TS_ASSERT_THROWS_NOTHING(ws->Int(4,7)); - TS_ASSERT_THROWS_NOTHING(ws->Int(5,7)); - TS_ASSERT_EQUALS(ws->String(4,0), ""); - TS_ASSERT_EQUALS(ws->Int(4,7), 0); - TS_ASSERT_EQUALS(ws->String(5,0), ""); - TS_ASSERT_EQUALS(ws->Int(5,7), 0); - TS_ASSERT_THROWS(ws->Int(6,7),std::runtime_error); - TS_ASSERT(Mock::VerifyAndClearExpectations(&mockView)); - AnalysisDataService::Instance().remove("Workspace"); - } - - void testAddRowSpecify() - { - std::vector rowlist; - rowlist.push_back(1); - AddDelProcView mockView; - EXPECT_CALL(mockView, askUserString(_,_,"Workspace")) - .Times(1) - .WillRepeatedly(Return("Workspace")); - EXPECT_CALL(mockView, getSelectedRowIndexes()) - .Times(2) - .WillRepeatedly(Return(rowlist)); - ReflBlankMainViewPresenter presenter(&mockView); - mockView.addDataForTest(); - presenter.notify(AddRowFlag); - presenter.notify(AddRowFlag); - presenter.notify(SaveFlag); - ITableWorkspace_sptr ws = AnalysisDataService::Instance().retrieveWS("Workspace"); - TS_ASSERT_EQUALS(ws->rowCount(), 6); - TS_ASSERT_EQUALS(ws->String(1,0), ""); - TS_ASSERT_EQUALS(ws->Int(1,7), 0); - TS_ASSERT_EQUALS(ws->String(2,0), ""); - TS_ASSERT_EQUALS(ws->Int(2,7), 0); - TS_ASSERT_THROWS_NOTHING(ws->Int(4,7)); - TS_ASSERT_THROWS_NOTHING(ws->Int(5,7)); - TS_ASSERT_EQUALS(ws->String(4,0), "13469"); - TS_ASSERT_EQUALS(ws->Int(4,7), 1); - TS_ASSERT_EQUALS(ws->String(5,0), "13470"); - TS_ASSERT_EQUALS(ws->Int(5,7), 1); - TS_ASSERT_THROWS(ws->Int(6,7),std::runtime_error); - TS_ASSERT(Mock::VerifyAndClearExpectations(&mockView)); - AnalysisDataService::Instance().remove("Workspace"); - } - - void testAddRowSpecifyPlural() - { - std::vector rowlist; - rowlist.push_back(1); - rowlist.push_back(2); - rowlist.push_back(3); - AddDelProcView mockView; - EXPECT_CALL(mockView, askUserString(_,_,"Workspace")) - .Times(1) - .WillRepeatedly(Return("Workspace")); - EXPECT_CALL(mockView, getSelectedRowIndexes()) - .Times(1) - .WillRepeatedly(Return(rowlist)); - ReflBlankMainViewPresenter presenter(&mockView); - mockView.addDataForTest(); - presenter.notify(AddRowFlag); - presenter.notify(SaveFlag); - ITableWorkspace_sptr ws = AnalysisDataService::Instance().retrieveWS("Workspace"); - TS_ASSERT_EQUALS(ws->rowCount(), 7); - TS_ASSERT_EQUALS(ws->String(1,0), ""); - TS_ASSERT_EQUALS(ws->Int(1,7), 0); - TS_ASSERT_EQUALS(ws->String(2,0), ""); - TS_ASSERT_EQUALS(ws->Int(2,7), 0); - TS_ASSERT_EQUALS(ws->String(3,0), ""); - TS_ASSERT_EQUALS(ws->Int(3,7), 0); - TS_ASSERT_THROWS_NOTHING(ws->Int(4,7)); - TS_ASSERT_THROWS_NOTHING(ws->Int(5,7)); - TS_ASSERT_THROWS_NOTHING(ws->Int(6,7)); - TS_ASSERT_EQUALS(ws->String(4,0), "13462"); - TS_ASSERT_EQUALS(ws->Int(4,7), 3); - TS_ASSERT_EQUALS(ws->String(5,0), "13469"); - TS_ASSERT_EQUALS(ws->Int(5,7), 1); - TS_ASSERT_EQUALS(ws->String(6,0), "13470"); - TS_ASSERT_EQUALS(ws->Int(6,7), 1); - TS_ASSERT_THROWS(ws->Int(7,7),std::runtime_error); - TS_ASSERT(Mock::VerifyAndClearExpectations(&mockView)); - AnalysisDataService::Instance().remove("Workspace"); - } - - void testAddRowNotSequential() - { - std::vector rowlist; - rowlist.push_back(2); - rowlist.push_back(3); - rowlist.push_back(0); - //The rowlist is sorted internally, so 0 will go to the top and be classed as the highest. - //So 3 rows will be added to the top. We can do this as we are only expecting chunks of - //sequential rows, thus this is the expected behavior - AddDelProcView mockView; - EXPECT_CALL(mockView, askUserString(_,_,"Workspace")) - .Times(1) - .WillRepeatedly(Return("Workspace")); - EXPECT_CALL(mockView, getSelectedRowIndexes()) - .Times(1) - .WillRepeatedly(Return(rowlist)); - ReflBlankMainViewPresenter presenter(&mockView); - mockView.addDataForTest(); - presenter.notify(AddRowFlag); - presenter.notify(SaveFlag); - ITableWorkspace_sptr ws = AnalysisDataService::Instance().retrieveWS("Workspace"); - TS_ASSERT_EQUALS(ws->rowCount(), 7); - TS_ASSERT_EQUALS(ws->String(0,0), ""); - TS_ASSERT_EQUALS(ws->Int(0,7), 0); - TS_ASSERT_EQUALS(ws->String(1,0), ""); - TS_ASSERT_EQUALS(ws->Int(1,7), 0); - TS_ASSERT_EQUALS(ws->String(2,0), ""); - TS_ASSERT_EQUALS(ws->Int(2,7), 0); - TS_ASSERT_THROWS_NOTHING(ws->Int(4,7)); - TS_ASSERT_THROWS_NOTHING(ws->Int(5,7)); - TS_ASSERT_THROWS_NOTHING(ws->Int(6,7)); - TS_ASSERT_EQUALS(ws->String(3,0), "13460"); - TS_ASSERT_EQUALS(ws->Int(3,7), 3); - TS_ASSERT_EQUALS(ws->String(4,0), "13462"); - TS_ASSERT_EQUALS(ws->Int(4,7), 3); - TS_ASSERT_EQUALS(ws->String(5,0), "13469"); - TS_ASSERT_EQUALS(ws->Int(5,7), 1); - TS_ASSERT_EQUALS(ws->String(6,0), "13470"); - TS_ASSERT_EQUALS(ws->Int(6,7), 1); - TS_ASSERT_THROWS(ws->Int(7,7),std::runtime_error); - TS_ASSERT(Mock::VerifyAndClearExpectations(&mockView)); - AnalysisDataService::Instance().remove("Workspace"); - } - - void testDeleteRowNone() - { - std::vector rowlist = std::vector(); - AddDelProcView mockView; - EXPECT_CALL(mockView, askUserString(_,_,"Workspace")) - .Times(1) - .WillRepeatedly(Return("Workspace")); - EXPECT_CALL(mockView, getSelectedRowIndexes()) - .Times(1) - .WillRepeatedly(Return(rowlist)); - ReflBlankMainViewPresenter presenter(&mockView); - mockView.addDataForTest(); - presenter.notify(DeleteRowFlag); - presenter.notify(SaveFlag); - ITableWorkspace_sptr ws = AnalysisDataService::Instance().retrieveWS("Workspace"); - TS_ASSERT_THROWS_NOTHING(ws->Int(0,7)); - TS_ASSERT_EQUALS(ws->rowCount(),4); - TS_ASSERT_EQUALS(ws->String(1,0), "13462"); - TS_ASSERT_EQUALS(ws->Int(1,7), 3); - TS_ASSERT_THROWS_NOTHING(ws->Int(2,7)); - TS_ASSERT_THROWS_NOTHING(ws->Int(3,7)); - TS_ASSERT(Mock::VerifyAndClearExpectations(&mockView)); - AnalysisDataService::Instance().remove("Workspace"); - } - - void testDeleteRowSingle() - { - std::vector rowlist; - rowlist.push_back(1); - AddDelProcView mockView; - EXPECT_CALL(mockView, askUserString(_,_,"Workspace")) - .Times(1) - .WillRepeatedly(Return("Workspace")); - EXPECT_CALL(mockView, getSelectedRowIndexes()) - .Times(1) - .WillRepeatedly(Return(rowlist)); - ReflBlankMainViewPresenter presenter(&mockView); - mockView.addDataForTest(); - presenter.notify(DeleteRowFlag); - presenter.notify(SaveFlag); - ITableWorkspace_sptr ws = AnalysisDataService::Instance().retrieveWS("Workspace"); - TS_ASSERT_EQUALS(ws->rowCount(),3); - TS_ASSERT_EQUALS(ws->String(1,0), "13469"); - TS_ASSERT_EQUALS(ws->Int(1,7), 1); - TS_ASSERT_THROWS(ws->Int(3,7),std::runtime_error); - TS_ASSERT(Mock::VerifyAndClearExpectations(&mockView)); - AnalysisDataService::Instance().remove("Workspace"); - } - - void testDeleteRowPlural() - { - std::vector rowlist; - rowlist.push_back(0); - rowlist.push_back(1); - rowlist.push_back(2); - AddDelProcView mockView; - EXPECT_CALL(mockView, askUserString(_,_,"Workspace")) - .Times(1) - .WillRepeatedly(Return("Workspace")); - EXPECT_CALL(mockView, getSelectedRowIndexes()) - .Times(1) - .WillRepeatedly(Return(rowlist)); - ReflBlankMainViewPresenter presenter(&mockView); - mockView.addDataForTest(); - presenter.notify(DeleteRowFlag); - presenter.notify(SaveFlag); - ITableWorkspace_sptr ws = AnalysisDataService::Instance().retrieveWS("Workspace"); - TS_ASSERT_EQUALS(ws->rowCount(),1); - TS_ASSERT_EQUALS(ws->String(0,0), "13470"); - TS_ASSERT_EQUALS(ws->Int(0,7), 1); - TS_ASSERT_THROWS(ws->Int(1,7),std::runtime_error); - TS_ASSERT_THROWS(ws->Int(2,7),std::runtime_error); - TS_ASSERT_THROWS(ws->Int(3,7),std::runtime_error); - TS_ASSERT(Mock::VerifyAndClearExpectations(&mockView)); - AnalysisDataService::Instance().remove("Workspace"); - } - - void testDeleteRowNotSequential() - { - std::vector rowlist; - rowlist.push_back(2); - rowlist.push_back(3); - rowlist.push_back(0); - //The rowlist is sorted internally, so 0 will go to the top and be classed as the highest. - //So 3 rows will be removed from the top. We can do this as we are only expecting chunks of - //sequential rows, thus this is the expected behavior - AddDelProcView mockView; - EXPECT_CALL(mockView, askUserString(_,_,"Workspace")) - .Times(1) - .WillRepeatedly(Return("Workspace")); - EXPECT_CALL(mockView, getSelectedRowIndexes()) - .Times(1) - .WillRepeatedly(Return(rowlist)); - ReflBlankMainViewPresenter presenter(&mockView); - mockView.addDataForTest(); - presenter.notify(DeleteRowFlag); - presenter.notify(SaveFlag); - ITableWorkspace_sptr ws = AnalysisDataService::Instance().retrieveWS("Workspace"); - TS_ASSERT_EQUALS(ws->rowCount(),1); - TS_ASSERT_EQUALS(ws->String(0,0), "13470"); - TS_ASSERT_EQUALS(ws->Int(0,7), 1); - TS_ASSERT_THROWS(ws->Int(1,7),std::runtime_error); - TS_ASSERT_THROWS(ws->Int(2,7),std::runtime_error); - TS_ASSERT_THROWS(ws->Int(3,7),std::runtime_error); - TS_ASSERT(Mock::VerifyAndClearExpectations(&mockView)); - AnalysisDataService::Instance().remove("Workspace"); - } -}; - - -#endif /* MANTID_CUSTOMINTERFACES_REFLBLANKMAINVIEWPRESENTERTEST_H_ */ diff --git a/Code/Mantid/MantidQt/CustomInterfaces/test/ReflLegacyTransferStrategyTest.h b/Code/Mantid/MantidQt/CustomInterfaces/test/ReflLegacyTransferStrategyTest.h new file mode 100644 index 000000000000..61ce4362ea8f --- /dev/null +++ b/Code/Mantid/MantidQt/CustomInterfaces/test/ReflLegacyTransferStrategyTest.h @@ -0,0 +1,182 @@ +#ifndef MANTID_CUSTOMINTERFACES_REFLLEGACYTRANSFERSTRATEGYTEST_H +#define MANTID_CUSTOMINTERFACES_REFLLEGACYTRANSFERSTRATEGYTEST_H + +#include +#include +#include +#include + +#include "MantidQtCustomInterfaces/ReflLegacyTransferStrategy.h" + +using namespace MantidQt::CustomInterfaces; + +class ReflLegacyTransferStrategyTest : 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 ReflLegacyTransferStrategyTest *createSuite() { return new ReflLegacyTransferStrategyTest(); } + static void destroySuite( ReflLegacyTransferStrategyTest *suite ) { delete suite; } + + ReflLegacyTransferStrategyTest() + { + } + + void testBasicTransfer() + { + std::map input; + input["1234"] = "fictitious run on gold"; + input["1235"] = "fictitious run on silver"; + input["1236"] = "fictitious run on bronze"; + + std::vector > expected; + std::map expectedRow; + + expectedRow["runs"] = "1234"; + expectedRow["theta"] = ""; + expectedRow["group"] = "0"; + expected.push_back(expectedRow); + + expectedRow["runs"] = "1235"; + expectedRow["theta"] = ""; + expectedRow["group"] = "1"; + expected.push_back(expectedRow); + + expectedRow["runs"] = "1236"; + expectedRow["theta"] = ""; + expectedRow["group"] = "2"; + expected.push_back(expectedRow); + + ReflLegacyTransferStrategy strategy; + auto output = strategy.transferRuns(input); + + TS_ASSERT_EQUALS(output, expected); + } + + void testGroupedTransfer() + { + std::map input; + input["1233"] = "fictitious run on platinum"; + input["1234"] = "fictitious run on gold"; + input["1235"] = "fictitious run on gold"; + input["1236"] = "fictitious run on silver"; + + std::vector > expected; + std::map expectedRow; + + expectedRow["runs"] = "1233"; + expectedRow["theta"] = ""; + expectedRow["group"] = "0"; + expected.push_back(expectedRow); + + expectedRow["runs"] = "1234+1235"; + expectedRow["theta"] = ""; + expectedRow["group"] = "1"; + expected.push_back(expectedRow); + + expectedRow["runs"] = "1236"; + expectedRow["theta"] = ""; + expectedRow["group"] = "2"; + expected.push_back(expectedRow); + + ReflLegacyTransferStrategy strategy; + auto output = strategy.transferRuns(input); + + TS_ASSERT_EQUALS(output, expected); + } + + void testThetaExtraction() + { + std::map input; + input["1234"] = "fictitious run on gold"; + input["1235"] = "fictitious run on silver in 3.14 theta"; + input["1236"] = "fictitious run on bronze th=2.17"; + input["1237"] = "fictitious run on platinum th:1.23 and pH=12"; + + std::vector > expected; + std::map expectedRow; + + expectedRow["runs"] = "1234"; + expectedRow["theta"] = ""; + expectedRow["group"] = "0"; + expected.push_back(expectedRow); + + expectedRow["runs"] = "1235"; + expectedRow["theta"] = "3.14"; + expectedRow["group"] = "1"; + expected.push_back(expectedRow); + + expectedRow["runs"] = "1236"; + expectedRow["theta"] = "2.17"; + expectedRow["group"] = "2"; + expected.push_back(expectedRow); + + expectedRow["runs"] = "1237"; + expectedRow["theta"] = "1.23"; + expectedRow["group"] = "3"; + expected.push_back(expectedRow); + + ReflLegacyTransferStrategy strategy; + auto output = strategy.transferRuns(input); + + TS_ASSERT_EQUALS(output, expected); + } + + void testComplexExtraction() + { + std::map input; + input["1230"] = "fictitious run on gold"; + input["1231"] = "fictitious run on silver in 3.14 theta"; + input["1232"] = "fictitious run on silver in 3.14 theta"; + input["1233"] = "fictitious run on silver in 2.17 theta"; + input["1234"] = "fictitious run on bronze th=2.17"; + input["1235"] = "fictitious run on bronze th=1.23"; + input["1236"] = "fictitious run on platinum th:1.23 and pH=12"; + input["1237"] = "fictitious run on fool's gold"; + + std::vector > expected; + std::map expectedRow; + + expectedRow["runs"] = "1230"; + expectedRow["theta"] = ""; + expectedRow["group"] = "0"; + expected.push_back(expectedRow); + + expectedRow["runs"] = "1231+1232"; + expectedRow["theta"] = "3.14"; + expectedRow["group"] = "1"; + expected.push_back(expectedRow); + + expectedRow["runs"] = "1233"; + expectedRow["theta"] = "2.17"; + expectedRow["group"] = "1"; + expected.push_back(expectedRow); + + expectedRow["runs"] = "1234"; + expectedRow["theta"] = "2.17"; + expectedRow["group"] = "2"; + expected.push_back(expectedRow); + + expectedRow["runs"] = "1235"; + expectedRow["theta"] = "1.23"; + expectedRow["group"] = "2"; + expected.push_back(expectedRow); + + expectedRow["runs"] = "1236"; + expectedRow["theta"] = "1.23"; + expectedRow["group"] = "3"; + expected.push_back(expectedRow); + + expectedRow["runs"] = "1237"; + expectedRow["theta"] = ""; + expectedRow["group"] = "4"; + expected.push_back(expectedRow); + + ReflLegacyTransferStrategy strategy; + auto output = strategy.transferRuns(input); + + TS_ASSERT_EQUALS(output, expected); + } +}; + +#endif diff --git a/Code/Mantid/MantidQt/CustomInterfaces/test/ReflLoadedMainViewPresenterTest.h b/Code/Mantid/MantidQt/CustomInterfaces/test/ReflLoadedMainViewPresenterTest.h deleted file mode 100644 index a37500ebf1a8..000000000000 --- a/Code/Mantid/MantidQt/CustomInterfaces/test/ReflLoadedMainViewPresenterTest.h +++ /dev/null @@ -1,545 +0,0 @@ -#ifndef MANTID_CUSTOMINTERFACES_REFLLOADEDMAINVIEWPRESENTERTEST_H_ -#define MANTID_CUSTOMINTERFACES_REFLLOADEDMAINVIEWPRESENTERTEST_H_ - -#include -#include -#include -#include -#include "MantidDataObjects/TableWorkspace.h" -#include "MantidAPI/ITableWorkspace.h" -#include "MantidQtCustomInterfaces/ReflMainView.h" -#include "MantidAPI/FrameworkManager.h" -#include "MantidAPI/TableRow.h" -#include "MantidQtCustomInterfaces/ReflLoadedMainViewPresenter.h" - -#include "ReflMainViewMockObjects.h" - -using namespace MantidQt::CustomInterfaces; -using namespace Mantid::API; -using namespace testing; - -//===================================================================================== -// Functional tests -//===================================================================================== -class ReflLoadedMainViewPresenterTest : public CxxTest::TestSuite -{ - -private: - - ITableWorkspace_sptr createWorkspace(bool ADS = true) - { - ITableWorkspace_sptr ws = WorkspaceFactory::Instance().createTable(); - if (ADS) - { - AnalysisDataService::Instance().addOrReplace("TestWorkspace", ws); - } - auto colRuns = ws->addColumn("str","Run(s)"); - auto colTheta = ws->addColumn("str","ThetaIn"); - auto colTrans = ws->addColumn("str","TransRun(s)"); - auto colQmin = ws->addColumn("str","Qmin"); - auto colQmax = ws->addColumn("str","Qmax"); - auto colDqq = ws->addColumn("str","dq/q"); - auto colScale = ws->addColumn("str","Scale"); - auto colStitch = ws->addColumn("int","StitchGroup"); - - colRuns->setPlotType(0); - colTheta->setPlotType(0); - colTrans->setPlotType(0); - colQmin->setPlotType(0); - colQmax->setPlotType(0); - colDqq->setPlotType(0); - colScale->setPlotType(0); - colStitch->setPlotType(0); - - TableRow row = ws->appendRow(); - row << "13460" << "0.7" << "13463,13464" << "0.01" << "0.06" << "0.04" << "1" << 3; - row = ws->appendRow(); - row << "13462" << "2.3" << "13463,13464" << "0.035" << "0.3" << "0.04" << "1" << 3; - row = ws->appendRow(); - row << "13469" << "0.7" << "13463,13464" << "0.01" << "0.06" << "0.04" << "1" << 1; - row = ws->appendRow(); - row << "13470" << "2.3" << "13463,13464" << "0.035" << "0.3" << "0.04" << "1" << 1; - return ws; - } - - ITableWorkspace_sptr createBadTypedWorkspace() - { - ITableWorkspace_sptr ws = WorkspaceFactory::Instance().createTable(); - - auto colRuns = ws->addColumn("str","Run(s)"); - auto colTheta = ws->addColumn("str","ThetaIn"); - auto colTrans = ws->addColumn("str","TransRun(s)"); - auto colQmin = ws->addColumn("str","Qmin"); - auto colQmax = ws->addColumn("str","Qmax"); - auto colDqq = ws->addColumn("str","dq/q"); - auto colScale = ws->addColumn("str","Scale"); - auto colStitch = ws->addColumn("str","StitchGroup"); - - colRuns->setPlotType(0); - colTheta->setPlotType(0); - colTrans->setPlotType(0); - colQmin->setPlotType(0); - colQmax->setPlotType(0); - colDqq->setPlotType(0); - colScale->setPlotType(0); - colStitch->setPlotType(0); - - TableRow row = ws->appendRow(); - - row << "13460" << "0.7" << "13463" << "0.01" << "0.06" << "0.04" << "2" << "1"; - - return ws; - } - - ITableWorkspace_sptr createBadLengthWorkspace(bool longer) - { - ITableWorkspace_sptr ws = WorkspaceFactory::Instance().createTable(); - - auto colRuns = ws->addColumn("str","Run(s)"); - auto colTheta = ws->addColumn("str","ThetaIn"); - auto colTrans = ws->addColumn("str","TransRun(s)"); - auto colQmin = ws->addColumn("str","Qmin"); - auto colQmax = ws->addColumn("str","Qmax"); - auto colDqq = ws->addColumn("str","dq/q"); - auto colScale = ws->addColumn("str","Scale"); - - colRuns->setPlotType(0); - colTheta->setPlotType(0); - colTrans->setPlotType(0); - colQmin->setPlotType(0); - colQmax->setPlotType(0); - colDqq->setPlotType(0); - colScale->setPlotType(0); - - if(longer) - { - auto colStitch = ws->addColumn("int","StitchGroup"); - auto colPlot = ws->addColumn("str","Plot"); - colStitch->setPlotType(0); - colPlot->setPlotType(0); - } - - TableRow row = ws->appendRow(); - - if(longer) - { - row << "13460" << "0.7" << "13463" << "0.01" << "0.06" << "0.04" << "2" << 1 << "plot"; - } - else - { - row << "13460" << "0.7" << "13463" << "0.01" << "0.06" << "0.04" << "2"; - } - - return ws; - } - -public: - // This pair of boilerplate methods prevent the suite being created statically - // This means the constructor isn't called when running other tests - static ReflLoadedMainViewPresenterTest *createSuite() { return new ReflLoadedMainViewPresenterTest(); } - static void destroySuite( ReflLoadedMainViewPresenterTest *suite ) { delete suite; } - - ReflLoadedMainViewPresenterTest() - { - FrameworkManager::Instance(); - } - - void testConstruction() - { - ConstructView constructView; - EXPECT_CALL(constructView, showTable(_)).Times(1); - ReflLoadedMainViewPresenter presenter(createWorkspace(),&constructView); - TS_ASSERT(Mock::VerifyAndClearExpectations(&constructView)); - AnalysisDataService::Instance().remove("TestWorkspace"); - } - - void testSave() - { - MockView mockView; - ReflLoadedMainViewPresenter presenter(createWorkspace(),&mockView); - presenter.notify(SaveFlag); - TS_ASSERT(Mock::VerifyAndClearExpectations(&mockView)); - AnalysisDataService::Instance().remove("TestWorkspace"); - } - - void testEditSave() - { - FakeView fakeView; - ReflLoadedMainViewPresenter presenter(createWorkspace(),&fakeView); - TS_ASSERT_EQUALS(AnalysisDataService::Instance().retrieveWS("TestWorkspace")->rowCount(),4); - presenter.notify(SaveFlag); - ITableWorkspace_sptr ws = AnalysisDataService::Instance().retrieveWS("TestWorkspace"); - TS_ASSERT_EQUALS(ws->rowCount(), 8); - TS_ASSERT_EQUALS(ws->String(0,0), "13460"); - TS_ASSERT_EQUALS(ws->Int(0,7), 3); - TS_ASSERT_EQUALS(ws->String(4,0), "13460"); - TS_ASSERT_EQUALS(ws->Int(4,7), 3); - TS_ASSERT(Mock::VerifyAndClearExpectations(&fakeView)); - AnalysisDataService::Instance().remove("TestWorkspace"); - } - - void testSaveAs() - { - MockView mockView; - EXPECT_CALL(mockView, askUserString(_,_,"Workspace")) - .Times(2) - .WillOnce(Return("")) - .WillRepeatedly(Return("Workspace")); - ReflLoadedMainViewPresenter presenter(createWorkspace(),&mockView); - presenter.notify(SaveAsFlag); - presenter.notify(SaveAsFlag); - TS_ASSERT(Mock::VerifyAndClearExpectations(&mockView)); - TS_ASSERT(AnalysisDataService::Instance().doesExist("Workspace")); - AnalysisDataService::Instance().remove("TestWorkspace"); - AnalysisDataService::Instance().remove("Workspace"); - } - - void testSaveProcess() - { - MockView mockView; - EXPECT_CALL(mockView, askUserString(_,_,"Workspace")) - .Times(2) - .WillOnce(Return("")) - .WillRepeatedly(Return("Workspace")); - ReflLoadedMainViewPresenter presenter(createWorkspace(),&mockView); - presenter.notify(SaveAsFlag); - presenter.notify(SaveAsFlag); - presenter.notify(SaveFlag); - TS_ASSERT(Mock::VerifyAndClearExpectations(&mockView)); - TS_ASSERT(AnalysisDataService::Instance().doesExist("Workspace")); - AnalysisDataService::Instance().remove("TestWorkspace"); - AnalysisDataService::Instance().remove("Workspace"); - } - - void testAddRow() - { - std::vector rowlist = std::vector(); - MockView mockView; - EXPECT_CALL(mockView, getSelectedRowIndexes()) - .Times(2) - .WillRepeatedly(Return(rowlist)); - ReflLoadedMainViewPresenter presenter(createWorkspace(),&mockView); - ITableWorkspace_sptr ws = AnalysisDataService::Instance().retrieveWS("TestWorkspace"); - TS_ASSERT_EQUALS(ws->rowCount(),4); - TS_ASSERT_EQUALS(ws->String(1,0), "13462"); - TS_ASSERT_EQUALS(ws->Int(1,7), 3); - TS_ASSERT_THROWS(ws->Int(4,7),std::runtime_error); - TS_ASSERT_THROWS(ws->Int(5,7),std::runtime_error); - TS_ASSERT_THROWS(ws->Int(6,7),std::runtime_error); - presenter.notify(AddRowFlag); - presenter.notify(AddRowFlag); - presenter.notify(SaveFlag); - ws = AnalysisDataService::Instance().retrieveWS("TestWorkspace"); - TS_ASSERT_EQUALS(ws->rowCount(), 6); - TS_ASSERT_EQUALS(ws->String(1,0), "13462"); - TS_ASSERT_EQUALS(ws->Int(1,7), 3); - TS_ASSERT_THROWS_NOTHING(ws->Int(4,7)); - TS_ASSERT_THROWS_NOTHING(ws->Int(5,7)); - TS_ASSERT_EQUALS(ws->String(4,0), ""); - TS_ASSERT_EQUALS(ws->Int(4,7), 0); - TS_ASSERT_EQUALS(ws->String(5,0), ""); - TS_ASSERT_EQUALS(ws->Int(5,7), 0); - TS_ASSERT_THROWS(ws->Int(6,7),std::runtime_error); - TS_ASSERT(Mock::VerifyAndClearExpectations(&mockView)); - AnalysisDataService::Instance().remove("TestWorkspace"); - } - - void testAddRowSpecify() - { - std::vector rowlist; - rowlist.push_back(1); - MockView mockView; - EXPECT_CALL(mockView, getSelectedRowIndexes()) - .Times(2) - .WillRepeatedly(Return(rowlist)); - ReflLoadedMainViewPresenter presenter(createWorkspace(),&mockView); - ITableWorkspace_sptr ws = AnalysisDataService::Instance().retrieveWS("TestWorkspace"); - TS_ASSERT_EQUALS(ws->rowCount(),4); - TS_ASSERT_EQUALS(ws->String(1,0), "13462"); - TS_ASSERT_EQUALS(ws->Int(1,7), 3); - TS_ASSERT_EQUALS(ws->String(2,0), "13469"); - TS_ASSERT_EQUALS(ws->Int(2,7), 1); - TS_ASSERT_THROWS(ws->Int(4,7),std::runtime_error); - TS_ASSERT_THROWS(ws->Int(5,7),std::runtime_error); - TS_ASSERT_THROWS(ws->Int(6,7),std::runtime_error); - presenter.notify(AddRowFlag); - presenter.notify(AddRowFlag); - presenter.notify(SaveFlag); - ws = AnalysisDataService::Instance().retrieveWS("TestWorkspace"); - TS_ASSERT_EQUALS(ws->rowCount(), 6); - TS_ASSERT_EQUALS(ws->String(1,0), ""); - TS_ASSERT_EQUALS(ws->Int(1,7), 0); - TS_ASSERT_EQUALS(ws->String(2,0), ""); - TS_ASSERT_EQUALS(ws->Int(2,7), 0); - TS_ASSERT_THROWS_NOTHING(ws->Int(4,7)); - TS_ASSERT_THROWS_NOTHING(ws->Int(5,7)); - TS_ASSERT_EQUALS(ws->String(4,0), "13469"); - TS_ASSERT_EQUALS(ws->Int(4,7), 1); - TS_ASSERT_EQUALS(ws->String(5,0), "13470"); - TS_ASSERT_EQUALS(ws->Int(5,7), 1); - TS_ASSERT_THROWS(ws->Int(6,7),std::runtime_error); - TS_ASSERT(Mock::VerifyAndClearExpectations(&mockView)); - AnalysisDataService::Instance().remove("TestWorkspace"); - } - - void testAddRowSpecifyPlural() - { - std::vector rowlist; - rowlist.push_back(1); - rowlist.push_back(2); - rowlist.push_back(3); - MockView mockView; - EXPECT_CALL(mockView, getSelectedRowIndexes()) - .Times(1) - .WillRepeatedly(Return(rowlist)); - ReflLoadedMainViewPresenter presenter(createWorkspace(),&mockView); - ITableWorkspace_sptr ws = AnalysisDataService::Instance().retrieveWS("TestWorkspace"); - TS_ASSERT_EQUALS(ws->rowCount(),4); - TS_ASSERT_EQUALS(ws->String(1,0), "13462"); - TS_ASSERT_EQUALS(ws->Int(1,7), 3); - TS_ASSERT_EQUALS(ws->String(2,0), "13469"); - TS_ASSERT_EQUALS(ws->Int(2,7), 1); - TS_ASSERT_THROWS(ws->Int(4,7),std::runtime_error); - TS_ASSERT_THROWS(ws->Int(5,7),std::runtime_error); - TS_ASSERT_THROWS(ws->Int(6,7),std::runtime_error); - TS_ASSERT_THROWS(ws->Int(7,7),std::runtime_error); - presenter.notify(AddRowFlag); - presenter.notify(SaveFlag); - ws = AnalysisDataService::Instance().retrieveWS("TestWorkspace"); - TS_ASSERT_EQUALS(ws->rowCount(), 7); - TS_ASSERT_EQUALS(ws->String(1,0), ""); - TS_ASSERT_EQUALS(ws->Int(1,7), 0); - TS_ASSERT_EQUALS(ws->String(2,0), ""); - TS_ASSERT_EQUALS(ws->Int(2,7), 0); - TS_ASSERT_EQUALS(ws->String(3,0), ""); - TS_ASSERT_EQUALS(ws->Int(3,7), 0); - TS_ASSERT_THROWS_NOTHING(ws->Int(4,7)); - TS_ASSERT_THROWS_NOTHING(ws->Int(5,7)); - TS_ASSERT_THROWS_NOTHING(ws->Int(6,7)); - TS_ASSERT_EQUALS(ws->String(4,0), "13462"); - TS_ASSERT_EQUALS(ws->Int(4,7), 3); - TS_ASSERT_EQUALS(ws->String(5,0), "13469"); - TS_ASSERT_EQUALS(ws->Int(5,7), 1); - TS_ASSERT_EQUALS(ws->String(6,0), "13470"); - TS_ASSERT_EQUALS(ws->Int(6,7), 1); - TS_ASSERT_THROWS(ws->Int(7,7),std::runtime_error); - TS_ASSERT(Mock::VerifyAndClearExpectations(&mockView)); - AnalysisDataService::Instance().remove("TestWorkspace"); - } - - void testAddRowNotSequential() - { - std::vector rowlist; - rowlist.push_back(2); - rowlist.push_back(3); - rowlist.push_back(0); - //The rowlist is sorted internally, so 0 will go to the top and be classed as the highest. - //So 3 rows will be added to the top. We can do this as we are only expecting chunks of - //sequential rows, thus this is the expected behavior - MockView mockView; - EXPECT_CALL(mockView, getSelectedRowIndexes()) - .Times(1) - .WillRepeatedly(Return(rowlist)); - ReflLoadedMainViewPresenter presenter(createWorkspace(),&mockView); - ITableWorkspace_sptr ws = AnalysisDataService::Instance().retrieveWS("TestWorkspace"); - TS_ASSERT_EQUALS(ws->rowCount(),4); - TS_ASSERT_EQUALS(ws->String(0,0), "13460"); - TS_ASSERT_EQUALS(ws->Int(0,7), 3); - TS_ASSERT_EQUALS(ws->String(1,0), "13462"); - TS_ASSERT_EQUALS(ws->Int(1,7), 3); - TS_ASSERT_EQUALS(ws->String(2,0), "13469"); - TS_ASSERT_EQUALS(ws->Int(2,7), 1); - TS_ASSERT_THROWS(ws->Int(4,7),std::runtime_error); - TS_ASSERT_THROWS(ws->Int(5,7),std::runtime_error); - TS_ASSERT_THROWS(ws->Int(6,7),std::runtime_error); - TS_ASSERT_THROWS(ws->Int(7,7),std::runtime_error); - presenter.notify(AddRowFlag); - presenter.notify(SaveFlag); - ws = AnalysisDataService::Instance().retrieveWS("TestWorkspace"); - TS_ASSERT_EQUALS(ws->rowCount(), 7); - TS_ASSERT_EQUALS(ws->String(0,0), ""); - TS_ASSERT_EQUALS(ws->Int(0,7), 0); - TS_ASSERT_EQUALS(ws->String(1,0), ""); - TS_ASSERT_EQUALS(ws->Int(1,7), 0); - TS_ASSERT_EQUALS(ws->String(2,0), ""); - TS_ASSERT_EQUALS(ws->Int(2,7), 0); - TS_ASSERT_THROWS_NOTHING(ws->Int(4,7)); - TS_ASSERT_THROWS_NOTHING(ws->Int(5,7)); - TS_ASSERT_THROWS_NOTHING(ws->Int(6,7)); - TS_ASSERT_EQUALS(ws->String(3,0), "13460"); - TS_ASSERT_EQUALS(ws->Int(3,7), 3); - TS_ASSERT_EQUALS(ws->String(4,0), "13462"); - TS_ASSERT_EQUALS(ws->Int(4,7), 3); - TS_ASSERT_EQUALS(ws->String(5,0), "13469"); - TS_ASSERT_EQUALS(ws->Int(5,7), 1); - TS_ASSERT_EQUALS(ws->String(6,0), "13470"); - TS_ASSERT_EQUALS(ws->Int(6,7), 1); - TS_ASSERT_THROWS(ws->Int(7,7),std::runtime_error); - TS_ASSERT(Mock::VerifyAndClearExpectations(&mockView)); - AnalysisDataService::Instance().remove("TestWorkspace"); - } - - void testDeleteRowNone() - { - std::vector rowlist = std::vector(); - MockView mockView; - EXPECT_CALL(mockView, getSelectedRowIndexes()) - .Times(1) - .WillRepeatedly(Return(rowlist)); - ReflLoadedMainViewPresenter presenter(createWorkspace(),&mockView); - ITableWorkspace_sptr ws = AnalysisDataService::Instance().retrieveWS("TestWorkspace"); - TS_ASSERT_THROWS_NOTHING(ws->Int(0,7)); - TS_ASSERT_EQUALS(ws->rowCount(),4); - TS_ASSERT_EQUALS(ws->String(1,0), "13462"); - TS_ASSERT_EQUALS(ws->Int(1,7), 3); - TS_ASSERT_THROWS_NOTHING(ws->Int(2,7)); - TS_ASSERT_THROWS_NOTHING(ws->Int(3,7)); - presenter.notify(DeleteRowFlag); - presenter.notify(SaveFlag); - ws = AnalysisDataService::Instance().retrieveWS("TestWorkspace"); - TS_ASSERT_THROWS_NOTHING(ws->Int(0,7)); - TS_ASSERT_EQUALS(ws->rowCount(),4); - TS_ASSERT_EQUALS(ws->String(1,0), "13462"); - TS_ASSERT_EQUALS(ws->Int(1,7), 3); - TS_ASSERT_THROWS_NOTHING(ws->Int(2,7)); - TS_ASSERT_THROWS_NOTHING(ws->Int(3,7)); - TS_ASSERT(Mock::VerifyAndClearExpectations(&mockView)); - AnalysisDataService::Instance().remove("TestWorkspace"); - } - - void testDeleteRowSingle() - { - std::vector rowlist; - rowlist.push_back(1); - MockView mockView; - EXPECT_CALL(mockView, getSelectedRowIndexes()) - .Times(1) - .WillRepeatedly(Return(rowlist)); - ReflLoadedMainViewPresenter presenter(createWorkspace(),&mockView); - ITableWorkspace_sptr ws = AnalysisDataService::Instance().retrieveWS("TestWorkspace"); - TS_ASSERT_EQUALS(ws->rowCount(),4); - TS_ASSERT_EQUALS(ws->String(1,0), "13462"); - TS_ASSERT_EQUALS(ws->Int(1,7), 3); - TS_ASSERT_THROWS_NOTHING(ws->Int(3,7)); - presenter.notify(DeleteRowFlag); - presenter.notify(SaveFlag); - ws = AnalysisDataService::Instance().retrieveWS("TestWorkspace"); - TS_ASSERT_EQUALS(ws->rowCount(),3); - TS_ASSERT_EQUALS(ws->String(1,0), "13469"); - TS_ASSERT_EQUALS(ws->Int(1,7), 1); - TS_ASSERT_THROWS(ws->Int(3,7),std::runtime_error); - TS_ASSERT(Mock::VerifyAndClearExpectations(&mockView)); - AnalysisDataService::Instance().remove("TestWorkspace"); - } - - void testDeleteRowPlural() - { - std::vector rowlist; - rowlist.push_back(0); - rowlist.push_back(1); - rowlist.push_back(2); - MockView mockView; - EXPECT_CALL(mockView, getSelectedRowIndexes()) - .Times(1) - .WillRepeatedly(Return(rowlist)); - ReflLoadedMainViewPresenter presenter(createWorkspace(),&mockView); - ITableWorkspace_sptr ws = AnalysisDataService::Instance().retrieveWS("TestWorkspace"); - TS_ASSERT_EQUALS(ws->rowCount(),4); - TS_ASSERT_EQUALS(ws->String(0,0), "13460"); - TS_ASSERT_EQUALS(ws->Int(0,7), 3); - TS_ASSERT_THROWS_NOTHING(ws->Int(1,7)); - TS_ASSERT_THROWS_NOTHING(ws->Int(2,7)); - TS_ASSERT_THROWS_NOTHING(ws->Int(3,7)); - presenter.notify(DeleteRowFlag); - presenter.notify(SaveFlag); - ws = AnalysisDataService::Instance().retrieveWS("TestWorkspace"); - TS_ASSERT_EQUALS(ws->rowCount(),1); - TS_ASSERT_EQUALS(ws->String(0,0), "13470"); - TS_ASSERT_EQUALS(ws->Int(0,7), 1); - TS_ASSERT_THROWS(ws->Int(1,7),std::runtime_error); - TS_ASSERT_THROWS(ws->Int(2,7),std::runtime_error); - TS_ASSERT_THROWS(ws->Int(3,7),std::runtime_error); - TS_ASSERT(Mock::VerifyAndClearExpectations(&mockView)); - AnalysisDataService::Instance().remove("TestWorkspace"); - } - - void testDeleteRowNotSequential() - { - std::vector rowlist; - rowlist.push_back(2); - rowlist.push_back(3); - rowlist.push_back(0); - //The rowlist is sorted internally, so 0 will go to the top and be classed as the highest. - //So 3 rows will be removed from the top. We can do this as we are only expecting chunks of - //sequential rows, thus this is the expected behavior - MockView mockView; - EXPECT_CALL(mockView, getSelectedRowIndexes()) - .Times(1) - .WillRepeatedly(Return(rowlist)); - ReflLoadedMainViewPresenter presenter(createWorkspace(),&mockView); - ITableWorkspace_sptr ws = AnalysisDataService::Instance().retrieveWS("TestWorkspace"); - TS_ASSERT_EQUALS(ws->rowCount(),4); - TS_ASSERT_EQUALS(ws->String(0,0), "13460"); - TS_ASSERT_EQUALS(ws->Int(0,7), 3); - TS_ASSERT_THROWS_NOTHING(ws->Int(1,7)); - TS_ASSERT_THROWS_NOTHING(ws->Int(2,7)); - TS_ASSERT_THROWS_NOTHING(ws->Int(3,7)); - presenter.notify(DeleteRowFlag); - presenter.notify(SaveFlag); - ws = AnalysisDataService::Instance().retrieveWS("TestWorkspace"); - TS_ASSERT_EQUALS(ws->rowCount(),1); - TS_ASSERT_EQUALS(ws->String(0,0), "13470"); - TS_ASSERT_EQUALS(ws->Int(0,7), 1); - TS_ASSERT_THROWS(ws->Int(1,7),std::runtime_error); - TS_ASSERT_THROWS(ws->Int(2,7),std::runtime_error); - TS_ASSERT_THROWS(ws->Int(3,7),std::runtime_error); - TS_ASSERT(Mock::VerifyAndClearExpectations(&mockView)); - AnalysisDataService::Instance().remove("TestWorkspace"); - } - - void testProcessAll() - { - std::vector rowlist = std::vector(); - MockView mockView; - EXPECT_CALL(mockView, askUserYesNo(_,_)) - .Times(1) - .WillRepeatedly(Return(true)); - EXPECT_CALL(mockView, getSelectedRowIndexes()) - .Times(1) - .WillRepeatedly(Return(rowlist)); - ReflLoadedMainViewPresenter presenter(createWorkspace(),&mockView); - ITableWorkspace_sptr ws = AnalysisDataService::Instance().retrieveWS("TestWorkspace"); - presenter.notify(ProcessFlag); - ws = AnalysisDataService::Instance().retrieveWS("TestWorkspace"); - TS_ASSERT(Mock::VerifyAndClearExpectations(&mockView)); - AnalysisDataService::Instance().remove("TestWorkspace"); - } - - void testBadWorkspaceName() - { - MockView mockView; - TS_ASSERT_THROWS(ReflLoadedMainViewPresenter presenter(createWorkspace(false),&mockView), std::runtime_error&); - } - - void testBadWorkspaceType() - { - MockView mockView; - TS_ASSERT_THROWS(ReflLoadedMainViewPresenter presenter(createBadTypedWorkspace(),&mockView), std::runtime_error&); - } - - void testBadWorkspaceShort() - { - MockView mockView; - TS_ASSERT_THROWS(ReflLoadedMainViewPresenter presenter(createBadLengthWorkspace(false),&mockView), std::runtime_error&); - } - - void testBadWorkspaceLong() - { - MockView mockView; - TS_ASSERT_THROWS(ReflLoadedMainViewPresenter presenter(createBadLengthWorkspace(true),&mockView), std::runtime_error&); - } - -}; - - -#endif /* MANTID_CUSTOMINTERFACES_REFLLOADEDMAINVIEWPRESENTERTEST_H_ */ diff --git a/Code/Mantid/MantidQt/CustomInterfaces/test/ReflMainViewMockObjects.h b/Code/Mantid/MantidQt/CustomInterfaces/test/ReflMainViewMockObjects.h index f8a82faa4b95..af9ae2078629 100644 --- a/Code/Mantid/MantidQt/CustomInterfaces/test/ReflMainViewMockObjects.h +++ b/Code/Mantid/MantidQt/CustomInterfaces/test/ReflMainViewMockObjects.h @@ -3,99 +3,59 @@ #include #include "MantidQtCustomInterfaces/ReflMainView.h" +#include "MantidQtCustomInterfaces/ReflSearchModel.h" +#include "MantidQtCustomInterfaces/QReflTableModel.h" #include "MantidAPI/TableRow.h" using namespace MantidQt::CustomInterfaces; using namespace Mantid::API; -//Clean flag aliases for use within tests. -const int SaveAsFlag = ReflMainView::SaveAsFlag; -const int SaveFlag = ReflMainView::SaveFlag; -const int ProcessFlag = ReflMainView::ProcessFlag; -const int AddRowFlag = ReflMainView::AddRowFlag; -const int DeleteRowFlag = ReflMainView::DeleteRowFlag; - -class ConstructView : public ReflMainView -{ -public: - ConstructView(){}; - MOCK_METHOD1(showTable, void(Mantid::API::ITableWorkspace_sptr)); - MOCK_METHOD3(askUserString, std::string(const std::string& prompt, const std::string& title, const std::string& defaultValue)); - MOCK_METHOD2(askUserYesNo, bool(std::string, std::string)); - MOCK_METHOD2(giveUserCritical, void(std::string, std::string)); - MOCK_METHOD2(giveUserInfo, void(std::string, std::string)); - MOCK_METHOD2(giveUserWarning, void(std::string, std::string)); - MOCK_CONST_METHOD0(getSelectedRowIndexes, std::vector()); - virtual ~ConstructView(){} -}; +//Clean column ids for use within tests +const int RunCol = ReflMainViewPresenter::COL_RUNS; +const int ThetaCol = ReflMainViewPresenter::COL_ANGLE; +const int TransCol = ReflMainViewPresenter::COL_TRANSMISSION; +const int QMinCol = ReflMainViewPresenter::COL_QMIN; +const int QMaxCol = ReflMainViewPresenter::COL_QMAX; +const int DQQCol = ReflMainViewPresenter::COL_DQQ; +const int ScaleCol = ReflMainViewPresenter::COL_SCALE; +const int GroupCol = ReflMainViewPresenter::COL_GROUP; +const int OptionsCol = ReflMainViewPresenter::COL_OPTIONS; class MockView : public ReflMainView { public: MockView(){}; - virtual void showTable(Mantid::API::ITableWorkspace_sptr model){(void)model;} - MOCK_METHOD3(askUserString, std::string(const std::string& prompt, const std::string& title, const std::string& defaultValue)); - MOCK_METHOD2(askUserYesNo, bool(std::string, std::string)); - MOCK_METHOD2(giveUserCritical, void(std::string, std::string)); - MOCK_METHOD2(giveUserInfo, void(std::string, std::string)); - MOCK_METHOD2(giveUserWarning, void(std::string, std::string)); - MOCK_CONST_METHOD0(getSelectedRowIndexes, std::vector()); virtual ~MockView(){} -}; -class FakeView : public ReflMainView -{ -public: - FakeView(){}; - virtual void showTable(Mantid::API::ITableWorkspace_sptr model) - { - TableRow row = model->appendRow(); - row << "13460" << "0.7" << "13463,13464" << "0.01" << "0.06" << "0.04" << "1" << 3; - row = model->appendRow(); - row << "13462" << "2.3" << "13463,13464" << "0.035" << "0.3" << "0.04" << "1" << 3; - row = model->appendRow(); - row << "13469" << "0.7" << "13463,13464" << "0.01" << "0.06" << "0.04" << "1" << 3; - row = model->appendRow(); - row << "13470" << "2.3" << "13463,13464" << "0.035" << "0.3" << "0.04" << "1" << 3; - } + //Prompts MOCK_METHOD3(askUserString, std::string(const std::string& prompt, const std::string& title, const std::string& defaultValue)); MOCK_METHOD2(askUserYesNo, bool(std::string, std::string)); MOCK_METHOD2(giveUserCritical, void(std::string, std::string)); MOCK_METHOD2(giveUserInfo, void(std::string, std::string)); MOCK_METHOD2(giveUserWarning, void(std::string, std::string)); - MOCK_CONST_METHOD0(getSelectedRowIndexes, std::vector()); - virtual ~FakeView(){} -}; -class AddDelProcView : public ReflMainView -{ -public: - AddDelProcView(){}; - virtual void showTable(Mantid::API::ITableWorkspace_sptr model) - { - m_model = model; - } - MOCK_METHOD3(askUserString, std::string(const std::string& prompt, const std::string& title, const std::string& defaultValue)); - MOCK_METHOD2(askUserYesNo, bool(std::string, std::string)); - MOCK_METHOD2(giveUserCritical, void(std::string, std::string)); - MOCK_METHOD2(giveUserInfo, void(std::string, std::string)); - MOCK_METHOD2(giveUserWarning, void(std::string, std::string)); - MOCK_CONST_METHOD0(getSelectedRowIndexes, std::vector()); - virtual ~AddDelProcView(){} - void addDataForTest() - { - TableRow row = m_model->appendRow(); - row << "13460" << "0.7" << "13463,13464" << "0.01" << "0.06" << "0.04" << "1" << 3; - row = m_model->appendRow(); - row << "13462" << "2.3" << "13463,13464" << "0.035" << "0.3" << "0.04" << "1" << 3; - row = m_model->appendRow(); - row << "13469" << "0.7" << "13463,13464" << "0.01" << "0.06" << "0.04" << "1" << 1; - row = m_model->appendRow(); - row << "13470" << "2.3" << "13463,13464" << "0.035" << "0.3" << "0.04" << "1" << 1; - m_model->removeRow(0); - } -private: - Mantid::API::ITableWorkspace_sptr m_model; + MOCK_METHOD1(showAlgorithmDialog, void(const std::string&)); + + //IO + MOCK_CONST_METHOD0(getWorkspaceToOpen, std::string()); + MOCK_METHOD1(setSelection, void(const std::set& rows)); + MOCK_CONST_METHOD0(getSelectedRows, std::set()); + MOCK_CONST_METHOD0(getSelectedSearchRows, std::set()); + MOCK_METHOD1(setClipboard, void(const std::string& text)); + MOCK_CONST_METHOD0(getClipboard, std::string()); + MOCK_CONST_METHOD0(getSearchString, std::string()); + MOCK_CONST_METHOD0(getSearchInstrument, std::string()); + + //Calls we don't care about + virtual void showTable(QReflTableModel_sptr) {}; + virtual void showSearch(ReflSearchModel_sptr) {}; + virtual void setOptionsHintStrategy(MantidQt::MantidWidgets::HintStrategy*) {}; + virtual void setProgressRange(int,int) {}; + virtual void setProgress(int) {}; + virtual void setTableList(const std::set&) {}; + virtual void setInstrumentList(const std::vector&, const std::string&) {}; + virtual std::string getProcessInstrument() const {return "FAKE";} + virtual boost::shared_ptr getPresenter() const {return boost::shared_ptr();} }; #endif /*MANTID_CUSTOMINTERFACES_REFLMAINVIEWMOCKOBJECTS_H*/ diff --git a/Code/Mantid/MantidQt/CustomInterfaces/test/ReflMainViewPresenterTest.h b/Code/Mantid/MantidQt/CustomInterfaces/test/ReflMainViewPresenterTest.h new file mode 100644 index 000000000000..5963ba6cd317 --- /dev/null +++ b/Code/Mantid/MantidQt/CustomInterfaces/test/ReflMainViewPresenterTest.h @@ -0,0 +1,1209 @@ +#ifndef MANTID_CUSTOMINTERFACES_REFLMAINVIEWPRESENTERTEST_H +#define MANTID_CUSTOMINTERFACES_REFLMAINVIEWPRESENTERTEST_H + +#include +#include +#include +#include + +#include "MantidAPI/AlgorithmManager.h" +#include "MantidAPI/FrameworkManager.h" +#include "MantidAPI/TableRow.h" +#include "MantidTestHelpers/WorkspaceCreationHelper.h" +#include "MantidQtCustomInterfaces/ReflMainViewPresenter.h" + +#include "ReflMainViewMockObjects.h" + +using namespace MantidQt::CustomInterfaces; +using namespace Mantid::API; +using namespace Mantid::Kernel; +using namespace testing; + +//===================================================================================== +// Functional tests +//===================================================================================== +class ReflMainViewPresenterTest : public CxxTest::TestSuite +{ + +private: + + ITableWorkspace_sptr createWorkspace(const std::string& wsName) + { + ITableWorkspace_sptr ws = WorkspaceFactory::Instance().createTable(); + + auto colRuns = ws->addColumn("str","Run(s)"); + auto colTheta = ws->addColumn("str","ThetaIn"); + auto colTrans = ws->addColumn("str","TransRun(s)"); + auto colQmin = ws->addColumn("str","Qmin"); + auto colQmax = ws->addColumn("str","Qmax"); + auto colDqq = ws->addColumn("str","dq/q"); + auto colScale = ws->addColumn("double","Scale"); + auto colStitch = ws->addColumn("int","StitchGroup"); + auto colOptions = ws->addColumn("str","Options"); + + colRuns->setPlotType(0); + colTheta->setPlotType(0); + colTrans->setPlotType(0); + colQmin->setPlotType(0); + colQmax->setPlotType(0); + colDqq->setPlotType(0); + colScale->setPlotType(0); + colStitch->setPlotType(0); + colOptions->setPlotType(0); + + if(wsName.length() > 0) + AnalysisDataService::Instance().addOrReplace(wsName, ws); + + return ws; + } + + void createTOFWorkspace(const std::string& wsName, const std::string& runNumber = "") + { + auto tinyWS = WorkspaceCreationHelper::create2DWorkspaceWithReflectometryInstrument(); + auto inst = tinyWS->getInstrument(); + + inst->getParameterMap()->addDouble(inst.get(), "I0MonitorIndex", 1.0); + inst->getParameterMap()->addDouble(inst.get(), "PointDetectorStart", 1.0); + inst->getParameterMap()->addDouble(inst.get(), "PointDetectorStop", 1.0); + inst->getParameterMap()->addDouble(inst.get(), "LambdaMin", 0.0); + inst->getParameterMap()->addDouble(inst.get(), "LambdaMax", 10.0); + inst->getParameterMap()->addDouble(inst.get(), "MonitorBackgroundMin", 0.0); + inst->getParameterMap()->addDouble(inst.get(), "MonitorBackgroundMax", 10.0); + inst->getParameterMap()->addDouble(inst.get(), "MonitorIntegralMin", 0.0); + inst->getParameterMap()->addDouble(inst.get(), "MonitorIntegralMax", 10.0); + + tinyWS->mutableRun().addLogData(new PropertyWithValue("Theta", 0.12345)); + if(!runNumber.empty()) + tinyWS->mutableRun().addLogData(new PropertyWithValue("run_number", runNumber)); + + AnalysisDataService::Instance().addOrReplace(wsName, tinyWS); + } + + ITableWorkspace_sptr createPrefilledWorkspace(const std::string& wsName) + { + auto ws = createWorkspace(wsName); + TableRow row = ws->appendRow(); + row << "12345" << "0.5" << "" << "0.1" << "1.6" << "0.04" << 1.0 << 0 << ""; + row = ws->appendRow(); + row << "12346" << "1.5" << "" << "1.4" << "2.9" << "0.04" << 1.0 << 0 << ""; + row = ws->appendRow(); + row << "24681" << "0.5" << "" << "0.1" << "1.6" << "0.04" << 1.0 << 1 << ""; + row = ws->appendRow(); + row << "24682" << "1.5" << "" << "1.4" << "2.9" << "0.04" << 1.0 << 1 << ""; + return ws; + } + +public: + // This pair of boilerplate methods prevent the suite being created statically + // This means the constructor isn't called when running other tests + static ReflMainViewPresenterTest *createSuite() { return new ReflMainViewPresenterTest(); } + static void destroySuite( ReflMainViewPresenterTest *suite ) { delete suite; } + + ReflMainViewPresenterTest() + { + FrameworkManager::Instance(); + } + + void testSaveNew() + { + MockView mockView; + ReflMainViewPresenter presenter(&mockView); + + presenter.notify(IReflPresenter::NewTableFlag); + + EXPECT_CALL(mockView, askUserString(_,_,"Workspace")).Times(1).WillOnce(Return("TestWorkspace")); + presenter.notify(IReflPresenter::SaveFlag); + + TS_ASSERT(AnalysisDataService::Instance().doesExist("TestWorkspace")); + AnalysisDataService::Instance().remove("TestWorkspace"); + } + + void testSaveExisting() + { + MockView mockView; + ReflMainViewPresenter presenter(&mockView); + + createPrefilledWorkspace("TestWorkspace"); + EXPECT_CALL(mockView, getWorkspaceToOpen()).Times(1).WillRepeatedly(Return("TestWorkspace")); + presenter.notify(IReflPresenter::OpenTableFlag); + + EXPECT_CALL(mockView, askUserString(_,_,"Workspace")).Times(0); + presenter.notify(IReflPresenter::SaveFlag); + + AnalysisDataService::Instance().remove("TestWorkspace"); + } + + void testSaveAs() + { + MockView mockView; + ReflMainViewPresenter presenter(&mockView); + + createPrefilledWorkspace("TestWorkspace"); + EXPECT_CALL(mockView, getWorkspaceToOpen()).Times(1).WillRepeatedly(Return("TestWorkspace")); + presenter.notify(IReflPresenter::OpenTableFlag); + + //The user hits "save as" but cancels when choosing a name + EXPECT_CALL(mockView, askUserString(_,_,"Workspace")).Times(1).WillOnce(Return("")); + presenter.notify(IReflPresenter::SaveAsFlag); + + //The user hits "save as" and and enters "Workspace" for a name + EXPECT_CALL(mockView, askUserString(_,_,"Workspace")).Times(1).WillOnce(Return("Workspace")); + presenter.notify(IReflPresenter::SaveAsFlag); + + TS_ASSERT(AnalysisDataService::Instance().doesExist("Workspace")); + + AnalysisDataService::Instance().remove("TestWorkspace"); + AnalysisDataService::Instance().remove("Workspace"); + } + + void testAppendRow() + { + MockView mockView; + ReflMainViewPresenter presenter(&mockView); + + createPrefilledWorkspace("TestWorkspace"); + EXPECT_CALL(mockView, getWorkspaceToOpen()).Times(1).WillRepeatedly(Return("TestWorkspace")); + presenter.notify(IReflPresenter::OpenTableFlag); + + //We should not receive any errors + EXPECT_CALL(mockView, giveUserCritical(_,_)).Times(0); + + //The user hits "append row" twice with no rows selected + EXPECT_CALL(mockView, getSelectedRows()).Times(2).WillRepeatedly(Return(std::set())); + presenter.notify(IReflPresenter::AppendRowFlag); + presenter.notify(IReflPresenter::AppendRowFlag); + + //The user hits "save" + presenter.notify(IReflPresenter::SaveFlag); + + //Check that the table has been modified correctly + auto ws = AnalysisDataService::Instance().retrieveWS("TestWorkspace"); + TS_ASSERT_EQUALS(ws->rowCount(), 6); + TS_ASSERT_EQUALS(ws->String(4, RunCol), ""); + TS_ASSERT_EQUALS(ws->String(5, RunCol), ""); + TS_ASSERT_EQUALS(ws->Int(0, GroupCol), 0); + TS_ASSERT_EQUALS(ws->Int(1, GroupCol), 0); + TS_ASSERT_EQUALS(ws->Int(2, GroupCol), 1); + TS_ASSERT_EQUALS(ws->Int(3, GroupCol), 1); + TS_ASSERT_EQUALS(ws->Int(4, GroupCol), 2); + TS_ASSERT_EQUALS(ws->Int(5, GroupCol), 3); + + //Tidy up + AnalysisDataService::Instance().remove("TestWorkspace"); + } + + void testAppendRowSpecify() + { + MockView mockView; + ReflMainViewPresenter presenter(&mockView); + + createPrefilledWorkspace("TestWorkspace"); + EXPECT_CALL(mockView, getWorkspaceToOpen()).Times(1).WillRepeatedly(Return("TestWorkspace")); + presenter.notify(IReflPresenter::OpenTableFlag); + + std::set rowlist; + rowlist.insert(1); + + //We should not receive any errors + EXPECT_CALL(mockView, giveUserCritical(_,_)).Times(0); + + //The user hits "append row" twice, with the second row selected + EXPECT_CALL(mockView, getSelectedRows()).Times(2).WillRepeatedly(Return(rowlist)); + presenter.notify(IReflPresenter::AppendRowFlag); + presenter.notify(IReflPresenter::AppendRowFlag); + + //The user hits "save" + presenter.notify(IReflPresenter::SaveFlag); + + //Check that the table has been modified correctly + auto ws = AnalysisDataService::Instance().retrieveWS("TestWorkspace"); + TS_ASSERT_EQUALS(ws->rowCount(), 6); + TS_ASSERT_EQUALS(ws->String(2, RunCol), ""); + TS_ASSERT_EQUALS(ws->String(3, RunCol), ""); + TS_ASSERT_EQUALS(ws->Int(0, GroupCol), 0); + TS_ASSERT_EQUALS(ws->Int(1, GroupCol), 0); + TS_ASSERT_EQUALS(ws->Int(2, GroupCol), 3); + TS_ASSERT_EQUALS(ws->Int(3, GroupCol), 2); + TS_ASSERT_EQUALS(ws->Int(4, GroupCol), 1); + TS_ASSERT_EQUALS(ws->Int(5, GroupCol), 1); + + //Tidy up + AnalysisDataService::Instance().remove("TestWorkspace"); + } + + void testAppendRowSpecifyPlural() + { + MockView mockView; + ReflMainViewPresenter presenter(&mockView); + + createPrefilledWorkspace("TestWorkspace"); + EXPECT_CALL(mockView, getWorkspaceToOpen()).Times(1).WillRepeatedly(Return("TestWorkspace")); + presenter.notify(IReflPresenter::OpenTableFlag); + + std::set rowlist; + rowlist.insert(1); + rowlist.insert(2); + + //We should not receive any errors + EXPECT_CALL(mockView, giveUserCritical(_,_)).Times(0); + + //The user hits "append row" once, with the second, third, and fourth row selected. + EXPECT_CALL(mockView, getSelectedRows()).Times(1).WillRepeatedly(Return(rowlist)); + presenter.notify(IReflPresenter::AppendRowFlag); + + //The user hits "save" + presenter.notify(IReflPresenter::SaveFlag); + + //Check that the table was modified correctly + auto ws = AnalysisDataService::Instance().retrieveWS("TestWorkspace"); + TS_ASSERT_EQUALS(ws->rowCount(), 5); + TS_ASSERT_EQUALS(ws->String(3, RunCol), ""); + TS_ASSERT_EQUALS(ws->Int(0, GroupCol), 0); + TS_ASSERT_EQUALS(ws->Int(1, GroupCol), 0); + TS_ASSERT_EQUALS(ws->Int(2, GroupCol), 1); + TS_ASSERT_EQUALS(ws->Int(3, GroupCol), 2); + TS_ASSERT_EQUALS(ws->Int(4, GroupCol), 1); + + //Tidy up + AnalysisDataService::Instance().remove("TestWorkspace"); + } + + void testPrependRow() + { + MockView mockView; + ReflMainViewPresenter presenter(&mockView); + + createPrefilledWorkspace("TestWorkspace"); + EXPECT_CALL(mockView, getWorkspaceToOpen()).Times(1).WillRepeatedly(Return("TestWorkspace")); + presenter.notify(IReflPresenter::OpenTableFlag); + + //We should not receive any errors + EXPECT_CALL(mockView, giveUserCritical(_,_)).Times(0); + + //The user hits "prepend row" twice with no rows selected + EXPECT_CALL(mockView, getSelectedRows()).Times(2).WillRepeatedly(Return(std::set())); + presenter.notify(IReflPresenter::PrependRowFlag); + presenter.notify(IReflPresenter::PrependRowFlag); + + //The user hits "save" + presenter.notify(IReflPresenter::SaveFlag); + + //Check that the table has been modified correctly + ITableWorkspace_sptr ws = AnalysisDataService::Instance().retrieveWS("TestWorkspace"); + TS_ASSERT_EQUALS(ws->rowCount(), 6); + TS_ASSERT_EQUALS(ws->Int(0, GroupCol), 3); + TS_ASSERT_EQUALS(ws->Int(1, GroupCol), 2); + TS_ASSERT_EQUALS(ws->Int(2, GroupCol), 0); + TS_ASSERT_EQUALS(ws->Int(3, GroupCol), 0); + TS_ASSERT_EQUALS(ws->Int(4, GroupCol), 1); + TS_ASSERT_EQUALS(ws->Int(5, GroupCol), 1); + + //Tidy up + AnalysisDataService::Instance().remove("TestWorkspace"); + } + + void testPrependRowSpecify() + { + MockView mockView; + ReflMainViewPresenter presenter(&mockView); + + createPrefilledWorkspace("TestWorkspace"); + EXPECT_CALL(mockView, getWorkspaceToOpen()).Times(1).WillRepeatedly(Return("TestWorkspace")); + presenter.notify(IReflPresenter::OpenTableFlag); + + std::set rowlist; + rowlist.insert(1); + + //We should not receive any errors + EXPECT_CALL(mockView, giveUserCritical(_,_)).Times(0); + + //The user hits "prepend row" twice, with the second row selected + EXPECT_CALL(mockView, getSelectedRows()).Times(2).WillRepeatedly(Return(rowlist)); + presenter.notify(IReflPresenter::PrependRowFlag); + presenter.notify(IReflPresenter::PrependRowFlag); + + //The user hits "save" + presenter.notify(IReflPresenter::SaveFlag); + + //Check that the table has been modified correctly + ITableWorkspace_sptr ws = AnalysisDataService::Instance().retrieveWS("TestWorkspace"); + TS_ASSERT_EQUALS(ws->rowCount(), 6); + TS_ASSERT_EQUALS(ws->Int(0, GroupCol), 0); + TS_ASSERT_EQUALS(ws->Int(1, GroupCol), 3); + TS_ASSERT_EQUALS(ws->Int(2, GroupCol), 2); + TS_ASSERT_EQUALS(ws->Int(3, GroupCol), 0); + TS_ASSERT_EQUALS(ws->Int(4, GroupCol), 1); + TS_ASSERT_EQUALS(ws->Int(5, GroupCol), 1); + + //Tidy up + AnalysisDataService::Instance().remove("TestWorkspace"); + } + + void testPrependRowSpecifyPlural() + { + MockView mockView; + ReflMainViewPresenter presenter(&mockView); + + createPrefilledWorkspace("TestWorkspace"); + EXPECT_CALL(mockView, getWorkspaceToOpen()).Times(1).WillRepeatedly(Return("TestWorkspace")); + presenter.notify(IReflPresenter::OpenTableFlag); + + std::set rowlist; + rowlist.insert(1); + rowlist.insert(2); + rowlist.insert(3); + + //We should not receive any errors + EXPECT_CALL(mockView, giveUserCritical(_,_)).Times(0); + + //The user hits "prepend row" once, with the second, third, and fourth row selected. + EXPECT_CALL(mockView, getSelectedRows()).Times(1).WillRepeatedly(Return(rowlist)); + presenter.notify(IReflPresenter::PrependRowFlag); + + //The user hits "save" + presenter.notify(IReflPresenter::SaveFlag); + + //Check that the table was modified correctly + ITableWorkspace_sptr ws = AnalysisDataService::Instance().retrieveWS("TestWorkspace"); + TS_ASSERT_EQUALS(ws->rowCount(), 5); + TS_ASSERT_EQUALS(ws->Int(0, GroupCol), 0); + TS_ASSERT_EQUALS(ws->Int(1, GroupCol), 2); + TS_ASSERT_EQUALS(ws->Int(2, GroupCol), 0); + TS_ASSERT_EQUALS(ws->Int(3, GroupCol), 1); + TS_ASSERT_EQUALS(ws->Int(4, GroupCol), 1); + + //Tidy up + AnalysisDataService::Instance().remove("TestWorkspace"); + } + + void testDeleteRowNone() + { + MockView mockView; + ReflMainViewPresenter presenter(&mockView); + + createPrefilledWorkspace("TestWorkspace"); + EXPECT_CALL(mockView, getWorkspaceToOpen()).Times(1).WillRepeatedly(Return("TestWorkspace")); + presenter.notify(IReflPresenter::OpenTableFlag); + + //We should not receive any errors + EXPECT_CALL(mockView, giveUserCritical(_,_)).Times(0); + + //The user hits "delete row" with no rows selected + EXPECT_CALL(mockView, getSelectedRows()).Times(1).WillRepeatedly(Return(std::set())); + presenter.notify(IReflPresenter::DeleteRowFlag); + + //The user hits save + presenter.notify(IReflPresenter::SaveFlag); + + //Check that the table has not lost any rows + auto ws = AnalysisDataService::Instance().retrieveWS("TestWorkspace"); + TS_ASSERT_EQUALS(ws->rowCount(), 4); + + //Tidy up + AnalysisDataService::Instance().remove("TestWorkspace"); + } + + void testDeleteRowSingle() + { + MockView mockView; + ReflMainViewPresenter presenter(&mockView); + + createPrefilledWorkspace("TestWorkspace"); + EXPECT_CALL(mockView, getWorkspaceToOpen()).Times(1).WillRepeatedly(Return("TestWorkspace")); + presenter.notify(IReflPresenter::OpenTableFlag); + + std::set rowlist; + rowlist.insert(1); + + //We should not receive any errors + EXPECT_CALL(mockView, giveUserCritical(_,_)).Times(0); + + //The user hits "delete row" with the second row selected + EXPECT_CALL(mockView, getSelectedRows()).Times(1).WillRepeatedly(Return(rowlist)); + presenter.notify(IReflPresenter::DeleteRowFlag); + + //The user hits "save" + presenter.notify(IReflPresenter::SaveFlag); + + auto ws = AnalysisDataService::Instance().retrieveWS("TestWorkspace"); + TS_ASSERT_EQUALS(ws->rowCount(), 3); + TS_ASSERT_EQUALS(ws->String(1, RunCol), "24681"); + TS_ASSERT_EQUALS(ws->Int(1, GroupCol), 1); + + //Tidy up + AnalysisDataService::Instance().remove("TestWorkspace"); + } + + void testDeleteRowPlural() + { + MockView mockView; + ReflMainViewPresenter presenter(&mockView); + + createPrefilledWorkspace("TestWorkspace"); + EXPECT_CALL(mockView, getWorkspaceToOpen()).Times(1).WillRepeatedly(Return("TestWorkspace")); + presenter.notify(IReflPresenter::OpenTableFlag); + + std::set rowlist; + rowlist.insert(0); + rowlist.insert(1); + rowlist.insert(2); + + //We should not receive any errors + EXPECT_CALL(mockView, giveUserCritical(_,_)).Times(0); + + //The user hits "delete row" with the first three rows selected + EXPECT_CALL(mockView, getSelectedRows()).Times(1).WillRepeatedly(Return(rowlist)); + presenter.notify(IReflPresenter::DeleteRowFlag); + + //The user hits save + presenter.notify(IReflPresenter::SaveFlag); + + //Check the rows were deleted as expected + auto ws = AnalysisDataService::Instance().retrieveWS("TestWorkspace"); + TS_ASSERT_EQUALS(ws->rowCount(), 1); + TS_ASSERT_EQUALS(ws->String(0, RunCol), "24682"); + TS_ASSERT_EQUALS(ws->Int(0, GroupCol), 1); + + //Tidy up + AnalysisDataService::Instance().remove("TestWorkspace"); + } + + void testProcess() + { + MockView mockView; + ReflMainViewPresenter presenter(&mockView); + + createPrefilledWorkspace("TestWorkspace"); + EXPECT_CALL(mockView, getWorkspaceToOpen()).Times(1).WillRepeatedly(Return("TestWorkspace")); + presenter.notify(IReflPresenter::OpenTableFlag); + + std::set rowlist; + rowlist.insert(0); + rowlist.insert(1); + + createTOFWorkspace("TOF_12345", "12345"); + createTOFWorkspace("TOF_12346", "12346"); + + //We should not receive any errors + EXPECT_CALL(mockView, giveUserCritical(_,_)).Times(0); + + //The user hits the "process" button with the first two rows selected + EXPECT_CALL(mockView, getSelectedRows()).Times(1).WillRepeatedly(Return(rowlist)); + presenter.notify(IReflPresenter::ProcessFlag); + + //Check output workspaces were created as expected + TS_ASSERT(AnalysisDataService::Instance().doesExist("IvsQ_12345")); + TS_ASSERT(AnalysisDataService::Instance().doesExist("IvsLam_12345")); + TS_ASSERT(AnalysisDataService::Instance().doesExist("TOF_12345")); + TS_ASSERT(AnalysisDataService::Instance().doesExist("IvsQ_12346")); + TS_ASSERT(AnalysisDataService::Instance().doesExist("IvsLam_12346")); + TS_ASSERT(AnalysisDataService::Instance().doesExist("TOF_12346")); + TS_ASSERT(AnalysisDataService::Instance().doesExist("IvsQ_12345_12346")); + + //Tidy up + AnalysisDataService::Instance().remove("TestWorkspace"); + AnalysisDataService::Instance().remove("IvsQ_12345"); + AnalysisDataService::Instance().remove("IvsLam_12345"); + AnalysisDataService::Instance().remove("TOF_12345"); + AnalysisDataService::Instance().remove("IvsQ_12346"); + AnalysisDataService::Instance().remove("IvsLam_12346"); + AnalysisDataService::Instance().remove("TOF_12346"); + AnalysisDataService::Instance().remove("IvsQ_12345_12346"); + } + + /* + * Test processing workspaces with non-standard names, with + * and without run_number information in the sample log. + */ + void testProcessCustomNames() + { + auto ws = createWorkspace("TestWorkspace"); + TableRow row = ws->appendRow(); + row << "dataA" << "0.7" << "" << "0.1" << "1.6" << "0.04" << 1.0 << 1; + row = ws->appendRow(); + row << "dataB" << "2.3" << "" << "1.4" << "2.9" << "0.04" << 1.0 << 1; + + createTOFWorkspace("dataA"); + createTOFWorkspace("dataB", "12346"); + + MockView mockView; + ReflMainViewPresenter presenter(&mockView); + EXPECT_CALL(mockView, getWorkspaceToOpen()).Times(1).WillRepeatedly(Return("TestWorkspace")); + presenter.notify(IReflPresenter::OpenTableFlag); + + std::set rowlist; + rowlist.insert(0); + rowlist.insert(1); + + //We should not receive any errors + EXPECT_CALL(mockView, giveUserCritical(_,_)).Times(0); + + //The user hits the "process" button with the first two rows selected + EXPECT_CALL(mockView, getSelectedRows()).Times(1).WillRepeatedly(Return(rowlist)); + presenter.notify(IReflPresenter::ProcessFlag); + + //Check output workspaces were created as expected + TS_ASSERT(AnalysisDataService::Instance().doesExist("IvsQ_dataA")); + TS_ASSERT(AnalysisDataService::Instance().doesExist("IvsQ_12346")); + TS_ASSERT(AnalysisDataService::Instance().doesExist("IvsQ_dataA_12346")); + TS_ASSERT(AnalysisDataService::Instance().doesExist("IvsLam_dataA")); + TS_ASSERT(AnalysisDataService::Instance().doesExist("IvsLam_12346")); + + //Tidy up + AnalysisDataService::Instance().remove("TestWorkspace"); + AnalysisDataService::Instance().remove("dataA"); + AnalysisDataService::Instance().remove("dataB"); + AnalysisDataService::Instance().remove("IvsQ_dataA"); + AnalysisDataService::Instance().remove("IvsLam_dataA"); + AnalysisDataService::Instance().remove("IvsQ_12346"); + AnalysisDataService::Instance().remove("IvsLam_12346"); + AnalysisDataService::Instance().remove("IvsQ_dataA_12346"); + } + + void testBadWorkspaceType() + { + ITableWorkspace_sptr ws = WorkspaceFactory::Instance().createTable(); + + //Wrong types + ws->addColumn("str","Run(s)"); + ws->addColumn("str","ThetaIn"); + ws->addColumn("str","TransRun(s)"); + ws->addColumn("str","Qmin"); + ws->addColumn("str","Qmax"); + ws->addColumn("str","dq/q"); + ws->addColumn("str","Scale"); + ws->addColumn("str","StitchGroup"); + ws->addColumn("str","Options"); + + AnalysisDataService::Instance().addOrReplace("TestWorkspace", ws); + + MockView mockView; + ReflMainViewPresenter presenter(&mockView); + + //We should receive an error + EXPECT_CALL(mockView, giveUserCritical(_,_)).Times(1); + + EXPECT_CALL(mockView, getWorkspaceToOpen()).Times(1).WillRepeatedly(Return("TestWorkspace")); + presenter.notify(IReflPresenter::OpenTableFlag); + + AnalysisDataService::Instance().remove("TestWorkspace"); + } + + void testBadWorkspaceLength() + { + MockView mockView; + ReflMainViewPresenter presenter(&mockView); + + //Because we to open twice, get an error twice + EXPECT_CALL(mockView, giveUserCritical(_,_)).Times(2); + EXPECT_CALL(mockView, getWorkspaceToOpen()).Times(2).WillRepeatedly(Return("TestWorkspace")); + + ITableWorkspace_sptr ws = WorkspaceFactory::Instance().createTable(); + ws->addColumn("str","Run(s)"); + ws->addColumn("str","ThetaIn"); + ws->addColumn("str","TransRun(s)"); + ws->addColumn("str","Qmin"); + ws->addColumn("str","Qmax"); + ws->addColumn("str","dq/q"); + ws->addColumn("double","Scale"); + ws->addColumn("int","StitchGroup"); + AnalysisDataService::Instance().addOrReplace("TestWorkspace", ws); + + //Try to open with too few columns + presenter.notify(IReflPresenter::OpenTableFlag); + + ws->addColumn("str","OptionsA"); + ws->addColumn("str","OptionsB"); + AnalysisDataService::Instance().addOrReplace("TestWorkspace", ws); + + //Try to open with too many columns + presenter.notify(IReflPresenter::OpenTableFlag); + + AnalysisDataService::Instance().remove("TestWorkspace"); + } + + void testParseKeyValueString() + { + std::map kvp = ReflMainViewPresenter::parseKeyValueString("a = 1,b=2.0, c=3, d='1,2,3',e=\"4,5,6\",f=1+1=2, g = '\\''"); + + TS_ASSERT_EQUALS(kvp["a"], "1"); + TS_ASSERT_EQUALS(kvp["b"], "2.0"); + TS_ASSERT_EQUALS(kvp["c"], "3"); + TS_ASSERT_EQUALS(kvp["d"], "1,2,3"); + TS_ASSERT_EQUALS(kvp["e"], "4,5,6"); + TS_ASSERT_EQUALS(kvp["f"], "1+1=2"); + TS_ASSERT_EQUALS(kvp["g"], "'"); + + TS_ASSERT_THROWS(ReflMainViewPresenter::parseKeyValueString("a = 1, b = 2, c = 3,"), std::runtime_error); + TS_ASSERT_THROWS(ReflMainViewPresenter::parseKeyValueString("a = 1, b = 2, c = 3,d"), std::runtime_error); + TS_ASSERT_THROWS(ReflMainViewPresenter::parseKeyValueString(",a = 1"), std::runtime_error); + TS_ASSERT_THROWS(ReflMainViewPresenter::parseKeyValueString(",a = 1 = 2,="), std::runtime_error); + TS_ASSERT_THROWS(ReflMainViewPresenter::parseKeyValueString("=,=,="), std::runtime_error); + } + + void testPromptSaveAfterAppendRow() + { + MockView mockView; + ReflMainViewPresenter presenter(&mockView); + + //User hits "append row" + EXPECT_CALL(mockView, getSelectedRows()).Times(1).WillRepeatedly(Return(std::set())); + presenter.notify(IReflPresenter::AppendRowFlag); + + //The user will decide not to discard their changes + EXPECT_CALL(mockView, askUserYesNo(_,_)).Times(1).WillOnce(Return(false)); + + //Then hits "new table" without having saved + presenter.notify(IReflPresenter::NewTableFlag); + + //The user saves + EXPECT_CALL(mockView, askUserString(_,_,"Workspace")).Times(1).WillOnce(Return("Workspace")); + presenter.notify(IReflPresenter::SaveFlag); + + //The user tries to create a new table again, and does not get bothered + EXPECT_CALL(mockView, askUserYesNo(_,_)).Times(0); + presenter.notify(IReflPresenter::NewTableFlag); + } + + void testPromptSaveAfterDeleteRow() + { + MockView mockView; + ReflMainViewPresenter presenter(&mockView); + + //User hits "append row" a couple of times + EXPECT_CALL(mockView, getSelectedRows()).Times(2).WillRepeatedly(Return(std::set())); + presenter.notify(IReflPresenter::AppendRowFlag); + presenter.notify(IReflPresenter::AppendRowFlag); + + //The user saves + EXPECT_CALL(mockView, askUserString(_,_,"Workspace")).Times(1).WillOnce(Return("Workspace")); + presenter.notify(IReflPresenter::SaveFlag); + + //...then deletes the 2nd row + std::set rows; + rows.insert(1); + EXPECT_CALL(mockView, getSelectedRows()).Times(1).WillRepeatedly(Return(rows)); + presenter.notify(IReflPresenter::DeleteRowFlag); + + //The user will decide not to discard their changes when asked + EXPECT_CALL(mockView, askUserYesNo(_,_)).Times(1).WillOnce(Return(false)); + + //Then hits "new table" without having saved + presenter.notify(IReflPresenter::NewTableFlag); + + //The user saves + presenter.notify(IReflPresenter::SaveFlag); + + //The user tries to create a new table again, and does not get bothered + EXPECT_CALL(mockView, askUserYesNo(_,_)).Times(0); + presenter.notify(IReflPresenter::NewTableFlag); + } + + void testPromptSaveAndDiscard() + { + MockView mockView; + ReflMainViewPresenter presenter(&mockView); + + //User hits "append row" a couple of times + EXPECT_CALL(mockView, getSelectedRows()).Times(2).WillRepeatedly(Return(std::set())); + presenter.notify(IReflPresenter::AppendRowFlag); + presenter.notify(IReflPresenter::AppendRowFlag); + + //Then hits "new table", and decides to discard + EXPECT_CALL(mockView, askUserYesNo(_,_)).Times(1).WillOnce(Return(true)); + presenter.notify(IReflPresenter::NewTableFlag); + + //These next two times they don't get prompted - they have a new table + presenter.notify(IReflPresenter::NewTableFlag); + presenter.notify(IReflPresenter::NewTableFlag); + } + + void testPromptSaveOnOpen() + { + MockView mockView; + ReflMainViewPresenter presenter(&mockView); + + createPrefilledWorkspace("TestWorkspace"); + + //User hits "append row" + EXPECT_CALL(mockView, getSelectedRows()).Times(1).WillRepeatedly(Return(std::set())); + presenter.notify(IReflPresenter::AppendRowFlag); + + //and tries to open a workspace, but gets prompted and decides not to discard + EXPECT_CALL(mockView, askUserYesNo(_,_)).Times(1).WillOnce(Return(false)); + presenter.notify(IReflPresenter::OpenTableFlag); + + //the user does it again, but discards + EXPECT_CALL(mockView, askUserYesNo(_,_)).Times(1).WillOnce(Return(true)); + EXPECT_CALL(mockView, getWorkspaceToOpen()).Times(1).WillRepeatedly(Return("TestWorkspace")); + presenter.notify(IReflPresenter::OpenTableFlag); + + //the user does it one more time, and is not prompted + EXPECT_CALL(mockView, getWorkspaceToOpen()).Times(1).WillRepeatedly(Return("TestWorkspace")); + EXPECT_CALL(mockView, askUserYesNo(_,_)).Times(0); + presenter.notify(IReflPresenter::OpenTableFlag); + } + + void testExpandSelection() + { + auto ws = createWorkspace("TestWorkspace"); + TableRow row = ws->appendRow(); + row << "" << "" << "" << "" << "" << "" << 1.0 << 0 << ""; //Row 0 + row = ws->appendRow(); + row << "" << "" << "" << "" << "" << "" << 1.0 << 1 << ""; //Row 1 + row = ws->appendRow(); + row << "" << "" << "" << "" << "" << "" << 1.0 << 1 << ""; //Row 2 + row = ws->appendRow(); + row << "" << "" << "" << "" << "" << "" << 1.0 << 2 << ""; //Row 3 + row = ws->appendRow(); + row << "" << "" << "" << "" << "" << "" << 1.0 << 2 << ""; //Row 4 + row = ws->appendRow(); + row << "" << "" << "" << "" << "" << "" << 1.0 << 2 << ""; //Row 5 + row = ws->appendRow(); + row << "" << "" << "" << "" << "" << "" << 1.0 << 3 << ""; //Row 6 + row = ws->appendRow(); + row << "" << "" << "" << "" << "" << "" << 1.0 << 4 << ""; //Row 7 + row = ws->appendRow(); + row << "" << "" << "" << "" << "" << "" << 1.0 << 4 << ""; //Row 8 + row = ws->appendRow(); + row << "" << "" << "" << "" << "" << "" << 1.0 << 5 << ""; //Row 9 + + MockView mockView; + ReflMainViewPresenter presenter(&mockView); + + EXPECT_CALL(mockView, getWorkspaceToOpen()).Times(1).WillRepeatedly(Return("TestWorkspace")); + presenter.notify(IReflPresenter::OpenTableFlag); + + //We should not receive any errors + EXPECT_CALL(mockView, giveUserCritical(_,_)).Times(0); + + std::set selection; + std::set expected; + + selection.insert(0); + expected.insert(0); + + //With row 0 selected, we shouldn't expand at all + EXPECT_CALL(mockView, getSelectedRows()).Times(1).WillRepeatedly(Return(selection)); + EXPECT_CALL(mockView, setSelection(ContainerEq(expected))).Times(1); + presenter.notify(IReflPresenter::ExpandSelectionFlag); + + //With 0,1 selected, we should finish with 0,1,2 selected + selection.clear(); + selection.insert(0); + selection.insert(1); + + expected.clear(); + expected.insert(0); + expected.insert(1); + expected.insert(2); + + EXPECT_CALL(mockView, getSelectedRows()).Times(1).WillRepeatedly(Return(selection)); + EXPECT_CALL(mockView, setSelection(ContainerEq(expected))).Times(1); + presenter.notify(IReflPresenter::ExpandSelectionFlag); + + //With 1,6 selected, we should finish with 1,2,6 selected + selection.clear(); + selection.insert(1); + selection.insert(6); + + expected.clear(); + expected.insert(1); + expected.insert(2); + expected.insert(6); + + EXPECT_CALL(mockView, getSelectedRows()).Times(1).WillRepeatedly(Return(selection)); + EXPECT_CALL(mockView, setSelection(ContainerEq(expected))).Times(1); + presenter.notify(IReflPresenter::ExpandSelectionFlag); + + //With 4,8 selected, we should finish with 3,4,5,7,8 selected + selection.clear(); + selection.insert(4); + selection.insert(8); + + expected.clear(); + expected.insert(3); + expected.insert(4); + expected.insert(5); + expected.insert(7); + expected.insert(8); + + EXPECT_CALL(mockView, getSelectedRows()).Times(1).WillRepeatedly(Return(selection)); + EXPECT_CALL(mockView, setSelection(ContainerEq(expected))).Times(1); + presenter.notify(IReflPresenter::ExpandSelectionFlag); + + //With nothing selected, we should finish with nothing selected + selection.clear(); + expected.clear(); + + EXPECT_CALL(mockView, getSelectedRows()).Times(1).WillRepeatedly(Return(selection)); + EXPECT_CALL(mockView, setSelection(ContainerEq(expected))).Times(1); + presenter.notify(IReflPresenter::ExpandSelectionFlag); + + //Tidy up + AnalysisDataService::Instance().remove("TestWorkspace"); + } + + void testClearRows() + { + MockView mockView; + ReflMainViewPresenter presenter(&mockView); + + createPrefilledWorkspace("TestWorkspace"); + EXPECT_CALL(mockView, getWorkspaceToOpen()).Times(1).WillRepeatedly(Return("TestWorkspace")); + presenter.notify(IReflPresenter::OpenTableFlag); + + std::set rowlist; + rowlist.insert(1); + rowlist.insert(2); + + //We should not receive any errors + EXPECT_CALL(mockView, giveUserCritical(_,_)).Times(0); + + //The user hits "clear selected" with the second and third rows selected + EXPECT_CALL(mockView, getSelectedRows()).Times(1).WillRepeatedly(Return(rowlist)); + presenter.notify(IReflPresenter::ClearSelectedFlag); + + //The user hits "save" + presenter.notify(IReflPresenter::SaveFlag); + + auto ws = AnalysisDataService::Instance().retrieveWS("TestWorkspace"); + TS_ASSERT_EQUALS(ws->rowCount(), 4); + //Check the unselected rows were unaffected + TS_ASSERT_EQUALS(ws->String(0, RunCol), "12345"); + TS_ASSERT_EQUALS(ws->String(3, RunCol), "24682"); + + //Check the group ids have been set correctly + TS_ASSERT_EQUALS(ws->Int(0, GroupCol), 0); + TS_ASSERT_EQUALS(ws->Int(1, GroupCol), 2); + TS_ASSERT_EQUALS(ws->Int(2, GroupCol), 3); + TS_ASSERT_EQUALS(ws->Int(3, GroupCol), 1); + + //Make sure the selected rows are clear + TS_ASSERT_EQUALS(ws->String(1, RunCol), ""); + TS_ASSERT_EQUALS(ws->String(2, RunCol), ""); + TS_ASSERT_EQUALS(ws->String(1, ThetaCol), ""); + TS_ASSERT_EQUALS(ws->String(2, ThetaCol), ""); + TS_ASSERT_EQUALS(ws->String(1, TransCol), ""); + TS_ASSERT_EQUALS(ws->String(2, TransCol), ""); + TS_ASSERT_EQUALS(ws->String(1, QMinCol), ""); + TS_ASSERT_EQUALS(ws->String(2, QMinCol), ""); + TS_ASSERT_EQUALS(ws->String(1, QMaxCol), ""); + TS_ASSERT_EQUALS(ws->String(2, QMaxCol), ""); + TS_ASSERT_EQUALS(ws->String(1, DQQCol), ""); + TS_ASSERT_EQUALS(ws->String(2, DQQCol), ""); + TS_ASSERT_EQUALS(ws->Double(1, ScaleCol), 1.0); + TS_ASSERT_EQUALS(ws->Double(2, ScaleCol), 1.0); + + //Tidy up + AnalysisDataService::Instance().remove("TestWorkspace"); + } + + void testCopyRow() + { + MockView mockView; + ReflMainViewPresenter presenter(&mockView); + + createPrefilledWorkspace("TestWorkspace"); + EXPECT_CALL(mockView, getWorkspaceToOpen()).Times(1).WillRepeatedly(Return("TestWorkspace")); + presenter.notify(IReflPresenter::OpenTableFlag); + + std::set rowlist; + rowlist.insert(1); + + const std::string expected = "12346\t1.5\t\t1.4\t2.9\t0.04\t1\t0\t"; + + //The user hits "copy selected" with the second and third rows selected + EXPECT_CALL(mockView, setClipboard(expected)); + EXPECT_CALL(mockView, getSelectedRows()).Times(1).WillRepeatedly(Return(rowlist)); + presenter.notify(IReflPresenter::CopySelectedFlag); + } + + void testCopyRows() + { + MockView mockView; + ReflMainViewPresenter presenter(&mockView); + + createPrefilledWorkspace("TestWorkspace"); + EXPECT_CALL(mockView, getWorkspaceToOpen()).Times(1).WillRepeatedly(Return("TestWorkspace")); + presenter.notify(IReflPresenter::OpenTableFlag); + + std::set rowlist; + rowlist.insert(0); + rowlist.insert(1); + rowlist.insert(2); + rowlist.insert(3); + + const std::string expected = "12345\t0.5\t\t0.1\t1.6\t0.04\t1\t0\t\n" + "12346\t1.5\t\t1.4\t2.9\t0.04\t1\t0\t\n" + "24681\t0.5\t\t0.1\t1.6\t0.04\t1\t1\t\n" + "24682\t1.5\t\t1.4\t2.9\t0.04\t1\t1\t"; + + //The user hits "copy selected" with the second and third rows selected + EXPECT_CALL(mockView, setClipboard(expected)); + EXPECT_CALL(mockView, getSelectedRows()).Times(1).WillRepeatedly(Return(rowlist)); + presenter.notify(IReflPresenter::CopySelectedFlag); + } + + void testCutRow() + { + MockView mockView; + ReflMainViewPresenter presenter(&mockView); + + createPrefilledWorkspace("TestWorkspace"); + EXPECT_CALL(mockView, getWorkspaceToOpen()).Times(1).WillRepeatedly(Return("TestWorkspace")); + presenter.notify(IReflPresenter::OpenTableFlag); + + std::set rowlist; + rowlist.insert(1); + + const std::string expected = "12346\t1.5\t\t1.4\t2.9\t0.04\t1\t0\t"; + + //The user hits "copy selected" with the second and third rows selected + EXPECT_CALL(mockView, setClipboard(expected)); + EXPECT_CALL(mockView, getSelectedRows()).Times(2).WillRepeatedly(Return(rowlist)); + presenter.notify(IReflPresenter::CutSelectedFlag); + + //The user hits "save" + presenter.notify(IReflPresenter::SaveFlag); + + auto ws = AnalysisDataService::Instance().retrieveWS("TestWorkspace"); + TS_ASSERT_EQUALS(ws->rowCount(), 3); + //Check the unselected rows were unaffected + TS_ASSERT_EQUALS(ws->String(0, RunCol), "12345"); + TS_ASSERT_EQUALS(ws->String(1, RunCol), "24681"); + TS_ASSERT_EQUALS(ws->String(2, RunCol), "24682"); + } + + void testCutRows() + { + MockView mockView; + ReflMainViewPresenter presenter(&mockView); + + createPrefilledWorkspace("TestWorkspace"); + EXPECT_CALL(mockView, getWorkspaceToOpen()).Times(1).WillRepeatedly(Return("TestWorkspace")); + presenter.notify(IReflPresenter::OpenTableFlag); + + std::set rowlist; + rowlist.insert(0); + rowlist.insert(1); + rowlist.insert(2); + + const std::string expected = "12345\t0.5\t\t0.1\t1.6\t0.04\t1\t0\t\n" + "12346\t1.5\t\t1.4\t2.9\t0.04\t1\t0\t\n" + "24681\t0.5\t\t0.1\t1.6\t0.04\t1\t1\t"; + + //The user hits "copy selected" with the second and third rows selected + EXPECT_CALL(mockView, setClipboard(expected)); + EXPECT_CALL(mockView, getSelectedRows()).Times(2).WillRepeatedly(Return(rowlist)); + presenter.notify(IReflPresenter::CutSelectedFlag); + + //The user hits "save" + presenter.notify(IReflPresenter::SaveFlag); + + auto ws = AnalysisDataService::Instance().retrieveWS("TestWorkspace"); + TS_ASSERT_EQUALS(ws->rowCount(), 1); + //Check the only unselected row is left behind + TS_ASSERT_EQUALS(ws->String(0, RunCol), "24682"); + } + + void testPasteRow() + { + MockView mockView; + ReflMainViewPresenter presenter(&mockView); + + createPrefilledWorkspace("TestWorkspace"); + EXPECT_CALL(mockView, getWorkspaceToOpen()).Times(1).WillRepeatedly(Return("TestWorkspace")); + presenter.notify(IReflPresenter::OpenTableFlag); + + std::set rowlist; + rowlist.insert(1); + + const std::string clipboard = "123\t0.5\t456\t1.2\t3.4\t3.14\t5\t6\tabc"; + + //The user hits "copy selected" with the second and third rows selected + EXPECT_CALL(mockView, getClipboard()).Times(1).WillRepeatedly(Return(clipboard)); + EXPECT_CALL(mockView, getSelectedRows()).Times(1).WillRepeatedly(Return(rowlist)); + presenter.notify(IReflPresenter::PasteSelectedFlag); + + //The user hits "save" + presenter.notify(IReflPresenter::SaveFlag); + + auto ws = AnalysisDataService::Instance().retrieveWS("TestWorkspace"); + TS_ASSERT_EQUALS(ws->rowCount(), 4); + //Check the unselected rows were unaffected + TS_ASSERT_EQUALS(ws->String(0, RunCol), "12345"); + TS_ASSERT_EQUALS(ws->String(2, RunCol), "24681"); + TS_ASSERT_EQUALS(ws->String(3, RunCol), "24682"); + + //Check the values were pasted correctly + TS_ASSERT_EQUALS(ws->String(1, RunCol), "123"); + TS_ASSERT_EQUALS(ws->String(1, ThetaCol), "0.5"); + TS_ASSERT_EQUALS(ws->String(1, TransCol), "456"); + TS_ASSERT_EQUALS(ws->String(1, QMinCol), "1.2"); + TS_ASSERT_EQUALS(ws->String(1, QMaxCol), "3.4"); + TS_ASSERT_EQUALS(ws->String(1, DQQCol), "3.14"); + TS_ASSERT_EQUALS(ws->Double(1, ScaleCol), 5.0); + TS_ASSERT_EQUALS(ws->Int(1, GroupCol), 6); + TS_ASSERT_EQUALS(ws->String(1, OptionsCol), "abc"); + } + + void testPasteNewRow() + { + MockView mockView; + ReflMainViewPresenter presenter(&mockView); + + createPrefilledWorkspace("TestWorkspace"); + EXPECT_CALL(mockView, getWorkspaceToOpen()).Times(1).WillRepeatedly(Return("TestWorkspace")); + presenter.notify(IReflPresenter::OpenTableFlag); + + const std::string clipboard = "123\t0.5\t456\t1.2\t3.4\t3.14\t5\t6\tabc"; + + //The user hits "copy selected" with the second and third rows selected + EXPECT_CALL(mockView, getClipboard()).Times(1).WillRepeatedly(Return(clipboard)); + EXPECT_CALL(mockView, getSelectedRows()).Times(1).WillRepeatedly(Return(std::set())); + presenter.notify(IReflPresenter::PasteSelectedFlag); + + //The user hits "save" + presenter.notify(IReflPresenter::SaveFlag); + + auto ws = AnalysisDataService::Instance().retrieveWS("TestWorkspace"); + TS_ASSERT_EQUALS(ws->rowCount(), 5); + //Check the unselected rows were unaffected + TS_ASSERT_EQUALS(ws->String(0, RunCol), "12345"); + TS_ASSERT_EQUALS(ws->String(1, RunCol), "12346"); + TS_ASSERT_EQUALS(ws->String(2, RunCol), "24681"); + TS_ASSERT_EQUALS(ws->String(3, RunCol), "24682"); + + //Check the values were pasted correctly + TS_ASSERT_EQUALS(ws->String(4, RunCol), "123"); + TS_ASSERT_EQUALS(ws->String(4, ThetaCol), "0.5"); + TS_ASSERT_EQUALS(ws->String(4, TransCol), "456"); + TS_ASSERT_EQUALS(ws->String(4, QMinCol), "1.2"); + TS_ASSERT_EQUALS(ws->String(4, QMaxCol), "3.4"); + TS_ASSERT_EQUALS(ws->String(4, DQQCol), "3.14"); + TS_ASSERT_EQUALS(ws->Double(4, ScaleCol), 5.0); + TS_ASSERT_EQUALS(ws->Int(4, GroupCol), 6); + TS_ASSERT_EQUALS(ws->String(4, OptionsCol), "abc"); + } + + void testPasteRows() + { + MockView mockView; + ReflMainViewPresenter presenter(&mockView); + + createPrefilledWorkspace("TestWorkspace"); + EXPECT_CALL(mockView, getWorkspaceToOpen()).Times(1).WillRepeatedly(Return("TestWorkspace")); + presenter.notify(IReflPresenter::OpenTableFlag); + + std::set rowlist; + rowlist.insert(1); + rowlist.insert(2); + + const std::string clipboard = "123\t0.5\t456\t1.2\t3.4\t3.14\t5\t6\tabc\n" + "345\t2.7\t123\t2.1\t4.3\t2.17\t3\t2\tdef"; + + //The user hits "copy selected" with the second and third rows selected + EXPECT_CALL(mockView, getClipboard()).Times(1).WillRepeatedly(Return(clipboard)); + EXPECT_CALL(mockView, getSelectedRows()).Times(1).WillRepeatedly(Return(rowlist)); + presenter.notify(IReflPresenter::PasteSelectedFlag); + + //The user hits "save" + presenter.notify(IReflPresenter::SaveFlag); + + auto ws = AnalysisDataService::Instance().retrieveWS("TestWorkspace"); + TS_ASSERT_EQUALS(ws->rowCount(), 4); + //Check the unselected rows were unaffected + TS_ASSERT_EQUALS(ws->String(0, RunCol), "12345"); + TS_ASSERT_EQUALS(ws->String(3, RunCol), "24682"); + + //Check the values were pasted correctly + TS_ASSERT_EQUALS(ws->String(1, RunCol), "123"); + TS_ASSERT_EQUALS(ws->String(1, ThetaCol), "0.5"); + TS_ASSERT_EQUALS(ws->String(1, TransCol), "456"); + TS_ASSERT_EQUALS(ws->String(1, QMinCol), "1.2"); + TS_ASSERT_EQUALS(ws->String(1, QMaxCol), "3.4"); + TS_ASSERT_EQUALS(ws->String(1, DQQCol), "3.14"); + TS_ASSERT_EQUALS(ws->Double(1, ScaleCol), 5.0); + TS_ASSERT_EQUALS(ws->Int(1, GroupCol), 6); + TS_ASSERT_EQUALS(ws->String(1, OptionsCol), "abc"); + + TS_ASSERT_EQUALS(ws->String(2, RunCol), "345"); + TS_ASSERT_EQUALS(ws->String(2, ThetaCol), "2.7"); + TS_ASSERT_EQUALS(ws->String(2, TransCol), "123"); + TS_ASSERT_EQUALS(ws->String(2, QMinCol), "2.1"); + TS_ASSERT_EQUALS(ws->String(2, QMaxCol), "4.3"); + TS_ASSERT_EQUALS(ws->String(2, DQQCol), "2.17"); + TS_ASSERT_EQUALS(ws->Double(2, ScaleCol), 3.0); + TS_ASSERT_EQUALS(ws->Int(2, GroupCol), 2); + TS_ASSERT_EQUALS(ws->String(2, OptionsCol), "def"); + } + + void testPasteNewRows() + { + MockView mockView; + ReflMainViewPresenter presenter(&mockView); + + createPrefilledWorkspace("TestWorkspace"); + EXPECT_CALL(mockView, getWorkspaceToOpen()).Times(1).WillRepeatedly(Return("TestWorkspace")); + presenter.notify(IReflPresenter::OpenTableFlag); + + const std::string clipboard = "123\t0.5\t456\t1.2\t3.4\t3.14\t5\t6\tabc\n" + "345\t2.7\t123\t2.1\t4.3\t2.17\t3\t2\tdef"; + + //The user hits "copy selected" with the second and third rows selected + EXPECT_CALL(mockView, getClipboard()).Times(1).WillRepeatedly(Return(clipboard)); + EXPECT_CALL(mockView, getSelectedRows()).Times(1).WillRepeatedly(Return(std::set())); + presenter.notify(IReflPresenter::PasteSelectedFlag); + + //The user hits "save" + presenter.notify(IReflPresenter::SaveFlag); + + auto ws = AnalysisDataService::Instance().retrieveWS("TestWorkspace"); + TS_ASSERT_EQUALS(ws->rowCount(), 6); + //Check the unselected rows were unaffected + TS_ASSERT_EQUALS(ws->String(0, RunCol), "12345"); + TS_ASSERT_EQUALS(ws->String(1, RunCol), "12346"); + TS_ASSERT_EQUALS(ws->String(2, RunCol), "24681"); + TS_ASSERT_EQUALS(ws->String(3, RunCol), "24682"); + + //Check the values were pasted correctly + TS_ASSERT_EQUALS(ws->String(4, RunCol), "123"); + TS_ASSERT_EQUALS(ws->String(4, ThetaCol), "0.5"); + TS_ASSERT_EQUALS(ws->String(4, TransCol), "456"); + TS_ASSERT_EQUALS(ws->String(4, QMinCol), "1.2"); + TS_ASSERT_EQUALS(ws->String(4, QMaxCol), "3.4"); + TS_ASSERT_EQUALS(ws->String(4, DQQCol), "3.14"); + TS_ASSERT_EQUALS(ws->Double(4, ScaleCol), 5.0); + TS_ASSERT_EQUALS(ws->Int(4, GroupCol), 6); + TS_ASSERT_EQUALS(ws->String(4, OptionsCol), "abc"); + + TS_ASSERT_EQUALS(ws->String(5, RunCol), "345"); + TS_ASSERT_EQUALS(ws->String(5, ThetaCol), "2.7"); + TS_ASSERT_EQUALS(ws->String(5, TransCol), "123"); + TS_ASSERT_EQUALS(ws->String(5, QMinCol), "2.1"); + TS_ASSERT_EQUALS(ws->String(5, QMaxCol), "4.3"); + TS_ASSERT_EQUALS(ws->String(5, DQQCol), "2.17"); + TS_ASSERT_EQUALS(ws->Double(5, ScaleCol), 3.0); + TS_ASSERT_EQUALS(ws->Int(5, GroupCol), 2); + TS_ASSERT_EQUALS(ws->String(5, OptionsCol), "def"); + } + + void testImportTable() + { + MockView mockView; + ReflMainViewPresenter presenter(&mockView); + EXPECT_CALL(mockView, showAlgorithmDialog("LoadReflTBL")); + presenter.notify(IReflPresenter::ImportTableFlag); + } + + void testExportTable() + { + MockView mockView; + ReflMainViewPresenter presenter(&mockView); + EXPECT_CALL(mockView, showAlgorithmDialog("SaveReflTBL")); + presenter.notify(IReflPresenter::ExportTableFlag); + } +}; + +#endif /* MANTID_CUSTOMINTERFACES_REFLMAINVIEWPRESENTERTEST_H */ diff --git a/Code/Mantid/MantidQt/Factory/inc/MantidQtFactory/WidgetFactory.h b/Code/Mantid/MantidQt/Factory/inc/MantidQtFactory/WidgetFactory.h index 2d603b0f68ce..e6a8f54f6c7b 100644 --- a/Code/Mantid/MantidQt/Factory/inc/MantidQtFactory/WidgetFactory.h +++ b/Code/Mantid/MantidQt/Factory/inc/MantidQtFactory/WidgetFactory.h @@ -13,6 +13,10 @@ namespace MantidQt { + namespace SliceViewer + { + class SliceViewerWindow; + } namespace Factory { @@ -53,6 +57,7 @@ namespace Factory MantidQt::SliceViewer::SliceViewerWindow* createSliceViewerWindow(const QString& wsName, const QString& label); MantidQt::SliceViewer::SliceViewerWindow* getSliceViewerWindow(const QString& wsName, const QString& label); void closeAllSliceViewerWindows(); + void closeSliceViewerWindow(SliceViewer::SliceViewerWindow* w); MantidQt::SliceViewer::SliceViewer* createSliceViewer(const QString& wsName); @@ -61,7 +66,7 @@ namespace Factory protected: /// List of the open SliceViewerWindows - std::vector > m_windows; + std::list > m_windows; /// Singleton instance static WidgetFactory * m_pInstance; }; diff --git a/Code/Mantid/MantidQt/Factory/src/WidgetFactory.cpp b/Code/Mantid/MantidQt/Factory/src/WidgetFactory.cpp index 1313eb702b43..7005a772e17f 100644 --- a/Code/Mantid/MantidQt/Factory/src/WidgetFactory.cpp +++ b/Code/Mantid/MantidQt/Factory/src/WidgetFactory.cpp @@ -77,9 +77,7 @@ namespace Factory */ MantidQt::SliceViewer::SliceViewerWindow* WidgetFactory::getSliceViewerWindow(const QString& wsName, const QString& label) { - - std::vector >::iterator it; - for (it = m_windows.begin(); it != m_windows.end(); ++it) + for (auto it = m_windows.begin(); it != m_windows.end(); ++it) { QPointer window = *it; if (window) @@ -99,8 +97,7 @@ namespace Factory */ void WidgetFactory::closeAllSliceViewerWindows() { - std::vector >::iterator it; - for (it = m_windows.begin(); it != m_windows.end(); ++it) + for (auto it = m_windows.begin(); it != m_windows.end(); ++it) { QPointer window = *it; if (window) @@ -110,6 +107,18 @@ namespace Factory m_windows.clear(); } + /** + * Closes one instance + */ + void WidgetFactory::closeSliceViewerWindow(SliceViewerWindow* w) + { + if (w) + { + w->close(true); + m_windows.remove(w); + } + } + //---------------------------------------------------------------------------------------------- /** Create an instance of a bare SliceViewer Widget. * This is only capable of doing 2D views, and cannot do line plots diff --git a/Code/Mantid/MantidQt/MantidWidgets/CMakeLists.txt b/Code/Mantid/MantidQt/MantidWidgets/CMakeLists.txt index 64ebe528e242..d81e332cfdc2 100644 --- a/Code/Mantid/MantidQt/MantidWidgets/CMakeLists.txt +++ b/Code/Mantid/MantidQt/MantidWidgets/CMakeLists.txt @@ -12,6 +12,7 @@ set ( SRC_FILES src/FitPropertyBrowser.cpp src/FormulaDialogEditor.cpp src/FunctionBrowser.cpp + src/HintingLineEdit.cpp src/InstrumentSelector.cpp src/MantidHelpWindow.cpp src/MWDiag.cpp @@ -53,6 +54,7 @@ set ( MOC_FILES inc/MantidQtMantidWidgets/FindDialog.h inc/MantidQtMantidWidgets/FitPropertyBrowser.h inc/MantidQtMantidWidgets/FunctionBrowser.h + inc/MantidQtMantidWidgets/HintingLineEdit.h inc/MantidQtMantidWidgets/CatalogSearch.h inc/MantidQtMantidWidgets/CatalogSelector.h inc/MantidQtMantidWidgets/InstrumentSelector.h @@ -87,8 +89,10 @@ set ( MOC_FILES # Add the include files are NOT already in MOC_FILES set ( INC_FILES ${MOC_FILES} + inc/MantidQtMantidWidgets/AlgorithmHintStrategy.h inc/MantidQtMantidWidgets/CatalogHelper.h inc/MantidQtMantidWidgets/WidgetDllOption.h + inc/MantidQtMantidWidgets/HintStrategy.h ) # QtDesigner UI files to process @@ -113,6 +117,10 @@ set ( TEST_PY_FILES test/MWRunFilesTest.py ) +set ( TEST_FILES + AlgorithmHintStrategyTest.h +) + find_package (Qt4 REQUIRED QtHelp QtWebKit QtNetwork QUIET) include(${QT_USE_FILE}) @@ -141,12 +149,10 @@ target_link_libraries ( MantidWidgets MantidQtAPI QtPropertyBrowser ) ########################################################################### -# Unit tests setup +# Testing ########################################################################### -if ( PYUNITTEST_FOUND ) - pyunittest_add_test (${CMAKE_CURRENT_SOURCE_DIR}/test MantidWidgetsTest ${TEST_PY_FILES} ) -endif () +add_subdirectory ( test ) ########################################################################### # Installation settings diff --git a/Code/Mantid/MantidQt/MantidWidgets/inc/MantidQtMantidWidgets/AlgorithmHintStrategy.h b/Code/Mantid/MantidQt/MantidWidgets/inc/MantidQtMantidWidgets/AlgorithmHintStrategy.h new file mode 100644 index 000000000000..760595d95611 --- /dev/null +++ b/Code/Mantid/MantidQt/MantidWidgets/inc/MantidQtMantidWidgets/AlgorithmHintStrategy.h @@ -0,0 +1,67 @@ +#ifndef MANTID_MANTIDWIDGETS_ALGORITHMHINTSTRATEGY_H +#define MANTID_MANTIDWIDGETS_ALGORITHMHINTSTRATEGY_H + +#include "MantidAPI/IAlgorithm.h" +#include "MantidQtMantidWidgets/HintStrategy.h" + +using namespace Mantid::API; + +namespace MantidQt +{ + namespace MantidWidgets + { + /** AlgorithmHintStrategy : Produces hints using a given algorithm's properties. + + Copyright © 2014 ISIS Rutherford Appleton Laboratory & NScD Oak Ridge National Laboratory + + This file is part of Mantid. + + Mantid is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + Mantid is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + + File change history is stored at: + Code Documentation is available at: + */ + class AlgorithmHintStrategy : public HintStrategy + { + public: + AlgorithmHintStrategy(IAlgorithm_sptr algorithm, std::set blacklist) : m_algorithm(algorithm), m_blacklist(blacklist) + { + } + + virtual ~AlgorithmHintStrategy() {}; + + virtual std::map createHints() + { + std::map hints; + + auto properties = m_algorithm->getProperties(); + for(auto it = properties.begin(); it != properties.end(); ++it) + { + const std::string name = (*it)->name(); + + //If it's not in the blacklist, add the property to our hints + if(m_blacklist.find(name) == m_blacklist.end()) + hints[name] = (*it)->briefDocumentation(); + } + + return hints; + } + private: + IAlgorithm_sptr m_algorithm; + std::set m_blacklist; + }; + } +} + +#endif /* MANTID_MANTIDWIDGETS_ALGORITHMHINTSTRATEGY_H */ diff --git a/Code/Mantid/MantidQt/MantidWidgets/inc/MantidQtMantidWidgets/HintStrategy.h b/Code/Mantid/MantidQt/MantidWidgets/inc/MantidQtMantidWidgets/HintStrategy.h new file mode 100644 index 000000000000..0554ac3609d3 --- /dev/null +++ b/Code/Mantid/MantidQt/MantidWidgets/inc/MantidQtMantidWidgets/HintStrategy.h @@ -0,0 +1,48 @@ +#ifndef MANTID_MANTIDWIDGETS_HINTSTRATEGY_H +#define MANTID_MANTIDWIDGETS_HINTSTRATEGY_H + +#include +#include + +namespace MantidQt +{ + namespace MantidWidgets + { + /** HintStrategy : Provides an interface for generating hints to be used by a HintingLineEdit. + + Copyright © 2014 ISIS Rutherford Appleton Laboratory & NScD Oak Ridge National Laboratory + + This file is part of Mantid. + + Mantid is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + Mantid is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + + File change history is stored at: + Code Documentation is available at: + */ + class HintStrategy + { + public: + HintStrategy() {}; + virtual ~HintStrategy() {}; + + /** Create a list of hints for auto completion + + @returns A map of keywords to short descriptions for the keyword. + */ + virtual std::map createHints() = 0; + }; + } +} + +#endif /* MANTID_MANTIDWIDGETS_HINTSTRATEGY_H */ diff --git a/Code/Mantid/MantidQt/MantidWidgets/inc/MantidQtMantidWidgets/HintingLineEdit.h b/Code/Mantid/MantidQt/MantidWidgets/inc/MantidQtMantidWidgets/HintingLineEdit.h new file mode 100644 index 000000000000..76df20b98b42 --- /dev/null +++ b/Code/Mantid/MantidQt/MantidWidgets/inc/MantidQtMantidWidgets/HintingLineEdit.h @@ -0,0 +1,67 @@ +#ifndef MANTID_MANTIDWIDGETS_HINTINGLINEEDIT_H_ +#define MANTID_MANTIDWIDGETS_HINTINGLINEEDIT_H_ + +#include "MantidKernel/System.h" +#include "MantidAPI/AlgorithmFactory.h" +#include "WidgetDllOption.h" + +#include +#include +#include + +//------------------------------------------------------------------------------ +// Forward declaration +//------------------------------------------------------------------------------ +namespace MantidQt +{ + namespace MantidWidgets + { + /** HintingLineEdit : A QLineEdit widget providing autocompletion. + + Copyright © 2014 ISIS Rutherford Appleton Laboratory & NScD Oak Ridge National Laboratory + + This file is part of Mantid. + + Mantid is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + Mantid is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + + File change history is stored at: + Code Documentation is available at: + */ + class EXPORT_OPT_MANTIDQT_MANTIDWIDGETS HintingLineEdit : public QLineEdit + { + Q_OBJECT + public: + HintingLineEdit(QWidget *parent, const std::map &hints); + virtual ~HintingLineEdit(); + protected: + virtual void keyPressEvent(QKeyEvent* e); + void updateMatches(); + void showToolTip(); + void insertSuggestion(); + void clearSuggestion(); + void nextSuggestion(); + void prevSuggestion(); + std::string m_curKey; + std::string m_curMatch; + std::map m_matches; + std::map m_hints; + bool m_dontComplete; + QLabel* m_hintLabel; + protected slots: + void updateHints(const QString& text); + }; + } //namespace MantidWidgets +} //namepsace MantidQt + +#endif /* MANTID_MANTIDWIDGETS_HINTINGLINEEDIT_H_ */ diff --git a/Code/Mantid/MantidQt/MantidWidgets/inc/MantidQtMantidWidgets/HintingLineEditFactory.h b/Code/Mantid/MantidQt/MantidWidgets/inc/MantidQtMantidWidgets/HintingLineEditFactory.h new file mode 100644 index 000000000000..1b14d6e39397 --- /dev/null +++ b/Code/Mantid/MantidQt/MantidWidgets/inc/MantidQtMantidWidgets/HintingLineEditFactory.h @@ -0,0 +1,61 @@ +#ifndef MANTID_MANTIDWIDGETS_HINTINGLINEEDITFACTORY_H +#define MANTID_MANTIDWIDGETS_HINTINGLINEEDITFACTORY_H + +#include + +#include "MantidAPI/AlgorithmManager.h" +#include "MantidQtMantidWidgets/HintingLineEdit.h" +#include "MantidQtMantidWidgets/HintStrategy.h" + +using namespace Mantid::API; +using namespace Mantid::Kernel; +using namespace MantidQt::MantidWidgets; + +namespace MantidQt +{ + namespace CustomInterfaces + { + /** HintingLineEditFactory : A QStyledItemDelegate that produces HintingLineEdits using the given hint strategy. + + Copyright © 2014 ISIS Rutherford Appleton Laboratory & NScD Oak Ridge National Laboratory + + This file is part of Mantid. + + Mantid is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + Mantid is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + + File change history is stored at: + Code Documentation is available at: + */ + class HintingLineEditFactory : public QStyledItemDelegate + { + public: + HintingLineEditFactory(HintStrategy* hintStrategy) : m_strategy(hintStrategy) {}; + virtual ~HintingLineEditFactory() {}; + virtual QWidget* createEditor(QWidget* parent, const QStyleOptionViewItem& option, const QModelIndex& index) const + { + Q_UNUSED(option); + Q_UNUSED(index); + + auto editor = new HintingLineEdit(parent, m_strategy->createHints()); + editor->setFrame(false); + + return editor; + } + protected: + boost::scoped_ptr m_strategy; + }; + } +} + +#endif /* MANTID_MANTIDWIDGETS_HINTINGLINEEDITFACTORY_H */ diff --git a/Code/Mantid/MantidQt/MantidWidgets/inc/MantidQtMantidWidgets/MWRunFiles.ui b/Code/Mantid/MantidQt/MantidWidgets/inc/MantidQtMantidWidgets/MWRunFiles.ui index 64e18aab8e7b..0e1cd0f8cea2 100644 --- a/Code/Mantid/MantidQt/MantidWidgets/inc/MantidQtMantidWidgets/MWRunFiles.ui +++ b/Code/Mantid/MantidQt/MantidWidgets/inc/MantidQtMantidWidgets/MWRunFiles.ui @@ -32,6 +32,9 @@ + + 500000 + 0 diff --git a/Code/Mantid/MantidQt/MantidWidgets/src/FitPropertyBrowser.cpp b/Code/Mantid/MantidQt/MantidWidgets/src/FitPropertyBrowser.cpp index 7569e77f952b..50fa40d4746f 100644 --- a/Code/Mantid/MantidQt/MantidWidgets/src/FitPropertyBrowser.cpp +++ b/Code/Mantid/MantidQt/MantidWidgets/src/FitPropertyBrowser.cpp @@ -185,11 +185,11 @@ void FitPropertyBrowser::init() m_minimizers << "Levenberg-Marquardt" << "Levenberg-MarquardtMD" << "Simplex" + << "FABADA" << "Conjugate gradient (Fletcher-Reeves imp.)" << "Conjugate gradient (Polak-Ribiere imp.)" << "BFGS" - << "Damping" - << "Fake"; + << "Damping"; m_ignoreInvalidData = m_boolManager->addProperty("Ignore invalid data"); setIgnoreInvalidData( settings.value("Ignore invalid data",false).toBool() ); @@ -1100,26 +1100,33 @@ std::string FitPropertyBrowser::minimizer(bool withProperties)const { foreach(QtProperty* prop,m_minimizerProperties) { - minimStr += "," + prop->propertyName() + "="; - if ( prop->propertyManager() == m_intManager ) + if ( prop->propertyManager() == m_stringManager ) { - minimStr += QString::number( m_intManager->value(prop) ); - } - else if ( prop->propertyManager() == m_doubleManager ) - { - minimStr += QString::number( m_doubleManager->value(prop) ); - } - else if ( prop->propertyManager() == m_boolManager ) - { - minimStr += QString::number( m_boolManager->value(prop) ); - } - else if ( prop->propertyManager() == m_stringManager ) - { - minimStr += m_stringManager->value(prop); + QString value = m_stringManager->value(prop); + if ( !value.isEmpty() ) + { + minimStr += "," + prop->propertyName() + "=" + value; + } } else { - throw std::runtime_error("The fit browser doesn't support the type of minimizer's property " + prop->propertyName().toStdString() ); + minimStr += "," + prop->propertyName() + "="; + if ( prop->propertyManager() == m_intManager ) + { + minimStr += QString::number( m_intManager->value(prop) ); + } + else if ( prop->propertyManager() == m_doubleManager ) + { + minimStr += QString::number( m_doubleManager->value(prop) ); + } + else if ( prop->propertyManager() == m_boolManager ) + { + minimStr += QString::number( m_boolManager->value(prop) ); + } + else + { + throw std::runtime_error("The fit browser doesn't support the type of minimizer's property " + prop->propertyName().toStdString() ); + } } } } @@ -3198,6 +3205,8 @@ void FitPropertyBrowser::minimizerChanged() QMessageBox::warning(this,"MantidPlot - Error","Type of minimizer's property " + propName + " is not yet supported by the browser."); continue; } + + if ( !prop ) continue; // set the tooltip from property doc string QString toolTip = QString::fromStdString( (**it).documentation() ); if ( !toolTip.isEmpty() ) @@ -3250,7 +3259,7 @@ void FitPropertyBrowser::functionHelp() if ( handler ) { // Create and open the URL of the help page - QString url = QString::fromStdString( "http://www.mantidproject.org/" + handler->ifun()->name() ); + QString url = QString::fromStdString( "http://docs.mantidproject.org/fitfunctions/" + handler->ifun()->name() ); QDesktopServices::openUrl(QUrl(url)); } } diff --git a/Code/Mantid/MantidQt/MantidWidgets/src/HintingLineEdit.cpp b/Code/Mantid/MantidQt/MantidWidgets/src/HintingLineEdit.cpp new file mode 100644 index 000000000000..0c128d666905 --- /dev/null +++ b/Code/Mantid/MantidQt/MantidWidgets/src/HintingLineEdit.cpp @@ -0,0 +1,201 @@ +#include "MantidQtMantidWidgets/HintingLineEdit.h" + +#include +#include + +namespace MantidQt +{ + namespace MantidWidgets + { + HintingLineEdit::HintingLineEdit(QWidget *parent, const std::map &hints) : QLineEdit(parent), m_hints(hints), m_dontComplete(false) + { + m_hintLabel = new QLabel(this, Qt::ToolTip); + m_hintLabel->setMargin(1 + style()->pixelMetric(QStyle::PM_ToolTipLabelFrameWidth, 0, m_hintLabel)); + m_hintLabel->setFrameStyle(QFrame::StyledPanel); + m_hintLabel->setAlignment(Qt::AlignLeft); + m_hintLabel->setWordWrap(true); + m_hintLabel->setIndent(1); + m_hintLabel->setAutoFillBackground(true); + m_hintLabel->setPalette(QToolTip::palette()); + m_hintLabel->setForegroundRole(QPalette::ToolTipText); + m_hintLabel->setBackgroundRole(QPalette::ToolTipBase); + m_hintLabel->ensurePolished(); + + connect(this, SIGNAL(textEdited(const QString&)), this, SLOT(updateHints(const QString&))); + } + + HintingLineEdit::~HintingLineEdit() + { + } + + /** Handle a key press event. + + @param e : A pointer to the event + */ + void HintingLineEdit::keyPressEvent(QKeyEvent* e) + { + m_dontComplete = (e->key() == Qt::Key_Backspace || e->key() == Qt::Key_Delete || e->key() == Qt::Key_Space); + + if(e->key() == Qt::Key_Up) + { + prevSuggestion(); + return; + } + + if(e->key() == Qt::Key_Down) + { + nextSuggestion(); + return; + } + QLineEdit::keyPressEvent(e); + } + + /** Rebuild a list of hints whenever the user edits the text, and use the hints + to make auto completion suggestions. + + @param text : The new contents of the QLineEdit + */ + void HintingLineEdit::updateHints(const QString& text) + { + const size_t curPos = (size_t)cursorPosition(); + const std::string line = text.toStdString(); + + //Get everything before the cursor + std::string prefix = line.substr(0, curPos); + + //Now remove everything before the last ',' to give us the current word + std::size_t startPos = prefix.find_last_of(","); + if(startPos != std::string::npos) + prefix = prefix.substr(startPos + 1, prefix.size() - (startPos + 1)); + + //Remove any leading or trailing whitespace + boost::trim(prefix); + + //Set the current key/prefix + m_curKey = prefix; + + //Update our current list of matches + updateMatches(); + + //Show the potential matches in a tooltip + showToolTip(); + + //Suggest one of them to the user via auto-completion + insertSuggestion(); + } + + /** Updates the list of hints matching the user's current input */ + void HintingLineEdit::updateMatches() + { + m_curMatch.clear(); + m_matches.clear(); + + for(auto it = m_hints.begin(); it != m_hints.end(); ++it) + { + const std::string& hint = it->first; + + if(hint.length() < m_curKey.length()) + continue; + + const std::string hintPrefix = hint.substr(0, m_curKey.length()); + + if(m_curKey == hintPrefix) + m_matches[hint] = it->second; + } + } + + /** Show a tooltip with the current relevant hints */ + void HintingLineEdit::showToolTip() + { + QString hintList; + for(auto mIt = m_matches.begin(); mIt != m_matches.end(); ++mIt) + { + hintList += "" + QString::fromStdString(mIt->first) + "
\n"; + if(!mIt->second.empty()) + hintList += QString::fromStdString(mIt->second) + "
\n"; + } + + if(!hintList.trimmed().isEmpty()) + { + m_hintLabel->show(); + m_hintLabel->setText(hintList.trimmed()); + m_hintLabel->adjustSize(); + m_hintLabel->move(mapToGlobal(QPoint(0, height()))); + } + else + { + m_hintLabel->hide(); + } + } + + /** Insert an auto completion suggestion beneath the user's cursor and select it */ + void HintingLineEdit::insertSuggestion() + { + if(m_curKey.length() < 1 || m_matches.size() < 1 || m_dontComplete) + return; + + //If we don't have a match, just use the first one in the map + if(m_curMatch.empty()) + m_curMatch = m_matches.begin()->first; + + QString line = text(); + const int curPos = cursorPosition(); + + //Don't perform insertions mid-word + if(curPos + 1 < line.size() && line[curPos+1].isLetterOrNumber()) + return; + + //Insert a suggestion under the cursor, then select it + line = line.left(curPos) + QString::fromStdString(m_curMatch).mid((int)m_curKey.size()) + line.mid(curPos); + + setText(line); + setSelection(curPos, (int)m_curMatch.size()); + } + + /** Remove any existing auto completion suggestion */ + void HintingLineEdit::clearSuggestion() + { + if(!hasSelectedText()) + return; + + //Carefully cut out the selected text + QString line = text(); + line = line.left(selectionStart()) + line.mid(selectionStart() + selectedText().length()); + setText(line); + } + + /** Change to the next available auto completion suggestion */ + void HintingLineEdit::nextSuggestion() + { + clearSuggestion(); + //Find the next suggestion in the hint map + auto it = m_matches.find(m_curMatch); + if(it != m_matches.end()) + { + it++; + if(it == m_matches.end()) + m_curMatch = m_matches.begin()->first; + else + m_curMatch = it->first; + insertSuggestion(); + } + } + + /** Change to the previous auto completion suggestion */ + void HintingLineEdit::prevSuggestion() + { + clearSuggestion(); + //Find the previous suggestion in the hint map + auto it = m_matches.find(m_curMatch); + if(it != m_matches.end()) + { + it--; + if(it == m_matches.end()) + m_curMatch = m_matches.rbegin()->first; + else + m_curMatch = it->first; + insertSuggestion(); + } + } + } //namespace MantidWidgets +} //namepsace MantidQt diff --git a/Code/Mantid/MantidQt/MantidWidgets/src/MWRunFiles.cpp b/Code/Mantid/MantidQt/MantidWidgets/src/MWRunFiles.cpp index f269286f0aef..8be6793b6488 100644 --- a/Code/Mantid/MantidQt/MantidWidgets/src/MWRunFiles.cpp +++ b/Code/Mantid/MantidQt/MantidWidgets/src/MWRunFiles.cpp @@ -236,10 +236,18 @@ MWRunFiles::MWRunFiles(QWidget *parent) setFocusPolicy(Qt::StrongFocus); setFocusProxy(m_uiForm.fileEditor); - // When first used try to starting directory better than the directory MantidPlot - // is installed in - QStringList datadirs = QString::fromStdString(Mantid::Kernel::ConfigService::Instance().getString("datasearch.directories")).split(";", QString::SkipEmptyParts); - if ( ! datadirs.isEmpty() ) m_lastDir = datadirs[0]; + // When first used try to starting directory better than the directory MantidPlot is installed in + // First try default save directory + m_lastDir = QString::fromStdString(Mantid::Kernel::ConfigService::Instance().getString("defaultsave.directory")); + + // If that fails pick the first data search directory + if(m_lastDir.isEmpty()) + { + QStringList dataDirs = QString::fromStdString(Mantid::Kernel::ConfigService::Instance().getString("datasearch.directories")).split(";", QString::SkipEmptyParts); + + if(!dataDirs.isEmpty()) + m_lastDir = dataDirs[0]; + } //this for accepts drops, but the underlying text input does not. this->setAcceptDrops(true); diff --git a/Code/Mantid/MantidQt/MantidWidgets/test/AlgorithmHintStrategyTest.h b/Code/Mantid/MantidQt/MantidWidgets/test/AlgorithmHintStrategyTest.h new file mode 100644 index 000000000000..c0da65e6b89c --- /dev/null +++ b/Code/Mantid/MantidQt/MantidWidgets/test/AlgorithmHintStrategyTest.h @@ -0,0 +1,64 @@ +#ifndef MANTID_MANTIDWIDGETS_ALGORITHMHINTSTRATEGYTEST_H +#define MANTID_MANTIDWIDGETS_ALGORITHMHINTSTRATEGYTEST_H + +#include +#include "MantidAPI/FrameworkManager.h" +#include "MantidAPI/AlgorithmManager.h" +#include "MantidQtMantidWidgets/HintStrategy.h" +#include "MantidQtMantidWidgets/AlgorithmHintStrategy.h" + +using namespace MantidQt::MantidWidgets; +using namespace Mantid::API; + +//===================================================================================== +// Functional tests +//===================================================================================== +class AlgorithmHintStrategyTest : 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 AlgorithmHintStrategyTest *createSuite() { return new AlgorithmHintStrategyTest(); } + static void destroySuite( AlgorithmHintStrategyTest *suite ) { delete suite; } + + AlgorithmHintStrategyTest() + { + FrameworkManager::Instance(); + m_propAlg = AlgorithmManager::Instance().create("PropertyAlgorithm"); + //Expected hints for PropertyAlgorithm + m_propMap["IntValue"] = ""; + m_propMap["DoubleValue"] = ""; + m_propMap["BoolValue"] = ""; + m_propMap["StringValue"] = ""; + m_propMap["PositiveIntValue"] = ""; + m_propMap["PositiveIntValue1"] = ""; + m_propMap["IntArray"] = ""; + m_propMap["DoubleArray"] = ""; + m_propMap["StringArray"] = ""; + } + + void testCreateHints() + { + boost::scoped_ptr strategy(new AlgorithmHintStrategy(m_propAlg, std::set())); + TS_ASSERT_EQUALS(m_propMap, strategy->createHints()); + } + + void testBlacklist() + { + std::set blacklist; + blacklist.insert("DoubleValue"); + blacklist.insert("IntArray"); + + boost::scoped_ptr strategy(new AlgorithmHintStrategy(m_propAlg, blacklist)); + auto expected = m_propMap; + expected.erase("DoubleValue"); + expected.erase("IntArray"); + TS_ASSERT_EQUALS(expected, strategy->createHints()); + } + +protected: + IAlgorithm_sptr m_propAlg; + std::map m_propMap; +}; + +#endif /*MANTID_MANTIDWIDGETS_ALGORITHMHINTSTRATEGYTEST_H */ diff --git a/Code/Mantid/MantidQt/MantidWidgets/test/CMakeLists.txt b/Code/Mantid/MantidQt/MantidWidgets/test/CMakeLists.txt new file mode 100644 index 000000000000..33347b2cbb92 --- /dev/null +++ b/Code/Mantid/MantidQt/MantidWidgets/test/CMakeLists.txt @@ -0,0 +1,13 @@ +if ( CXXTEST_FOUND ) + include_directories ( SYSTEM ${CXXTEST_INCLUDE_DIR} ${GMOCK_INCLUDE_DIR} ${GTEST_INCLUDE_DIR} ) + + cxxtest_add_test ( MantidWidgetsTest ${TEST_FILES} ) + target_link_libraries( MantidWidgetsTest MantidWidgets ) + + # Add to the 'UnitTests' group in VS + set_property( TARGET MantidWidgetsTest PROPERTY FOLDER "UnitTests" ) +endif () + +if ( PYUNITTEST_FOUND ) + pyunittest_add_test (${CMAKE_CURRENT_SOURCE_DIR} MantidWidgetsTest ${TEST_PY_FILES} ) +endif () diff --git a/Code/Mantid/MantidQt/RefDetectorViewer/inc/MantidQtRefDetectorViewer/RefIVConnections.h b/Code/Mantid/MantidQt/RefDetectorViewer/inc/MantidQtRefDetectorViewer/RefIVConnections.h index ef2450fe9112..dd1a37e0c5b1 100644 --- a/Code/Mantid/MantidQt/RefDetectorViewer/inc/MantidQtRefDetectorViewer/RefIVConnections.h +++ b/Code/Mantid/MantidQt/RefDetectorViewer/inc/MantidQtRefDetectorViewer/RefIVConnections.h @@ -12,21 +12,20 @@ #include "MantidQtSpectrumViewer/GraphDisplay.h" #include "DllOption.h" - /** - @class RefIVConnections - - This class provides the connections between the SpectrumView GUI components + @class RefIVConnections + + This class provides the connections between the SpectrumView GUI components made using QtDesigner and the classes that do the actual work for the - SpectrumView. It basically provides SLOTS that are called by the GUI - components' SIGNALS and in turn call methods on the SpectrumView - implementation objects. - - @author Dennis Mikkelson - @date 2012-04-03 - + SpectrumView. It basically provides SLOTS that are called by the GUI + components' SIGNALS and in turn call methods on the SpectrumView + implementation objects. + + @author Dennis Mikkelson + @date 2012-04-03 + Copyright © 2012 ORNL, STFC Rutherford Appleton Laboratories - + This file is part of Mantid. Mantid is free software; you can redistribute it and/or modify @@ -41,8 +40,8 @@ You should have received a copy of the GNU General Public License along with this program. If not, see . - - Code Documentation is available at + + Code Documentation is available at */ @@ -51,75 +50,73 @@ namespace MantidQt namespace RefDetectorViewer { - class EXPORT_OPT_MANTIDQT_REFDETECTORVIEWER RefIVConnections: public QWidget { Q_OBJECT public: - /// Construct the object that links the GUI components to the other specifed /// higher level objects. - RefIVConnections( Ui_RefImageViewer* ui, - RefImageView* image_view, - RefImageDisplay* image_display, - SpectrumView::GraphDisplay* h_graph_display, - SpectrumView::GraphDisplay* v_graph_display ); + RefIVConnections( Ui_RefImageViewer* ui, + RefImageView* imageView, + RefImageDisplay* imageDisplay, + SpectrumView::GraphDisplay* hGraphDisplay, + SpectrumView::GraphDisplay* vGraphDisplay ); ~RefIVConnections(); /// Set the pix map that shows the color scale from the specified color maps - void ShowColorScale( std::vector & positive_color_table, - std::vector & negative_color_table ); + void showColorScale( std::vector & positiveColorTable, + std::vector & negativeColorTable ); public slots: - void close_viewer(); - void toggle_Hscroll(); - void toggle_Vscroll(); - void image_horizontal_range_changed(); - void graph_range_changed(); - void v_scroll_bar_moved(); - void h_scroll_bar_moved(); - void imageSplitter_moved(); - void imagePicker_moved(); - void imagePicker2_moved(); - void h_graphPicker_moved(); - void v_graphPicker_moved(); - void intensity_slider_moved(); - void heat_color_scale(); - void gray_color_scale(); - void negative_gray_color_scale(); - void green_yellow_color_scale(); - void rainbow_color_scale(); - void optimal_color_scale(); - void multi_color_scale(); - void spectrum_color_scale(); - void edit_manual_input(); - void peak_back_tof_range_update(); - -public: - signals: - void peak_back_tof_range_update(double, double, double, double, double, double); + void closeViewer(); + void toggleHScroll(); + void toggleVScroll(); + void imageHorizontalRangeChanged(); + void graphRangeChanged(); + void vScrollBarMoved(); + void hScrollBarMoved(); + void imageSplitterMoved(); + void imagePickerMoved(); + void imagePicker2Moved(); + void hGraphPickerMoved(); + void vGraphPickerMoved(); + void intensitySliderMoved(); + void editManualInput(); + void peakBackTofRangeUpdate(); + + void heatColorScale(); + void grayColorScale(); + void negativeGrayColorScale(); + void greenYellowColorScale(); + void rainbowColorScale(); + void optimalColorScale(); + void multiColorScale(); + void spectrumColorScale(); + +signals: + void peakBackTofRangeUpdate(double, double, double, double, double, double); + +private: + RefIVConnections() {} - private: - RefIVConnections() {} - private: - Ui_RefImageViewer* iv_ui; - RefImageView* iv_main_window; - RefImageDisplay* image_display; - SpectrumView::GraphDisplay* h_graph_display; - SpectrumView::GraphDisplay* v_graph_display; - SpectrumView::TrackingPicker* image_picker; - SpectrumView::TrackingPicker* image_picker2; - SpectrumView::TrackingPicker* h_graph_picker; - SpectrumView::TrackingPicker* v_graph_picker; - QActionGroup* color_group; + Ui_RefImageViewer* m_ivUI; + RefImageView* m_ivMainWindow; + RefImageDisplay* m_imageDisplay; + SpectrumView::GraphDisplay* m_hGraphDisplay; + SpectrumView::GraphDisplay* m_vGraphDisplay; + SpectrumView::TrackingPicker* m_imagePicker; + SpectrumView::TrackingPicker* m_imagePicker2; + SpectrumView::TrackingPicker* m_hGraphPicker; + SpectrumView::TrackingPicker* m_vGraphPicker; + QActionGroup* m_colorGroup; }; } // namespace RefDetectorViewer -} // namespace MantidQt +} // namespace MantidQt #endif // REF_IV_CONNECTIONS_H diff --git a/Code/Mantid/MantidQt/RefDetectorViewer/inc/MantidQtRefDetectorViewer/RefImageDisplay.h b/Code/Mantid/MantidQt/RefDetectorViewer/inc/MantidQtRefDetectorViewer/RefImageDisplay.h index c4a50e126a38..7be75a2da20e 100644 --- a/Code/Mantid/MantidQt/RefDetectorViewer/inc/MantidQtRefDetectorViewer/RefImageDisplay.h +++ b/Code/Mantid/MantidQt/RefDetectorViewer/inc/MantidQtRefDetectorViewer/RefImageDisplay.h @@ -34,29 +34,31 @@ namespace RefDetectorViewer Code Documentation is available at */ + class EXPORT_OPT_MANTIDQT_REFDETECTORVIEWER RefImageDisplay : public SpectrumView::SpectrumDisplay { public: - /// Make a SpectrumDisplay to display with the given widgets and controls - RefImageDisplay( QwtPlot* image_plot, - RefSliderHandler* slider_handler, - RefRangeHandler* range_handler, - RefLimitsHandler* limits_handler, - SpectrumView::GraphDisplay* h_graph, - SpectrumView::GraphDisplay* v_graph, - QTableWidget* table_widget); + /// Make a SpectrumDisplay to display with the given widgets and controls + RefImageDisplay( QwtPlot* imagePlot, + RefSliderHandler* sliderHandler, + RefRangeHandler* rangeHandler, + RefLimitsHandler* limitsHandler, + SpectrumView::GraphDisplay* hGraph, + SpectrumView::GraphDisplay* vGraph, + QTableWidget* tableWidget); ~RefImageDisplay(); /// Record the point that the user is currently pointing at with the mouse /// default right click (mouseClick = 2) - QPair SetPointedAtPoint( QPoint point, int mouseClick = 2 ); + QPair setPointedAtPoint( QPoint point, int mouseClick = 2 ); private: RefLimitsHandler* m_limitsHandler; // Owned by RefImagePlotItem + }; } // namespace RefDetectorViewer -} // namespace MantidQt +} // namespace MantidQt #endif // REF_IMAGE_DISPLAY_H diff --git a/Code/Mantid/MantidQt/RefDetectorViewer/inc/MantidQtRefDetectorViewer/RefImagePlotItem.h b/Code/Mantid/MantidQt/RefDetectorViewer/inc/MantidQtRefDetectorViewer/RefImagePlotItem.h index cd0d69fa2bd9..77a5bc5ee0ae 100644 --- a/Code/Mantid/MantidQt/RefDetectorViewer/inc/MantidQtRefDetectorViewer/RefImagePlotItem.h +++ b/Code/Mantid/MantidQt/RefDetectorViewer/inc/MantidQtRefDetectorViewer/RefImagePlotItem.h @@ -31,6 +31,7 @@ namespace RefDetectorViewer Code Documentation is available at */ + class EXPORT_OPT_MANTIDQT_REFDETECTORVIEWER RefImagePlotItem : public SpectrumView::SpectrumPlotItem { @@ -39,19 +40,20 @@ class EXPORT_OPT_MANTIDQT_REFDETECTORVIEWER RefImagePlotItem : public SpectrumVi RefImagePlotItem(const RefLimitsHandler * const limitsHandler); ~RefImagePlotItem(); - + /// Draw the image (this is called by QWT and must not be called directly.) virtual void draw( QPainter * painter, - const QwtScaleMap & xMap, + const QwtScaleMap & xMap, const QwtScaleMap & yMap, const QRect & canvasRect) const; private: const RefLimitsHandler * const m_limitsHandler; + }; } // namespace RefDetectorViewer -} // namespace MantidQt +} // namespace MantidQt -#endif // REF_IMAGE_PLOT_ITEM_H +#endif // REF_IMAGE_PLOT_ITEM_H diff --git a/Code/Mantid/MantidQt/RefDetectorViewer/inc/MantidQtRefDetectorViewer/RefImageView.h b/Code/Mantid/MantidQt/RefDetectorViewer/inc/MantidQtRefDetectorViewer/RefImageView.h index 42f71bd46f24..8e76609b4d3a 100644 --- a/Code/Mantid/MantidQt/RefDetectorViewer/inc/MantidQtRefDetectorViewer/RefImageView.h +++ b/Code/Mantid/MantidQt/RefDetectorViewer/inc/MantidQtRefDetectorViewer/RefImageView.h @@ -9,17 +9,17 @@ #include "DllOption.h" /** - @class RefImageView - - This is the QMainWindow for the SpectrumView data viewer. Data is + @class RefImageView + + This is the QMainWindow for the SpectrumView data viewer. Data is displayed in an SpectrumView, by constructing the SpectrumView object and specifying a particular data source. - - @author Dennis Mikkelson - @date 2012-04-03 - + + @author Dennis Mikkelson + @date 2012-04-03 + Copyright © 2012 ORNL, STFC Rutherford Appleton Laboratories - + This file is part of Mantid. Mantid is free software; you can redistribute it and/or modify @@ -34,45 +34,52 @@ You should have received a copy of the GNU General Public License along with this program. If not, see . - - Code Documentation is available at + + Code Documentation is available at */ +namespace Ui +{ +class RefImageViewer; +} + namespace MantidQt { namespace RefDetectorViewer { +class RefSliderHandler; +class RefRangeHandler; +class RefImageDisplay; +class RefIVConnections; - class RefIVConnections; class EXPORT_OPT_MANTIDQT_REFDETECTORVIEWER RefImageView : public QMainWindow { public: - /// Construct an RefImageView to display data from the specified data source - RefImageView( SpectrumView::SpectrumDataSource* data_source, int peak_min, int peak_max, int back_min, int back_max, int tof_min, int tof_max); + /// Construct an RefImageView to display data from the specified data source + RefImageView( SpectrumView::SpectrumDataSource_sptr dataSource, + int peakMin, int peakMax, + int backMin, int backMax, + int tofMin, int tofMax); + + ~RefImageView(); - ~RefImageView(); - RefIVConnections* getIVConnections(); private: - SpectrumView::GraphDisplay* h_graph; - SpectrumView::GraphDisplay* v_graph; - - // keep void pointers to the following objects, to avoid having to - // include ui_RefImageView.h, which disappears by the time MantidPlot is - // being built. We need the pointers so we can delete them in the - // destructor. - void* saved_ui; // Ui_RefImageViewer* - void* saved_slider_handler; // SliderHandler* - void* saved_range_handler; // RangeHandler* - void* saved_image_display; // RefImageDisplay* - // void* saved_iv_connections; // IVConnections* - RefIVConnections* saved_iv_connections; // IVConnections* + SpectrumView::GraphDisplay* m_hGraph; + SpectrumView::GraphDisplay* m_vGraph; + + Ui::RefImageViewer* m_ui; + RefSliderHandler* m_sliderHandler; + RefRangeHandler* m_rangeHandler; + RefImageDisplay* m_imageDisplay; + RefIVConnections* m_ivConnections; + }; } // namespace RefDetectorViewer -} // namespace MantidQt +} // namespace MantidQt #endif // REF_IMAGE_VIEW_H diff --git a/Code/Mantid/MantidQt/RefDetectorViewer/inc/MantidQtRefDetectorViewer/RefLimitsHandler.h b/Code/Mantid/MantidQt/RefDetectorViewer/inc/MantidQtRefDetectorViewer/RefLimitsHandler.h index 7ab3b8de5c76..7d0d4d19b727 100644 --- a/Code/Mantid/MantidQt/RefDetectorViewer/inc/MantidQtRefDetectorViewer/RefLimitsHandler.h +++ b/Code/Mantid/MantidQt/RefDetectorViewer/inc/MantidQtRefDetectorViewer/RefLimitsHandler.h @@ -28,11 +28,12 @@ namespace RefDetectorViewer Code Documentation is available at */ + class RefLimitsHandler { public: /// Construct object to manage range (peak/back/TOF) controls in the UI - RefLimitsHandler( Ui_RefImageViewer* iv_ui ); + RefLimitsHandler( Ui_RefImageViewer* ivUI ); /// get peak, back and tof values int getPeakLeft() const; @@ -53,6 +54,7 @@ class RefLimitsHandler private: const Ui_RefImageViewer* const m_ui; + }; } // namespace RefDetectorViewer diff --git a/Code/Mantid/MantidQt/RefDetectorViewer/inc/MantidQtRefDetectorViewer/RefMatrixWSImageView.h b/Code/Mantid/MantidQt/RefDetectorViewer/inc/MantidQtRefDetectorViewer/RefMatrixWSImageView.h index 8ddab8ee97c2..364ac4648e22 100644 --- a/Code/Mantid/MantidQt/RefDetectorViewer/inc/MantidQtRefDetectorViewer/RefMatrixWSImageView.h +++ b/Code/Mantid/MantidQt/RefDetectorViewer/inc/MantidQtRefDetectorViewer/RefMatrixWSImageView.h @@ -7,16 +7,16 @@ #include "MantidQtRefDetectorViewer/RefImageView.h" /** - @class RefMatrixWSImageView - - This is the top level class for showing a matrix workspace + @class RefMatrixWSImageView + + This is the top level class for showing a matrix workspace using an ImageViewer. - - @author Dennis Mikkelson - @date 2012-05-08 - + + @author Dennis Mikkelson + @date 2012-05-08 + Copyright © 2012 ORNL, STFC Rutherford Appleton Laboratories - + This file is part of Mantid. Mantid is free software; you can redistribute it and/or modify @@ -31,8 +31,8 @@ You should have received a copy of the GNU General Public License along with this program. If not, see . - - Code Documentation is available at + + Code Documentation is available at */ @@ -40,27 +40,30 @@ namespace MantidQt { namespace RefDetectorViewer { +class RefIVConnections; - class RefIVConnections; - class EXPORT_OPT_MANTIDQT_REFDETECTORVIEWER RefMatrixWSImageView +class EXPORT_OPT_MANTIDQT_REFDETECTORVIEWER RefMatrixWSImageView { - public: - /// Construct an image viewer for the specifed MatrixWorkspace - RefMatrixWSImageView ( Mantid::API::MatrixWorkspace_sptr /*mat_ws*/ ); +public: + /// Construct an image viewer for the specifed MatrixWorkspace + RefMatrixWSImageView ( Mantid::API::MatrixWorkspace_sptr /*mat_ws*/ ); + + RefMatrixWSImageView( QString wpsName, + int peakMin, int peakMax, + int backMin, int backMax, + int tofMin, int tofMax); - RefMatrixWSImageView( QString wps_name, int peak_min, int peak_max, int back_min, int back_max, int tof_min, int tof_max); - RefIVConnections* getConnections(); + RefIVConnections* getConnections(); - ~RefMatrixWSImageView(); + ~RefMatrixWSImageView(); private: - - RefImageView *image_view; - + RefImageView *m_imageView; + }; } // namespace RefDetectorViewer -} // namespace MantidQt +} // namespace MantidQt #endif // REF_MATRIX_WS_IMAGE_VIEW_H diff --git a/Code/Mantid/MantidQt/RefDetectorViewer/inc/MantidQtRefDetectorViewer/RefRangeHandler.h b/Code/Mantid/MantidQt/RefDetectorViewer/inc/MantidQtRefDetectorViewer/RefRangeHandler.h index c251cc3990c3..ae03e10bafa3 100644 --- a/Code/Mantid/MantidQt/RefDetectorViewer/inc/MantidQtRefDetectorViewer/RefRangeHandler.h +++ b/Code/Mantid/MantidQt/RefDetectorViewer/inc/MantidQtRefDetectorViewer/RefRangeHandler.h @@ -7,16 +7,16 @@ #include "DllOption.h" /** - @class RangeHandler - - This manages the min, max and step range controls for the SpectrumView - data viewer. - - @author Dennis Mikkelson - @date 2012-04-25 - + @class RangeHandler + + This manages the min, max and step range controls for the SpectrumView + data viewer. + + @author Dennis Mikkelson + @date 2012-04-25 + Copyright © 2012 ORNL, STFC Rutherford Appleton Laboratories - + This file is part of Mantid. Mantid is free software; you can redistribute it and/or modify @@ -31,8 +31,8 @@ You should have received a copy of the GNU General Public License along with this program. If not, see . - - Code Documentation is available at + + Code Documentation is available at */ @@ -41,33 +41,34 @@ namespace MantidQt namespace RefDetectorViewer { - class EXPORT_OPT_MANTIDQT_REFDETECTORVIEWER RefRangeHandler : public SpectrumView::IRangeHandler { public: /// Construct object to manage min, max and step controls in the UI - RefRangeHandler( Ui_RefImageViewer* iv_ui ); + RefRangeHandler( Ui_RefImageViewer* ivUI ); /// Configure min, max and step controls for the specified data source - void ConfigureRangeControls( SpectrumView::SpectrumDataSource* data_source ); + void configureRangeControls( SpectrumView::SpectrumDataSource_sptr dataSource ); /// Get the range of data to display in the image, from GUI controls - void GetRange( double &min, double &max, double &step ); + void getRange( double &min, double &max, double &step ); /// Set the values displayed in the GUI controls - void SetRange( double min, double max, double step, char type ); + void setRange( double min, double max, double step, char type ); private: - Ui_RefImageViewer* iv_ui; - double total_min_x; - double total_max_x; - double total_max_y; - double total_min_y; - size_t total_n_steps; + Ui_RefImageViewer* m_ivUI; + + double m_totalMinX; + double m_totalMaxX; + double m_totalMaxY; + double m_totalMinY; + size_t m_totalNSteps; + }; } // namespace RefDetectorViewer -} // namespace MantidQt +} // namespace MantidQt #endif // REF_RANGE_HANDLER_H diff --git a/Code/Mantid/MantidQt/RefDetectorViewer/inc/MantidQtRefDetectorViewer/RefSliderHandler.h b/Code/Mantid/MantidQt/RefDetectorViewer/inc/MantidQtRefDetectorViewer/RefSliderHandler.h index e46b7d818904..d534fb55db24 100644 --- a/Code/Mantid/MantidQt/RefDetectorViewer/inc/MantidQtRefDetectorViewer/RefSliderHandler.h +++ b/Code/Mantid/MantidQt/RefDetectorViewer/inc/MantidQtRefDetectorViewer/RefSliderHandler.h @@ -9,16 +9,16 @@ #include "MantidQtRefDetectorViewer/DllOption.h" /** - @class SliderHandler - + @class SliderHandler + This manages the horizontal and vertical scroll bars for the - SpectrumView data viewer. - - @author Dennis Mikkelson - @date 2012-04-03 - + SpectrumView data viewer. + + @author Dennis Mikkelson + @date 2012-04-03 + Copyright © 2012 ORNL, STFC Rutherford Appleton Laboratories - + This file is part of Mantid. Mantid is free software; you can redistribute it and/or modify @@ -33,8 +33,8 @@ You should have received a copy of the GNU General Public License along with this program. If not, see . - - Code Documentation is available at + + Code Documentation is available at */ @@ -47,41 +47,41 @@ namespace RefDetectorViewer class EXPORT_OPT_MANTIDQT_REFDETECTORVIEWER RefSliderHandler : public SpectrumView::ISliderHandler { public: - /// Construct object to manage image scrollbars from the specified UI - RefSliderHandler( Ui_RefImageViewer* iv_ui ); + RefSliderHandler( Ui_RefImageViewer* ivUI ); /// Configure the image scrollbars for the specified data and drawing area - void ConfigureSliders( QRect draw_area, - SpectrumView::SpectrumDataSource* data_source ); + void configureSliders( QRect drawArea, + SpectrumView::SpectrumDataSource_sptr dataSource ); /// Configure the horizontal scrollbar to cover the specified range - void ConfigureHSlider( int n_data_steps, - int n_pixels ); + void configureHSlider( int nDataSteps, + int nPixels ); /// Return true if the image horizontal scrollbar is enabled. - bool HSliderOn(); + bool hSliderOn(); /// Return true if the image vertical scrollbar is enabled. - bool VSliderOn(); + bool vSliderOn(); /// Get the range of columns to display in the image. - void GetHSliderInterval( int &x_min, int &x_max ); + void getHSliderInterval( int &xMin, int &xMax ); /// Get the range of rows to display in the image. - void GetVSliderInterval( int &y_min, int &y_max ); + void getVSliderInterval( int &yMin, int &yMax ); private: /// Configure the specified scrollbar to cover the specified range - void ConfigureSlider( QScrollBar* scroll_bar, - int n_data_steps, - int n_pixels, + void configureSlider( QScrollBar* scrollBar, + int nDataSteps, + int nPixels, int val ); - Ui_RefImageViewer* iv_ui; + Ui_RefImageViewer* m_ivUI; + }; } // namespace RefDetectorViewer -} // namespace MantidQt +} // namespace MantidQt #endif // REF_SLIDER_HANDLER_H diff --git a/Code/Mantid/MantidQt/RefDetectorViewer/src/RefDetectorViewDemo.cpp b/Code/Mantid/MantidQt/RefDetectorViewer/src/RefDetectorViewDemo.cpp index 8e8317e238b2..e2ea0e8b756f 100644 --- a/Code/Mantid/MantidQt/RefDetectorViewer/src/RefDetectorViewDemo.cpp +++ b/Code/Mantid/MantidQt/RefDetectorViewer/src/RefDetectorViewDemo.cpp @@ -1,7 +1,7 @@ #include -#include +#include #include #include @@ -14,30 +14,30 @@ using namespace RefDetectorViewer; /** * Construct an array of test data over the specified region with the - * specified region using the specified number of rows and columns. + * specified region using the specified number of rows and columns. * * @param total_xmin The x-coordinate at the left edge of the data region * @param total_xmax The x-coordinate at the right edge of the data region * @param total_ymin The y-coordinate at the bottom edge of the data region * @param total_ymax The y-coordinate at the top edge of the data region * @param total_rows The number of rows the test data should be divided into - * @param total_cols The number of columns the test data should be divided + * @param total_cols The number of columns the test data should be divided * into */ -float * MakeTestData( double total_xmin, double total_xmax, - double total_ymin, double total_ymax, - size_t total_rows, size_t total_cols ) +std::vector makeTestData( double total_xmin, double total_xmax, + double total_ymin, double total_ymax, + size_t total_rows, size_t total_cols ) { - // make some test data in array data[] double x; double y; - float* data = new float[total_rows*total_cols]; + std::vector data(total_rows*total_cols); + for ( size_t row = 0; row < total_rows; row++ ) for ( size_t col = 0; col < total_cols; col++ ) { x = ((double)col - (double)total_cols/2.0)/(double)total_cols; y = ((double)row - (double)total_rows/2.0)/(double)total_rows; - data[ row * total_cols + col ] = + data[ row * total_cols + col ] = (float)(1000.0 * cos( (x*x + y*y)*20.0 )); } // mark a row 1/4 way up @@ -75,10 +75,10 @@ int main( int argc, char **argv ) { QApplication a( argc, argv ); - float * data = MakeTestData( 10, 110, 220, 320, 2000, 2000 ); + std::vector data = makeTestData( 10, 110, 220, 320, 2000, 2000 ); - SpectrumView::ArrayDataSource* source = - new SpectrumView::ArrayDataSource( 10, 110, 220, 320, 2000, 2000, data ); + SpectrumView::ArrayDataSource_sptr source = + SpectrumView::ArrayDataSource_sptr( new SpectrumView::ArrayDataSource( 10, 110, 220, 320, 2000, 2000, data ) ); MantidQt::RefDetectorViewer::RefImageView image_view( source, 10, 110, 220, 320, 200, 500 ); diff --git a/Code/Mantid/MantidQt/RefDetectorViewer/src/RefIVConnections.cpp b/Code/Mantid/MantidQt/RefDetectorViewer/src/RefIVConnections.cpp index 9dc227fc497f..f79cab72cd20 100644 --- a/Code/Mantid/MantidQt/RefDetectorViewer/src/RefIVConnections.cpp +++ b/Code/Mantid/MantidQt/RefDetectorViewer/src/RefIVConnections.cpp @@ -1,17 +1,15 @@ - #include #include #include #include "MantidQtRefDetectorViewer/RefIVConnections.h" #include "MantidQtSpectrumViewer/ColorMaps.h" -#include "MantidQtSpectrumViewer/ErrorHandler.h" namespace MantidQt { namespace RefDetectorViewer { - using namespace SpectrumView; +using namespace SpectrumView; /** * Construct the object that links the GUI components to the other specifed @@ -19,535 +17,536 @@ namespace RefDetectorViewer * The objects passed in must be constructed elsewhere and must be deleted * elsewhere, when the SpectrumViewer is closed. * - * @param ui The object containing the gui components for - * the ImageView viewer. - * @param iv_main_window The main window. - * @param image_display The SpectrumDisplay object that will dispaly the - * image - * @param h_graph_display The GraphDisplay object that will display - * horizontal cuts through the image - * @param v_graph_display The GraphDisplay object that will display - * vertical cuts through the image - * + * @param ui The object containing the gui components for + * the ImageView viewer. + * @param ivMainWindow The main window. + * @param imageDisplay The SpectrumDisplay object that will dispaly the image + * @param hGraphDisplay The GraphDisplay object that will display + * horizontal cuts through the image + * @param vGraphDisplay The GraphDisplay object that will display + * vertical cuts through the image */ -RefIVConnections::RefIVConnections( Ui_RefImageViewer* ui, - RefImageView* iv_main_window, - RefImageDisplay* image_display, - GraphDisplay* h_graph_display, - GraphDisplay* v_graph_display ) +RefIVConnections::RefIVConnections( Ui_RefImageViewer* ui, + RefImageView* ivMainWindow, + RefImageDisplay* imageDisplay, + GraphDisplay* hGraphDisplay, + GraphDisplay* vGraphDisplay ) : + m_ivUI(ui), + m_ivMainWindow(ivMainWindow), + m_imageDisplay(imageDisplay), + m_hGraphDisplay(hGraphDisplay), + m_vGraphDisplay(vGraphDisplay) { - iv_ui = ui; - // first disable a few un-implemented controls - iv_ui->menuGraph_Selected->setDisabled(true); - iv_ui->actionClear_Selections->setDisabled(true); - iv_ui->actionOverlaid->setDisabled(true); - iv_ui->actionOffset_Vertically->setDisabled(true); - iv_ui->actionOffset_Diagonally->setDisabled(true); - iv_ui->actionGraph_Rebinned_Data->setDisabled(true); - iv_ui->menuHelp->setDisabled(true); - - this->iv_main_window = iv_main_window; - QObject::connect( iv_ui->actionClose, SIGNAL(triggered()), - this, SLOT(close_viewer()) ); - - // now set up the gui components - this->image_display = image_display; - this->h_graph_display = h_graph_display; - this->v_graph_display = v_graph_display; - + // First disable a few un-implemented controls + m_ivUI->menuGraph_Selected->setDisabled(true); + m_ivUI->actionClear_Selections->setDisabled(true); + m_ivUI->actionOverlaid->setDisabled(true); + m_ivUI->actionOffset_Vertically->setDisabled(true); + m_ivUI->actionOffset_Diagonally->setDisabled(true); + m_ivUI->actionGraph_Rebinned_Data->setDisabled(true); + m_ivUI->menuHelp->setDisabled(true); + + QObject::connect( m_ivUI->actionClose, SIGNAL(triggered()), + this, SLOT(closeViewer()) ); + + // Now set up the GUI components QList image_sizes; image_sizes.append( 500 ); image_sizes.append( 250 ); - iv_ui->imageSplitter->setSizes( image_sizes ); + m_ivUI->imageSplitter->setSizes( image_sizes ); QList vgraph_sizes; vgraph_sizes.append( 500 ); vgraph_sizes.append( 30 ); vgraph_sizes.append( 220 ); - iv_ui->vgraphSplitter->setSizes( vgraph_sizes ); + m_ivUI->vgraphSplitter->setSizes( vgraph_sizes ); QList horiz_sizes; horiz_sizes.append( 250 ); horiz_sizes.append( 750 ); horiz_sizes.append( 150 ); - iv_ui->left_right_splitter->setSizes( horiz_sizes ); - - iv_ui->imageHorizontalScrollBar->setFocusPolicy( Qt::StrongFocus ); - iv_ui->imageHorizontalScrollBar->setMinimum(20); - iv_ui->imageHorizontalScrollBar->setMaximum(2000); - iv_ui->imageHorizontalScrollBar->setPageStep(30); - iv_ui->imageHorizontalScrollBar->setSingleStep(30/2); - - iv_ui->imageVerticalScrollBar->setFocusPolicy( Qt::StrongFocus ); - iv_ui->imageVerticalScrollBar->setMinimum(0); - iv_ui->imageVerticalScrollBar->setMaximum(10000000); - iv_ui->imageVerticalScrollBar->setPageStep(500); - iv_ui->imageVerticalScrollBar->setSingleStep(500/2); - - iv_ui->action_Hscroll->setCheckable(true); - iv_ui->action_Hscroll->setChecked(false); - iv_ui->imageHorizontalScrollBar->hide(); - iv_ui->imageHorizontalScrollBar->setEnabled(false); - - iv_ui->action_Vscroll->setCheckable(true); - iv_ui->action_Vscroll->setChecked(true); - iv_ui->imageVerticalScrollBar->show(); - iv_ui->imageVerticalScrollBar->setEnabled(true); - - iv_ui->intensity_slider->setTickInterval(10); - iv_ui->intensity_slider->setTickPosition(QSlider::TicksBelow); - iv_ui->intensity_slider->setSliderPosition(30); - -// iv_ui->graph_max_slider->setTickInterval(10); -// iv_ui->graph_max_slider->setTickPosition(QSlider::TicksBelow); -// iv_ui->graph_max_slider->setSliderPosition(100); - - image_picker2 = new TrackingPicker( iv_ui->imagePlot->canvas() ); - image_picker2->setMousePattern(QwtPicker::MouseSelect1, Qt::LeftButton); - image_picker2->setTrackerMode(QwtPicker::ActiveOnly); - image_picker2->setRubberBandPen(QColor(Qt::gray)); - - image_picker = new TrackingPicker( iv_ui->imagePlot->canvas() ); - image_picker->setMousePattern(QwtPicker::MouseSelect1, Qt::RightButton); - image_picker->setTrackerMode(QwtPicker::ActiveOnly); - image_picker->setRubberBandPen(QColor(Qt::blue)); - - -/* // point selections & connection works on mouse release -*/ - image_picker->setRubberBand(QwtPicker::CrossRubberBand); - image_picker->setSelectionFlags(QwtPicker::PointSelection | - QwtPicker::DragSelection ); - - image_picker2->setRubberBand(QwtPicker::CrossRubberBand); - image_picker2->setSelectionFlags(QwtPicker::PointSelection | - QwtPicker::DragSelection ); - - /* - QObject::connect( image_picker, SIGNAL(selected(const QwtPolygon &)), - this, SLOT(imagePickerSelectedPoint()) ); -*/ - -/* // point selection works on mouse click, NO CROSSHAIRS... - - image_picker->setRubberBand(QwtPicker::CrossRubberBand); - image_picker->setSelectionFlags(QwtPicker::PointSelection | - QwtPicker::ClickSelection ); - QObject::connect( image_picker, SIGNAL(selected(const QwtPolygon &)), - this, SLOT(imagePickerSelectedPoint()) ); -*/ - -/* // rect selection calls SLOT on mouse release - - image_picker->setMousePattern(QwtPicker::MouseSelect1, Qt::MidButton); - image_picker->setRubberBand(QwtPicker::RectRubberBand); - image_picker->setSelectionFlags(QwtPicker::RectSelection | - QwtPicker::DragSelection ); - QObject::connect( image_picker, SIGNAL(selected(const QwtPolygon &)), - this, SLOT(imagePickerSelectedPoint()) ); -*/ - -/* - image_picker->setRubberBand(QwtPicker::CrossRubberBand); - image_picker->setSelectionFlags(QwtPicker::PointSelection | - QwtPicker::ClickSelection ); -*/ - - QObject::connect( image_picker2, SIGNAL(mouseMoved()), - this, SLOT(imagePicker2_moved()) ); - - QObject::connect( image_picker, SIGNAL(mouseMoved()), - this, SLOT(imagePicker_moved()) ); - - /* - * Connections on the peak, back and TOF input boxes + m_ivUI->left_right_splitter->setSizes( horiz_sizes ); + + m_ivUI->imageHorizontalScrollBar->setFocusPolicy( Qt::StrongFocus ); + m_ivUI->imageHorizontalScrollBar->setMinimum(20); + m_ivUI->imageHorizontalScrollBar->setMaximum(2000); + m_ivUI->imageHorizontalScrollBar->setPageStep(30); + m_ivUI->imageHorizontalScrollBar->setSingleStep(30/2); + + m_ivUI->imageVerticalScrollBar->setFocusPolicy( Qt::StrongFocus ); + m_ivUI->imageVerticalScrollBar->setMinimum(0); + m_ivUI->imageVerticalScrollBar->setMaximum(10000000); + m_ivUI->imageVerticalScrollBar->setPageStep(500); + m_ivUI->imageVerticalScrollBar->setSingleStep(500/2); + + m_ivUI->action_Hscroll->setCheckable(true); + m_ivUI->action_Hscroll->setChecked(false); + m_ivUI->imageHorizontalScrollBar->hide(); + m_ivUI->imageHorizontalScrollBar->setEnabled(false); + + m_ivUI->action_Vscroll->setCheckable(true); + m_ivUI->action_Vscroll->setChecked(true); + m_ivUI->imageVerticalScrollBar->show(); + m_ivUI->imageVerticalScrollBar->setEnabled(true); + + m_ivUI->intensity_slider->setTickInterval(10); + m_ivUI->intensity_slider->setTickPosition(QSlider::TicksBelow); + m_ivUI->intensity_slider->setSliderPosition(30); + + // m_ivUI->graph_max_slider->setTickInterval(10); + // m_ivUI->graph_max_slider->setTickPosition(QSlider::TicksBelow); + // m_ivUI->graph_max_slider->setSliderPosition(100); + + m_imagePicker2 = new TrackingPicker( m_ivUI->imagePlot->canvas() ); + m_imagePicker2->setMousePattern(QwtPicker::MouseSelect1, Qt::LeftButton); + m_imagePicker2->setTrackerMode(QwtPicker::ActiveOnly); + m_imagePicker2->setRubberBandPen(QColor(Qt::gray)); + + m_imagePicker = new TrackingPicker( m_ivUI->imagePlot->canvas() ); + m_imagePicker->setMousePattern(QwtPicker::MouseSelect1, Qt::RightButton); + m_imagePicker->setTrackerMode(QwtPicker::ActiveOnly); + m_imagePicker->setRubberBandPen(QColor(Qt::blue)); + + // Point selections & connection works on mouse release + m_imagePicker->setRubberBand(QwtPicker::CrossRubberBand); + m_imagePicker->setSelectionFlags(QwtPicker::PointSelection | + QwtPicker::DragSelection ); + + m_imagePicker2->setRubberBand(QwtPicker::CrossRubberBand); + m_imagePicker2->setSelectionFlags(QwtPicker::PointSelection | + QwtPicker::DragSelection ); + + /* + QObject::connect( m_imagePicker, SIGNAL(selected(const QwtPolygon &)), + this, SLOT(imagePickerSelectedPoint()) ); + */ + + /* // point selection works on mouse click, NO CROSSHAIRS... + + m_imagePicker->setRubberBand(QwtPicker::CrossRubberBand); + m_imagePicker->setSelectionFlags(QwtPicker::PointSelection | + QwtPicker::ClickSelection ); + QObject::connect( m_imagePicker, SIGNAL(selected(const QwtPolygon &)), + this, SLOT(imagePickerSelectedPoint()) ); + */ + + /* // rect selection calls SLOT on mouse release + + m_imagePicker->setMousePattern(QwtPicker::MouseSelect1, Qt::MidButton); + m_imagePicker->setRubberBand(QwtPicker::RectRubberBand); + m_imagePicker->setSelectionFlags(QwtPicker::RectSelection | + QwtPicker::DragSelection ); + QObject::connect( m_imagePicker, SIGNAL(selected(const QwtPolygon &)), + this, SLOT(imagePickerSelectedPoint()) ); + */ + + /* + m_imagePicker->setRubberBand(QwtPicker::CrossRubberBand); + m_imagePicker->setSelectionFlags(QwtPicker::PointSelection | + QwtPicker::ClickSelection ); */ - QObject::connect(iv_ui->lineEdit_peakLeft, SIGNAL(returnPressed()), - this, SLOT(edit_manual_input()) ); - QObject::connect(iv_ui->lineEdit_peakRight, SIGNAL(returnPressed()), - this, SLOT(edit_manual_input()) ); - QObject::connect(iv_ui->lineEdit_backLeft, SIGNAL(returnPressed()), - this, SLOT(edit_manual_input()) ); - QObject::connect(iv_ui->lineEdit_backRight, SIGNAL(returnPressed()), - this, SLOT(edit_manual_input()) ); - QObject::connect(iv_ui->lineEdit_TOFmin, SIGNAL(returnPressed()), - this, SLOT(edit_manual_input()) ); - QObject::connect(iv_ui->lineEdit_TOFmax, SIGNAL(returnPressed()), - this, SLOT(edit_manual_input()) ); - - QObject::connect(iv_ui->imageSplitter, SIGNAL(splitterMoved(int,int)), - this, SLOT(imageSplitter_moved()) ); - - QObject::connect(iv_ui->x_min_input, SIGNAL( returnPressed() ), - this, SLOT(image_horizontal_range_changed()) ); - - QObject::connect(iv_ui->x_max_input, SIGNAL( returnPressed() ), - this, SLOT(image_horizontal_range_changed()) ); - -// QObject::connect(iv_ui->step_input, SIGNAL( returnPressed() ), -// this, SLOT(image_horizontal_range_changed()) ); - - QObject::connect(iv_ui->imageVerticalScrollBar, SIGNAL(valueChanged(int)), - this, SLOT(v_scroll_bar_moved()) ); - - QObject::connect(iv_ui->imageHorizontalScrollBar, SIGNAL(valueChanged(int)), - this, SLOT(h_scroll_bar_moved()) ); - - QObject::connect(iv_ui->action_Hscroll, SIGNAL(changed()), - this, SLOT(toggle_Hscroll()) ); - - QObject::connect(iv_ui->action_Vscroll, SIGNAL(changed()), - this, SLOT(toggle_Vscroll()) ); - - QObject::connect(iv_ui->intensity_slider, SIGNAL(valueChanged(int)), - this, SLOT(intensity_slider_moved()) ); - -// QObject::connect(iv_ui->graph_max_slider, SIGNAL(valueChanged(int)), -// this, SLOT(graph_range_changed()) ); - - // color scale selections - iv_ui->actionHeat->setCheckable(true); - iv_ui->actionHeat->setChecked(true); - iv_ui->actionGray->setCheckable(true); - iv_ui->actionNegative_Gray->setCheckable(true); - iv_ui->actionGreen_Yellow->setCheckable(true); - iv_ui->actionRainbow->setCheckable(true); - iv_ui->actionOptimal->setCheckable(true); - iv_ui->actionMulti->setCheckable(true); - iv_ui->actionSpectrum->setCheckable(true); - // set up initial color - // scale display - iv_ui->color_scale->setScaledContents(true); - iv_ui->color_scale->setMinimumHeight(15); - iv_ui->color_scale->setMinimumWidth(15); - std::vector positive_color_table; - ColorMaps::GetColorMap( ColorMaps::HEAT, 256, positive_color_table ); - - std::vector negative_color_table; - ColorMaps::GetColorMap( ColorMaps::GRAY, 256, negative_color_table ); - - ShowColorScale( positive_color_table, negative_color_table ); - - - color_group = new QActionGroup(this); - color_group->addAction(iv_ui->actionHeat); - color_group->addAction(iv_ui->actionGray); - color_group->addAction(iv_ui->actionNegative_Gray); - color_group->addAction(iv_ui->actionGreen_Yellow); - color_group->addAction(iv_ui->actionRainbow); - color_group->addAction(iv_ui->actionOptimal); - color_group->addAction(iv_ui->actionMulti); - color_group->addAction(iv_ui->actionSpectrum); - - QObject::connect(iv_ui->actionHeat, SIGNAL(triggered()), - this, SLOT(heat_color_scale()) ); - - QObject::connect(iv_ui->actionGray, SIGNAL(triggered()), - this, SLOT(gray_color_scale()) ); - - QObject::connect(iv_ui->actionNegative_Gray, SIGNAL(triggered()), - this, SLOT(negative_gray_color_scale()) ); - - QObject::connect(iv_ui->actionGreen_Yellow, SIGNAL(triggered()), - this, SLOT(green_yellow_color_scale()) ); - - QObject::connect(iv_ui->actionRainbow, SIGNAL(triggered()), - this, SLOT(rainbow_color_scale()) ); - - QObject::connect(iv_ui->actionOptimal, SIGNAL(triggered()), - this, SLOT(optimal_color_scale()) ); - - QObject::connect(iv_ui->actionMulti, SIGNAL(triggered()), - this, SLOT(multi_color_scale()) ); - - QObject::connect(iv_ui->actionSpectrum, SIGNAL(triggered()), - this, SLOT(spectrum_color_scale()) ); - - h_graph_picker = new TrackingPicker( iv_ui->h_graphPlot->canvas() ); - h_graph_picker->setMousePattern(QwtPicker::MouseSelect1, Qt::RightButton); - h_graph_picker->setTrackerMode(QwtPicker::ActiveOnly); - h_graph_picker->setRubberBandPen(QColor(Qt::gray)); - h_graph_picker->setRubberBand(QwtPicker::CrossRubberBand); - h_graph_picker->setSelectionFlags(QwtPicker::PointSelection | - QwtPicker::DragSelection ); - QObject::connect( h_graph_picker, SIGNAL(mouseMoved()), - this, SLOT(h_graphPicker_moved()) ); + + QObject::connect( m_imagePicker2, SIGNAL(mouseMoved()), + this, SLOT(imagePicker2Moved()) ); + + QObject::connect( m_imagePicker, SIGNAL(mouseMoved()), + this, SLOT(imagePickerMoved()) ); + + /* + * Connections on the peak, back and TOF input boxes + */ + QObject::connect(m_ivUI->lineEdit_peakLeft, SIGNAL(returnPressed()), + this, SLOT(editManualInput()) ); + QObject::connect(m_ivUI->lineEdit_peakRight, SIGNAL(returnPressed()), + this, SLOT(editManualInput()) ); + QObject::connect(m_ivUI->lineEdit_backLeft, SIGNAL(returnPressed()), + this, SLOT(editManualInput()) ); + QObject::connect(m_ivUI->lineEdit_backRight, SIGNAL(returnPressed()), + this, SLOT(editManualInput()) ); + QObject::connect(m_ivUI->lineEdit_TOFmin, SIGNAL(returnPressed()), + this, SLOT(editManualInput()) ); + QObject::connect(m_ivUI->lineEdit_TOFmax, SIGNAL(returnPressed()), + this, SLOT(editManualInput()) ); + + QObject::connect(m_ivUI->imageSplitter, SIGNAL(splitterMoved(int,int)), + this, SLOT(imageSplitterMoved()) ); + + QObject::connect(m_ivUI->x_min_input, SIGNAL( returnPressed() ), + this, SLOT(imageHorizontalRangeChanged()) ); + + QObject::connect(m_ivUI->x_max_input, SIGNAL( returnPressed() ), + this, SLOT(imageHorizontalRangeChanged()) ); + + // QObject::connect(m_ivUI->step_input, SIGNAL( returnPressed() ), + // this, SLOT(image_horizontal_range_changed()) ); + + QObject::connect(m_ivUI->imageVerticalScrollBar, SIGNAL(valueChanged(int)), + this, SLOT(vScrollBarMoved()) ); + + QObject::connect(m_ivUI->imageHorizontalScrollBar, SIGNAL(valueChanged(int)), + this, SLOT(hScrollBarMoved()) ); + + QObject::connect(m_ivUI->action_Hscroll, SIGNAL(changed()), + this, SLOT(toggleHScroll()) ); + + QObject::connect(m_ivUI->action_Vscroll, SIGNAL(changed()), + this, SLOT(toggleVScroll()) ); + + QObject::connect(m_ivUI->intensity_slider, SIGNAL(valueChanged(int)), + this, SLOT(intensitySliderMoved()) ); + + // QObject::connect(m_ivUI->graph_max_slider, SIGNAL(valueChanged(int)), + // this, SLOT(graphRangeChanged()) ); + + // color scale selections + m_ivUI->actionHeat->setCheckable(true); + m_ivUI->actionHeat->setChecked(true); + m_ivUI->actionGray->setCheckable(true); + m_ivUI->actionNegative_Gray->setCheckable(true); + m_ivUI->actionGreen_Yellow->setCheckable(true); + m_ivUI->actionRainbow->setCheckable(true); + m_ivUI->actionOptimal->setCheckable(true); + m_ivUI->actionMulti->setCheckable(true); + m_ivUI->actionSpectrum->setCheckable(true); + // set up initial color + // scale display + m_ivUI->color_scale->setScaledContents(true); + m_ivUI->color_scale->setMinimumHeight(15); + m_ivUI->color_scale->setMinimumWidth(15); + std::vector positiveColorTable; + ColorMaps::GetColorMap( ColorMaps::HEAT, 256, positiveColorTable ); + + std::vector negativeColorTable; + ColorMaps::GetColorMap( ColorMaps::GRAY, 256, negativeColorTable ); + + showColorScale( positiveColorTable, negativeColorTable ); + + + m_colorGroup = new QActionGroup(this); + m_colorGroup->addAction(m_ivUI->actionHeat); + m_colorGroup->addAction(m_ivUI->actionGray); + m_colorGroup->addAction(m_ivUI->actionNegative_Gray); + m_colorGroup->addAction(m_ivUI->actionGreen_Yellow); + m_colorGroup->addAction(m_ivUI->actionRainbow); + m_colorGroup->addAction(m_ivUI->actionOptimal); + m_colorGroup->addAction(m_ivUI->actionMulti); + m_colorGroup->addAction(m_ivUI->actionSpectrum); + + QObject::connect(m_ivUI->actionHeat, SIGNAL(triggered()), + this, SLOT(heatColorScale()) ); + + QObject::connect(m_ivUI->actionGray, SIGNAL(triggered()), + this, SLOT(grayColorScale()) ); + + QObject::connect(m_ivUI->actionNegative_Gray, SIGNAL(triggered()), + this, SLOT(negative_grayColorScale()) ); + + QObject::connect(m_ivUI->actionGreen_Yellow, SIGNAL(triggered()), + this, SLOT(green_yellowColorScale()) ); + + QObject::connect(m_ivUI->actionRainbow, SIGNAL(triggered()), + this, SLOT(rainbowColorScale()) ); + + QObject::connect(m_ivUI->actionOptimal, SIGNAL(triggered()), + this, SLOT(optimalColorScale()) ); + + QObject::connect(m_ivUI->actionMulti, SIGNAL(triggered()), + this, SLOT(multiColorScale()) ); + + QObject::connect(m_ivUI->actionSpectrum, SIGNAL(triggered()), + this, SLOT(spectrumColorScale()) ); + + m_hGraphPicker = new TrackingPicker( m_ivUI->h_graphPlot->canvas() ); + m_hGraphPicker->setMousePattern(QwtPicker::MouseSelect1, Qt::RightButton); + m_hGraphPicker->setTrackerMode(QwtPicker::ActiveOnly); + m_hGraphPicker->setRubberBandPen(QColor(Qt::gray)); + m_hGraphPicker->setRubberBand(QwtPicker::CrossRubberBand); + m_hGraphPicker->setSelectionFlags(QwtPicker::PointSelection | + QwtPicker::DragSelection ); + QObject::connect( m_hGraphPicker, SIGNAL(mouseMoved()), + this, SLOT(hGraphPickerMoved()) ); // NOTE: This initialization could be a (static?) method in TrackingPicker - v_graph_picker = new TrackingPicker( iv_ui->v_graphPlot->canvas() ); - v_graph_picker->setMousePattern(QwtPicker::MouseSelect1, Qt::RightButton); - v_graph_picker->setTrackerMode(QwtPicker::ActiveOnly); - v_graph_picker->setRubberBandPen(QColor(Qt::gray)); - v_graph_picker->setRubberBand(QwtPicker::CrossRubberBand); - v_graph_picker->setSelectionFlags(QwtPicker::PointSelection | - QwtPicker::DragSelection ); - QObject::connect( v_graph_picker, SIGNAL(mouseMoved()), - this, SLOT(v_graphPicker_moved()) ); + m_vGraphPicker = new TrackingPicker( m_ivUI->v_graphPlot->canvas() ); + m_vGraphPicker->setMousePattern(QwtPicker::MouseSelect1, Qt::RightButton); + m_vGraphPicker->setTrackerMode(QwtPicker::ActiveOnly); + m_vGraphPicker->setRubberBandPen(QColor(Qt::gray)); + m_vGraphPicker->setRubberBand(QwtPicker::CrossRubberBand); + m_vGraphPicker->setSelectionFlags(QwtPicker::PointSelection | + QwtPicker::DragSelection ); + QObject::connect( m_vGraphPicker, SIGNAL(mouseMoved()), + this, SLOT(vGraphPickerMoved()) ); } RefIVConnections::~RefIVConnections() { - // std::cout << "IVConnections destructor called" << std::endl; - - delete image_picker; - delete image_picker2; - delete h_graph_picker; - delete v_graph_picker; - delete color_group; } -void RefIVConnections::close_viewer() +void RefIVConnections::closeViewer() { - iv_main_window->close(); + m_ivMainWindow->close(); } -void RefIVConnections::toggle_Hscroll() +void RefIVConnections::toggleHScroll() { - bool is_on = iv_ui->action_Hscroll->isChecked(); - iv_ui->imageHorizontalScrollBar->setVisible( is_on ); - iv_ui->imageHorizontalScrollBar->setEnabled( is_on ); - image_display->UpdateImage(); + bool is_on = m_ivUI->action_Hscroll->isChecked(); + m_ivUI->imageHorizontalScrollBar->setVisible( is_on ); + m_ivUI->imageHorizontalScrollBar->setEnabled( is_on ); + m_imageDisplay->updateImage(); } -void RefIVConnections::toggle_Vscroll() +void RefIVConnections::toggleVScroll() { - bool is_on = iv_ui->action_Vscroll->isChecked(); - iv_ui->imageVerticalScrollBar->setVisible( is_on ); - iv_ui->imageVerticalScrollBar->setEnabled( is_on ); - image_display->UpdateImage(); + bool is_on = m_ivUI->action_Vscroll->isChecked(); + m_ivUI->imageVerticalScrollBar->setVisible( is_on ); + m_ivUI->imageVerticalScrollBar->setEnabled( is_on ); + m_imageDisplay->updateImage(); } -void RefIVConnections::image_horizontal_range_changed() +void RefIVConnections::imageHorizontalRangeChanged() { - image_display->UpdateRange(); + m_imageDisplay->updateRange(); } -void RefIVConnections::graph_range_changed() +void RefIVConnections::graphRangeChanged() { -// double value = (double)iv_ui->graph_max_slider->value(); -// double min = (double)iv_ui->graph_max_slider->minimum(); -// double max = (double)iv_ui->graph_max_slider->maximum(); -// -// double range_scale = (value - min)/(max - min); -// if ( range_scale < 0.01 ) -// range_scale = 0.01; -// -// h_graph_display->SetRangeScale( range_scale ); -// v_graph_display->SetRangeScale( range_scale ); + // double value = (double)m_ivUI->graph_max_slider->value(); + // double min = (double)m_ivUI->graph_max_slider->minimum(); + // double max = (double)m_ivUI->graph_max_slider->maximum(); + // + // double range_scale = (value - min)/(max - min); + // if ( range_scale < 0.01 ) + // range_scale = 0.01; + // + // m_hGraphDisplay->setRangeScale( range_scale ); + // m_vGraphDisplay->setRangeScale( range_scale ); } -void RefIVConnections::peak_back_tof_range_update() + +void RefIVConnections::peakBackTofRangeUpdate() { - QLineEdit * peak_left_control = iv_ui->lineEdit_peakLeft; - double peakmin = peak_left_control->text().toDouble(); - - QLineEdit * peak_right_control = iv_ui->lineEdit_peakRight; - double peakmax = peak_right_control->text().toDouble(); - - QLineEdit * back_left_control = iv_ui->lineEdit_backLeft; - double backmin = back_left_control->text().toDouble(); - - QLineEdit * back_right_control = iv_ui->lineEdit_backRight; - double backmax = back_right_control->text().toDouble(); - - QLineEdit * tof_min_control = iv_ui->lineEdit_TOFmin; - double tofmin = tof_min_control->text().toDouble(); - - QLineEdit * tof_max_control = iv_ui->lineEdit_TOFmax; - double tofmax = tof_max_control->text().toDouble(); - - emit peak_back_tof_range_update(peakmin, peakmax, backmin, backmax, tofmin, tofmax); + QLineEdit * peak_left_control = m_ivUI->lineEdit_peakLeft; + double peakmin = peak_left_control->text().toDouble(); + + QLineEdit * peak_right_control = m_ivUI->lineEdit_peakRight; + double peakmax = peak_right_control->text().toDouble(); + + QLineEdit * back_left_control = m_ivUI->lineEdit_backLeft; + double backmin = back_left_control->text().toDouble(); + + QLineEdit * back_right_control = m_ivUI->lineEdit_backRight; + double backmax = back_right_control->text().toDouble(); + + QLineEdit * tof_min_control = m_ivUI->lineEdit_TOFmin; + double tofmin = tof_min_control->text().toDouble(); + + QLineEdit * tof_max_control = m_ivUI->lineEdit_TOFmax; + double tofmax = tof_max_control->text().toDouble(); + + emit peakBackTofRangeUpdate(peakmin, peakmax, backmin, backmax, tofmin, tofmax); } -void RefIVConnections::edit_manual_input() -{ - image_display->UpdateImage(); - peak_back_tof_range_update(); +void RefIVConnections::editManualInput() +{ + m_imageDisplay->updateImage(); + peakBackTofRangeUpdate(); } - - -void RefIVConnections::v_scroll_bar_moved() + + +void RefIVConnections::vScrollBarMoved() { - image_display->UpdateImage(); + m_imageDisplay->updateImage(); } -void RefIVConnections::h_scroll_bar_moved() +void RefIVConnections::hScrollBarMoved() { - image_display->UpdateImage(); + m_imageDisplay->updateImage(); } -void RefIVConnections::imageSplitter_moved() +void RefIVConnections::imageSplitterMoved() { - QList sizes = iv_ui->imageSplitter->sizes(); + QList sizes = m_ivUI->imageSplitter->sizes(); QList vgraph_sizes; vgraph_sizes.append( sizes[0] ); vgraph_sizes.append( 30 ); vgraph_sizes.append( sizes[1] ); - iv_ui->vgraphSplitter->setSizes( vgraph_sizes ); - image_display->UpdateImage(); + m_ivUI->vgraphSplitter->setSizes( vgraph_sizes ); + m_imageDisplay->updateImage(); } - //Right click -void RefIVConnections::imagePicker_moved() +// Right click +void RefIVConnections::imagePickerMoved() { - QwtPolygon selected_points = image_picker->selection(); - if ( selected_points.size() >= 1 ) + QwtPolygon selectedPoints = m_imagePicker->selection(); + if ( selectedPoints.size() >= 1 ) { - int index = selected_points.size() - 1; - image_display->SetPointedAtPoint( selected_points[index] ); + int index = selectedPoints.size() - 1; + m_imageDisplay->setPointedAtPoint( selectedPoints[index] ); } } - //Left click -void RefIVConnections::imagePicker2_moved() + +// Left click +void RefIVConnections::imagePicker2Moved() { - QwtPolygon selected_points = image_picker2->selection(); - if ( selected_points.size() >= 1 ) - { - peak_back_tof_range_update(); - int index = selected_points.size() - 1; - int mouseClick = 1; - image_display->SetPointedAtPoint( selected_points[index], mouseClick ); - peak_back_tof_range_update(); - - } + QwtPolygon selectedPoints = m_imagePicker2->selection(); + if ( selectedPoints.size() >= 1 ) + { + peakBackTofRangeUpdate(); + int index = selectedPoints.size() - 1; + int mouseClick = 1; + m_imageDisplay->setPointedAtPoint( selectedPoints[index], mouseClick ); + peakBackTofRangeUpdate(); + + } } -void RefIVConnections::h_graphPicker_moved() +void RefIVConnections::hGraphPickerMoved() { - QwtPolygon selected_points = h_graph_picker->selection(); - if ( selected_points.size() >= 1 ) + QwtPolygon selectedPoints = m_hGraphPicker->selection(); + if ( selectedPoints.size() >= 1 ) { - int index = selected_points.size() - 1; - h_graph_display->SetPointedAtPoint( selected_points[index]); + int index = selectedPoints.size() - 1; + m_hGraphDisplay->setPointedAtPoint( selectedPoints[index]); } } -void RefIVConnections::v_graphPicker_moved() +void RefIVConnections::vGraphPickerMoved() { - QwtPolygon selected_points = v_graph_picker->selection(); - if ( selected_points.size() >= 1 ) + QwtPolygon selectedPoints = m_vGraphPicker->selection(); + if ( selectedPoints.size() >= 1 ) { - int index = selected_points.size() - 1; - v_graph_display->SetPointedAtPoint( selected_points[index] ); + int index = selectedPoints.size() - 1; + m_vGraphDisplay->setPointedAtPoint( selectedPoints[index] ); } } -void RefIVConnections::intensity_slider_moved() + +void RefIVConnections::intensitySliderMoved() { - double value = (double)iv_ui->intensity_slider->value(); - double min = (double)iv_ui->intensity_slider->minimum(); - double max = (double)iv_ui->intensity_slider->maximum(); + double value = (double)m_ivUI->intensity_slider->value(); + double min = (double)m_ivUI->intensity_slider->minimum(); + double max = (double)m_ivUI->intensity_slider->maximum(); - double scaled_value = 100.0*(value - min)/(max - min); - image_display->SetIntensity( scaled_value ); + double scaledValue = 100.0*(value - min)/(max - min); + m_imageDisplay->setIntensity( scaledValue ); } -void RefIVConnections::heat_color_scale() + +/* COLOUR MAP SLOTS */ + +void RefIVConnections::heatColorScale() { - std::vector positive_color_table; - ColorMaps::GetColorMap( ColorMaps::HEAT, 256, positive_color_table ); + std::vector positiveColorTable; + ColorMaps::GetColorMap( ColorMaps::HEAT, 256, positiveColorTable ); - std::vector negative_color_table; - ColorMaps::GetColorMap( ColorMaps::GRAY, 256, negative_color_table ); + std::vector negativeColorTable; + ColorMaps::GetColorMap( ColorMaps::GRAY, 256, negativeColorTable ); - image_display->SetColorScales( positive_color_table, negative_color_table ); - ShowColorScale( positive_color_table, negative_color_table ); + m_imageDisplay->setColorScales( positiveColorTable, negativeColorTable ); + showColorScale( positiveColorTable, negativeColorTable ); } -void RefIVConnections::gray_color_scale() + +void RefIVConnections::grayColorScale() { - std::vector positive_color_table; - ColorMaps::GetColorMap( ColorMaps::GRAY, 256, positive_color_table ); + std::vector positiveColorTable; + ColorMaps::GetColorMap( ColorMaps::GRAY, 256, positiveColorTable ); - std::vector negative_color_table; - ColorMaps::GetColorMap( ColorMaps::HEAT, 256, negative_color_table ); + std::vector negativeColorTable; + ColorMaps::GetColorMap( ColorMaps::HEAT, 256, negativeColorTable ); - image_display->SetColorScales( positive_color_table, negative_color_table ); - ShowColorScale( positive_color_table, negative_color_table ); + m_imageDisplay->setColorScales( positiveColorTable, negativeColorTable ); + showColorScale( positiveColorTable, negativeColorTable ); } -void RefIVConnections::negative_gray_color_scale() + +void RefIVConnections::negativeGrayColorScale() { - std::vector positive_color_table; - ColorMaps::GetColorMap( ColorMaps::NEGATIVE_GRAY,256, positive_color_table); + std::vector positiveColorTable; + ColorMaps::GetColorMap( ColorMaps::NEGATIVE_GRAY,256, positiveColorTable); - std::vector negative_color_table; - ColorMaps::GetColorMap( ColorMaps::HEAT, 256, negative_color_table ); + std::vector negativeColorTable; + ColorMaps::GetColorMap( ColorMaps::HEAT, 256, negativeColorTable ); - image_display->SetColorScales( positive_color_table, negative_color_table ); - ShowColorScale( positive_color_table, negative_color_table ); + m_imageDisplay->setColorScales( positiveColorTable, negativeColorTable ); + showColorScale( positiveColorTable, negativeColorTable ); } -void RefIVConnections::green_yellow_color_scale() + +void RefIVConnections::greenYellowColorScale() { - std::vector positive_color_table; - ColorMaps::GetColorMap( ColorMaps::GREEN_YELLOW, 256, positive_color_table); + std::vector positiveColorTable; + ColorMaps::GetColorMap( ColorMaps::GREEN_YELLOW, 256, positiveColorTable); - std::vector negative_color_table; - ColorMaps::GetColorMap( ColorMaps::GRAY, 256, negative_color_table ); + std::vector negativeColorTable; + ColorMaps::GetColorMap( ColorMaps::GRAY, 256, negativeColorTable ); - image_display->SetColorScales( positive_color_table, negative_color_table ); - ShowColorScale( positive_color_table, negative_color_table ); + m_imageDisplay->setColorScales( positiveColorTable, negativeColorTable ); + showColorScale( positiveColorTable, negativeColorTable ); } -void RefIVConnections::rainbow_color_scale() + +void RefIVConnections::rainbowColorScale() { - std::vector positive_color_table; - ColorMaps::GetColorMap( ColorMaps::RAINBOW, 256, positive_color_table ); + std::vector positiveColorTable; + ColorMaps::GetColorMap( ColorMaps::RAINBOW, 256, positiveColorTable ); - std::vector negative_color_table; - ColorMaps::GetColorMap( ColorMaps::GRAY, 256, negative_color_table ); + std::vector negativeColorTable; + ColorMaps::GetColorMap( ColorMaps::GRAY, 256, negativeColorTable ); - image_display->SetColorScales( positive_color_table, negative_color_table ); - ShowColorScale( positive_color_table, negative_color_table ); + m_imageDisplay->setColorScales( positiveColorTable, negativeColorTable ); + showColorScale( positiveColorTable, negativeColorTable ); } -void RefIVConnections::optimal_color_scale() + +void RefIVConnections::optimalColorScale() { - std::vector positive_color_table; - ColorMaps::GetColorMap( ColorMaps::OPTIMAL, 256, positive_color_table ); + std::vector positiveColorTable; + ColorMaps::GetColorMap( ColorMaps::OPTIMAL, 256, positiveColorTable ); - std::vector negative_color_table; - ColorMaps::GetColorMap( ColorMaps::GRAY, 256, negative_color_table ); + std::vector negativeColorTable; + ColorMaps::GetColorMap( ColorMaps::GRAY, 256, negativeColorTable ); - image_display->SetColorScales( positive_color_table, negative_color_table ); - ShowColorScale( positive_color_table, negative_color_table ); + m_imageDisplay->setColorScales( positiveColorTable, negativeColorTable ); + showColorScale( positiveColorTable, negativeColorTable ); } -void RefIVConnections::multi_color_scale() + +void RefIVConnections::multiColorScale() { - std::vector positive_color_table; - ColorMaps::GetColorMap( ColorMaps::MULTI, 256, positive_color_table ); + std::vector positiveColorTable; + ColorMaps::GetColorMap( ColorMaps::MULTI, 256, positiveColorTable ); - std::vector negative_color_table; - ColorMaps::GetColorMap( ColorMaps::GRAY, 256, negative_color_table ); + std::vector negativeColorTable; + ColorMaps::GetColorMap( ColorMaps::GRAY, 256, negativeColorTable ); - image_display->SetColorScales( positive_color_table, negative_color_table ); - ShowColorScale( positive_color_table, negative_color_table ); + m_imageDisplay->setColorScales( positiveColorTable, negativeColorTable ); + showColorScale( positiveColorTable, negativeColorTable ); } -void RefIVConnections::spectrum_color_scale() + +void RefIVConnections::spectrumColorScale() { - std::vector positive_color_table; - ColorMaps::GetColorMap( ColorMaps::SPECTRUM, 256, positive_color_table ); + std::vector positiveColorTable; + ColorMaps::GetColorMap( ColorMaps::SPECTRUM, 256, positiveColorTable ); - std::vector negative_color_table; - ColorMaps::GetColorMap( ColorMaps::GRAY, 256, negative_color_table ); + std::vector negativeColorTable; + ColorMaps::GetColorMap( ColorMaps::GRAY, 256, negativeColorTable ); - image_display->SetColorScales( positive_color_table, negative_color_table ); - ShowColorScale( positive_color_table, negative_color_table ); + m_imageDisplay->setColorScales( positiveColorTable, negativeColorTable ); + showColorScale( positiveColorTable, negativeColorTable ); } @@ -555,43 +554,40 @@ void RefIVConnections::spectrum_color_scale() * Set the pix map that shows the color scale from the specified positive * and negative color tables. * - * @param positive_color_table The new color table used to map positive data + * @param positiveColorTable The new color table used to map positive data * values to an RGB color. - * @param negative_color_table The new color table used to map negative data + * @param negativeColorTable The new color table used to map negative data * values to an RGB color. This must have the * same number of entries as the positive * color table. */ -void RefIVConnections::ShowColorScale( std::vector & positive_color_table, - std::vector & negative_color_table ) +void RefIVConnections::showColorScale( std::vector & positiveColorTable, + std::vector & negativeColorTable ) { - size_t total_colors = positive_color_table.size() + - negative_color_table.size(); + size_t totalColors = positiveColorTable.size() + negativeColorTable.size(); - unsigned int *rgb_data = new unsigned int[ total_colors ]; + QImage image((int)totalColors, 1, QImage::Format_RGB32); + int index = 0; - size_t index = 0; - size_t n_colors = negative_color_table.size(); - for ( size_t i = 0; i < n_colors; i++ ) + size_t numColors = negativeColorTable.size(); + for(size_t i = 0; i < numColors; i++) { - rgb_data[index] = negative_color_table[ n_colors - 1 - i ]; + unsigned int pixel = static_cast(negativeColorTable[numColors - 1 - i]); + image.setPixel(index, 0, pixel); index++; } - n_colors = positive_color_table.size(); - for ( size_t i = 0; i < n_colors; i++ ) + numColors = positiveColorTable.size(); + for(size_t i = 0; i < numColors; i++) { - rgb_data[index] = positive_color_table[i]; + unsigned int pixel = static_cast(positiveColorTable[i]); + image.setPixel(index, 0, pixel); index++; } - uchar *buffer = (uchar*)rgb_data; - QImage image( buffer, (int)total_colors, 1, QImage::Format_RGB32 ); QPixmap pixmap = QPixmap::fromImage(image); - iv_ui->color_scale->setPixmap( pixmap ); - - delete[] rgb_data; + m_ivUI->color_scale->setPixmap(pixmap); } } // namespace RefDetectorViewer -} // namespace MantidQt +} // namespace MantidQt diff --git a/Code/Mantid/MantidQt/RefDetectorViewer/src/RefImageDisplay.cpp b/Code/Mantid/MantidQt/RefDetectorViewer/src/RefImageDisplay.cpp index dcb895af65e0..1bfa27e37eb2 100644 --- a/Code/Mantid/MantidQt/RefDetectorViewer/src/RefImageDisplay.cpp +++ b/Code/Mantid/MantidQt/RefDetectorViewer/src/RefImageDisplay.cpp @@ -12,34 +12,34 @@ namespace RefDetectorViewer using namespace SpectrumView; /** - * Make an RefImageDisplay to display with the given widgets and controls. + * Make a RefImageDisplay to display with the given widgets and controls. * - * @param image_plot The QwtPlot that will hold the image - * @param slider_handler The object that manages interaction with the - * horizontal and vertical scroll bars - * @param range_handler The object that manages the data range - * @param limits_handler The object that manages the limits - * @param h_graph The GraphDisplay for the graph showing horizontal - * cuts through the image at the bottom of the image. - * @param v_graph The GraphDisplay for the graph showing vertical - * cuts through the image at the left side of the image. - * @param table_widget The widget where the information about a pointed - * at location will be displayed. + * @param imagePlot The QwtPlot that will hold the image + * @param sliderHandler The object that manages interaction with the + * horizontal and vertical scroll bars + * @param rangeHandler The object that manages the data range + * @param limitsHandler The object that manages the limits + * @param hGraph The GraphDisplay for the graph showing horizontal + * cuts through the image at the bottom of the image. + * @param vGraph The GraphDisplay for the graph showing vertical + * cuts through the image at the left side of the image. + * @param tableWidget The widget where the information about a pointed + * at location will be displayed. */ -RefImageDisplay::RefImageDisplay( QwtPlot* image_plot, - RefSliderHandler* slider_handler, - RefRangeHandler* range_handler, - RefLimitsHandler* limits_handler, - GraphDisplay* h_graph, - GraphDisplay* v_graph, - QTableWidget* table_widget) - : SpectrumView::SpectrumDisplay(image_plot,slider_handler,range_handler,h_graph,v_graph,table_widget), - m_limitsHandler(limits_handler) +RefImageDisplay::RefImageDisplay( QwtPlot* imagePlot, + RefSliderHandler* sliderHandler, + RefRangeHandler* rangeHandler, + RefLimitsHandler* limitsHandler, + GraphDisplay* hGraph, + GraphDisplay* vGraph, + QTableWidget* tableWidget) + : SpectrumView::SpectrumDisplay(imagePlot, sliderHandler, rangeHandler, hGraph, vGraph, tableWidget), + m_limitsHandler(limitsHandler) { // We need a different SpectrumPlotItem class, so delete the one created in the // base class constructor and create the one we want - delete spectrum_plot_item; - spectrum_plot_item = new RefImagePlotItem(limits_handler); + delete m_spectrumPlotItem; + m_spectrumPlotItem = new RefImagePlotItem(limitsHandler); setupSpectrumPlotItem(); } @@ -52,25 +52,25 @@ RefImageDisplay::~RefImageDisplay() * show those as graphs in the horizontal and vertical graphs and show * information about the specified point. * - * @param point The point that the user is currently pointing at with + * @param point The point that the user is currently pointing at with * the mouse. * @param mouseClick Which mouse button was clicked * @return A pair containing the (x,y) values in the graph of the point */ -QPair RefImageDisplay::SetPointedAtPoint( QPoint point, int mouseClick) +QPair RefImageDisplay::setPointedAtPoint( QPoint point, int mouseClick) { // Call the base class method for most of the work - QPair xy = SpectrumDisplay::SetPointedAtPoint( point, mouseClick ); + QPair xy = SpectrumDisplay::setPointedAtPoint( point, mouseClick ); // Now, for a left click, set the position in the appropriate lineedit if (mouseClick == 1) //left click { m_limitsHandler->setActiveValue( xy.first, xy.second ); - UpdateImage(); //force refresh of the plot + updateImage(); //force refresh of the plot } - + return xy; } } // namespace RefDetectorViewer -} // namespace MantidQt +} // namespace MantidQt diff --git a/Code/Mantid/MantidQt/RefDetectorViewer/src/RefImagePlotItem.cpp b/Code/Mantid/MantidQt/RefDetectorViewer/src/RefImagePlotItem.cpp index b4696bee11cf..a3ed6ee58c26 100644 --- a/Code/Mantid/MantidQt/RefDetectorViewer/src/RefImagePlotItem.cpp +++ b/Code/Mantid/MantidQt/RefDetectorViewer/src/RefImagePlotItem.cpp @@ -4,12 +4,13 @@ namespace MantidQt { namespace RefDetectorViewer { - + RefImagePlotItem::RefImagePlotItem(const RefLimitsHandler * const limitsHandler) : SpectrumView::SpectrumPlotItem(), m_limitsHandler(limitsHandler) { } + RefImagePlotItem::~RefImagePlotItem() { delete m_limitsHandler; @@ -25,35 +26,31 @@ RefImagePlotItem::~RefImagePlotItem() * columns in the actual displayed image * @param yMap The QwtScaleMap used by QWT to map y-values to pixel * rows in the actual displayed image - * @param canvasRect rectangle containing the pixel region where QWT will + * @param canvasRect rectangle containing the pixel region where QWT will * draw the image. This rectangle is slightly larger * than the actual rectangle used for the image. This * parameter is NOT USED by the SpectrumPlotItem, but is - * passed in when QWT calls this method. + * passed in when QWT calls this method. */ -void RefImagePlotItem::draw( QPainter * painter, - const QwtScaleMap & xMap, - const QwtScaleMap & yMap, - const QRect & canvasRect) const +void RefImagePlotItem::draw( QPainter * painter, + const QwtScaleMap & xMap, + const QwtScaleMap & yMap, + const QRect & canvasRect) const { SpectrumPlotItem::draw(painter,xMap,yMap,canvasRect); ////////////////////////////////////////////////////////////////////////////////// // TODO: Eliminate the code duplication (from SpectrumPlotItem::draw) in this section - SpectrumView::DataArray* data_array; - if ( buffer_ID == 0 ) - { - data_array = data_array_0; - } + SpectrumView::DataArray_const_sptr data_array; + if ( m_bufferID == 0 ) + data_array = m_dataArray0; else - { - data_array = data_array_1; - } + data_array = m_dataArray1; - const double x_min = data_array->GetXMin(); - const double x_max = data_array->GetXMax(); - const double y_min = data_array->GetYMin(); - const double y_max = data_array->GetYMax(); + const double x_min = data_array->getXMin(); + const double x_max = data_array->getXMax(); + const double y_min = data_array->getYMin(); + const double y_max = data_array->getYMax(); // find the actual plot region // using the scale maps. @@ -129,8 +126,7 @@ void RefImagePlotItem::draw( QPainter * painter, tof_value = int(coeff_left * coeff_bottom_right + float(pix_x_min)); painter->drawLine(QPoint(tof_value,pix_y_min), QPoint(tof_value,pix_y_max)); } - } } // namespace RefDetectorViewer -} // namespace MantidQt +} // namespace MantidQt diff --git a/Code/Mantid/MantidQt/RefDetectorViewer/src/RefImageView.cpp b/Code/Mantid/MantidQt/RefDetectorViewer/src/RefImageView.cpp index b6a59ffcd799..d5385cb4dfab 100644 --- a/Code/Mantid/MantidQt/RefDetectorViewer/src/RefImageView.cpp +++ b/Code/Mantid/MantidQt/RefDetectorViewer/src/RefImageView.cpp @@ -16,7 +16,6 @@ namespace MantidQt namespace RefDetectorViewer { - /** * Construct an SpectrumView to display data from the specified data source. * The specified SpectrumDataSource must be constructed elsewhere and passed @@ -25,111 +24,90 @@ namespace RefDetectorViewer * parts of the SpectrumView are constructed here and are deleted when the * SpectrumView destructor is called. * - * @param data_source The source of the data that will be displayed. - * @param peak_min The min peak value - * @param peak_max The max peak value - * @param back_min The min background value - * @param back_max The max background value - * @param tof_min The min time of flight value - * @param tof_max The max time of flight value + * @param dataSource The source of the data that will be displayed. + * @param peakMin The min peak value + * @param peakMax The max peak value + * @param backMin The min background value + * @param backMax The max background value + * @param tofMin The min time of flight value + * @param tofMax The max time of flight value */ -RefImageView::RefImageView( SpectrumView::SpectrumDataSource* data_source, int peak_min, int peak_max, int back_min, int back_max, int tof_min, int tof_max) +RefImageView::RefImageView( SpectrumView::SpectrumDataSource_sptr dataSource, + int peakMin, int peakMax, + int backMin, int backMax, + int tofMin, int tofMax) + : m_ui(new Ui::RefImageViewer()) { - Ui_RefImageViewer* ui = new Ui_RefImageViewer(); - saved_ui = ui; - QMainWindow* window = this; - ui->setupUi( window ); + m_ui->setupUi( window ); window->resize( 1050, 800 ); window->show(); window->setAttribute(Qt::WA_DeleteOnClose); // We just need to close the - // window to trigger the + // window to trigger the // destructor and clean up window->setWindowTitle(QString::fromUtf8("Reflector Detector Viewer")); - RefSliderHandler* slider_handler = new RefSliderHandler( ui ); - saved_slider_handler = slider_handler; - - RefRangeHandler* range_handler = new RefRangeHandler( ui ); - saved_range_handler = range_handler; + m_sliderHandler = new RefSliderHandler( m_ui ); + m_rangeHandler = new RefRangeHandler( m_ui ); // Create the handler for comminicating peak/background/tof values to/from the ui // This ends up being owned by the RefImagePlotItem instance - RefLimitsHandler* limits_handler = new RefLimitsHandler(ui); + RefLimitsHandler* limits_handler = new RefLimitsHandler(m_ui); - h_graph = new SpectrumView::GraphDisplay( ui->h_graphPlot, NULL, false ); - v_graph = new SpectrumView::GraphDisplay( ui->v_graphPlot, NULL, true ); + m_hGraph = new SpectrumView::GraphDisplay( m_ui->h_graphPlot, NULL, false ); + m_vGraph = new SpectrumView::GraphDisplay( m_ui->v_graphPlot, NULL, true ); + m_imageDisplay = new RefImageDisplay( m_ui->imagePlot, + m_sliderHandler, + m_rangeHandler, + limits_handler, + m_hGraph, m_vGraph, + m_ui->image_table); - RefImageDisplay* image_display = new RefImageDisplay( ui->imagePlot, - slider_handler, - range_handler, - limits_handler, - h_graph, v_graph, - ui->image_table); - saved_image_display = image_display; + RefIVConnections * iv_connections = new RefIVConnections( m_ui, this, + m_imageDisplay, + m_hGraph, m_vGraph ); - RefIVConnections * iv_connections = new RefIVConnections( ui, this, - image_display, - h_graph, v_graph ); - // Set validators on the QLineEdits to restrict them to integers - ui->lineEdit_peakLeft->setValidator(new QIntValidator(this)); - ui->lineEdit_peakRight->setValidator(new QIntValidator(this)); - ui->lineEdit_backLeft->setValidator(new QIntValidator(this)); - ui->lineEdit_backRight->setValidator(new QIntValidator(this)); - ui->lineEdit_TOFmin->setValidator(new QIntValidator(this)); - ui->lineEdit_TOFmax->setValidator(new QIntValidator(this)); + m_ui->lineEdit_peakLeft->setValidator(new QIntValidator(this)); + m_ui->lineEdit_peakRight->setValidator(new QIntValidator(this)); + m_ui->lineEdit_backLeft->setValidator(new QIntValidator(this)); + m_ui->lineEdit_backRight->setValidator(new QIntValidator(this)); + m_ui->lineEdit_TOFmin->setValidator(new QIntValidator(this)); + m_ui->lineEdit_TOFmax->setValidator(new QIntValidator(this)); //populate widgets with peak, back and tof values - limits_handler->setPeakLeft(peak_min); - limits_handler->setPeakRight(peak_max); - limits_handler->setBackLeft(back_min); - limits_handler->setBackRight(back_max); - limits_handler->setTOFmin(tof_min); - limits_handler->setTOFmax(tof_max); - - saved_iv_connections = iv_connections; - - image_display->UpdateImage(); - iv_connections->peak_back_tof_range_update(); - - - image_display->SetDataSource( data_source ); -} - - RefIVConnections* RefImageView::getIVConnections() - { - return saved_iv_connections; - } + limits_handler->setPeakLeft(peakMin); + limits_handler->setPeakRight(peakMax); + limits_handler->setBackLeft(backMin); + limits_handler->setBackRight(backMax); + limits_handler->setTOFmin(tofMin); + limits_handler->setTOFmax(tofMax); -RefImageView::~RefImageView() -{ -// std::cout << "RefImageView destructor called" << std::endl; + m_ivConnections = iv_connections; - delete h_graph; - delete v_graph; + m_imageDisplay->updateImage(); + iv_connections->peakBackTofRangeUpdate(); - RefImageDisplay* image_display = static_cast(saved_image_display); - delete image_display; + m_imageDisplay->setDataSource( dataSource ); +} - RefSliderHandler* slider_handler = - static_cast(saved_slider_handler); - delete slider_handler; - RefRangeHandler* range_handler = - static_cast(saved_range_handler); - delete range_handler; +RefImageView::~RefImageView() +{ + delete m_imageDisplay; + delete m_sliderHandler; + delete m_rangeHandler; + delete m_ivConnections; + delete m_ui; +} - RefIVConnections* iv_connections = - static_cast(saved_iv_connections); - delete iv_connections; - Ui_RefImageViewer* ui = static_cast(saved_ui); - delete ui; +RefIVConnections* RefImageView::getIVConnections() +{ + return m_ivConnections; } - } // namespace RefDetectorViewer -} // namespace MantidQt +} // namespace MantidQt diff --git a/Code/Mantid/MantidQt/RefDetectorViewer/src/RefLimitsHandler.cpp b/Code/Mantid/MantidQt/RefDetectorViewer/src/RefLimitsHandler.cpp index b21e02ae7dc8..10b634068667 100644 --- a/Code/Mantid/MantidQt/RefDetectorViewer/src/RefLimitsHandler.cpp +++ b/Code/Mantid/MantidQt/RefDetectorViewer/src/RefLimitsHandler.cpp @@ -5,7 +5,7 @@ namespace MantidQt namespace RefDetectorViewer { -RefLimitsHandler::RefLimitsHandler( Ui_RefImageViewer* iv_ui ) : m_ui(iv_ui) +RefLimitsHandler::RefLimitsHandler( Ui_RefImageViewer* ivUI ) : m_ui(ivUI) { } diff --git a/Code/Mantid/MantidQt/RefDetectorViewer/src/RefMatrixWSImageView.cpp b/Code/Mantid/MantidQt/RefDetectorViewer/src/RefMatrixWSImageView.cpp index 558a8d6fab87..9fd85f6ace04 100644 --- a/Code/Mantid/MantidQt/RefDetectorViewer/src/RefMatrixWSImageView.cpp +++ b/Code/Mantid/MantidQt/RefDetectorViewer/src/RefMatrixWSImageView.cpp @@ -20,72 +20,60 @@ using namespace Mantid::API; */ RefMatrixWSImageView::RefMatrixWSImageView( MatrixWorkspace_sptr /*mat_ws*/ ) { - return; - // RefMatrixWSDataSource* source = new RefMatrixWSDataSource( mat_ws ); + return; + // RefMatrixWSDataSource* source = new RefMatrixWSDataSource( mat_ws ); // image_view = new RefImageView( source ); // this is the QMainWindow // // for the viewer. It is // // deleted when the window // // is closed } -RefMatrixWSImageView::RefMatrixWSImageView( QString wps_name, int peak_min, int peak_max, int back_min, int back_max, int tof_min, int tof_max) +RefMatrixWSImageView::RefMatrixWSImageView( QString wpsName, + int peakMin, int peakMax, + int backMin, int backMax, + int tofMin, int tofMax) { + IEventWorkspace_sptr ws; + ws = AnalysisDataService::Instance().retrieveWS(wpsName.toStdString()); - IEventWorkspace_sptr ws; - ws = AnalysisDataService::Instance().retrieveWS(wps_name.toStdString()); + const double totalYMin = 0.0; + const double totalYMax = 255.0; //303 + const size_t totalRows = 256; //304 - const double total_ymin = 0.0; - const double total_ymax = 255.0; - const size_t total_rows = 256; -// const double total_ymax = 303; -// const size_t total_rows = 304; - - - std::vector xaxis = ws->readX(0); - const size_t sz = xaxis.size()-1; - const size_t total_cols = sz; - - double total_xmin = xaxis[0]; - double total_xmax = xaxis[sz]; - - float *data = new float[static_cast(total_ymax) * sz]; - -// std::cout << "Starting the for loop " << std::endl; -// std::cout << "total_xmax: " << total_xmax << std::endl; -// std::cout << "sz is : " << sz << std::endl; - - std::vector yaxis; - for (size_t px=0; pxreadY(px); - for (size_t tof=0; tof(yaxis[tof]); - } - } - - SpectrumView::ArrayDataSource* source = new SpectrumView::ArrayDataSource(total_xmin, total_xmax, - total_ymin, total_ymax, - total_rows, total_cols, - data); - -// std::cout << "ws->readX(0).size(): " << ws->readX(0).size() << std::endl; + std::vector xAxis = ws->readX(0); + const size_t sz = xAxis.size() - 1; + const size_t totalCols = sz; - - - image_view = new RefImageView( source, - peak_min, peak_max, - back_min, back_max, - tof_min, tof_max); + double totalXMin = xAxis[0]; + double totalXMax = xAxis[sz]; + std::vector data(static_cast(totalYMax) * sz); + + std::vector yAxis; + for (size_t px = 0; px < totalYMax; px++) + { + // Retrieve data now + yAxis = ws->readY(px); + for (size_t tof = 0; tof < sz; tof++) + data[px * sz + tof] = static_cast(yAxis[tof]); + } + + SpectrumView::ArrayDataSource_sptr source = + SpectrumView::ArrayDataSource_sptr( new SpectrumView::ArrayDataSource(totalXMin, totalXMax, + totalYMin, totalYMax, + totalRows, totalCols, + data) ); + + m_imageView = new RefImageView( source, + peakMin, peakMax, + backMin, backMax, + tofMin, tofMax); } RefIVConnections* RefMatrixWSImageView::getConnections() { - return image_view->getIVConnections(); - + return m_imageView->getIVConnections(); } @@ -93,4 +81,3 @@ RefMatrixWSImageView::~RefMatrixWSImageView() { // nothing to do here, since image_view is deleted when the window closes } - diff --git a/Code/Mantid/MantidQt/RefDetectorViewer/src/RefRangeHandler.cpp b/Code/Mantid/MantidQt/RefDetectorViewer/src/RefRangeHandler.cpp index b0aaee783531..ec36c81c7b99 100644 --- a/Code/Mantid/MantidQt/RefDetectorViewer/src/RefRangeHandler.cpp +++ b/Code/Mantid/MantidQt/RefDetectorViewer/src/RefRangeHandler.cpp @@ -1,65 +1,62 @@ - #include #include #include "MantidQtRefDetectorViewer/RefRangeHandler.h" #include "MantidQtSpectrumViewer/QtUtils.h" #include "MantidQtSpectrumViewer/SVUtils.h" -#include "MantidQtSpectrumViewer/ErrorHandler.h" +#include "MantidKernel/Logger.h" + + +namespace +{ + Mantid::Kernel::Logger g_log("SpectrumView"); +} + namespace MantidQt { namespace RefDetectorViewer { - using namespace SpectrumView; + +using namespace SpectrumView; /** * Construct a RefRangeHandler object to manage min, max and step controls * in the specified UI */ -RefRangeHandler::RefRangeHandler( Ui_RefImageViewer* iv_ui ) +RefRangeHandler::RefRangeHandler( Ui_RefImageViewer* ivUI ) : m_ivUI(ivUI) { - this->iv_ui = iv_ui; } /** * Configure the min, max and step controls for the specified data source. * - * @param data_source SpectrumDataSource that provides the data to be drawn + * @param dataSource SpectrumDataSource that provides the data to be drawn */ -void RefRangeHandler::ConfigureRangeControls( SpectrumDataSource* data_source ) +void RefRangeHandler::configureRangeControls( SpectrumDataSource_sptr dataSource ) { - - //x axis - total_min_x = data_source->GetXMin(); - total_max_x = data_source->GetXMax(); - total_n_steps = data_source->GetNCols(); - total_min_y = data_source->GetYMin(); - total_max_y = data_source->GetYMax(); - - double defaultx_step = (total_max_x - total_min_x)/(double)total_n_steps; - if ( total_n_steps > 2000 ) - { - defaultx_step = (total_max_x - total_min_x)/2000.0; - } + // X axis + m_totalMinX = dataSource->getXMin(); + m_totalMaxX = dataSource->getXMax(); + m_totalNSteps = dataSource->getNCols(); - SetRange( total_min_x, total_max_x, defaultx_step, 'x'); + double defaultStepX = (m_totalMaxX - m_totalMinX) / (double)m_totalNSteps; + if(m_totalNSteps > 2000) + defaultStepX = (m_totalMaxX - m_totalMinX) / 2000.0; - //y axis - total_min_y = data_source->GetYMin(); - total_max_y = data_source->GetYMax(); - total_n_steps = data_source->GetNCols(); - - double defaulty_step = (total_max_y - total_min_y)/(double)total_n_steps; - if ( total_n_steps > 2000 ) - { - defaulty_step = (total_max_y - total_min_y)/2000.0; - } - - SetRange( total_min_y, total_max_y, defaulty_step, 'y' ); + setRange(m_totalMinX, m_totalMaxX, defaultStepX, 'x'); + + // Y axis + m_totalMinY = dataSource->getYMin(); + m_totalMaxY = dataSource->getYMax(); + m_totalNSteps = dataSource->getNCols(); + double defaultStepY = (m_totalMaxY - m_totalMinY) / (double)m_totalNSteps; + if(m_totalNSteps > 2000) + defaultStepY = (m_totalMaxY - m_totalMinY) / 2000.0; + setRange(m_totalMinY, m_totalMaxY, defaultStepY, 'y' ); } @@ -71,7 +68,7 @@ void RefRangeHandler::ConfigureRangeControls( SpectrumDataSource* data_source ) * * @param min On input, this should be the default value that the * min should be set to, if getting the range fails. - * On output this is will be set to the x value at the + * On output this is will be set to the x value at the * left edge of the first bin to display, if getting the * range succeeds. * @param max On input, this should be the default value that the @@ -79,152 +76,142 @@ void RefRangeHandler::ConfigureRangeControls( SpectrumDataSource* data_source ) * On output, if getting the range succeeds, this will * be set an x value at the right edge of the last bin * to display. This will be adjusted so that it is larger - * than min by an integer number of steps. + * than min by an integer number of steps. * @param step On input this should be the default number of steps * to use if getting the range information fails. * On output, this is size of the step to use between - * min and max. If it is less than zero, a log scale + * min and max. If it is less than zero, a log scale * is requested. */ -void RefRangeHandler::GetRange( double &min, double &max, double &step ) -{ - double original_min = min; - double original_max = max; - double original_step = step; +void RefRangeHandler::getRange( double &min, double &max, double &step ) +{ + double originalMin = min; + double originalMax = max; + double originalStep = step; - QLineEdit* min_control = iv_ui->x_min_input; - QLineEdit* max_control = iv_ui->x_max_input; -// QLineEdit* step_control = iv_ui->step_input; + QLineEdit* min_control = m_ivUI->x_min_input; + QLineEdit* max_control = m_ivUI->x_max_input; - if ( !SVUtils::StringToDouble( min_control->text().toStdString(), min ) ) + bool minIsNumber = false; + bool maxIsNumber = false; + + min = min_control->text().toDouble(&minIsNumber); + max = max_control->text().toDouble(&maxIsNumber); + + if(!minIsNumber) { - ErrorHandler::Error("X Min is not a NUMBER! Value reset."); - min = original_min; + g_log.information("X Min is not a NUMBER! Value reset."); + min = originalMin; } - if ( !SVUtils::StringToDouble( max_control->text().toStdString(), max ) ) + + if(!maxIsNumber) { - ErrorHandler::Error("X Max is not a NUMBER! Value reset."); - max = original_max; + g_log.information("X Max is not a NUMBER! Value reset."); + max = originalMax; } -// if ( !SVUtils::StringToDouble( step_control->text().toStdString(), step ) ) -// { -// ErrorHandler::Error("Step is not a NUMBER! Value reset."); -// step = original_step; -// } - - // just require step to be non-zero, no other - // bounds. If zero, take a default step size - if ( step == 0 ) + + // Just require step to be non-zero, no other bounds. If zero, take a default step size + if ( step == 0 ) { - ErrorHandler::Error("Step = 0, resetting to default step"); - step = original_step; + g_log.information("Step = 0, resetting to default step"); + step = originalStep; } if ( step > 0 ) { if ( !SVUtils::FindValidInterval( min, max ) ) { - ErrorHandler::Warning( - "In GetRange: [Min,Max] interval invalid, values adjusted" ); - min = original_min; - max = original_max; - step = original_step; + g_log.information("In GetRange: [Min,Max] interval invalid, values adjusted"); + min = originalMin; + max = originalMax; + step = originalStep; } } else { if ( !SVUtils::FindValidLogInterval( min, max ) ) { - ErrorHandler::Warning( - "In GetRange: [Min,Max] log interval invalid, values adjusted"); - min = original_min; - max = original_max; - step = original_step; + g_log.information("In GetRange: [Min,Max] log interval invalid, values adjusted"); + min = originalMin; + max = originalMax; + step = originalStep; } } - SetRange( min, max, step, 'x' ); + setRange( min, max, step, 'x' ); } /** - * Adjust the values to be consistent with the available data and + * Adjust the values to be consistent with the available data and * diplay them in the controls. * * @param min This is the x value at the left edge of the first bin. * @param max This is an x value at the right edge of the last bin. - * @param step This is size of the step to use between min and max. + * @param step This is size of the step to use between min and max. * If it is less than zero, a log scale is requested. * @param type x or y */ -void RefRangeHandler::SetRange( double min, double max, double step, char type ) +void RefRangeHandler::setRange( double min, double max, double step, char type ) { - if (type == 'x') { - - if ( !SVUtils::FindValidInterval( min, max ) ) - { - ErrorHandler::Warning( - "In SetRange: [XMin,XMax] interval invalid, values adjusted" ); - } + if (type == 'x') { - if ( min < total_min_x || min > total_max_x ) - { -// ErrorHandler::Warning("X Min out of range, resetting to range min."); - min = total_min_x; - } + if ( !SVUtils::FindValidInterval( min, max ) ) + g_log.information("In setRange: [XMin,XMax] interval invalid, values adjusted"); - if ( max < total_min_x || max > total_max_x ) - { -// ErrorHandler::Warning("X Max out of range, resetting to range max."); - max = total_max_x; - } + if ( min < m_totalMinX || min > m_totalMaxX ) + { + g_log.information("X Min out of range, resetting to range min."); + min = m_totalMinX; + } + + if ( max < m_totalMinX || max > m_totalMaxX ) + { + g_log.information("X Max out of range, resetting to range max."); + max = m_totalMaxX; + } + + if ( step == 0 ) + { + g_log.information("Step = 0, resetting to default step"); + step = (max-min)/2000.0; + } + + QtUtils::SetText( 8, 2, min, m_ivUI->x_min_input ); + QtUtils::SetText( 8, 2, max, m_ivUI->x_max_input ); + // QtUtils::SetText( 8, 4, step, m_ivUI->step_input ); - if ( step == 0 ) - { - ErrorHandler::Error("Step = 0, resetting to default step"); - step = (max-min)/2000.0; } - QtUtils::SetText( 8, 2, min, iv_ui->x_min_input ); - QtUtils::SetText( 8, 2, max, iv_ui->x_max_input ); -// QtUtils::SetText( 8, 4, step, iv_ui->step_input ); - - } - - if (type == 'y') { - - if ( !SVUtils::FindValidInterval( min, max ) ) - { - ErrorHandler::Warning( - "In SetRange: [YMin,YMax] interval invalid, values adjusted" ); - } - - if ( min < total_min_y || min > total_max_y ) - { - // ErrorHandler::Warning("Y Min out of range, resetting to range min."); - min = total_min_y; - } - - if ( max < total_min_y || max > total_max_y ) - { - // ErrorHandler::Warning("Y Max out of range, resetting to range max."); - max = total_max_y; - } - - if ( step == 0 ) - { - ErrorHandler::Error("Step = 0, resetting to default step"); - step = (max-min)/2000.0; - } - - QtUtils::SetText( 8, 2, min, iv_ui->y_min_input ); - QtUtils::SetText( 8, 2, max, iv_ui->y_max_input ); - // QtUtils::SetText( 8, 4, step, iv_ui->step_input ); - - } - + if (type == 'y') { + + if ( !SVUtils::FindValidInterval( min, max ) ) + g_log.information("In setRange: [YMin,YMax] interval invalid, values adjusted"); + + if ( min < m_totalMinY || min > m_totalMaxY ) + { + g_log.information("Y Min out of range, resetting to range min."); + min = m_totalMinY; + } + + if ( max < m_totalMinY || max > m_totalMaxY ) + { + g_log.information("Y Max out of range, resetting to range max."); + max = m_totalMaxY; + } + + if ( step == 0 ) + { + g_log.information("Step = 0, resetting to default step"); + step = (max-min)/2000.0; + } + + QtUtils::SetText( 8, 2, min, m_ivUI->y_min_input ); + QtUtils::SetText( 8, 2, max, m_ivUI->y_max_input ); + // QtUtils::SetText( 8, 4, step, m_ivUI->step_input ); + } } } // namespace RefDetectorViewer -} // namespace MantidQt +} // namespace MantidQt diff --git a/Code/Mantid/MantidQt/RefDetectorViewer/src/RefSliderHandler.cpp b/Code/Mantid/MantidQt/RefDetectorViewer/src/RefSliderHandler.cpp index 60bf13210049..2fc6a2faef46 100644 --- a/Code/Mantid/MantidQt/RefDetectorViewer/src/RefSliderHandler.cpp +++ b/Code/Mantid/MantidQt/RefDetectorViewer/src/RefSliderHandler.cpp @@ -13,157 +13,147 @@ namespace RefDetectorViewer * Construct a RefSliderHandler object to manage the image scrollbars from the * specified UI. */ -RefSliderHandler::RefSliderHandler( Ui_RefImageViewer* iv_ui ) +RefSliderHandler::RefSliderHandler( Ui_RefImageViewer* ivUI ) : m_ivUI(ivUI) { - this->iv_ui = iv_ui; } /** * Configure the image scrollbars for the specified data and drawing area. * - * @param draw_area Rectangle specifiying the region where the image will - * be drawn - * @param data_source SpectrumDataSource that provides the data to be drawn + * @param drawArea Rectangle specifiying the region where the image will + * be drawn + * @param dataSource SpectrumDataSource that provides the data to be drawn */ -void RefSliderHandler::ConfigureSliders( QRect draw_area, - SpectrumView::SpectrumDataSource* data_source ) +void RefSliderHandler::configureSliders( QRect drawArea, + SpectrumView::SpectrumDataSource_sptr dataSource ) { - QScrollBar* v_scroll = iv_ui->imageVerticalScrollBar; - int n_rows = (int)data_source->GetNRows(); - ConfigureSlider( v_scroll, n_rows, draw_area.height(), n_rows ); + QScrollBar* v_scroll = m_ivUI->imageVerticalScrollBar; + int n_rows = (int)dataSource->getNRows(); + configureSlider( v_scroll, n_rows, drawArea.height(), n_rows ); - ConfigureHSlider( 2000, draw_area.width() ); // initial default, 2000 bins + configureHSlider( 2000, drawArea.width() ); // initial default, 2000 bins } /** - * Public method to configure the horizontal scrollbar to cover the + * Public method to configure the horizontal scrollbar to cover the * specified range of data columns, displayed in the specified number of - * pixels. + * pixels. * - * @param n_data_steps The number of columns in the data that should be - * displayed - * @param n_pixels The number of pixels avaliable to show the data + * @param nDataSteps The number of columns in the data that should be + * displayed + * @param nPixels The number of pixels avaliable to show the data */ -void RefSliderHandler::ConfigureHSlider( int n_data_steps, - int n_pixels ) +void RefSliderHandler::configureHSlider( int nDataSteps, + int nPixels ) { - QScrollBar* h_scroll = iv_ui->imageHorizontalScrollBar; - ConfigureSlider( h_scroll, n_data_steps, n_pixels, 0 ); + QScrollBar* h_scroll = m_ivUI->imageHorizontalScrollBar; + configureSlider( h_scroll, nDataSteps, nPixels, 0 ); } /** * Configure the specified scrollbar to cover the specified range of data - * steps, displayed in the specified number of pixels. + * steps, displayed in the specified number of pixels. * - * @param scroll_bar The scroll bar that will be configured - * @param n_data_steps The number of bins in the data that should be - * displayed - * @param n_pixels The number of pixels avaliable to show the data - * @param val The initial position of the scrollbar, between 0 and - * n_data_steps. + * @param scrollBar The scroll bar that will be configured + * @param nDataSteps The number of bins in the data that should be + * displayed + * @param nPixels The number of pixels avaliable to show the data + * @param val The initial position of the scrollbar, between 0 and + * nDataSteps. */ -void RefSliderHandler::ConfigureSlider( QScrollBar* scroll_bar, - int n_data_steps, - int n_pixels, - int val ) +void RefSliderHandler::configureSlider( QScrollBar* scrollBar, + int nDataSteps, + int nPixels, + int val ) { - int step = n_pixels; - if ( step > n_data_steps ) - { - step = n_data_steps; - } + int step = nPixels; + if ( step > nDataSteps ) + step = nDataSteps; + if ( step <= 0 ) - { step = 1; - } - int max = n_data_steps - step; + int max = nDataSteps - step; if ( max <= 0 ) - { max = 0; - } if ( val < 0 ) - { val = 0; - } if ( val > max ) - { val = max; - } - scroll_bar->setMinimum( 0 ); - scroll_bar->setMaximum( max ); - scroll_bar->setPageStep( step ); - scroll_bar->setValue( val ); + scrollBar->setMinimum( 0 ); + scrollBar->setMaximum( max ); + scrollBar->setPageStep( step ); + scrollBar->setValue( val ); } /** * Return true if the image horizontal scrollbar is enabled. */ -bool RefSliderHandler::HSliderOn() +bool RefSliderHandler::hSliderOn() { - return iv_ui->imageHorizontalScrollBar->isEnabled(); + return m_ivUI->imageHorizontalScrollBar->isEnabled(); } /** * Return true if the image vertical scrollbar is enabled. */ -bool RefSliderHandler::VSliderOn() +bool RefSliderHandler::vSliderOn() { - return iv_ui->imageVerticalScrollBar->isEnabled(); + return m_ivUI->imageVerticalScrollBar->isEnabled(); } /** - * Get the range of columns to display in the image. NOTE: x_min will be + * Get the range of columns to display in the image. NOTE: xMin will be * the smaller column number in the array, corresponding to lower values on * the calibrated x-scale. * - * @param x_min This will be set to the first bin number to display in the + * @param xMin This will be set to the first bin number to display in the * x direction. - * @param x_max This will be set to the last bin number to display in the + * @param xMax This will be set to the last bin number to display in the * x direction */ -void RefSliderHandler::GetHSliderInterval( int &x_min, int &x_max ) +void RefSliderHandler::getHSliderInterval( int &xMin, int &xMax ) { - QScrollBar* h_scroll = iv_ui->imageHorizontalScrollBar; + QScrollBar* h_scroll = m_ivUI->imageHorizontalScrollBar; int step = h_scroll->pageStep(); int value = h_scroll->value(); - x_min = value; - x_max = x_min + step; + xMin = value; + xMax = xMin + step; } /** - * Get the range of rows to display in the image. NOTE: y_min will be + * Get the range of rows to display in the image. NOTE: yMin will be * the smaller row number in the array, corresponding to lower values on * the calibrated y-scale. * - * @param y_min This will be set to the first bin number to display in the + * @param yMin This will be set to the first bin number to display in the * y direction. - * @param y_max This will be set to the last bin number to display in the + * @param yMax This will be set to the last bin number to display in the * y direction */ -void RefSliderHandler::GetVSliderInterval( int &y_min, int &y_max ) +void RefSliderHandler::getVSliderInterval( int &yMin, int &yMax ) { - QScrollBar* v_scroll = iv_ui->imageVerticalScrollBar; + QScrollBar* v_scroll = m_ivUI->imageVerticalScrollBar; int max = v_scroll->maximum(); int step = v_scroll->pageStep(); int value = v_scroll->value(); - - y_min = max - value; // invert value since scale increases from - y_max = y_min + step; // bottom to top, but scroll bar increases + + yMin = max - value; // invert value since scale increases from + yMax = yMin + step; // bottom to top, but scroll bar increases // the other way. } } // namespace RefDetectorViewer -} // namespace MantidQt +} // namespace MantidQt diff --git a/Code/Mantid/MantidQt/SliceViewer/src/LineViewer.cpp b/Code/Mantid/MantidQt/SliceViewer/src/LineViewer.cpp index afb51d9a38a7..ee376586af0c 100644 --- a/Code/Mantid/MantidQt/SliceViewer/src/LineViewer.cpp +++ b/Code/Mantid/MantidQt/SliceViewer/src/LineViewer.cpp @@ -301,7 +301,8 @@ IAlgorithm_sptr LineViewer::applyMatrixWorkspace(Mantid::API::MatrixWorkspace_sp if (getPlanarWidth() <= 0) throw std::runtime_error("Planar Width must be > 0"); - IAlgorithm_sptr alg = AlgorithmManager::Instance().create("Rebin2D"); + IAlgorithm_sptr alg = AlgorithmManager::Instance().createUnmanaged("Rebin2D"); + alg->initialize(); alg->setProperty("InputWorkspace", ws); alg->setPropertyValue("OutputWorkspace", m_integratedWSName); if(ws->id() == "RebinnedOutput") diff --git a/Code/Mantid/MantidQt/SpectrumViewer/CMakeLists.txt b/Code/Mantid/MantidQt/SpectrumViewer/CMakeLists.txt index 125ef94307c6..5f26803546b3 100644 --- a/Code/Mantid/MantidQt/SpectrumViewer/CMakeLists.txt +++ b/Code/Mantid/MantidQt/SpectrumViewer/CMakeLists.txt @@ -1,22 +1,21 @@ set ( SRC_FILES - src/ColorMaps.cpp - src/SpectrumDisplay.cpp - src/SVUtils.cpp + src/ColorMaps.cpp + src/SpectrumDisplay.cpp + src/SVUtils.cpp src/TrackingPicker.cpp - src/DataArray.cpp - src/SpectrumPlotItem.cpp + src/DataArray.cpp + src/SpectrumPlotItem.cpp src/QtUtils.cpp - src/GraphDisplay.cpp - src/SpectrumView.cpp + src/GraphDisplay.cpp + src/SpectrumView.cpp src/SliderHandler.cpp src/RangeHandler.cpp src/EModeHandler.cpp - src/SpectrumDataSource.cpp - src/SVConnections.cpp + src/SpectrumDataSource.cpp + src/SVConnections.cpp src/MatrixWSDataSource.cpp src/MatrixWSSpectrumView.cpp src/ArrayDataSource.cpp - src/ErrorHandler.cpp ) # Include files aren't required, but this makes them appear in Visual Studio @@ -40,21 +39,20 @@ set ( INC_FILES inc/MantidQtSpectrumViewer/MatrixWSDataSource.h inc/MantidQtSpectrumViewer/MatrixWSSpectrumView.h inc/MantidQtSpectrumViewer/ArrayDataSource.h - inc/MantidQtSpectrumViewer/ErrorHandler.h ) -set ( MOC_FILES +set ( MOC_FILES inc/MantidQtSpectrumViewer/SpectrumView.h inc/MantidQtSpectrumViewer/SVConnections.h inc/MantidQtSpectrumViewer/TrackingPicker.h ) -set ( UI_FILES +set ( UI_FILES inc/MantidQtSpectrumViewer/SpectrumView.ui ) # Python unit tests -set ( TEST_PY_FILES +set ( TEST_PY_FILES ) include_directories ( inc ) @@ -70,7 +68,7 @@ qt4_wrap_cpp ( MOCCED_FILES ${MOC_FILES} ) set ( ALL_SRC ${SRC_FILES} ${MOCCED_FILES} ) -qt4_wrap_ui ( UI_HDRS ${UI_FILES} ) +qt4_wrap_ui ( UI_HDRS ${UI_FILES} ) include_directories ( ${CMAKE_CURRENT_BINARY_DIR} ) @@ -84,22 +82,6 @@ add_library ( MantidQtSpectrumViewer ${ALL_SRC} ${INC_FILES} ${UI_HDRS} ) target_link_libraries ( MantidQtSpectrumViewer MantidQtAPI MantidWidgets ${CORE_MANTIDLIBS} ${QT_LIBRARIES} ${QWT_LIBRARIES} ) -########################################################################### -# DEMO/GUI TESTING APPLICATIONS -########################################################################### - -if ( NOT WIN32 ) -add_executable ( SpectrumViewDemo EXCLUDE_FROM_ALL src/SpectrumViewDemo.cpp ) -target_link_libraries ( SpectrumViewDemo MantidQtSpectrumViewer ) - -add_executable ( SpectrumViewNxEventFile EXCLUDE_FROM_ALL src/SpectrumViewNxEventFile.cpp ) -target_link_libraries ( SpectrumViewNxEventFile MantidQtSpectrumViewer ) -endif () - -########################################################################### -# Unit tests setup -########################################################################### - ########################################################################### # Installation settings diff --git a/Code/Mantid/MantidQt/SpectrumViewer/inc/MantidQtSpectrumViewer/ArrayDataSource.h b/Code/Mantid/MantidQt/SpectrumViewer/inc/MantidQtSpectrumViewer/ArrayDataSource.h index 8c4d915b7308..62b9b418c654 100644 --- a/Code/Mantid/MantidQt/SpectrumViewer/inc/MantidQtSpectrumViewer/ArrayDataSource.h +++ b/Code/Mantid/MantidQt/SpectrumViewer/inc/MantidQtSpectrumViewer/ArrayDataSource.h @@ -6,17 +6,17 @@ #include "MantidQtSpectrumViewer/SpectrumDataSource.h" /** - @class ArrayDataSource - + @class ArrayDataSource + This class provides a wrapper around a simple 2-D array of doubles stored in row-major order in a 1-D array, so that the array can be viewed using the SpectrumView data viewer. - - @author Dennis Mikkelson - @date 2012-05-14 - + + @author Dennis Mikkelson + @date 2012-05-14 + Copyright © 2012 ORNL, STFC Rutherford Appleton Laboratories - + This file is part of Mantid. Mantid is free software; you can redistribute it and/or modify @@ -31,8 +31,8 @@ You should have received a copy of the GNU General Public License along with this program. If not, see . - - Code Documentation is available at + + Code Documentation is available at */ @@ -49,7 +49,7 @@ class EXPORT_OPT_MANTIDQT_SPECTRUMVIEWER ArrayDataSource: public SpectrumDataSou ArrayDataSource( double total_xmin, double total_xmax, double total_ymin, double total_ymax, size_t total_rows, size_t total_cols, - float* data ); + std::vector data ); ~ArrayDataSource(); @@ -57,26 +57,31 @@ class EXPORT_OPT_MANTIDQT_SPECTRUMVIEWER ArrayDataSource: public SpectrumDataSou const boost::shared_ptr ws); /// Get DataArray covering full range of data in x, and y directions - DataArray * GetDataArray( bool is_log_x ); + DataArray_const_sptr getDataArray( bool is_log_x ); - /// Get DataArray covering restricted range of data - DataArray * GetDataArray( double xmin, - double xmax, - double ymin, - double ymax, - size_t n_rows, - size_t n_cols, - bool is_log_x ); + /// Get DataArray covering restricted range of data + DataArray_const_sptr getDataArray( double xMin, + double xMax, + double yMin, + double yMax, + size_t nRows, + size_t nCols, + bool isLogX ); /// Get a list containing pairs of strings with information about x,y - void GetInfoList( double x, + void getInfoList( double x, double y, std::vector &list ); + private: - float* data; + std::vector m_data; + }; +typedef boost::shared_ptr ArrayDataSource_sptr; +typedef boost::shared_ptr ArrayDataSource_const_sptr; + } // namespace SpectrumView -} // namespace MantidQt +} // namespace MantidQt #endif // ARRAY_DATA_SOURCE_H diff --git a/Code/Mantid/MantidQt/SpectrumViewer/inc/MantidQtSpectrumViewer/DataArray.h b/Code/Mantid/MantidQt/SpectrumViewer/inc/MantidQtSpectrumViewer/DataArray.h index 1c08949a6e36..f7fe3cdd4bfc 100644 --- a/Code/Mantid/MantidQt/SpectrumViewer/inc/MantidQtSpectrumViewer/DataArray.h +++ b/Code/Mantid/MantidQt/SpectrumViewer/inc/MantidQtSpectrumViewer/DataArray.h @@ -2,20 +2,23 @@ #define DATA_ARRAY_H #include +#include + +#include #include "MantidQtSpectrumViewer/DllOptionSV.h" /** - @class DataArray - + @class DataArray + This class provides a simple immutable wrapper around a block of data returned from an SpectrumDataSource. - - @author Dennis Mikkelson - @date 2012-04-03 - + + @author Dennis Mikkelson + @date 2012-04-03 + Copyright © 2012 ORNL, STFC Rutherford Appleton Laboratories - + This file is part of Mantid. Mantid is free software; you can redistribute it and/or modify @@ -30,8 +33,8 @@ You should have received a copy of the GNU General Public License along with this program. If not, see . - - Code Documentation is available at + + Code Documentation is available at */ @@ -45,91 +48,95 @@ class EXPORT_OPT_MANTIDQT_SPECTRUMVIEWER DataArray public: /// Construct a DataArray "wrapper" around the data and region info - DataArray( double xmin, double xmax, - double ymin, double ymax, - bool is_log_x, - size_t n_rows, size_t n_cols, - float *data ); + DataArray( double xMin, double xMax, + double yMin, double yMax, + bool isLogX, + size_t nRows, size_t nCols, + std::vector data ); ~DataArray(); /// Get the smallest 'x' value actually covered by this DataArray - double GetXMin() const; + double getXMin() const; /// Get the largest 'x' value actually covered by this DataArray - double GetXMax() const; + double getXMax() const; /// Get the smallest 'y' value actually covered by this DataArray - double GetYMin() const; + double getYMin() const; /// Get the largest 'y' value actually covered by this DataArray - double GetYMax() const; + double getYMax() const; /// Check if the returned array is binned logarithmically in 'x' - bool IsLogX() const; + bool isLogX() const; /// Get smallest value recorded in this DataArray - double GetDataMin() const; + double getDataMin() const; /// Get largest value recorded in this DataArray - double GetDataMax() const; + double getDataMax() const; // Get the actual number of rows in this DataArray - size_t GetNRows() const; + size_t getNRows() const; /// Get the actual number of columns in this DataArray - size_t GetNCols() const; + size_t getNCols() const; - /// Get simple array containing all values, packed in a 1-D array - float* GetData() const; + /// Get vector containing all values, packed in a 1-D array + std::vector getData() const; /// Get the value at the specified row and column - double GetValue( int row, int col ) const; + double getValue( int row, int col ) const; /// Get the value from the row and column containing the specified point - double GetValue( double x, double y ) const; + double getValue( double x, double y ) const; /// Clamp x to the interval of x-values covered by this DataArray - void RestrictX( double & x ) const; - + void restrictX( double & x ) const; + /// Clamp y to the interval of y-values covered by this DataArray - void RestrictY( double & y ) const; + void restrictY( double & y ) const; /// Clamp row to a valid row number for this DataArray - void RestrictRow( int & row ) const; + void restrictRow( int & row ) const; /// Clamp col to a valid column number for this DataArray - void RestrictCol( int & col ) const; + void restrictCol( int & col ) const; /// Calculate the column number containing the specified x - size_t ColumnOfX( double x ) const; + size_t columnOfX( double x ) const; /// Calculate the x-value at the center of the specified column - double XOfColumn( size_t col ) const; + double xOfColumn( size_t col ) const; /// Calculate the row number containing the specified y - size_t RowOfY( double y ) const; + size_t rowOfY( double y ) const; - /// Calculate the y-value at the center of the specified row - double YOfRow( size_t row ) const; + /// Calculate the y-value at the center of the specified row + double yOfRow( size_t row ) const; private: - double xmin; - double xmax; - double ymin; - double ymax; - bool is_log_x; - double data_min; - double data_max; - size_t n_rows; - size_t n_cols; - float *data; // This is given a reference to the data block, - // which is allocated in the SpectrumDataSource, - // but will be deleted in this object's Destructor + double m_xMin; + double m_xMax; + double m_yMin; + double m_yMax; + bool m_isLogX; + size_t m_nRows; + size_t m_nCols; + + double m_dataMin; + double m_dataMax; + + std::vector m_data; + }; +typedef boost::shared_ptr DataArray_sptr; +typedef boost::shared_ptr DataArray_const_sptr; + } // namespace SpectrumView -} // namespace MantidQt +} // namespace MantidQt #endif // DATA_ARRAY_H diff --git a/Code/Mantid/MantidQt/SpectrumViewer/inc/MantidQtSpectrumViewer/EModeHandler.h b/Code/Mantid/MantidQt/SpectrumViewer/inc/MantidQtSpectrumViewer/EModeHandler.h index 0b7c3a56ca0e..2e5c33da7fae 100644 --- a/Code/Mantid/MantidQt/SpectrumViewer/inc/MantidQtSpectrumViewer/EModeHandler.h +++ b/Code/Mantid/MantidQt/SpectrumViewer/inc/MantidQtSpectrumViewer/EModeHandler.h @@ -6,16 +6,16 @@ #include "MantidQtSpectrumViewer/DllOptionSV.h" /** - @class EModeHandler - - This manages the instrument type combo box (emode) and E Fixed controls - for the SpectrumView data viewer. - - @author Dennis Mikkelson + @class EModeHandler + + This manages the instrument type combo box (emode) and E Fixed controls + for the SpectrumView data viewer. + + @author Dennis Mikkelson @date 2012-10-12 - + Copyright © 2012 ORNL, STFC Rutherford Appleton Laboratories - + This file is part of Mantid. Mantid is free software; you can redistribute it and/or modify @@ -30,8 +30,8 @@ You should have received a copy of the GNU General Public License along with this program. If not, see . - - Code Documentation is available at + + Code Documentation is available at */ @@ -40,30 +40,31 @@ namespace MantidQt namespace SpectrumView { -class EXPORT_OPT_MANTIDQT_SPECTRUMVIEWER EModeHandler +class EXPORT_OPT_MANTIDQT_SPECTRUMVIEWER EModeHandler { public: /// Construct object to manage E Mode controls in the UI - EModeHandler(Ui_SpectrumViewer* sv_ui ); + EModeHandler( Ui_SpectrumViewer* sv_ui ); /// Get the E Mode to control units calculation, from the combo box - int GetEMode(); + int getEMode(); /// Set the E Mode to control units calculation, in the combo box - void SetEMode( const int mode ); + void setEMode( const int mode ); /// Get the E Fixed value from the GUI - double GetEFixed(); + double getEFixed(); /// Set the E Fixed value in the GUI - void SetEFixed( const double efixed ); + void setEFixed( const double efixed ); private: - Ui_SpectrumViewer* sv_ui; + Ui_SpectrumViewer* m_svUI; + }; } // namespace SpectrumView -} // namespace MantidQt +} // namespace MantidQt #endif // EMODE_HANDLER_H diff --git a/Code/Mantid/MantidQt/SpectrumViewer/inc/MantidQtSpectrumViewer/ErrorHandler.h b/Code/Mantid/MantidQt/SpectrumViewer/inc/MantidQtSpectrumViewer/ErrorHandler.h deleted file mode 100644 index 7667f0686714..000000000000 --- a/Code/Mantid/MantidQt/SpectrumViewer/inc/MantidQtSpectrumViewer/ErrorHandler.h +++ /dev/null @@ -1,60 +0,0 @@ -#ifndef ERROR_HANDLER_H -#define ERROR_HANDLER_H - -#include "MantidQtSpectrumViewer/DllOptionSV.h" - -/** - @class ErrorHandler - - This class has static methods that do various basic calculations - needed by other parts of the SpectrumView package. - - @author Dennis Mikkelson - @date 2012-05-18 - - Copyright © 2012 ORNL, STFC Rutherford Appleton Laboratories - - 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 . - - Code Documentation is available at - - */ - -namespace MantidQt -{ -namespace SpectrumView -{ - - -class EXPORT_OPT_MANTIDQT_SPECTRUMVIEWER ErrorHandler -{ - public: - - /// Display the specified string in an error message - static void Error( std::string text ); - - /// Display the specified string in a warning message - static void Warning( std::string text ); - - /// Display the specified string in a notice message - static void Notice( std::string text ); - -}; - -} // namespace SpectrumView -} // namespace MantidQt - -#endif // ERROR_HANLDER_H diff --git a/Code/Mantid/MantidQt/SpectrumViewer/inc/MantidQtSpectrumViewer/GraphDisplay.h b/Code/Mantid/MantidQt/SpectrumViewer/inc/MantidQtSpectrumViewer/GraphDisplay.h index 2b32c02ab1ab..9a84c535fa4a 100644 --- a/Code/Mantid/MantidQt/SpectrumViewer/inc/MantidQtSpectrumViewer/GraphDisplay.h +++ b/Code/Mantid/MantidQt/SpectrumViewer/inc/MantidQtSpectrumViewer/GraphDisplay.h @@ -9,16 +9,16 @@ #include "MantidQtSpectrumViewer/DllOptionSV.h" /** - @class GraphDisplay - + @class GraphDisplay + This class handles the display of vertical and horizontal cuts through the data in an SpectrumView display. - - @author Dennis Mikkelson - @date 2012-04-03 - + + @author Dennis Mikkelson + @date 2012-04-03 + Copyright © 2012 ORNL, STFC Rutherford Appleton Laboratories - + This file is part of Mantid. Mantid is free software; you can redistribute it and/or modify @@ -33,8 +33,8 @@ You should have received a copy of the GNU General Public License along with this program. If not, see . - - Code Documentation is available at + + Code Documentation is available at */ @@ -43,58 +43,59 @@ namespace MantidQt namespace SpectrumView { -class EXPORT_OPT_MANTIDQT_SPECTRUMVIEWER GraphDisplay +class EXPORT_OPT_MANTIDQT_SPECTRUMVIEWER GraphDisplay { public: - /// Construct a GraphDisplay to display in the specifed plot and table - GraphDisplay( QwtPlot* graph_plot, - QTableWidget* graph_table, - bool is_vertical ); + /// Construct a GraphDisplay to display in the specifed plot and table + GraphDisplay( QwtPlot* graphPlot, + QTableWidget* graphTable, + bool isVertical ); - ~GraphDisplay(); + ~GraphDisplay(); - /// Set the source of information for the table of position information - void SetDataSource( SpectrumDataSource* data_source ); + /// Set the source of information for the table of position information + void setDataSource( SpectrumDataSource_sptr dataSource ); /// Set the actual data that will be displayed on the graph - void SetData( const QVector & xData, + void setData( const QVector & xData, const QVector & yData, - double cut_value ); + double cutValue ); /// Clear the graph(s) off the display - void Clear(); + void clear(); - /// Set up axes using the specified scale factor and replot the graph - void SetRangeScale( double range_scale ); + /// Set up axes using the specified scale factor and replot the graph + void setRangeScale( double rangeScale ); /// Set flag indicating whether or not to use a log scale on the x-axis - void SetLogX( bool is_log_x ); + void setLogX( bool isLogX ); /// Record the point that the user is currently pointing at with the mouse - void SetPointedAtPoint( QPoint point ); + void setPointedAtPoint( QPoint point ); private: /// Show information about the point (x, y) on the graph, in the info table - void ShowInfoList( double x, double y ); - - QwtPlot* graph_plot; - QwtPlotCurve* curve; - QTableWidget* graph_table; - SpectrumDataSource* data_source; - - bool is_vertical; - bool is_log_x; - double image_x; - double image_y; - double range_scale; // fraction of data range to be graphed - double min_x, - max_x; - double min_y, - max_y; + void showInfoList( double x, double y ); + + QwtPlot * m_graphPlot; + QwtPlotCurve * m_curve; + QTableWidget * m_graphTable; + SpectrumDataSource_sptr m_dataSource; + + bool m_isVertical; + bool m_isLogX; + double m_imageX; + double m_imageY; + double m_rangeScale; // Fraction of data range to be graphed + double m_minX; + double m_maxX; + double m_minY; + double m_maxY; + }; } // namespace SpectrumView -} // namespace MantidQt +} // namespace MantidQt #endif // GRAPH_DISPLAY_H diff --git a/Code/Mantid/MantidQt/SpectrumViewer/inc/MantidQtSpectrumViewer/IRangeHandler.h b/Code/Mantid/MantidQt/SpectrumViewer/inc/MantidQtSpectrumViewer/IRangeHandler.h index c0de659597ce..a92b32eeb499 100644 --- a/Code/Mantid/MantidQt/SpectrumViewer/inc/MantidQtSpectrumViewer/IRangeHandler.h +++ b/Code/Mantid/MantidQt/SpectrumViewer/inc/MantidQtSpectrumViewer/IRangeHandler.h @@ -8,6 +8,7 @@ namespace MantidQt { namespace SpectrumView { + /** An interface to the RangeHandler class, which manages the min, max and step range controls for the SpectrumView data viewer. @@ -30,20 +31,24 @@ namespace SpectrumView Code Documentation is available at */ + class EXPORT_OPT_MANTIDQT_SPECTRUMVIEWER IRangeHandler { + public: /// Construct object to manage min, max and step controls in the UI IRangeHandler() {} virtual ~IRangeHandler() {} /// Configure min, max and step controls for the specified data source - virtual void ConfigureRangeControls( SpectrumDataSource* data_source ) = 0; + virtual void configureRangeControls( SpectrumDataSource_sptr dataSource ) = 0; + /// Get the range of data to display in the image, from GUI controls - virtual void GetRange( double &min, double &max, double &step ) = 0; + virtual void getRange( double &min, double &max, double &step ) = 0; + }; } // namespace SpectrumView -} // namespace MantidQt +} // namespace MantidQt #endif // IRANGE_HANDLER_H diff --git a/Code/Mantid/MantidQt/SpectrumViewer/inc/MantidQtSpectrumViewer/ISliderHandler.h b/Code/Mantid/MantidQt/SpectrumViewer/inc/MantidQtSpectrumViewer/ISliderHandler.h index 4223243d67fb..4c837ac813d0 100644 --- a/Code/Mantid/MantidQt/SpectrumViewer/inc/MantidQtSpectrumViewer/ISliderHandler.h +++ b/Code/Mantid/MantidQt/SpectrumViewer/inc/MantidQtSpectrumViewer/ISliderHandler.h @@ -9,6 +9,7 @@ namespace MantidQt { namespace SpectrumView { + /** An interface to the SliderHandler, which manages the horizontal and vertical scroll bars for the SpectrumView data viewer. @@ -31,30 +32,37 @@ namespace SpectrumView Code Documentation is available at */ + class EXPORT_OPT_MANTIDQT_SPECTRUMVIEWER ISliderHandler { + public: /// Construct object to manage image scrollbars from the specified UI ISliderHandler() {} virtual ~ISliderHandler() {} /// Configure the image scrollbars for the specified data and drawing area - virtual void ConfigureSliders( QRect draw_area, - SpectrumDataSource* data_source ) = 0; + virtual void configureSliders( QRect drawArea, + SpectrumDataSource_sptr dataSource ) = 0; + /// Configure the horizontal scrollbar to cover the specified range - virtual void ConfigureHSlider( int n_data_steps, - int n_pixels ) = 0; + virtual void configureHSlider( int nDataSteps, + int nPixels ) = 0; + /// Return true if the image horizontal scrollbar is enabled. - virtual bool HSliderOn() = 0; + virtual bool hSliderOn() = 0; + /// Return true if the image vertical scrollbar is enabled. - virtual bool VSliderOn() = 0; + virtual bool vSliderOn() = 0; + /// Get the range of columns to display in the image. - virtual void GetHSliderInterval( int &x_min, int &x_max ) = 0; + virtual void getHSliderInterval( int &xMin, int &xMax ) = 0; + /// Get the range of rows to display in the image. - virtual void GetVSliderInterval( int &y_min, int &y_max ) = 0; + virtual void getVSliderInterval( int &yMin, int &yMax ) = 0; }; } // namespace SpectrumView -} // namespace MantidQt +} // namespace MantidQt #endif // ISLIDER_HANDLER_H diff --git a/Code/Mantid/MantidQt/SpectrumViewer/inc/MantidQtSpectrumViewer/MatrixWSDataSource.h b/Code/Mantid/MantidQt/SpectrumViewer/inc/MantidQtSpectrumViewer/MatrixWSDataSource.h index 8711b5d46d01..e042d6058e92 100644 --- a/Code/Mantid/MantidQt/SpectrumViewer/inc/MantidQtSpectrumViewer/MatrixWSDataSource.h +++ b/Code/Mantid/MantidQt/SpectrumViewer/inc/MantidQtSpectrumViewer/MatrixWSDataSource.h @@ -5,22 +5,21 @@ #include "MantidQtSpectrumViewer/DataArray.h" #include "MantidQtSpectrumViewer/SpectrumDataSource.h" -#include "MantidQtSpectrumViewer/EModeHandler.h" #include "MantidQtSpectrumViewer/DllOptionSV.h" #include "MantidAPI/MatrixWorkspace.h" /** - @class MatrixWSDataSource - - This class provides a concrete implementation of an SpectrumDataSource + @class MatrixWSDataSource + + This class provides a concrete implementation of an SpectrumDataSource that gets it's data from a matrix workspace. - - @author Dennis Mikkelson - @date 2012-05-08 - + + @author Dennis Mikkelson + @date 2012-05-08 + Copyright © 2012 ORNL, STFC Rutherford Appleton Laboratories - + This file is part of Mantid. Mantid is free software; you can redistribute it and/or modify @@ -35,8 +34,8 @@ You should have received a copy of the GNU General Public License along with this program. If not, see . - - Code Documentation is available at + + Code Documentation is available at */ @@ -44,57 +43,62 @@ namespace MantidQt { namespace SpectrumView { +class EModeHandler; class EXPORT_OPT_MANTIDQT_SPECTRUMVIEWER MatrixWSDataSource: public SpectrumDataSource { public: /// Construct a DataSource object around the specifed MatrixWorkspace - MatrixWSDataSource( Mantid::API::MatrixWorkspace_const_sptr mat_ws ); + MatrixWSDataSource( Mantid::API::MatrixWorkspace_const_sptr matWs ); - ~MatrixWSDataSource(); + ~MatrixWSDataSource(); virtual bool hasData(const std::string& wsName, const boost::shared_ptr ws); /// OVERRIDES: Get the smallest 'x' value covered by the data - virtual double GetXMin(); + virtual double getXMin(); /// OVERRIDES: Get the largest 'x' value covered by the data - virtual double GetXMax(); + virtual double getXMax(); /// OVERRIDES: Get the largest 'y' value covered by the data - virtual double GetYMax(); + virtual double getYMax(); /// OVERRIDES: Get the total number of rows of data - virtual size_t GetNRows(); + virtual size_t getNRows(); /// Get DataArray covering full range of data in x, and y directions - DataArray * GetDataArray( bool is_log_x ); + DataArray_const_sptr getDataArray( bool isLogX ); - /// Get DataArray covering restricted range of data - DataArray * GetDataArray( double xmin, - double xmax, - double ymin, - double ymax, - size_t n_rows, - size_t n_cols, - bool is_log_x ); + /// Get DataArray covering restricted range of data + DataArray_const_sptr getDataArray( double xMin, + double xMax, + double yMin, + double yMax, + size_t nRows, + size_t nCols, + bool isLogX ); /// Set the class that gets the emode & efixed info from the user. - void SetEModeHandler( EModeHandler* emode_handler ); + void setEModeHandler( EModeHandler* emodeHandler ); /// Get a list containing pairs of strings with information about x,y - void GetInfoList( double x, + void getInfoList( double x, double y, std::vector &list ); private: - Mantid::API::MatrixWorkspace_const_sptr mat_ws; - EModeHandler* saved_emode_handler; + Mantid::API::MatrixWorkspace_const_sptr m_matWs; + EModeHandler* m_emodeHandler; + }; +typedef boost::shared_ptr MatrixWSDataSource_sptr; +typedef boost::shared_ptr MatrixWSDataSource_const_sptr; + } // namespace SpectrumView -} // namespace MantidQt +} // namespace MantidQt #endif // MATRIX_WS_DATA_SOURCE_H diff --git a/Code/Mantid/MantidQt/SpectrumViewer/inc/MantidQtSpectrumViewer/QtUtils.h b/Code/Mantid/MantidQt/SpectrumViewer/inc/MantidQtSpectrumViewer/QtUtils.h index 5fb439e824c3..a9cc8650935b 100644 --- a/Code/Mantid/MantidQt/SpectrumViewer/inc/MantidQtSpectrumViewer/QtUtils.h +++ b/Code/Mantid/MantidQt/SpectrumViewer/inc/MantidQtSpectrumViewer/QtUtils.h @@ -7,16 +7,16 @@ #include "MantidQtSpectrumViewer/DllOptionSV.h" /** - @class QtUtils - + @class QtUtils + This class has some static methods to simplify interaction with Qt and Qwt for the SpectrumView data viewer. - - @author Dennis Mikkelson - @date 2012-04-03 - + + @author Dennis Mikkelson + @date 2012-04-03 + Copyright © 2012 ORNL, STFC Rutherford Appleton Laboratories - + This file is part of Mantid. Mantid is free software; you can redistribute it and/or modify @@ -31,8 +31,8 @@ You should have received a copy of the GNU General Public License along with this program. If not, see . - - Code Documentation is available at + + Code Documentation is available at */ @@ -46,14 +46,14 @@ class EXPORT_OPT_MANTIDQT_SPECTRUMVIEWER QtUtils { public: /// enter the specified string in the table - static void SetTableEntry( int row, - int col, + static void SetTableEntry( int row, + int col, const std::string & string, QTableWidget* table ); /// enter the specified double, formatted, in the table - static void SetTableEntry( int row, - int col, + static void SetTableEntry( int row, + int col, int width, int precision, double value, @@ -61,16 +61,16 @@ class EXPORT_OPT_MANTIDQT_SPECTRUMVIEWER QtUtils /// Set the specified string into the specified QLineEdit widget. static void SetText( const std::string & string, - QLineEdit* q_line_edit ); + QLineEdit* lineEdit ); /// enter the specified double, formatted, in the QLineEdit control static void SetText( int width, int precision, double value, - QLineEdit* q_line_edit ); + QLineEdit* lineEdit ); }; } // namespace SpectrumView -} // namespace MantidQt +} // namespace MantidQt #endif // QT_UTILS_H diff --git a/Code/Mantid/MantidQt/SpectrumViewer/inc/MantidQtSpectrumViewer/RangeHandler.h b/Code/Mantid/MantidQt/SpectrumViewer/inc/MantidQtSpectrumViewer/RangeHandler.h index d0ec0b35a50f..f92406d17c7d 100644 --- a/Code/Mantid/MantidQt/SpectrumViewer/inc/MantidQtSpectrumViewer/RangeHandler.h +++ b/Code/Mantid/MantidQt/SpectrumViewer/inc/MantidQtSpectrumViewer/RangeHandler.h @@ -7,16 +7,16 @@ #include "MantidQtSpectrumViewer/DllOptionSV.h" /** - @class RangeHandler - - This manages the min, max and step range controls for the SpectrumView - data viewer. - - @author Dennis Mikkelson - @date 2012-04-25 - + @class RangeHandler + + This manages the min, max and step range controls for the SpectrumView + data viewer. + + @author Dennis Mikkelson + @date 2012-04-25 + Copyright © 2012 ORNL, STFC Rutherford Appleton Laboratories - + This file is part of Mantid. Mantid is free software; you can redistribute it and/or modify @@ -31,8 +31,8 @@ You should have received a copy of the GNU General Public License along with this program. If not, see . - - Code Documentation is available at + + Code Documentation is available at */ @@ -41,31 +41,30 @@ namespace MantidQt namespace SpectrumView { - class EXPORT_OPT_MANTIDQT_SPECTRUMVIEWER RangeHandler : public IRangeHandler { public: - /// Construct object to manage min, max and step controls in the UI - RangeHandler( Ui_SpectrumViewer* sv_ui ); + RangeHandler( Ui_SpectrumViewer* svUI ); /// Configure min, max and step controls for the specified data source - void ConfigureRangeControls( SpectrumDataSource* data_source ); + void configureRangeControls( SpectrumDataSource_sptr dataSource ); /// Get the range of data to display in the image, from GUI controls - void GetRange( double &min, double &max, double &step ); + void getRange( double &min, double &max, double &step ); /// Set the values displayed in the GUI controls - void SetRange( double min, double max, double step ); + void setRange( double min, double max, double step ); private: - Ui_SpectrumViewer* sv_ui; - double total_min_x; - double total_max_x; - size_t total_n_steps; + Ui_SpectrumViewer* m_svUI; + double m_totalMinX; + double m_totalMaxX; + size_t m_totalNSteps; + }; } // namespace SpectrumView -} // namespace MantidQt +} // namespace MantidQt #endif // RANGE_HANDLER_H diff --git a/Code/Mantid/MantidQt/SpectrumViewer/inc/MantidQtSpectrumViewer/SVConnections.h b/Code/Mantid/MantidQt/SpectrumViewer/inc/MantidQtSpectrumViewer/SVConnections.h index 07ee7c366ba5..144d416d4384 100644 --- a/Code/Mantid/MantidQt/SpectrumViewer/inc/MantidQtSpectrumViewer/SVConnections.h +++ b/Code/Mantid/MantidQt/SpectrumViewer/inc/MantidQtSpectrumViewer/SVConnections.h @@ -14,19 +14,19 @@ /** - @class SVConnections - - This class provides the connections between the SpectrumView GUI components + @class SVConnections + + This class provides the connections between the SpectrumView GUI components made using QtDesigner and the classes that do the actual work for the - SpectrumView. It basically provides SLOTS that are called by the GUI - components' SIGNALS and in turn call methods on the SpectrumView - implementation objects. - - @author Dennis Mikkelson - @date 2012-04-03 - + SpectrumView. It basically provides SLOTS that are called by the GUI + components' SIGNALS and in turn call methods on the SpectrumView + implementation objects. + + @author Dennis Mikkelson + @date 2012-04-03 + Copyright © 2012 ORNL, STFC Rutherford Appleton Laboratories - + This file is part of Mantid. Mantid is free software; you can redistribute it and/or modify @@ -41,8 +41,8 @@ You should have received a copy of the GNU General Public License along with this program. If not, see . - - Code Documentation is available at + + Code Documentation is available at */ @@ -51,7 +51,6 @@ namespace MantidQt namespace SpectrumView { - class EXPORT_OPT_MANTIDQT_SPECTRUMVIEWER SVConnections: public QWidget { Q_OBJECT @@ -60,59 +59,66 @@ class EXPORT_OPT_MANTIDQT_SPECTRUMVIEWER SVConnections: public QWidget /// Construct the object that links the GUI components to the other specifed /// higher level objects. - SVConnections( Ui_SpectrumViewer* ui, - SpectrumView* spectrum_view, - SpectrumDisplay* spectrum_display, - GraphDisplay* h_graph_display, - GraphDisplay* v_graph_display ); + SVConnections( Ui_SpectrumViewer* ui, + SpectrumView* spectrumView, + SpectrumDisplay* spectrumDisplay, + GraphDisplay* hGraphDisplay, + GraphDisplay* vGraphDisplay ); ~SVConnections(); /// Set the pix map that shows the color scale from the specified color maps - void ShowColorScale( std::vector & positive_color_table, - std::vector & negative_color_table ); + void showColorScale( std::vector & positiveColorTable, + std::vector & negativeColorTable ); public slots: - void close_viewer(); - void toggle_Hscroll(); - void toggle_Vscroll(); - void image_horizontal_range_changed(); - void graph_range_changed(); - void v_scroll_bar_moved(); - void h_scroll_bar_moved(); - void imageSplitter_moved(); - void imagePicker_moved(); - void h_graphPicker_moved(); - void v_graphPicker_moved(); - void intensity_slider_moved(); - void heat_color_scale(); - void gray_color_scale(); - void negative_gray_color_scale(); - void green_yellow_color_scale(); - void rainbow_color_scale(); - void optimal_color_scale(); - void multi_color_scale(); - void spectrum_color_scale(); - void load_color_map(); - void online_help_slot(); - + void closeViewer(); + void toggleHScroll(); + void toggleVScroll(); + void imageHorizontalRangeChanged(); + void graphRangeChanged(); + void scrollBarMoved(); + void imageSplitterMoved(); + void vgraphSplitterMoved(); + void imagePickerMoved(const QPoint &point); + void hGraphPickerMoved(const QPoint &point); + void vGraphPickerMoved(const QPoint &point); + void intensitySliderMoved(); + void loadColorMap(); + void openOnlineHelp(); + + void heatColorScale(); + void grayColorScale(); + void negativeGrayColorScale(); + void greenYellowColorScale(); + void rainbowColorScale(); + void optimalColorScale(); + void multiColorScale(); + void spectrumColorScale(); + private: /// Event filter for mouse wheel capture bool eventFilter(QObject *object, QEvent *event); - Ui_SpectrumViewer* sv_ui; - SpectrumView* sv_main_window; - SpectrumDisplay* spectrum_display; - GraphDisplay* h_graph_display; - GraphDisplay* v_graph_display; - TrackingPicker* image_picker; - TrackingPicker* h_graph_picker; - TrackingPicker* v_graph_picker; - QActionGroup* color_group; + Ui_SpectrumViewer* m_svUI; + SpectrumView* m_svMainWindow; + SpectrumDisplay* m_spectrumDisplay; + GraphDisplay* m_hGraphDisplay; + GraphDisplay* m_vGraphDisplay; + TrackingPicker* m_imagePicker; + TrackingPicker* m_hGraphPicker; + TrackingPicker* m_vGraphPicker; + QActionGroup* m_colorGroup; + + /// Last known cursor position in the data (x-direction). + int m_pickerX; + + /// Last known cursor position in the data (y-direction). + int m_pickerY; }; } // namespace SpectrumView -} // namespace MantidQt +} // namespace MantidQt #endif // SV_CONNECTIONS_H diff --git a/Code/Mantid/MantidQt/SpectrumViewer/inc/MantidQtSpectrumViewer/SVUtils.h b/Code/Mantid/MantidQt/SpectrumViewer/inc/MantidQtSpectrumViewer/SVUtils.h index 7e26f2a28f1d..22eb2fb1fac0 100644 --- a/Code/Mantid/MantidQt/SpectrumViewer/inc/MantidQtSpectrumViewer/SVUtils.h +++ b/Code/Mantid/MantidQt/SpectrumViewer/inc/MantidQtSpectrumViewer/SVUtils.h @@ -6,16 +6,16 @@ #include "MantidQtSpectrumViewer/DllOptionSV.h" /** - @class SVUtils - - This class has static methods that do various basic calculations + @class SVUtils + + This class has static methods that do various basic calculations needed by other parts of the SpectrumView package. - - @author Dennis Mikkelson - @date 2012-04-03 - + + @author Dennis Mikkelson + @date 2012-04-03 + Copyright © 2012 ORNL, STFC Rutherford Appleton Laboratories - + This file is part of Mantid. Mantid is free software; you can redistribute it and/or modify @@ -30,8 +30,8 @@ You should have received a copy of the GNU General Public License along with this program. If not, see . - - Code Documentation is available at + + Code Documentation is available at */ @@ -40,20 +40,13 @@ namespace MantidQt namespace SpectrumView { - class EXPORT_OPT_MANTIDQT_SPECTRUMVIEWER SVUtils { public: - - /// Get the double value stored in a string, if possible - static bool StringToDouble( std::string text, - double &value ); - - /// Get a formatted string representation of a double - static void Format( int width, - int precision, - double value, + static void Format( int width, + int precision, + double value, std::string & str ); /// push a name, value pair onto a vector of strings @@ -63,7 +56,7 @@ class EXPORT_OPT_MANTIDQT_SPECTRUMVIEWER SVUtils double value, std::vector & list ); - /// find a non-degenerate interval containing all the specified values + /// find a non-degenerate interval containing all the specified values static bool FindValidInterval( const QVector & values, double & min, double & max ); @@ -84,31 +77,31 @@ class EXPORT_OPT_MANTIDQT_SPECTRUMVIEWER SVUtils static bool Interpolate( double min, double max, double val, - double new_min, - double new_max, - double & new_val ); + double newMin, + double newMax, + double & newVal ); /// Find the value in [new_min,new_max] on a logarithmic scale that - /// would correspond to the point val on a linear scale on [min,max]. + /// would correspond to the point val on a linear scale on [min,max]. static bool LogInterpolate( double min, double max, double val, - double new_min, - double new_max, - double & new_val ); + double newMin, + double newMax, + double & newVal ); /// adjust the values defining a subinterval to match the boundaries of /// the global data. (Currently only for uniformly spaced bins.) - static bool CalculateInterval( double global_min, - double global_max, - size_t global_steps, - size_t & first_index, + static bool CalculateInterval( double globalMin, + double globalMax, + size_t globalSteps, + size_t & firstIndex, double & min, double & max, size_t & steps ); }; } // namespace SpectrumView -} // namespace MantidQt +} // namespace MantidQt #endif // SV_UTILS_H diff --git a/Code/Mantid/MantidQt/SpectrumViewer/inc/MantidQtSpectrumViewer/SliderHandler.h b/Code/Mantid/MantidQt/SpectrumViewer/inc/MantidQtSpectrumViewer/SliderHandler.h index c4e7b2199168..95531114d6c2 100644 --- a/Code/Mantid/MantidQt/SpectrumViewer/inc/MantidQtSpectrumViewer/SliderHandler.h +++ b/Code/Mantid/MantidQt/SpectrumViewer/inc/MantidQtSpectrumViewer/SliderHandler.h @@ -9,16 +9,16 @@ #include "MantidQtSpectrumViewer/DllOptionSV.h" /** - @class SliderHandler - - This manages the horizontal and vertical scroll bars for the - SpectrumView data viewer. - - @author Dennis Mikkelson - @date 2012-04-03 - + @class SliderHandler + + This manages the horizontal and vertical scroll bars for the + SpectrumView data viewer. + + @author Dennis Mikkelson + @date 2012-04-03 + Copyright © 2012 ORNL, STFC Rutherford Appleton Laboratories - + This file is part of Mantid. Mantid is free software; you can redistribute it and/or modify @@ -33,8 +33,8 @@ You should have received a copy of the GNU General Public License along with this program. If not, see . - - Code Documentation is available at + + Code Documentation is available at */ @@ -43,45 +43,48 @@ namespace MantidQt namespace SpectrumView { - class EXPORT_OPT_MANTIDQT_SPECTRUMVIEWER SliderHandler : public ISliderHandler { public: /// Construct object to manage image scrollbars from the specified UI - SliderHandler( Ui_SpectrumViewer* sv_ui ); + SliderHandler( Ui_SpectrumViewer* svUI ); /// Configure the image scrollbars for the specified data and drawing area - void ConfigureSliders( QRect draw_area, - SpectrumDataSource* data_source ); + void configureSliders( QRect drawArea, + SpectrumDataSource_sptr dataSource ); + + /// Configure the image scrollbars for the specified drawing area + void reConfigureSliders( QRect drawArea, + SpectrumDataSource_sptr dataSource ); /// Configure the horizontal scrollbar to cover the specified range - void ConfigureHSlider( int n_data_steps, - int n_pixels ); + void configureHSlider( int nDataSteps, + int nPixels ); /// Return true if the image horizontal scrollbar is enabled. - bool HSliderOn(); + bool hSliderOn(); /// Return true if the image vertical scrollbar is enabled. - bool VSliderOn(); + bool vSliderOn(); /// Get the range of columns to display in the image. - void GetHSliderInterval( int &x_min, int &x_max ); + void getHSliderInterval( int &xMin, int &xMax ); /// Get the range of rows to display in the image. - void GetVSliderInterval( int &y_min, int &y_max ); + void getVSliderInterval( int &yMin, int &yMax ); private: /// Configure the specified scrollbar to cover the specified range - void ConfigureSlider( QScrollBar* scroll_bar, - int n_data_steps, - int n_pixels, + void configureSlider( QScrollBar* scrollBar, + int nDataSteps, + int nPixels, int val ); - Ui_SpectrumViewer* sv_ui; + Ui_SpectrumViewer* m_svUI; }; } // namespace SpectrumView -} // namespace MantidQt +} // namespace MantidQt #endif // SLIDER_HANDLER_H diff --git a/Code/Mantid/MantidQt/SpectrumViewer/inc/MantidQtSpectrumViewer/SpectrumDataSource.h b/Code/Mantid/MantidQt/SpectrumViewer/inc/MantidQtSpectrumViewer/SpectrumDataSource.h index d4b8bd84063e..c5899cd1de51 100644 --- a/Code/Mantid/MantidQt/SpectrumViewer/inc/MantidQtSpectrumViewer/SpectrumDataSource.h +++ b/Code/Mantid/MantidQt/SpectrumViewer/inc/MantidQtSpectrumViewer/SpectrumDataSource.h @@ -10,16 +10,16 @@ #include "MantidQtSpectrumViewer/DllOptionSV.h" /** - @class SpectrumDataSource - - This class is an abstract base class for classes that can provide + @class SpectrumDataSource + + This class is an abstract base class for classes that can provide data to be displayed in an SpectrumView data viewer. - - @author Dennis Mikkelson - @date 2012-04-03 - + + @author Dennis Mikkelson + @date 2012-04-03 + Copyright © 2012 ORNL, STFC Rutherford Appleton Laboratories - + This file is part of Mantid. Mantid is free software; you can redistribute it and/or modify @@ -34,8 +34,8 @@ You should have received a copy of the GNU General Public License along with this program. If not, see . - - Code Documentation is available at + + Code Documentation is available at */ @@ -44,15 +44,14 @@ namespace MantidQt namespace SpectrumView { - class EXPORT_OPT_MANTIDQT_SPECTRUMVIEWER SpectrumDataSource { public: - /// construct data source with specified total range and data size - SpectrumDataSource( double total_xmin, double total_xmax, - double total_ymin, double total_ymax, - size_t total_rows, size_t total_cols ); + /// Construct data source with specified total range and data size + SpectrumDataSource( double totalXmin, double totalXmax, + double totalYmin, double totalYmax, + size_t totalRows, size_t totalCols ); virtual ~SpectrumDataSource(); @@ -60,63 +59,68 @@ class EXPORT_OPT_MANTIDQT_SPECTRUMVIEWER SpectrumDataSource const boost::shared_ptr ws) = 0; /// Get the smallest 'x' value covered by the data - virtual double GetXMin(); + virtual double getXMin(); /// Get the largest 'x' value covered by the data - virtual double GetXMax(); + virtual double getXMax(); /// Get the smallest 'y' value covered by the data - virtual double GetYMin(); + virtual double getYMin(); /// Get the largest 'y' value covered by the data - virtual double GetYMax(); + virtual double getYMax(); /// Get the total number of rows of data - virtual size_t GetNRows(); + virtual size_t getNRows(); /// Get the total number of columns of data - virtual size_t GetNCols(); + virtual size_t getNCols(); /// Clamp x to the interval of x-values covered by this DataSource - virtual void RestrictX( double & x ); + virtual void restrictX( double & x ); /// Clamp y to the interval of y-values covered by this DataSource - virtual void RestrictY( double & y ); + virtual void restrictY( double & y ); /// Clamp row to a valid row number for this DataSource - virtual void RestrictRow( int & row ); + virtual void restrictRow( int & row ); /// Clamp col to a valid column number for this dataSource - virtual void RestrictCol( int & col ); + virtual void restrictCol( int & col ); /// Get a DataArray roughly spaning the specified rectangle. NOTE: The - /// actual size and number of steps returned in the DataArray will be + /// actual size and number of steps returned in the DataArray will be /// adjusted to match the underlying data. - virtual DataArray* GetDataArray( double xmin, - double xmax, - double ymin, - double ymax, - size_t n_rows, - size_t n_cols, - bool is_log_x ) = 0; + virtual DataArray_const_sptr getDataArray( double xMin, + double xMax, + double yMin, + double yMax, + size_t nRows, + size_t nCols, + bool isLogX ) = 0; /// Convenience method to get data covering the full range at max resolution - virtual DataArray* GetDataArray( bool is_log_x ); + virtual DataArray_const_sptr getDataArray( bool is_log_x ); /// Get list of pairs of strings with info about the data at location x, y - virtual void GetInfoList( double x, + virtual void getInfoList( double x, double y, std::vector &list ) = 0; + protected: - double total_xmin; - double total_xmax; - double total_ymin; - double total_ymax; - size_t total_rows; - size_t total_cols; + double m_totalXMin; + double m_totalXMax; + double m_totalYMin; + double m_totalYMax; + size_t m_totalRows; + size_t m_totalCols; + }; +typedef boost::shared_ptr SpectrumDataSource_sptr; +typedef boost::shared_ptr SpectrumDataSource_const_sptr; + } // namespace SpectrumView -} // namespace MantidQt +} // namespace MantidQt #endif // SPECTRUM_DATA_SOURCE_H diff --git a/Code/Mantid/MantidQt/SpectrumViewer/inc/MantidQtSpectrumViewer/SpectrumDisplay.h b/Code/Mantid/MantidQt/SpectrumViewer/inc/MantidQtSpectrumViewer/SpectrumDisplay.h index 1023476010ca..6a464403e7f7 100644 --- a/Code/Mantid/MantidQt/SpectrumViewer/inc/MantidQtSpectrumViewer/SpectrumDisplay.h +++ b/Code/Mantid/MantidQt/SpectrumViewer/inc/MantidQtSpectrumViewer/SpectrumDisplay.h @@ -15,16 +15,16 @@ #include "MantidQtSpectrumViewer/DllOptionSV.h" /** - @class SpectrumDisplay - + @class SpectrumDisplay + This class provides the image display and coordinates the image and graph displays for the SpectrumView data viewer. - - @author Dennis Mikkelson - @date 2012-04-03 - + + @author Dennis Mikkelson + @date 2012-04-03 + Copyright © 2012 ORNL, STFC Rutherford Appleton Laboratories - + This file is part of Mantid. Mantid is free software; you can redistribute it and/or modify @@ -39,8 +39,8 @@ You should have received a copy of the GNU General Public License along with this program. If not, see . - - Code Documentation is available at + + Code Documentation is available at */ @@ -49,18 +49,17 @@ namespace MantidQt namespace SpectrumView { - class EXPORT_OPT_MANTIDQT_SPECTRUMVIEWER SpectrumDisplay { public: - /// Make an SpectrumDisplay to display with the given widgets and controls - SpectrumDisplay( QwtPlot* spectrum_plot, - ISliderHandler* slider_handler, - IRangeHandler* range_handler, - GraphDisplay* h_graph, - GraphDisplay* v_graph, - QTableWidget* table_widget ); + /// Make an SpectrumDisplay to display with the given widgets and controls + SpectrumDisplay( QwtPlot* spectrumPlot, + ISliderHandler* sliderHandler, + IRangeHandler* rangeHandler, + GraphDisplay* hGraph, + GraphDisplay* vGraph, + QTableWidget* tableWidget ); virtual ~SpectrumDisplay(); @@ -71,72 +70,89 @@ class EXPORT_OPT_MANTIDQT_SPECTRUMVIEWER SpectrumDisplay void setupSpectrumPlotItem(); /// Set the source of the image data and information for the table - void SetDataSource( SpectrumDataSource* data_source ); + void setDataSource( SpectrumDataSource_sptr dataSource ); /// Rebuild the scroll bars and image due to change of xmin, xmax, step - void UpdateRange(); + void updateRange(); + + /// Updates scroll bars when window is resized + void handleResize(); /// Rebuild image from data source, due to resize or scroll bar movement - void UpdateImage(); + void updateImage(); /// Change the color tables used to map intensity to color - void SetColorScales( std::vector & positive_color_table, - std::vector & negative_color_table ); + void setColorScales( std::vector & positiveColorTable, + std::vector & negativeColorTable ); /// Change the control parameter (0...100) used to brighten the image - void SetIntensity( double control_parameter ); - + void setIntensity( double controlParameter ); + /// Record the point that the user is currently pointing at with the mouse - virtual QPair SetPointedAtPoint( QPoint point, int mouseClick = 2 ); + virtual QPair setPointedAtPoint( QPoint point, int mouseClick = 2 ); /// Set horizontal graph wit data from the array at the specified y value - void SetHGraph( double y ); + void setHGraph( double y ); /// Set vertical graph with data from the array at the specified x value - void SetVGraph( double x ); + void setVGraph( double x ); + + /// Show information about the point (x, y) on the image in the table + std::vector showInfoList( double x, double y ); + + /// Gets a point on the graph area for a set of axis values + QPoint getPlotTransform( QPair values ); + + /// Gets a set of axis values for a point on the graph area + QPair getPlotInvTransform( QPoint point ); + + // Gets the X value pointed at + double getPointedAtX(); + + // Gets the Y value pointed at + double getPointedAtY(); protected: - SpectrumPlotItem* spectrum_plot_item; + SpectrumPlotItem* m_spectrumPlotItem; private: /// Check if the DataSource has been changed under us - bool DataSourceRangeChanged(); + bool dataSourceRangeChanged(); /// Get the rectangle currently covered by the image in pixel coordinates - void GetDisplayRectangle( QRect &rect ); + void getDisplayRectangle( QRect &rect ); - /// Show information about the point (x, y) on the image in the table - void ShowInfoList( double x, double y ); + std::vector m_positiveColorTable; + std::vector m_negativeColorTable; + std::vector m_intensityTable; + + SpectrumDataSource_sptr m_dataSource; + DataArray_const_sptr m_dataArray; - std::vector positive_color_table; - std::vector negative_color_table; - std::vector intensity_table; + QwtPlot* m_spectrumPlot; - SpectrumDataSource* data_source; - DataArray* data_array; + ISliderHandler* m_sliderHandler; + IRangeHandler* m_rangeHandler; - QwtPlot* spectrum_plot; + GraphDisplay* m_hGraphDisplay; + GraphDisplay* m_vGraphDisplay; - ISliderHandler* slider_handler; - IRangeHandler* range_handler; + double m_pointedAtX; + double m_pointedAtY; - GraphDisplay* h_graph_display; - GraphDisplay* v_graph_display; + /* Save current total data range */ + /* so we can reset the data source */ + /* if we detect a change of range */ + QTableWidget* m_imageTable; - double pointed_at_x; - double pointed_at_y; + double m_totalYMin; + double m_totalYMax; + double m_totalXMin; + double m_totalXMax; - QTableWidget* image_table; - // save current total data range - // so we can reset the data source - // if we detect a change of range - double total_y_min; - double total_y_max; - double total_x_min; - double total_x_max; }; } // namespace SpectrumView -} // namespace MantidQt +} // namespace MantidQt #endif // SPECTRUM_DISPLAY_H diff --git a/Code/Mantid/MantidQt/SpectrumViewer/inc/MantidQtSpectrumViewer/SpectrumPlotItem.h b/Code/Mantid/MantidQt/SpectrumViewer/inc/MantidQtSpectrumViewer/SpectrumPlotItem.h index 56551b6b1757..22ae48d89de8 100644 --- a/Code/Mantid/MantidQt/SpectrumViewer/inc/MantidQtSpectrumViewer/SpectrumPlotItem.h +++ b/Code/Mantid/MantidQt/SpectrumViewer/inc/MantidQtSpectrumViewer/SpectrumPlotItem.h @@ -11,16 +11,16 @@ #include "MantidQtSpectrumViewer/DllOptionSV.h" /** - @class SpectrumPlotItem - - This class is responsible for actually drawing the image data onto + @class SpectrumPlotItem + + This class is responsible for actually drawing the image data onto a QwtPlot for the SpectrumView data viewer. - - @author Dennis Mikkelson - @date 2012-04-03 - + + @author Dennis Mikkelson + @date 2012-04-03 + Copyright © 2012 ORNL, STFC Rutherford Appleton Laboratories - + This file is part of Mantid. Mantid is free software; you can redistribute it and/or modify @@ -35,8 +35,8 @@ You should have received a copy of the GNU General Public License along with this program. If not, see . - - Code Documentation is available at + + Code Documentation is available at */ @@ -45,47 +45,46 @@ namespace MantidQt namespace SpectrumView { - class EXPORT_OPT_MANTIDQT_SPECTRUMVIEWER SpectrumPlotItem : public QwtPlotItem { public: - + /// Construct basic plot item with NO data to plot. SpectrumPlotItem(); virtual ~SpectrumPlotItem(); - + /// Specify the data to be plotted and the color table to use - void SetData( DataArray* data_array, - std::vector* positive_color_table, - std::vector* negative_color_table ); + void setData( DataArray_const_sptr dataArray, + std::vector* positiveColorTable, + std::vector* negativeColorTable ); /// Set a non-linear lookup table to scale data values before mapping to color - void SetIntensityTable( std::vector* intensity_table ); + void setIntensityTable( std::vector* intensityTable ); /// Draw the image (this is called by QWT and must not be called directly.) virtual void draw( QPainter * painter, - const QwtScaleMap & xMap, + const QwtScaleMap & xMap, const QwtScaleMap & yMap, const QRect & canvasRect) const; protected: - int buffer_ID; // set to 0 or 1 to select buffer - DataArray* data_array_0; // these provide double buffers - DataArray* data_array_1; // for the float data. + int m_bufferID; // set to 0 or 1 to select buffer + DataArray_const_sptr m_dataArray0; // these provide double buffers + DataArray_const_sptr m_dataArray1; // for the float data. private: - // This class just uses the following - // but they are created and deleted - // in the upper level classes - std::vector* positive_color_table; - std::vector* negative_color_table; - std::vector* intensity_table; + /* This class just uses the following */ + /* but they are created and deleted */ + /* in the upper level classes */ + std::vector * m_positiveColorTable; + std::vector * m_negativeColorTable; + std::vector * m_intensityTable; }; } // namespace SpectrumView -} // namespace MantidQt +} // namespace MantidQt #endif // SPECTRUM_PLOT_ITEM_H diff --git a/Code/Mantid/MantidQt/SpectrumViewer/inc/MantidQtSpectrumViewer/SpectrumView.h b/Code/Mantid/MantidQt/SpectrumViewer/inc/MantidQtSpectrumViewer/SpectrumView.h index 346a1eddf169..4fbfa10fa6d0 100644 --- a/Code/Mantid/MantidQt/SpectrumViewer/inc/MantidQtSpectrumViewer/SpectrumView.h +++ b/Code/Mantid/MantidQt/SpectrumViewer/inc/MantidQtSpectrumViewer/SpectrumView.h @@ -9,20 +9,21 @@ #include "MantidQtAPI/WorkspaceObserver.h" #include "MantidQtSpectrumViewer/GraphDisplay.h" #include "MantidQtSpectrumViewer/SpectrumDataSource.h" +#include "MantidQtSpectrumViewer/MatrixWSDataSource.h" #include "MantidQtSpectrumViewer/DllOptionSV.h" /** - @class SpectrumView - - This is the QMainWindow for the SpectrumView data viewer. Data is + @class SpectrumView + + This is the QMainWindow for the SpectrumView data viewer. Data is displayed in an SpectrumView, by constructing the SpectrumView object and specifying a particular data source. - - @author Dennis Mikkelson - @date 2012-04-03 - + + @author Dennis Mikkelson + @date 2012-04-03 + Copyright © 2012 ORNL, STFC Rutherford Appleton Laboratories - + This file is part of Mantid. Mantid is free software; you can redistribute it and/or modify @@ -37,14 +38,14 @@ You should have received a copy of the GNU General Public License along with this program. If not, see . - - Code Documentation is available at + + Code Documentation is available at */ namespace Ui { -class SpectrumViewer; // forward declaration of ui file +class SpectrumViewer; // Forward declaration of UI file } namespace MantidQt @@ -52,20 +53,21 @@ namespace MantidQt namespace SpectrumView { -// forward declarations +// Forward declarations class EModeHandler; class RangeHandler; class SliderHandler; class SpectrumDisplay; class SVConnections; +class MatrixWSDataSource; class EXPORT_OPT_MANTIDQT_SPECTRUMVIEWER SpectrumView : public QMainWindow, public MantidQt::API::WorkspaceObserver { Q_OBJECT -public: - /// Construct an SpectrumView to display data from the specified data source - SpectrumView( QWidget * parent = 0); +public: + /// Construct a SpectrumView to display data from the specified data source + SpectrumView( QWidget * parent = 0 ); ~SpectrumView(); void renderWorkspace(Mantid::API::MatrixWorkspace_const_sptr wksp); @@ -75,25 +77,25 @@ protected slots: void updateWorkspace(); protected: - void preDeleteHandle(const std::string& wsName,const boost::shared_ptr ws); - void afterReplaceHandle(const std::string& wsName,const boost::shared_ptr ws); + virtual void resizeEvent(QResizeEvent * event); + void preDeleteHandle(const std::string& wsName, const boost::shared_ptr ws); + void afterReplaceHandle(const std::string& wsName, const boost::shared_ptr ws); private: - void init(SpectrumDataSource* data_source); - void updateHandlers(SpectrumDataSource* data_source); - GraphDisplay* h_graph; - GraphDisplay* v_graph; - - // keep void pointers to the following objects, to avoid having to - // include ui_SpectrumView.h, which disappears by the time MantidPlot is - // being built. We need the pointers so we can delete them in the - // destructor. - Ui::SpectrumViewer *m_ui; ///< Ui_SpectrumViewer* - SliderHandler *m_slider_handler; // SliderHandler* - RangeHandler *m_range_handler; // RangeHandler* - SpectrumDisplay *m_spectrum_display; // SpectrumDisplay* - SVConnections *m_sv_connections; // SVConnections* - EModeHandler *m_emode_handler; // EModeHandler* + void init(SpectrumDataSource_sptr dataSource); + void updateHandlers(SpectrumDataSource_sptr dataSource); + + GraphDisplay* m_hGraph; + GraphDisplay* m_vGraph; + + MatrixWSDataSource_sptr m_dataSource; + + Ui::SpectrumViewer *m_ui; + SliderHandler *m_sliderHandler; + RangeHandler *m_rangeHandler; + SpectrumDisplay *m_spectrumDisplay; + SVConnections *m_svConnections; + EModeHandler *m_emodeHandler; signals: void needToClose(); @@ -101,6 +103,6 @@ protected slots: }; } // namespace SpectrumView -} // namespace MantidQt +} // namespace MantidQt #endif // SPECTRUM_VIEW_H diff --git a/Code/Mantid/MantidQt/SpectrumViewer/inc/MantidQtSpectrumViewer/SpectrumView.ui b/Code/Mantid/MantidQt/SpectrumViewer/inc/MantidQtSpectrumViewer/SpectrumView.ui index dd3afc5470b1..34c4368a443f 100644 --- a/Code/Mantid/MantidQt/SpectrumViewer/inc/MantidQtSpectrumViewer/SpectrumView.ui +++ b/Code/Mantid/MantidQt/SpectrumViewer/inc/MantidQtSpectrumViewer/SpectrumView.ui @@ -21,16 +21,41 @@ Qt::Horizontal
+ + true + Qt::Vertical - - - - Vertical Graph Info + + + true + + + + 0 + 0 + - + + + + + + Vertical Graph Info + + + + + + + true + + + + + @@ -57,7 +82,29 @@
- + + + + + + + + + Qt::Horizontal + + + QSizePolicy::Fixed + + + + 16 + 20 + + + + + + @@ -143,23 +190,37 @@ + + true + Image Info - + + + true + + + + true + Horizontal Graph Info - + + + true + + @@ -210,7 +271,7 @@ 0 0 1251 - 26 + 20
diff --git a/Code/Mantid/MantidQt/SpectrumViewer/inc/MantidQtSpectrumViewer/TrackingPicker.h b/Code/Mantid/MantidQt/SpectrumViewer/inc/MantidQtSpectrumViewer/TrackingPicker.h index 93c88bf63741..9139d1569aee 100644 --- a/Code/Mantid/MantidQt/SpectrumViewer/inc/MantidQtSpectrumViewer/TrackingPicker.h +++ b/Code/Mantid/MantidQt/SpectrumViewer/inc/MantidQtSpectrumViewer/TrackingPicker.h @@ -5,17 +5,17 @@ #include #include "MantidQtSpectrumViewer/DllOptionSV.h" -/** - @class TrackingPicker - - This class is a QwtPlotPicker that will emit a signal whenever the - mouse is moved. It was adapted from the SliceViewer's CustomPicker - - @author Dennis Mikkelson - @date 2012-04-03 - +/** + @class TrackingPicker + + This class is a QwtPlotPicker that will emit a signal whenever the + mouse is moved. It was adapted from the SliceViewer's CustomPicker + + @author Dennis Mikkelson + @date 2012-04-03 + Copyright © 2012 ORNL, STFC Rutherford Appleton Laboratories - + This file is part of Mantid. Mantid is free software; you can redistribute it and/or modify @@ -30,8 +30,8 @@ You should have received a copy of the GNU General Public License along with this program. If not, see . - - Code Documentation is available at + + Code Documentation is available at */ @@ -52,11 +52,11 @@ class EXPORT_OPT_MANTIDQT_SPECTRUMVIEWER TrackingPicker : public QwtPlotPicker /// Disable (or enable) position readout at cursor position, even if /// tracking is ON. Tracking MUST be on for the mouseMoved signal to be /// emitted. - void HideReadout( bool hide ); + void hideReadout( bool hide ); signals: /// This signal will be emitted for each mouse moved event - void mouseMoved() const; + void mouseMoved(const QPoint & point) const; protected: @@ -65,11 +65,11 @@ class EXPORT_OPT_MANTIDQT_SPECTRUMVIEWER TrackingPicker : public QwtPlotPicker QwtText trackerText( const QwtDoublePoint & pos) const; private: - bool hide_readout; + bool m_hideReadout; }; } // namespace SpectrumView -} // namespace MantidQt +} // namespace MantidQt #endif // TRACKING_PICKER_H diff --git a/Code/Mantid/MantidQt/SpectrumViewer/src/ArrayDataSource.cpp b/Code/Mantid/MantidQt/SpectrumViewer/src/ArrayDataSource.cpp index ac905e0bbea5..f07a4d1fff27 100644 --- a/Code/Mantid/MantidQt/SpectrumViewer/src/ArrayDataSource.cpp +++ b/Code/Mantid/MantidQt/SpectrumViewer/src/ArrayDataSource.cpp @@ -16,39 +16,38 @@ namespace SpectrumView * when this class is deleted. The calling code should not change the * values in the array or delete it! * - * @param total_xmin The x-coordinate at the left edge of the first column - * of data. - * @param total_xmax The x-coordinate at the right edge of the last column - * of data. - * @param total_ymin The y-coordinate at the bottom edge of bottom row of + * @param m_totalXMin The x-coordinate at the left edge of the first column + * of data. + * @param m_totalXMax The x-coordinate at the right edge of the last column + * of data. + * @param m_totalYMin The y-coordinate at the bottom edge of bottom row of * the data region. - * @param total_ymax The y-coordinate at the top edge of the top row of + * @param m_totalYMax The y-coordinate at the top edge of the top row of * the data region - * @param total_rows The number of rows the data values are divided into. - * @param total_cols The number of columns the test values are divided + * @param m_totalRows The number of rows the data values are divided into. + * @param m_totalCols The number of columns the test values are divided * into. * @param data The list of floats holding the data to be displayed, - * stored in row major order. + * stored in row major order. */ -ArrayDataSource::ArrayDataSource( double total_xmin, double total_xmax, - double total_ymin, double total_ymax, - size_t total_rows, size_t total_cols, - float* data ) - :SpectrumDataSource( total_xmin, total_xmax, - total_ymin, total_ymax, - total_rows, total_cols ) +ArrayDataSource::ArrayDataSource( double m_totalXMin, double m_totalXMax, + double m_totalYMin, double m_totalYMax, + size_t m_totalRows, size_t m_totalCols, + std::vector data ) : + SpectrumDataSource( m_totalXMin, m_totalXMax, + m_totalYMin, m_totalYMax, + m_totalRows, m_totalCols ), + m_data(data) { - this->data = data; } ArrayDataSource::~ArrayDataSource() { - delete[] data; } bool ArrayDataSource::hasData(const std::string& wsName, - const boost::shared_ptr ws) + const boost::shared_ptr ws) { UNUSED_ARG(wsName); UNUSED_ARG(ws); @@ -57,66 +56,73 @@ bool ArrayDataSource::hasData(const std::string& wsName, /** * Get a data array covering the specified range of data, at the specified - * resolution. NOTE: The calling code is responsible for deleting the + * resolution. NOTE: The calling code is responsible for deleting the * DataArray that is returned, when it is no longer needed. * - * @param xmin Left edge of region to be covered. - * @param xmax Right edge of region to be covered. - * @param ymin Bottom edge of region to be covered. - * @param ymax Top edge of region to be covered. - * @param n_rows Number of rows to return. If the number of rows is less - * than the actual number of data rows in [ymin,ymax], the - * data will be subsampled, and only the specified number + * @param xMin Left edge of region to be covered. + * @param xMax Right edge of region to be covered. + * @param yMin Bottom edge of region to be covered. + * @param yMax Top edge of region to be covered. + * @param nRows Number of rows to return. If the number of rows is less + * than the actual number of data rows in [yMin,yMax], the + * data will be subsampled, and only the specified number * of rows will be returned. - * @param n_cols The event data will be rebinned using the specified + * @param nCols The event data will be rebinned using the specified * number of colums. - * @param is_log_x Flag indicating whether or not the data should be + * @param isLogX Flag indicating whether or not the data should be * binned logarithmically in the X-direction. This * DataSource does not support rebinning to a log axis, so - * the DataArray is always returned with is_log_x = false. + * the DataArray is always returned with isLogX = false. */ -DataArray * ArrayDataSource::GetDataArray( double xmin, double xmax, - double ymin, double ymax, - size_t n_rows, size_t n_cols, - bool is_log_x ) +DataArray_const_sptr ArrayDataSource::getDataArray( double xMin, double xMax, + double yMin, double yMax, + size_t nRows, size_t nCols, + bool isLogX ) { - size_t first_col; - SVUtils::CalculateInterval( total_xmin, total_xmax, total_cols, - first_col, xmin, xmax, n_cols ); - - size_t first_row; - SVUtils::CalculateInterval( total_ymin, total_ymax, total_rows, - first_row, ymin, ymax, n_rows ); - - float* new_data = new float[n_rows * n_cols]; // This is deleted in the - // DataArray destructor - - double x_step = (xmax - xmin) / (double)n_cols; - double y_step = (ymax - ymin) / (double)n_rows; - double d_x_index, - d_y_index; - size_t index = 0; // get data for middle of - for ( size_t row = 0; row < n_rows; row++ ) // each destination position + size_t firstCol; + SVUtils::CalculateInterval( m_totalXMin, m_totalXMax, m_totalCols, + firstCol, xMin, xMax, nCols ); + + size_t firstRow; + SVUtils::CalculateInterval( m_totalYMin, m_totalYMax, m_totalRows, + firstRow, yMin, yMax, nRows ); + + std::vector newData(nRows * nCols); + + double xStep = (xMax - xMin) / (double)nCols; + double yStep = (yMax - yMin) / (double)nRows; + + double xIndex; + double yIndex; + size_t index = 0; + + /* Get data for middle of */ + /* each destination position */ + for ( size_t row = 0; row < nRows; row++ ) { - double mid_y = ymin + ((double)row + 0.5) * y_step; - SVUtils::Interpolate( total_ymin, total_ymax, mid_y, - 0.0, (double)total_rows, d_y_index ); - size_t source_row = (size_t)d_y_index; - for ( size_t col = 0; col < n_cols; col++ ) + double midY = yMin + ((double)row + 0.5) * yStep; + SVUtils::Interpolate( m_totalYMin, m_totalYMax, midY, + 0.0, (double)m_totalRows, yIndex ); + + size_t sourceRow = (size_t)yIndex; + for ( size_t col = 0; col < nCols; col++ ) { - double mid_x = xmin + ((double)col + 0.5) * x_step; - SVUtils::Interpolate( total_xmin, total_xmax, mid_x, - 0.0, (double)total_cols, d_x_index ); - size_t source_col = (size_t)d_x_index; - new_data[index] = data[source_row * total_cols + source_col]; + double midX = xMin + ((double)col + 0.5) * xStep; + SVUtils::Interpolate( m_totalXMin, m_totalXMax, midX, + 0.0, (double)m_totalCols, xIndex ); + + size_t sourceCol = (size_t)xIndex; + + newData[index] = m_data[sourceRow * m_totalCols + sourceCol]; index++; - } + } } - // The calling code is responsible - is_log_x = false; // for deleting the DataArray - DataArray* new_data_array = new DataArray( xmin, xmax, ymin, ymax, - is_log_x, n_rows, n_cols, new_data); - return new_data_array; + + // The calling code is responsible for deleting the DataArray + isLogX = false; + DataArray_const_sptr newDataArray( new DataArray( xMin, xMax, yMin, yMax, + isLogX, nRows, nCols, newData) ); + return newDataArray; } @@ -125,22 +131,22 @@ DataArray * ArrayDataSource::GetDataArray( double xmin, double xmax, * NOTE: The calling code is responsible for deleting the DataArray that is * returned, when it is no longer needed. * - * @param is_log_x Flag indicating whether or not the data should be - * binned logarithmically. This DataSource does not - * support rebinning to a log axis, so the DataArray is - * always returned with is_log_x = false. + * @param isLogX Flag indicating whether or not the data should be + * binned logarithmically. This DataSource does not + * support rebinning to a log axis, so the DataArray is + * always returned with isLogX = false. */ -DataArray * ArrayDataSource::GetDataArray( bool is_log_x ) +DataArray_const_sptr ArrayDataSource::getDataArray( bool isLogX ) { - is_log_x = false; - return GetDataArray( total_xmin, total_xmax, total_ymin, total_ymax, - total_rows, total_cols, is_log_x ); + isLogX = false; + return getDataArray( m_totalXMin, m_totalXMax, m_totalYMin, m_totalYMax, + m_totalRows, m_totalCols, isLogX ); } /** * Clear the vector of strings and then add pairs of strings giving information - * about the specified point, x, y. The first string in a pair should + * about the specified point, x, y. The first string in a pair should * generally be a string describing the value being presented and the second * string should contain the value. * @@ -148,7 +154,7 @@ DataArray * ArrayDataSource::GetDataArray( bool is_log_x ) * @param y The y-coordinate of the point of interest in the data. * @param list Vector that will be filled out with the information strings. */ -void ArrayDataSource::GetInfoList( double x, +void ArrayDataSource::getInfoList( double x, double y, std::vector &list ) { @@ -159,4 +165,4 @@ void ArrayDataSource::GetInfoList( double x, } } // namespace SpectrumView -} // namespace MantidQt +} // namespace MantidQt diff --git a/Code/Mantid/MantidQt/SpectrumViewer/src/ColorMaps.cpp b/Code/Mantid/MantidQt/SpectrumViewer/src/ColorMaps.cpp index 7cc440bba05a..9b09dc5da6ff 100644 --- a/Code/Mantid/MantidQt/SpectrumViewer/src/ColorMaps.cpp +++ b/Code/Mantid/MantidQt/SpectrumViewer/src/ColorMaps.cpp @@ -11,17 +11,17 @@ namespace SpectrumView { /** - * Get a color map of the specified type, with the specified number of + * Get a color map of the specified type, with the specified number of * colors by interpolating between key colors. * @param name The name of the color scale as listed in the * enum ColorMaps::ColorScale - * @param n_colors The number of colors to use when forming the + * @param n_colors The number of colors to use when forming the * color map. The number of colors must be at least 7 * for some of the constructed color maps. - * @param color_table Vector of colors that will be cleard and filled out + * @param color_table Vector of colors that will be cleard and filled out * with the requested color map. */ -void ColorMaps::GetColorMap( ColorScale name, +void ColorMaps::GetColorMap( ColorScale name, size_t n_colors, std::vector & color_table ) { @@ -31,7 +31,7 @@ void ColorMaps::GetColorMap( ColorScale name, double base_green[] = { 20, 0, 127, 180, 255 }; double base_blue[] = { 20, 0, 0, 77, 255 }; size_t n_base_colors = 5; - InterpolateColorScale( base_red, base_green, base_blue, + InterpolateColorScale( base_red, base_green, base_blue, n_base_colors, n_colors, color_table ); } else if ( name == GRAY ) @@ -104,14 +104,14 @@ void ColorMaps::GetColorMap( ColorScale name, * Get an intensity lookup table to adjust the apparent brightness of a * displayed image. The lookup table makes an adjustment to the image * intensity similar to a gamma correction, but over a wide range. The - * table will be created with the specified number of entries and the + * table will be created with the specified number of entries and the * entries will increase monotonically (but non-linearly) from 0 to 1. * * @param control_s Control parameter between 0 and 100. When * the parameter is at 0, the look up table is * linear. As the parameter increases, low * intensity values will increasingly get larger - * scale factors. + * scale factors. * @param n_entries The number of entries to create in the table. * This controls the resolution of the mapping and * should be quite large (10,000-100,000) to preserve @@ -144,45 +144,45 @@ void ColorMaps::GetIntensityMap( double control_s, intensity_table[i] = (double)i / (double)(n_entries - 1); } } - else // build log-shaped correction scale + else // build log-shaped correction scale { - // first map control value - // exponentially to make the control + // first map control value + // exponentially to make the control // parameter act more linearly double s = exp( 20.0 * control_s / MAX_CONTROL ) + 0.1; - double scale = 1.0 / log( s ); + double scale = 1.0 / log( s ); for ( size_t i = 0; i < n_entries - 1; i++ ) { - intensity_table[i] = scale * + intensity_table[i] = scale * log( 1.0+((s-1.0)*(double)i) / (double)(n_entries-1) ); } intensity_table[n_entries - 1] = 1.0; // this could have been calculated - // by running the loop one step - // further, but due to rounding + // by running the loop one step + // further, but due to rounding // errors, it might exceed 1. } } - /** + /** * Build a color table by interpolating between a base set of colors. * The "base" color arrays must all be of the same length ( the length * being the number of base colors given. The base color values must * be between 0 and 255. The arrays of base colors must be of length * two or more. - * The calling routine must provide red, green and blue arrays, each - * of the same length (n_colors) to hold the color table being - * constructed. + * The calling routine must provide red, green and blue arrays, each + * of the same length (n_colors) to hold the color table being + * constructed. * * @param base_red Red components of the base colors to interpolate. * @param base_green Green components of the base colors to interpolate. * @param base_blue Blue components of the base colors to interpolate. * @param n_base_colors The number of key colors that will be interpolated - * form the color table. + * form the color table. * @param n_colors The number of colors to be created in the output * color table. - * @param color_table Vector containing n_colors qRgb colors, - * interpolated from the specified base colors. + * @param color_table Vector containing n_colors qRgb colors, + * interpolated from the specified base colors. */ void ColorMaps::InterpolateColorScale( double base_red[], @@ -195,15 +195,15 @@ void ColorMaps::InterpolateColorScale( double base_red[], color_table.clear(); color_table.resize( n_colors ); // first output color is first base color - color_table[0] = qRgb( (unsigned char)base_red[0], - (unsigned char)base_green[0], + color_table[0] = qRgb( (unsigned char)base_red[0], + (unsigned char)base_green[0], (unsigned char)base_blue[0] ); // last output color is last base color - size_t last_out = n_colors - 1; + size_t last_out = n_colors - 1; size_t last_in = n_base_colors - 1; - color_table[last_out] = qRgb( (unsigned char)base_red[last_in], - (unsigned char)base_green[last_in], + color_table[last_out] = qRgb( (unsigned char)base_red[last_in], + (unsigned char)base_green[last_in], (unsigned char)base_blue[last_in] ); // interpolate remaining output colors @@ -212,7 +212,7 @@ void ColorMaps::InterpolateColorScale( double base_red[], // fraction of way along output indices double t_out = (double)i / (double)last_out; - double float_index = t_out * (double)last_in; + double float_index = t_out * (double)last_in; // corresponding "floating point" // index in array of input colors int base_index = (int)float_index; @@ -229,7 +229,5 @@ void ColorMaps::InterpolateColorScale( double base_red[], } } - - } // namespace SpectrumView -} // namespace MantidQt +} // namespace MantidQt diff --git a/Code/Mantid/MantidQt/SpectrumViewer/src/DataArray.cpp b/Code/Mantid/MantidQt/SpectrumViewer/src/DataArray.cpp index 9898c991f145..e869d8da3869 100644 --- a/Code/Mantid/MantidQt/SpectrumViewer/src/DataArray.cpp +++ b/Code/Mantid/MantidQt/SpectrumViewer/src/DataArray.cpp @@ -13,123 +13,118 @@ namespace SpectrumView { /** - * Construct a DataArray "wrapper" around the data and region info. The + * Construct a DataArray "wrapper" around the data and region info. The * actual data must be provided in a one-dimensional array, with n_rows*n_cols - * entries. The data corresponds to the "real" region [xmin,xmax]X[ymin,ymax]. + * entries. The data corresponds to the "real" region [xMin,xMax]X[yMin,yMax]. * Xmin must correspond to the left edge of the first column and xmax must - * correspond to the right edge of the last column. Simiarly, ymin must - * correspond to the outer edge of the first row and ymax must correspond to + * correspond to the right edge of the last column. Simiarly, ymin must + * correspond to the outer edge of the first row and ymax must correspond to * the outer edge of the last row. * - * @param xmin Left edge of data region - * @param xmax Right edge of data region - * @param ymin Bottom edge of data region - * @param ymax Top edge of data region - * @param is_log_x Flag indication whether or not the data is binned + * @param xMin Left edge of data region + * @param xMax Right edge of data region + * @param yMin Bottom edge of data region + * @param yMax Top edge of data region + * @param isLogX Flag indication whether or not the data is binned * logarithmically in the 'x' direction. - * @param n_rows Number of rows in the data array - * @param n_cols Number of columns in the data array - * @param data Pointer to start of memory block holding the actual + * @param nRows Number of rows in the data array + * @param nCols Number of columns in the data array + * @param data Pointer to start of memory block holding the actual * data as a list of floats. */ -DataArray::DataArray( double xmin, double xmax, - double ymin, double ymax, - bool is_log_x, - size_t n_rows, size_t n_cols, - float *data ) +DataArray::DataArray( double xMin, double xMax, + double yMin, double yMax, + bool isLogX, + size_t nRows, size_t nCols, + std::vector data ): + m_xMin(xMin), m_xMax(xMax), + m_yMin(yMin), m_yMax(yMax), + m_isLogX(isLogX), + m_nRows(nRows), m_nCols(nCols), + m_dataMin(data[0]), m_dataMax(data[0]), + m_data(data) { - this->xmin = xmin; - this->xmax = xmax; - this->ymin = ymin; - this->ymax = ymax; - this->is_log_x = is_log_x; - this->n_rows = n_rows; - this->n_cols = n_cols; - this->data = data; - - data_min = data[0]; - data_max = data[0]; double value; size_t index = 0; - for ( size_t row = 0; row < n_rows; row++ ) - for ( size_t col = 0; col < n_cols; col++ ) + + for ( size_t row = 0; row < nRows; row++ ) + { + for ( size_t col = 0; col < nCols; col++ ) { value = data[index]; - if ( value < data_min ) - data_min = value; - else if ( value > data_max ) - data_max = value; + + if ( value < m_dataMin ) + m_dataMin = value; + + else if ( value > m_dataMax ) + m_dataMax = value; + index++; } + } } DataArray::~DataArray() { -// std::cout << "DataArray destructor called" << std::endl; - - if ( data ) - { - delete[] data; - } } /** * Get the value corresponding to the left edge of the array. */ -double DataArray::GetXMin() const +double DataArray::getXMin() const { - return xmin; + return m_xMin; } /** * Get the value corresponding to the right edge of the array. */ -double DataArray::GetXMax() const +double DataArray::getXMax() const { - return xmax; + return m_xMax; } /** * Get the value corresponding to the bottom edge of the array (outer edge * of first row). */ -double DataArray::GetYMin() const +double DataArray::getYMin() const { - return ymin; + return m_yMin; } /** * Get the value corresponding to the top edge of the array (outer edge * of last row). */ -double DataArray::GetYMax() const +double DataArray::getYMax() const { - return ymax; + return m_yMax; } /** * Check if the returned array is binned logarithmically in 'x'. */ -bool DataArray::IsLogX() const +bool DataArray::isLogX() const { - return is_log_x; + return m_isLogX; } /** * Get smallest value recorded in this DataArray */ -double DataArray::GetDataMin() const +double DataArray::getDataMin() const { - return data_min; + return m_dataMin; } /** * Get largest value recorded in this DataArray */ -double DataArray::GetDataMax() const +double DataArray::getDataMax() const { - return data_max; + return m_dataMax; } @@ -137,27 +132,27 @@ double DataArray::GetDataMax() const * Get the actual number of rows in this DataArray * */ -size_t DataArray::GetNRows() const +size_t DataArray::getNRows() const { - return n_rows; + return m_nRows; } /** * Get the actual number of columns in this DataArray */ -size_t DataArray::GetNCols() const +size_t DataArray::getNCols() const { - return n_cols; + return m_nCols; } /** * Get the list of all values, packed in a 1-D array, in row-major order */ -float * DataArray::GetData() const +std::vector DataArray::getData() const { - return data; + return m_data; } @@ -166,92 +161,73 @@ float * DataArray::GetData() const * value is outside of the array, a value from the edge of the array * will be returned. That is, the row and column numbers are "clamped" * to always lie in the range of valid values. + * + * @param row Row of data to get + * @param col Columns of data to get + * @returns Data at [row,col] */ -double DataArray::GetValue( int row, int col ) const +double DataArray::getValue( int row, int col ) const { if ( row < 0 ) - { row = 0; - } - if ( row > (int)n_rows - 1 ) - { - row = (int)n_rows - 1; - } + + if ( row > (int)m_nRows - 1 ) + row = (int)m_nRows - 1; + if ( col < 0 ) - { col = 0; - } - if ( col > (int)n_cols - 1 ) - { - col = (int)n_cols - 1; - } - return data[ row * n_cols + col ]; + if ( col > (int)m_nCols - 1 ) + col = (int)m_nCols - 1; + + return m_data[ row * m_nCols + col ]; } /** * Get the value from the row and column containing the specified point. * If the specified point (x,y) is off the edge of the array, a value - * from the edge of the array will be returned. + * from the edge of the array will be returned. + * + * @param x X value of data to get + * @param y Y value of data to get + * @returns Data at [x,y] */ -double DataArray::GetValue( double x, double y ) const +double DataArray::getValue( double x, double y ) const { -/* - int col = 0; - if ( is_log_x ) - { - col = (int)((double)n_cols * log(x/xmin)/log(xmax/xmin) ); - } - else - { - double relative_x = (x - xmin) / (xmax - xmin); - col = (int)( relative_x * (double)n_cols ); - } + size_t col = columnOfX( x ); + size_t row = rowOfY( y ); - double relative_y = (y - ymin) / (ymax - ymin); - int row = (int)( relative_y * (double)n_rows ); -*/ - size_t col = ColumnOfX( x ); - size_t row = RowOfY( y ); - - return GetValue( (int)row, (int)col ); + return getValue( (int)row, (int)col ); } /** * Clamp x to the interval of x-values covered by this DataArray. - * @param x If x is more than xmax it will be set to xmax. If x is less - * than xmin, it will be set to xmin. + * + * @param x If x is more than xmax it will be set to xmax. If x is less + * than xmin, it will be set to xmin. */ -void DataArray::RestrictX( double & x ) const +void DataArray::restrictX( double & x ) const { - if ( x > xmax ) - { - x = xmax; - } - else if ( x < xmin ) - { - x = xmin; - } + if ( x > m_xMax ) + x = m_xMax; + else if ( x < m_xMin ) + x = m_xMin; } /** * Clamp y to the interval of y-values covered by this DataArray. - * @param y If y is more than ymax it will be set to ymax. If y is less + * @param y If y is more than ymax it will be set to ymax. If y is less * than ymin, it will be set to ymin. */ -void DataArray::RestrictY( double & y ) const +void DataArray::restrictY( double & y ) const { - if ( y > ymax ) - { - y = ymax; - } - else if ( y < ymin ) - { - y = ymin; - } + if ( y > m_yMax ) + y = m_yMax; + else if ( y < m_yMin ) + y = m_yMin; } @@ -260,16 +236,12 @@ void DataArray::RestrictY( double & y ) const * @param row If row is more than n_rows-1, it is set to n_rows-1. If * row < 0 it is set to zero. */ -void DataArray::RestrictRow( int & row ) const +void DataArray::restrictRow( int & row ) const { - if ( row >= (int)n_rows ) - { - row = (int)n_rows - 1; - } + if ( row >= (int)m_nRows ) + row = (int)m_nRows - 1; else if ( row < 0 ) - { row = 0; - } } @@ -278,16 +250,12 @@ void DataArray::RestrictRow( int & row ) const * @param col If col is more than n_cols-1, it is set to n_cols-1. If * col < 0 it is set to zero. */ -void DataArray::RestrictCol( int & col ) const +void DataArray::restrictCol( int & col ) const { - if ( col >= (int)n_cols ) - { - col = (int)n_cols - 1; - } + if ( col >= (int)m_nCols ) + col = (int)m_nCols - 1; else if ( col < 0 ) - { col = 0; - } } @@ -303,25 +271,21 @@ void DataArray::RestrictCol( int & col ) const * @return A valid column number, containing x, if x is in range, or the * first or last column number if x is out of range. */ -size_t DataArray::ColumnOfX( double x ) const +size_t DataArray::columnOfX( double x ) const { int col; - if ( is_log_x ) - { - col = (int)((double)n_cols * log(x/xmin)/log(xmax/xmin)); - } + if ( m_isLogX ) + col = (int)((double)m_nCols * log(x / m_xMin) / log(m_xMax / m_xMin)); else - { - col = (int)((double)n_cols * (x-xmin)/(xmax-xmin)); - } + col = (int)((double)m_nCols * (x - m_xMin) / (m_xMax - m_xMin)); - RestrictCol( col ); + restrictCol( col ); return (size_t)col; } /* - * Calculate the x-value at the center of the specified column. If the + * Calculate the x-value at the center of the specified column. If the * column number is too large, xmax is returned. If the column number is * too small, xmin is returned. This method uses the is_log_x flag to * determine whether to use a "log" tranformation to map the column to x. @@ -330,60 +294,56 @@ size_t DataArray::ColumnOfX( double x ) const * * @return A corresponding x value between xmin and xmax. */ -double DataArray::XOfColumn( size_t col ) const +double DataArray::xOfColumn( size_t col ) const { - double xval; - if ( is_log_x ) - { - xval = xmin * exp( ((double)col+0.5)/(double)n_cols * log(xmax/xmin)); - } + double xVal; + if ( m_isLogX ) + xVal = m_xMin * exp(((double)col + 0.5)/(double)m_nCols * log(m_xMax / m_xMin)); else - { - xval = ((double)col+0.5)/(double)n_cols * (xmax-xmin) + xmin; - } - - RestrictX( xval ); - return xval; + xVal = ((double)col + 0.5)/(double)m_nCols * (m_xMax - m_xMin) + m_xMin; + + restrictX( xVal ); + return xVal; } /** * Calculate the row number containing the specified y value. If the * specified value is less than ymin, 0 is returned. If the specified - * value is more than or equal to ymax, n_rows-1 is returned. + * value is more than or equal to ymax, n_rows-1 is returned. * * @param y The y value to map to a row number * * @return A valid row number, containing y, if y is in range, or the * first or last row number if y is out of range. */ -size_t DataArray::RowOfY( double y ) const +size_t DataArray::rowOfY( double y ) const { - int row = (int)((double)n_rows * (y-ymin)/(ymax-ymin)); + int row = (int)((double)m_nRows * (y - m_yMin) / (m_yMax - m_yMin)); - RestrictRow( row ); + restrictRow( row ); return (size_t)row; } /* - * Calculate the y-value at the center of the specified row. If the + * Calculate the y-value at the center of the specified row. If the * row number is too large, ymax is returned. If the row number is - * too small, ymin is returned. + * too small, ymin is returned. * * @param row The row number to map to an y-value. * * @return A corresponding y value between ymin and ymax. */ -double DataArray::YOfRow( size_t row ) const +double DataArray::yOfRow( size_t row ) const { - double yval; - yval = ((double)row+0.5)/(double)n_rows * (ymax-ymin) + ymin; + double yVal; + yVal = ((double)row + 0.5)/(double)m_nRows * (m_yMax - m_yMin) + m_yMin; - RestrictY( yval ); - return yval; + restrictY( yVal ); + return yVal; } } // namespace SpectrumView -} // namespace MantidQt +} // namespace MantidQt diff --git a/Code/Mantid/MantidQt/SpectrumViewer/src/EModeHandler.cpp b/Code/Mantid/MantidQt/SpectrumViewer/src/EModeHandler.cpp index 0f5dd40cc8bd..2024410a2953 100644 --- a/Code/Mantid/MantidQt/SpectrumViewer/src/EModeHandler.cpp +++ b/Code/Mantid/MantidQt/SpectrumViewer/src/EModeHandler.cpp @@ -1,11 +1,16 @@ - #include #include #include "MantidQtSpectrumViewer/EModeHandler.h" #include "MantidQtSpectrumViewer/QtUtils.h" -#include "MantidQtSpectrumViewer/SVUtils.h" -#include "MantidQtSpectrumViewer/ErrorHandler.h" +#include "MantidKernel/Logger.h" + + +namespace +{ + Mantid::Kernel::Logger g_log("SpectrumView"); +} + namespace MantidQt { @@ -13,90 +18,87 @@ namespace SpectrumView { /** - * Construct an EModeHandler object to manage the E Mode and E Fixed controls + * Construct an EModeHandler object to manage the E Mode and E Fixed controls * in the specified UI */ -EModeHandler::EModeHandler( Ui_SpectrumViewer* sv_ui ) +EModeHandler::EModeHandler( Ui_SpectrumViewer* svUI ): + m_svUI(svUI) { - this->sv_ui = sv_ui; } /** * Get the EMode value (0,1,2) from the GUI. */ -int EModeHandler::GetEMode() +int EModeHandler::getEMode() { - return sv_ui->emode_combo_box->currentIndex(); + return m_svUI->emode_combo_box->currentIndex(); } /** * Set the EMode to display in the GUI. * - * @param mode Integer code for the emode type, + * @param mode Integer code for the emode type, * 0 = Diffractometer * 1 = Direct Geometry Spectrometer * 2 = Indirect Geometry Spectrometer * NOTE: Any other value will be interpreted as 0 * and the gui will not be changed. */ -void EModeHandler::SetEMode( const int mode ) +void EModeHandler::setEMode( const int mode ) { - if ( mode >= 0 && mode <= 2 ) - { - sv_ui->emode_combo_box->setCurrentIndex( mode ); - } + if(mode >= 0 && mode <= 2) + m_svUI->emode_combo_box->setCurrentIndex( mode ); else - { - ErrorHandler::Error("Mode number invalid: " + mode ); - } + g_log.error() << "Mode number invalid: " << QString::number(mode).toStdString() << std::endl; } /** - * Return the user specified EFixed value, OR 0, if no valid + * Return the user specified EFixed value, OR 0, if no valid * EFixed value was set. */ -double EModeHandler::GetEFixed() +double EModeHandler::getEFixed() { - double efixed; - std::string text = sv_ui->efixed_control->text().toStdString(); - if ( !SVUtils::StringToDouble( text, efixed ) ) + QString text = m_svUI->efixed_control->text(); + bool isNumber = false; + double eFixed = text.toDouble(&isNumber); + if(!isNumber) { - ErrorHandler::Error("E Fixed is not a NUMBER! Value reset to default."); - efixed = 0; + g_log.information("E Fixed is not a NUMBER! Value reset to default."); + eFixed = 0; } - else if ( efixed < 0 ) + else if ( eFixed < 0 ) { - ErrorHandler::Error("E Fixed is negative, Value reset to default."); - efixed = 0; + g_log.information("E Fixed is negative, Value reset to default."); + eFixed = 0; } - SetEFixed( efixed ); - return efixed; + setEFixed( eFixed ); + return eFixed; } /** * Set the EFixed value that is displayed in the UI. * - * @param efixed The new efixed value to display in the + * @param eFixed The new efixed value to display in the * UI. This must be positive, or the * displayed value will be set to zero. */ -void EModeHandler::SetEFixed( const double efixed ) +void EModeHandler::setEFixed( const double eFixed ) { - double new_value = efixed; - if ( efixed < 0 ) + double newValue = eFixed; + if ( eFixed < 0 ) { - ErrorHandler::Error("E Fixed is negative, reset to default."); - new_value = 0; + g_log.information("E Fixed is negative, reset to default."); + newValue = 0; } - QtUtils::SetText( 10, 4, new_value, sv_ui->efixed_control ); + QtUtils::SetText( 10, 4, newValue, m_svUI->efixed_control ); } } // namespace SpectrumView -} // namespace MantidQt +} // namespace MantidQt diff --git a/Code/Mantid/MantidQt/SpectrumViewer/src/ErrorHandler.cpp b/Code/Mantid/MantidQt/SpectrumViewer/src/ErrorHandler.cpp deleted file mode 100644 index dbc6f588e725..000000000000 --- a/Code/Mantid/MantidQt/SpectrumViewer/src/ErrorHandler.cpp +++ /dev/null @@ -1,54 +0,0 @@ -#include - -#include "MantidKernel/Logger.h" - -#include "MantidQtSpectrumViewer/ErrorHandler.h" - -namespace MantidQt -{ -namespace SpectrumView -{ - -using namespace Mantid; - - namespace - { - ///static logger - Kernel::Logger g_log("SpectrumView"); - } - -/** - * Display the specified string in an error message. - * - * @param text The string containing the text of the error message - */ -void ErrorHandler::Error( std::string text ) -{ - g_log.error( "ERROR: " + text ); -} - - -/** - * Display the specified string in a warning message. - * - * @param text The string containing the text of the warning message - */ -void ErrorHandler::Warning( std::string text ) -{ - g_log.warning( "WARNING: " + text ); -} - - -/** - * Display the specified string in a warning message. - * - * @param text The string containing the text of the warning message - */ -void ErrorHandler::Notice( std::string text ) -{ - g_log.notice( "Notice: " + text ); -} - - -} // namespace SpectrumView -} // namespace MantidQt diff --git a/Code/Mantid/MantidQt/SpectrumViewer/src/GraphDisplay.cpp b/Code/Mantid/MantidQt/SpectrumViewer/src/GraphDisplay.cpp index f7afa51747f0..a791cb8d5542 100644 --- a/Code/Mantid/MantidQt/SpectrumViewer/src/GraphDisplay.cpp +++ b/Code/Mantid/MantidQt/SpectrumViewer/src/GraphDisplay.cpp @@ -1,4 +1,3 @@ - #include #include #include @@ -15,43 +14,35 @@ namespace SpectrumView { /** - * Construct a GraphDisplay to display selected graph on the specifed plot + * Construct a GraphDisplay to display selected graph on the specifed plot * and to disply information in the specified table. * - * @param graph_plot The QwtPlot where the graph will be displayed. - * @param graph_table The QTableWidget where information about a - * pointed at location will be displayed. - * Can be NULL (e.g. the RefDetectorViewer doesn't use it). - * @param is_vertical Flag indicating whether this graph displays the - * vertical or horizontal cut through the image. + * @param graphPlot The QwtPlot where the graph will be displayed. + * @param graphTable The QTableWidget where information about a + * pointed at location will be displayed. + * Can be NULL (e.g. the RefDetectorViewer doesn't use it). + * @param isVertical Flag indicating whether this graph displays the + * vertical or horizontal cut through the image. */ -GraphDisplay::GraphDisplay( QwtPlot* graph_plot, - QTableWidget* graph_table, - bool is_vertical ) +GraphDisplay::GraphDisplay( QwtPlot* graphPlot, + QTableWidget* graphTable, + bool isVertical ) : + m_graphPlot(graphPlot), + m_curve(new QwtPlotCurve("Curve 1")), + m_graphTable(graphTable), + m_isVertical(isVertical), + m_isLogX(false), + m_imageX(0.0), m_imageY(0.0), + m_rangeScale(1.0) { - this->graph_plot = graph_plot; - this->graph_table = graph_table; - this->data_source = 0; - this->is_vertical = is_vertical; - - is_log_x = false; - image_x = 0; - image_y = 0; - range_scale = 1.0; - - if ( is_vertical ) - { - graph_plot->setAxisMaxMajor( QwtPlot::xBottom, 3 ); - } - - curve = new QwtPlotCurve("Curve 1"); + if(isVertical) + graphPlot->setAxisMaxMajor( QwtPlot::xBottom, 3 ); } GraphDisplay::~GraphDisplay() { - // std::cout << "GraphDisplay destructor called" << std::endl; - delete curve; + delete m_curve; } @@ -59,91 +50,90 @@ GraphDisplay::~GraphDisplay() * Set the data source from which the table information will be obtained * (must be set to allow information to be displayed in the table.) * - * @param data_source The SpectrumDataSource that provides information for - * the table. + * @param dataSource The SpectrumDataSource that provides information for + * the table. */ -void GraphDisplay::SetDataSource( SpectrumDataSource* data_source ) +void GraphDisplay::setDataSource( SpectrumDataSource_sptr dataSource ) { - this->data_source = data_source; + m_dataSource = dataSource; } /** * Set flag indicating whether or not to use a log scale on the x-axis * - * @param is_log_x Pass in true to use a log scale on the x-axis and false - * to use a linear scale. + * @param isLogX Pass in true to use a log scale on the x-axis and false + * to use a linear scale. */ -void GraphDisplay::SetLogX( bool is_log_x ) +void GraphDisplay::setLogX( bool isLogX ) { - this->is_log_x = is_log_x; + m_isLogX = isLogX; } /** - * Set the actual data that will be displayed on the graph and the + * Set the actual data that will be displayed on the graph and the * coordinates on the image corresponding to this data. The image * coordinates are needed to determine the point of interest, when the * user points at a location on the graph. * - * @param xData Vector of x coordinates of points to plot - * @param yData Vector of y coordinates of points to plot. This should - * be the same size as the xData vector. - * @param cut_value the cut value + * @param xData Vector of x coordinates of points to plot + * @param yData Vector of y coordinates of points to plot. This should + * be the same size as the xData vector. + * @param cutValue the cut value */ -void GraphDisplay::SetData(const QVector & xData, +void GraphDisplay::setData(const QVector & xData, const QVector & yData, - double cut_value ) + double cutValue ) { if ( xData.size() == 0 || // ignore invalid data vectors yData.size() == 0 || - xData.size() != yData.size() ) + xData.size() != yData.size() ) { return; } - - curve->attach(0); // detach from any plot, before changing + m_curve->attach(0); // detach from any plot, before changing // the data and attaching - if ( is_vertical ) + if ( m_isVertical ) { - this->image_x = cut_value; - min_y = yData[0]; - max_y = yData[yData.size()-1]; - SVUtils::FindValidInterval( xData, min_x, max_x ); + m_imageX = cutValue; + m_minY = yData[0]; + m_maxY = yData[yData.size()-1]; + SVUtils::FindValidInterval( xData, m_minX, m_maxX ); } else { - this->image_y = cut_value; - min_x = xData[0]; - max_x = xData[xData.size()-1]; - SVUtils::FindValidInterval( yData, min_y, max_y ); + m_imageY = cutValue; + m_minX = xData[0]; + m_maxX = xData[xData.size()-1]; + SVUtils::FindValidInterval( yData, m_minY, m_maxY ); - if ( is_log_x ) // only set log scale for x if NOT vertical + if ( m_isLogX ) // only set log scale for x if NOT vertical { QwtLog10ScaleEngine* log_engine = new QwtLog10ScaleEngine(); - graph_plot->setAxisScaleEngine( QwtPlot::xBottom, log_engine ); + m_graphPlot->setAxisScaleEngine( QwtPlot::xBottom, log_engine ); } else { QwtLinearScaleEngine* linear_engine = new QwtLinearScaleEngine(); - graph_plot->setAxisScaleEngine( QwtPlot::xBottom, linear_engine ); + m_graphPlot->setAxisScaleEngine( QwtPlot::xBottom, linear_engine ); } } - curve->setData( xData, yData ); - curve->attach( graph_plot ); + m_curve->setData( xData, yData ); + m_curve->attach( m_graphPlot ); - SetRangeScale( range_scale ); + setRangeScale( m_rangeScale ); - graph_plot->setAutoReplot(true); + m_graphPlot->setAutoReplot(true); } -void GraphDisplay::Clear() +void GraphDisplay::clear() { - curve->attach(0); // detach from plot - graph_plot->replot(); + m_curve->attach(0); // detach from plot + m_graphPlot->replot(); } @@ -152,61 +142,62 @@ void GraphDisplay::Clear() * This is useful for seeing low-level values, by clipping off the higher * magnitude values. * - * @param range_scale Value between 0 and 1 indicating what fraction of + * @param rangeScale Value between 0 and 1 indicating what fraction of * graph value range should be plotted. */ -void GraphDisplay::SetRangeScale( double range_scale ) +void GraphDisplay::setRangeScale( double rangeScale ) { - this->range_scale = range_scale; - if ( is_vertical ) + m_rangeScale = rangeScale; + + if ( m_isVertical ) { - double axis_max = range_scale * ( max_x - min_x ) + min_x; - graph_plot->setAxisScale( QwtPlot::xBottom, min_x, axis_max ); - graph_plot->setAxisScale( QwtPlot::yLeft, min_y, max_y ); + double axis_max = m_rangeScale * ( m_maxX - m_minX ) + m_minX; + m_graphPlot->setAxisScale( QwtPlot::xBottom, m_minX, axis_max ); + m_graphPlot->setAxisScale( QwtPlot::yLeft, m_minY, m_maxY ); } else { - double axis_max = range_scale * ( max_y - min_y ) + min_y; - graph_plot->setAxisScale( QwtPlot::yLeft, min_y, axis_max ); - graph_plot->setAxisScale( QwtPlot::xBottom, min_x, max_x ); + double axis_max = m_rangeScale * ( m_maxY - m_minY ) + m_minY; + m_graphPlot->setAxisScale( QwtPlot::yLeft, m_minY, axis_max ); + m_graphPlot->setAxisScale( QwtPlot::xBottom, m_minX, m_maxX ); } - graph_plot->replot(); + m_graphPlot->replot(); } /** * Show information about the specified point. * - * @param point The point that the user is currently pointing at with + * @param point The point that the user is currently pointing at with * the mouse. */ -void GraphDisplay::SetPointedAtPoint( QPoint point ) +void GraphDisplay::setPointedAtPoint( QPoint point ) { - if ( data_source == 0 ) + if ( m_dataSource == 0 ) { return; } - double x = graph_plot->invTransform( QwtPlot::xBottom, point.x() ); - double y = graph_plot->invTransform( QwtPlot::yLeft, point.y() ); + double x = m_graphPlot->invTransform( QwtPlot::xBottom, point.x() ); + double y = m_graphPlot->invTransform( QwtPlot::yLeft, point.y() ); - if ( is_vertical ) // x can be anywhere on graph, y must be + if ( m_isVertical ) // x can be anywhere on graph, y must be { // a valid data source position, vertically - data_source->RestrictY( y ); + m_dataSource->restrictY( y ); } else // y can be anywhere on graph, x must be { // a valid data source position, horizontally - data_source->RestrictX( x ); + m_dataSource->restrictX( x ); } - ShowInfoList( x, y ); + showInfoList( x, y ); } /** * Get the information about a pointed at location and show it in the * table. NOTE: If this is the "horizontal" graph, the relevant coordinates - * are x and the image_y that generated the graph. If this is the "vertical" - * graph, the relevant coordinates are y and the image_x that generated + * are x and the m_imageY that generated the graph. If this is the "vertical" + * graph, the relevant coordinates are y and the m_imageX that generated * the graph. * The method is a no-op if the table is not being used (e.g. as in the * case of the RefDetectorViewer). @@ -214,23 +205,23 @@ void GraphDisplay::SetPointedAtPoint( QPoint point ) * @param x The x coordinate of the pointed at location on the graph. * @param y The y coordinate of the pointed at location on the graph. */ -void GraphDisplay::ShowInfoList( double x, double y ) +void GraphDisplay::showInfoList( double x, double y ) { // This whole method is a no-op if no table object was injected on construction - if ( graph_table != NULL ) + if ( m_graphTable != NULL ) { int n_infos = 0; int n_rows = 1; std::vector info_list; - if ( data_source != 0 ) + if ( m_dataSource != 0 ) { - if ( is_vertical ) + if ( m_isVertical ) { - data_source->GetInfoList( image_x, y, info_list ); + m_dataSource->getInfoList( m_imageX, y, info_list ); } else { - data_source->GetInfoList( x, image_y, info_list ); + m_dataSource->getInfoList( x, m_imageY, info_list ); } } else @@ -240,34 +231,34 @@ void GraphDisplay::ShowInfoList( double x, double y ) n_infos = (int)info_list.size()/2; n_rows += n_infos; - graph_table->setRowCount(n_rows); - graph_table->setColumnCount(2); - graph_table->verticalHeader()->hide(); - graph_table->horizontalHeader()->hide(); + m_graphTable->setRowCount(n_rows); + m_graphTable->setColumnCount(2); + m_graphTable->verticalHeader()->hide(); + m_graphTable->horizontalHeader()->hide(); int width = 9; int prec = 3; - if ( is_vertical ) + if ( m_isVertical ) { - QtUtils::SetTableEntry( 0, 0, "Value", graph_table ); - QtUtils::SetTableEntry( 0, 1, width, prec, x, graph_table ); + QtUtils::SetTableEntry( 0, 0, "Value", m_graphTable ); + QtUtils::SetTableEntry( 0, 1, width, prec, x, m_graphTable ); } else { - QtUtils::SetTableEntry( 0, 0, "Value", graph_table ); - QtUtils::SetTableEntry( 0, 1, width, prec, y, graph_table ); + QtUtils::SetTableEntry( 0, 0, "Value", m_graphTable ); + QtUtils::SetTableEntry( 0, 1, width, prec, y, m_graphTable ); } for ( int i = 0; i < n_infos; i++ ) { - QtUtils::SetTableEntry( i+1, 0, info_list[2*i], graph_table ); - QtUtils::SetTableEntry( i+1, 1, info_list[2*i+1], graph_table ); + QtUtils::SetTableEntry( i+1, 0, info_list[2*i], m_graphTable ); + QtUtils::SetTableEntry( i+1, 1, info_list[2*i+1], m_graphTable ); } - graph_table->resizeColumnsToContents(); + m_graphTable->resizeColumnsToContents(); } } } // namespace SpectrumView -} // namespace MantidQt +} // namespace MantidQt diff --git a/Code/Mantid/MantidQt/SpectrumViewer/src/MatrixWSDataSource.cpp b/Code/Mantid/MantidQt/SpectrumViewer/src/MatrixWSDataSource.cpp index ba24e6921032..812f0be942dc 100644 --- a/Code/Mantid/MantidQt/SpectrumViewer/src/MatrixWSDataSource.cpp +++ b/Code/Mantid/MantidQt/SpectrumViewer/src/MatrixWSDataSource.cpp @@ -10,19 +10,28 @@ #include #include "MantidQtSpectrumViewer/MatrixWSDataSource.h" +#include "MantidQtSpectrumViewer/EModeHandler.h" #include "MantidQtSpectrumViewer/SVUtils.h" #include "MantidAPI/ISpectrum.h" #include "MantidGeometry/Instrument/Detector.h" #include "MantidGeometry/Instrument.h" +#include "MantidKernel/Logger.h" #include "MantidKernel/UnitFactory.h" #include "MantidAPI/Run.h" -#include "MantidQtSpectrumViewer/ErrorHandler.h" + using namespace Mantid; using namespace Kernel; using namespace API; using namespace Geometry; + +namespace +{ + Kernel::Logger g_log("SpectrumView"); +} + + namespace MantidQt { namespace SpectrumView @@ -31,24 +40,21 @@ namespace SpectrumView /** * Construct a DataSource object around the specifed MatrixWorkspace. * - * @param mat_ws Shared pointer to the matrix workspace being "wrapped" + * @param matWs Shared pointer to the matrix workspace being "wrapped" */ -MatrixWSDataSource::MatrixWSDataSource( MatrixWorkspace_const_sptr mat_ws ) - :SpectrumDataSource( 0.0, 1.0, 0.0, 1.0, 0, 0 ) // some defaults +MatrixWSDataSource::MatrixWSDataSource( MatrixWorkspace_const_sptr matWs ) : + SpectrumDataSource( 0.0, 1.0, 0.0, 1.0, 0, 0 ), + m_matWs(matWs), + m_emodeHandler(NULL) { - this->mat_ws = mat_ws; - - total_xmin = mat_ws->getXMin(); - total_xmax = mat_ws->getXMax(); - - total_ymin = 0; // y direction is spectrum index - total_ymax = (double)mat_ws->getNumberHistograms(); + m_totalXMin = matWs->getXMin(); + m_totalXMax = matWs->getXMax(); - total_rows = mat_ws->getNumberHistograms(); + m_totalYMin = 0; // Y direction is spectrum index + m_totalYMax = (double)matWs->getNumberHistograms(); - total_cols = 1000000; // Default data resolution - - saved_emode_handler = 0; + m_totalRows = matWs->getNumberHistograms(); + m_totalCols = 1000000; // Default data resolution } @@ -56,28 +62,29 @@ MatrixWSDataSource::~MatrixWSDataSource() { } + bool MatrixWSDataSource::hasData(const std::string& wsName, const boost::shared_ptr ws) { - if (mat_ws->getName() == wsName) + if (m_matWs->getName() == wsName) return true; - Mantid::API::MatrixWorkspace_const_sptr other - = boost::dynamic_pointer_cast(ws); + Mantid::API::MatrixWorkspace_const_sptr other = boost::dynamic_pointer_cast(ws); if (!other) return false; - return (mat_ws == other); + return (m_matWs == other); } + /** * Get the smallest 'x' value covered by the data. Must override base class * method, since the DataSource can be changed! */ -double MatrixWSDataSource::GetXMin() +double MatrixWSDataSource::getXMin() { - total_xmin = mat_ws->getXMin(); - return total_xmin; + m_totalXMin = m_matWs->getXMin(); + return m_totalXMin; } @@ -85,10 +92,10 @@ double MatrixWSDataSource::GetXMin() * Get the largest 'x' value covered by the data. Must override base class * method, since the DataSource can be changed! */ -double MatrixWSDataSource::GetXMax() +double MatrixWSDataSource::getXMax() { - total_xmax = mat_ws->getXMax(); - return total_xmax; + m_totalXMax = m_matWs->getXMax(); + return m_totalXMax; } @@ -96,10 +103,10 @@ double MatrixWSDataSource::GetXMax() * Get the largest 'y' value covered by the data. Must override base class * method, since the DataSource can be changed! */ -double MatrixWSDataSource::GetYMax() +double MatrixWSDataSource::getYMax() { - total_ymax = (double)mat_ws->getNumberHistograms(); - return total_ymax; + m_totalYMax = (double)m_matWs->getNumberHistograms(); + return m_totalYMax; } @@ -107,10 +114,10 @@ double MatrixWSDataSource::GetYMax() * Get the total number of rows the data is divided into. Must override base * class method, since the DataSource can be changed! */ -size_t MatrixWSDataSource::GetNRows() +size_t MatrixWSDataSource::getNRows() { - total_ymax = (double)mat_ws->getNumberHistograms(); - return total_rows; + m_totalYMax = (double)m_matWs->getNumberHistograms(); + return m_totalRows; } @@ -119,119 +126,110 @@ size_t MatrixWSDataSource::GetNRows() * resolution. NOTE: The calling code is responsible for deleting the * DataArray that is constructed in and returned by this method. * - * @param xmin Left edge of region to be covered. - * @param xmax Right edge of region to be covered. - * @param ymin Bottom edge of region to be covered. - * @param ymax Top edge of region to be covered. - * @param n_rows Number of rows to return. If the number of rows is less - * than the actual number of data rows in [ymin,ymax], the - * data will be subsampled, and only the specified number - * of rows will be returned. - * @param n_cols The specrum data will be rebinned using the specified - * number of colums. - * @param is_log_x Flag indicating whether or not the data should be - * binned logarithmically. + * @param xMin Left edge of region to be covered. + * @param xMax Right edge of region to be covered. + * @param yMin Bottom edge of region to be covered. + * @param yMax Top edge of region to be covered. + * @param numRows Number of rows to return. If the number of rows is less + * than the actual number of data rows in [yMin,yMax], the + * data will be subsampled, and only the specified number + * of rows will be returned. + * @param numCols The specrum data will be rebinned using the specified + * number of colums. + * @param isLogX Flag indicating whether or not the data should be + * binned logarithmically. */ -DataArray* MatrixWSDataSource::GetDataArray( double xmin, double xmax, - double ymin, double ymax, - size_t n_rows, size_t n_cols, - bool is_log_x ) +DataArray_const_sptr MatrixWSDataSource::getDataArray( double xMin, double xMax, + double yMin, double yMax, + size_t numRows, size_t numCols, + bool isLogX ) { -/* - std::cout << "Start MatrixWSDataSource::GetDataArray " << std::endl; - std::cout << " xmin = " << xmin - << " xmax = " << xmax - << " ymin = " << ymin - << " ymax = " << ymax - << " n_rows = " << n_rows - << " n_cols = " << n_cols << std::endl; -*/ - // since we're rebinning, the - // columns can be arbitrary - // but rows must be aligned - // to get whole spectra + /* Since we're rebinning, the columns can be arbitrary */ + /* but rows must be aligned to get whole spectra */ size_t first_row; - SVUtils::CalculateInterval( total_ymin, total_ymax, total_rows, - first_row, ymin, ymax, n_rows ); - - float* new_data = new float[n_rows * n_cols]; // this array is deleted in - // the DataArrray destructor - MantidVec x_scale; - x_scale.resize(n_cols+1); - if ( is_log_x ) + SVUtils::CalculateInterval( m_totalYMin, m_totalYMax, m_totalRows, + first_row, yMin, yMax, numRows ); + + std::vector newData(numRows * numCols); + + MantidVec xScale; + xScale.resize(numCols + 1); + if ( isLogX ) { - for ( size_t i = 0; i < n_cols+1; i++ ) + for ( size_t i = 0; i < numCols+1; i++ ) { - x_scale[i] = xmin * exp ( (double)i / (double)n_cols * log(xmax/xmin) ); + xScale[i] = xMin * exp ( (double)i / (double)numCols * log(xMax/xMin) ); } } else { - double dx = (xmax - xmin)/((double)n_cols + 1.0); - for ( size_t i = 0; i < n_cols+1; i++ ) + double dx = (xMax - xMin) / ((double)numCols + 1.0); + for ( size_t i = 0; i < numCols+1; i++ ) { - x_scale[i] = xmin + (double)i * dx; + xScale[i] = xMin + (double)i * dx; } - } // choose spectra from - // required range of - // spectrum indexes - double y_step = (ymax - ymin) / (double)n_rows; - double d_y_index; + } - MantidVec y_vals; + // Choose spectra from required range of spectrum indexes + double yStep = (yMax - yMin) / (double)numRows; + double dYIndex; + + MantidVec yVals; MantidVec err; - y_vals.resize(n_cols); - err.resize(n_cols); + yVals.resize(numCols); + err.resize(numCols); size_t index = 0; - for ( size_t i = 0; i < n_rows; i++ ) + for ( size_t i = 0; i < numRows; i++ ) { - double mid_y = ymin + ((double)i + 0.5) * y_step; - SVUtils::Interpolate( total_ymin, total_ymax, mid_y, - 0.0, (double)total_rows, d_y_index ); - size_t source_row = (size_t)d_y_index; - y_vals.clear(); + double midY = yMin + ((double)i + 0.5) * yStep; + SVUtils::Interpolate( m_totalYMin, m_totalYMax, midY, + 0.0, (double)m_totalRows, dYIndex ); + size_t sourceRow = (size_t)dYIndex; + yVals.clear(); err.clear(); - y_vals.resize(n_cols,0); - err.resize(n_cols,0); + yVals.resize(numCols, 0); + err.resize(numCols, 0); - mat_ws->generateHistogram( source_row, x_scale, y_vals, err, true ); - for ( size_t col = 0; col < n_cols; col++ ) + m_matWs->generateHistogram( sourceRow, xScale, yVals, err, true ); + for ( size_t col = 0; col < numCols; col++ ) { - new_data[index] = (float)y_vals[col]; + newData[index] = (float)yVals[col]; index++; } } - // The calling code is responsible for deleting - // the DataArray when it is done with it - DataArray* new_data_array = new DataArray( xmin, xmax, ymin, ymax, - is_log_x, - n_rows, n_cols, new_data); - return new_data_array; + + // The calling code is responsible for deleting the DataArray when it is done with it + DataArray_const_sptr newDataArray( new DataArray( xMin, xMax, yMin, yMax, + isLogX, + numRows, numCols, + newData) ); + + return newDataArray; } /** * Get a data array covering the full range of data. * - * @param is_log_x Flag indicating whether or not the data should be - * binned logarithmically. + * @param isLogX Flag indicating whether or not the data should be + * binned logarithmically. */ -DataArray * MatrixWSDataSource::GetDataArray( bool is_log_x ) +DataArray_const_sptr MatrixWSDataSource::getDataArray( bool isLogX ) { - return GetDataArray( total_xmin, total_xmax, total_ymin, total_ymax, - total_rows, total_cols, is_log_x ); + return getDataArray( m_totalXMin, m_totalXMax, m_totalYMin, m_totalYMax, + m_totalRows, m_totalCols, isLogX ); } /** * Set the class that gets the emode & efixed info from the user. * - * @param emode_handler Pointer to the user interface handler that - * can provide user values for emode and efixed. + * @param emodeHandler Pointer to the user interface handler that + * can provide user values for emode and efixed. */ -void MatrixWSDataSource::SetEModeHandler( EModeHandler* emode_handler ) +void MatrixWSDataSource::setEModeHandler( EModeHandler* emodeHandler ) { - saved_emode_handler = emode_handler; + m_emodeHandler = emodeHandler; } @@ -245,23 +243,23 @@ void MatrixWSDataSource::SetEModeHandler( EModeHandler* emode_handler ) * @param y The y-coordinate of the point of interest in the data. * @param list Vector that will be filled out with the information strings. */ -void MatrixWSDataSource::GetInfoList( double x, +void MatrixWSDataSource::getInfoList( double x, double y, std::vector &list ) { + // First get the info that is always available for any matrix workspace list.clear(); - // first get the info that is always - // available for any matrix workspace + int row = (int)y; - RestrictRow( row ); + restrictRow( row ); - const ISpectrum* spec = mat_ws->getSpectrum( row ); + const ISpectrum* spec = m_matWs->getSpectrum( row ); double spec_num = spec->getSpectrumNo(); SVUtils::PushNameValue( "Spec Num", 8, 0, spec_num, list ); std::string x_label = ""; - Unit_sptr& old_unit = mat_ws->getAxis(0)->unit(); + Unit_sptr& old_unit = m_matWs->getAxis(0)->unit(); if ( old_unit != 0 ) { x_label = old_unit->caption(); @@ -276,50 +274,50 @@ void MatrixWSDataSource::GetInfoList( double x, list.push_back(boost::lexical_cast(id)); } - IDetector_const_sptr det; // now try to do various unit conversions - try // to get equivalent info - { // first make sure we can get the needed - // information + /* Now try to do various unit conversions to get equivalent info */ + /* first make sure we can get the needed information */ + IDetector_const_sptr det; + try + { + if ( old_unit == 0 ) { - ErrorHandler::Error("No UNITS on MatrixWorkspace X-axis"); + g_log.debug("No UNITS on MatrixWorkspace X-axis"); return; } - Instrument_const_sptr instrument = mat_ws->getInstrument(); + Instrument_const_sptr instrument = m_matWs->getInstrument(); if ( instrument == 0 ) { - ErrorHandler::Error("No INSTRUMENT on MatrixWorkspace"); + g_log.debug("No INSTRUMENT on MatrixWorkspace"); return; } IComponent_const_sptr source = instrument->getSource(); if ( source == 0 ) { - ErrorHandler::Error("No SOURCE on instrument in MatrixWorkspace"); + g_log.debug("No SOURCE on instrument in MatrixWorkspace"); return; } IComponent_const_sptr sample = instrument->getSample(); if ( sample == 0 ) { - ErrorHandler::Error("No SAMPLE on instrument in MatrixWorkspace"); + g_log.debug("No SAMPLE on instrument in MatrixWorkspace"); return; } - det = mat_ws->getDetector( row ); + det = m_matWs->getDetector( row ); if ( det == 0 ) { - std::ostringstream message; - message << "No DETECTOR for row " << row << " in MatrixWorkspace"; - ErrorHandler::Error( message.str() ); + g_log.debug() << "No DETECTOR for row " << row << " in MatrixWorkspace" << std::endl; return; } double l1 = source->getDistance(*sample); - double l2 = 0.; - double two_theta = 0.; - double azi = 0.; + double l2 = 0.0; + double two_theta = 0.0; + double azi = 0.0; if ( det->isMonitor() ) { l2 = det->getDistance(*source); @@ -328,45 +326,40 @@ void MatrixWSDataSource::GetInfoList( double x, else { l2 = det->getDistance(*sample); - two_theta = mat_ws->detectorTwoTheta(det); + two_theta = m_matWs->detectorTwoTheta(det); azi = det->getPhi(); } SVUtils::PushNameValue( "L2", 8, 4, l2, list ); SVUtils::PushNameValue( "TwoTheta", 8, 2, two_theta*180./M_PI, list ); SVUtils::PushNameValue( "Azimuthal", 8, 2, azi*180./M_PI, list ); - // For now, only support diffractometers and monitors. - // We need a portable way to determine emode and - // and efixed that will work for any matrix workspace! + /* For now, only support diffractometers and monitors. */ + /* We need a portable way to determine emode and */ + /* and efixed that will work for any matrix workspace! */ int emode = 0; - double efixed = 0.; - double delta = 0.; + double efixed = 0.0; + double delta = 0.0; -// std::cout << "Start of checks for emode" << std::endl; - - // First try to get emode & efixed from the user - if ( saved_emode_handler != 0 ) + // First try to get emode & efixed from the user + if ( m_emodeHandler != NULL ) { - efixed = saved_emode_handler->GetEFixed(); + efixed = m_emodeHandler->getEFixed(); if ( efixed != 0 ) { - emode = saved_emode_handler->GetEMode(); + emode = m_emodeHandler->getEMode(); if ( emode == 0 ) { - ErrorHandler::Error("EMode invalid, spectrometer needed if emode != 0"); - ErrorHandler::Error("Assuming Direct Geometry Spectrometer...."); + g_log.information("EMode invalid, spectrometer needed if emode != 0"); + g_log.information("Assuming Direct Geometry Spectrometer...."); emode = 1; } } } -// std::cout << "Done with calls to GetEFixed and GetEMode" << std::endl; -// std::cout << "EMode = " << emode << std::endl; -// std::cout << "EFixed = " << efixed << std::endl; - - if ( efixed == 0 ) // Did NOT get emode & efixed from user, try getting - { // direct geometry information from the run object - const API::Run & run = mat_ws->run(); + // Did NOT get emode & efixed from user, try getting direct geometry information from the run object + if ( efixed == 0 ) + { + const API::Run & run = m_matWs->run(); if ( run.hasProperty("Ei") ) { Kernel::Property* prop = run.getProperty("Ei"); @@ -387,17 +380,14 @@ void MatrixWSDataSource::GetInfoList( double x, } } -// std::cout << "Done with getting info from run" << std::endl; -// std::cout << "EMode = " << emode << std::endl; -// std::cout << "EFixed = " << efixed << std::endl; - - if ( efixed == 0 ) // finally, try getting indirect geometry information - { // from the detector object + // Finally, try getting indirect geometry information from the detector object + if ( efixed == 0 ) + { if ( !(det->isMonitor() && det->hasParameter("Efixed"))) { try { - const ParameterMap& pmap = mat_ws->constInstrumentParameters(); + const ParameterMap& pmap = m_matWs->constInstrumentParameters(); Parameter_sptr par = pmap.getRecursive(det.get(),"Efixed"); if (par) { @@ -407,36 +397,26 @@ void MatrixWSDataSource::GetInfoList( double x, } catch ( std::runtime_error& ) { - std::ostringstream message; - message << "Failed to get Efixed from detector ID: " - << det->getID() << " in MatrixWSDataSource"; - ErrorHandler::Error( message.str() ); + g_log.debug() << "Failed to get Efixed from detector ID: " + << det->getID() << " in MatrixWSDataSource" << std::endl; efixed = 0; } } } -// std::cout << "Done with getting info from detector" << std::endl; -// std::cout << "EMode = " << emode << std::endl; -// std::cout << "EFixed = " << efixed << std::endl; - if ( efixed == 0 ) - { emode = 0; - } - if ( saved_emode_handler != 0 ) + if ( m_emodeHandler != NULL ) { - saved_emode_handler -> SetEFixed( efixed ); - saved_emode_handler -> SetEMode ( emode ); + m_emodeHandler -> setEFixed( efixed ); + m_emodeHandler -> setEMode ( emode ); } double tof = old_unit->convertSingleToTOF( x, l1, l2, two_theta, emode, efixed, delta ); if ( ! (x_label == "Time-of-flight") ) - { SVUtils::PushNameValue( "Time-of-flight", 8, 1, tof, list ); - } if ( ! (x_label == "Wavelength") ) { @@ -480,8 +460,7 @@ void MatrixWSDataSource::GetInfoList( double x, } catch (std::exception & e) { - ErrorHandler::Notice("Failed to get information from Workspace:"); - ErrorHandler::Notice( e.what() ); + g_log.debug() << "Failed to get information from Workspace:" << e.what() << std::endl; } } diff --git a/Code/Mantid/MantidQt/SpectrumViewer/src/MatrixWSSpectrumView.cpp b/Code/Mantid/MantidQt/SpectrumViewer/src/MatrixWSSpectrumView.cpp index c8d995c67453..f98607a19165 100644 --- a/Code/Mantid/MantidQt/SpectrumViewer/src/MatrixWSSpectrumView.cpp +++ b/Code/Mantid/MantidQt/SpectrumViewer/src/MatrixWSSpectrumView.cpp @@ -6,26 +6,23 @@ using Mantid::API::MatrixWorkspace_const_sptr; using namespace MantidQt; using namespace SpectrumView; + /** * Construct an SpectrumView for the specified matrix workspace */ MatrixWSSpectrumView::MatrixWSSpectrumView( MatrixWorkspace_const_sptr mat_ws ) { - spectrum_view = new SpectrumView(); // this is the QMainWindow - // for the viewer. It is - // deleted when the window - // is closed - - std::string title = std::string("SpectrumView ( ") + - mat_ws->getTitle() + - std::string(" )"); + /* This is the QMainWindow for the viewer. */ + /* It is deleted when the window is closed. */ + spectrum_view = new SpectrumView(); + std::string title = "SpectrumView (" + mat_ws->getTitle() + ")"; QString qtitle = QString::fromStdString(title); - spectrum_view->setCaption( qtitle ); spectrum_view->renderWorkspace(mat_ws); } + MatrixWSSpectrumView::~MatrixWSSpectrumView() { // nothing to do here, since spectrum_view is deleted when the window closes diff --git a/Code/Mantid/MantidQt/SpectrumViewer/src/QtUtils.cpp b/Code/Mantid/MantidQt/SpectrumViewer/src/QtUtils.cpp index edc3348cf7cb..ed1c3a2d250a 100644 --- a/Code/Mantid/MantidQt/SpectrumViewer/src/QtUtils.cpp +++ b/Code/Mantid/MantidQt/SpectrumViewer/src/QtUtils.cpp @@ -1,5 +1,4 @@ - -#include "MantidQtSpectrumViewer/QtUtils.h" +#include "MantidQtSpectrumViewer/QtUtils.h" #include "MantidQtSpectrumViewer/SVUtils.h" namespace MantidQt @@ -16,19 +15,19 @@ namespace SpectrumView * @param string The string that will be placed in the table. * @param table Pointer to the table */ -void QtUtils::SetTableEntry( int row, - int col, +void QtUtils::SetTableEntry( int row, + int col, const std::string & string, QTableWidget* table ) { - QString q_string = QString::fromStdString( string ); - QTableWidgetItem *item = new QTableWidgetItem( q_string ); + QString qString = QString::fromStdString( string ).simplified(); + QTableWidgetItem *item = new QTableWidgetItem( qString ); table->setItem( row, col, item ); } /** - * Format and set the specified double as the entry at the specified row + * Format and set the specified double as the entry at the specified row * and col of the specified table. * * @param row The row number where the string should appear. @@ -39,8 +38,8 @@ void QtUtils::SetTableEntry( int row, * @param value The number to be formatted and placed in the table. * @param table Pointer to the table */ -void QtUtils::SetTableEntry( int row, - int col, +void QtUtils::SetTableEntry( int row, + int col, int width, int precision, double value, @@ -53,39 +52,38 @@ void QtUtils::SetTableEntry( int row, /** - * Set the specified string into the specified QLineEdit widget. + * Set the specified string into the specified QLineEdit widget. * - * @param string The string that will be placed in the widget. - * @param q_line_edit Pointer to the QLineEdit widget. + * @param string The string that will be placed in the widget. + * @param lineEdit Pointer to the QLineEdit widget. */ void QtUtils::SetText( const std::string & string, - QLineEdit* q_line_edit ) + QLineEdit* lineEdit ) { - QString q_string = QString::fromStdString( string ); - q_line_edit->setText( q_string ); + QString qString = QString::fromStdString( string ); + lineEdit->setText( qString.trimmed() ); } /** - * Format and set the specified double as the text in the specified - * QLineEdit widget. + * Format and set the specified double as the text in the specified + * QLineEdit widget. * - * @param width The number of spaces to use when formatting the value. - * @param precision The number of significant figures to use when formatting - * the value. - * @param value The number to be formatted and placed in the table. - * @param q_line_edit Pointer to the QLineEdit widget. + * @param width The number of spaces to use when formatting the value. + * @param precision The number of significant figures to use when formatting + * the value. + * @param value The number to be formatted and placed in the table. + * @param lineEdit Pointer to the QLineEdit widget. */ void QtUtils::SetText( int width, int precision, double value, - QLineEdit* q_line_edit ) + QLineEdit* lineEdit ) { std::string str; SVUtils::Format( width, precision, value, str ); - SetText( str, q_line_edit ); + SetText( str, lineEdit ); } - } // namespace SpectrumView -} // namespace MantidQt +} // namespace MantidQt diff --git a/Code/Mantid/MantidQt/SpectrumViewer/src/RangeHandler.cpp b/Code/Mantid/MantidQt/SpectrumViewer/src/RangeHandler.cpp index 73238c78f253..1323f46d9255 100644 --- a/Code/Mantid/MantidQt/SpectrumViewer/src/RangeHandler.cpp +++ b/Code/Mantid/MantidQt/SpectrumViewer/src/RangeHandler.cpp @@ -1,11 +1,17 @@ - #include #include #include "MantidQtSpectrumViewer/RangeHandler.h" #include "MantidQtSpectrumViewer/QtUtils.h" #include "MantidQtSpectrumViewer/SVUtils.h" -#include "MantidQtSpectrumViewer/ErrorHandler.h" +#include "MantidKernel/Logger.h" + + +namespace +{ + Mantid::Kernel::Logger g_log("SpectrumView"); +} + namespace MantidQt { @@ -13,34 +19,31 @@ namespace SpectrumView { /** - * Construct a RangeHandler object to manage min, max and step controls + * Construct a RangeHandler object to manage min, max and step controls * in the specified UI */ -RangeHandler::RangeHandler( Ui_SpectrumViewer* sv_ui ) : IRangeHandler() +RangeHandler::RangeHandler( Ui_SpectrumViewer* svUI ) + : IRangeHandler(), m_svUI(svUI) { - this->sv_ui = sv_ui; } /** * Configure the min, max and step controls for the specified data source. * - * @param data_source SpectrumDataSource that provides the data to be drawn + * @param dataSource SpectrumDataSource that provides the data to be drawn */ -void RangeHandler::ConfigureRangeControls( SpectrumDataSource* data_source ) +void RangeHandler::configureRangeControls( SpectrumDataSource_sptr dataSource ) { - - total_min_x = data_source->GetXMin(); - total_max_x = data_source->GetXMax(); - total_n_steps = data_source->GetNCols(); + m_totalMinX = dataSource->getXMin(); + m_totalMaxX = dataSource->getXMax(); + m_totalNSteps = dataSource->getNCols(); - double default_step = (total_max_x - total_min_x)/(double)total_n_steps; - if ( total_n_steps > 2000 ) - { - default_step = (total_max_x - total_min_x)/2000.0; - } + double defaultStep = (m_totalMaxX - m_totalMinX) / (double)m_totalNSteps; + if ( m_totalNSteps > 2000 ) + defaultStep = (m_totalMaxX - m_totalMinX) / 2000.0; - SetRange( total_min_x, total_max_x, default_step ); + setRange( m_totalMinX, m_totalMaxX, defaultStep ); } @@ -52,7 +55,7 @@ void RangeHandler::ConfigureRangeControls( SpectrumDataSource* data_source ) * * @param min On input, this should be the default value that the * min should be set to, if getting the range fails. - * On output this is will be set to the x value at the + * On output this is will be set to the x value at the * left edge of the first bin to display, if getting the * range succeeds. * @param max On input, this should be the default value that the @@ -60,114 +63,118 @@ void RangeHandler::ConfigureRangeControls( SpectrumDataSource* data_source ) * On output, if getting the range succeeds, this will * be set an x value at the right edge of the last bin * to display. This will be adjusted so that it is larger - * than min by an integer number of steps. + * than min by an integer number of steps. * @param step On input this should be the default number of steps * to use if getting the range information fails. * On output, this is size of the step to use between - * min and max. If it is less than zero, a log scale + * min and max. If it is less than zero, a log scale * is requested. */ -void RangeHandler::GetRange( double &min, double &max, double &step ) +void RangeHandler::getRange( double &min, double &max, double &step ) { - double original_min = min; - double original_max = max; - double original_step = step; + double originalMin = min; + double originalMax = max; + double originalStep = step; - QLineEdit* min_control = sv_ui->x_min_input; - QLineEdit* max_control = sv_ui->x_max_input; - QLineEdit* step_control = sv_ui->step_input; + QLineEdit* minControl = m_svUI->x_min_input; + QLineEdit* maxControl = m_svUI->x_max_input; + QLineEdit* stepControl = m_svUI->step_input; - if ( !SVUtils::StringToDouble( min_control->text().toStdString(), min ) ) + bool minIsNumber = false; + bool maxIsNumber = false; + bool stepIsNumber = false; + + min = minControl->text().toDouble(&minIsNumber); + max = maxControl->text().toDouble(&maxIsNumber); + step = stepControl->text().toDouble(&stepIsNumber); + + if(!minIsNumber) { - ErrorHandler::Error("X Min is not a NUMBER! Value reset."); - min = original_min; + g_log.information("X Min is not a NUMBER! Value reset."); + min = originalMin; } - if ( !SVUtils::StringToDouble( max_control->text().toStdString(), max ) ) + + if(!maxIsNumber) { - ErrorHandler::Error("X Max is not a NUMBER! Value reset."); - max = original_max; + g_log.information("X Max is not a NUMBER! Value reset."); + max = originalMax; } - if ( !SVUtils::StringToDouble( step_control->text().toStdString(), step ) ) + + if(!stepIsNumber) { - ErrorHandler::Error("Step is not a NUMBER! Value reset."); - step = original_step; + g_log.information("Step is not a NUMBER! Value reset."); + step = originalStep; } - // just require step to be non-zero, no other - // bounds. If zero, take a default step size - if ( step == 0 ) + // Just require step to be non-zero, no other bounds. If zero, take a default step size + if ( step == 0 ) { - ErrorHandler::Error("Step = 0, resetting to default step"); - step = original_step; + g_log.information("Step = 0, resetting to default step"); + step = originalStep; } if ( step > 0 ) { if ( !SVUtils::FindValidInterval( min, max ) ) { - ErrorHandler::Warning( - "In GetRange: [Min,Max] interval invalid, values adjusted" ); - min = original_min; - max = original_max; - step = original_step; + g_log.information( "In GetRange: [Min,Max] interval invalid, values adjusted" ); + min = originalMin; + max = originalMax; + step = originalStep; } } else { if ( !SVUtils::FindValidLogInterval( min, max ) ) { - ErrorHandler::Warning( - "In GetRange: [Min,Max] log interval invalid, values adjusted"); - min = original_min; - max = original_max; - step = original_step; + g_log.information( "In GetRange: [Min,Max] log interval invalid, values adjusted"); + min = originalMin; + max = originalMax; + step = originalStep; } } - SetRange( min, max, step ); + setRange( min, max, step ); } /** - * Adjust the values to be consistent with the available data and + * Adjust the values to be consistent with the available data and * diplay them in the controls. * * @param min This is the x value at the left edge of the first bin. * @param max This is an x value at the right edge of the last bin. - * @param step This is size of the step to use between min and max. + * @param step This is size of the step to use between min and max. * If it is less than zero, a log scale is requested. */ -void RangeHandler::SetRange( double min, double max, double step ) +void RangeHandler::setRange( double min, double max, double step ) { if ( !SVUtils::FindValidInterval( min, max ) ) - { - ErrorHandler::Warning( - "In SetRange: [Min,Max] interval invalid, values adjusted" ); - } + g_log.information("In SetRange: [Min,Max] interval invalid, values adjusted" ); - if ( min < total_min_x || min > total_max_x ) + if ( min < m_totalMinX || min > m_totalMaxX ) { -// ErrorHandler::Warning("X Min out of range, resetting to range min."); - min = total_min_x; + g_log.information("X Min out of range, resetting to range min."); + min = m_totalMinX; } - if ( max < total_min_x || max > total_max_x ) + if ( max < m_totalMinX || max > m_totalMaxX ) { -// ErrorHandler::Warning("X Max out of range, resetting to range max."); - max = total_max_x; + g_log.information("X Max out of range, resetting to range max."); + max = m_totalMaxX; } if ( step == 0 ) { - ErrorHandler::Error("Step = 0, resetting to default step"); - step = (max-min)/2000.0; + g_log.information("Step = 0, resetting to default step"); + step = (max - min) / 2000.0; } - QtUtils::SetText( 8, 2, min, sv_ui->x_min_input ); - QtUtils::SetText( 8, 2, max, sv_ui->x_max_input ); - QtUtils::SetText( 8, 6, step, sv_ui->step_input ); + QtUtils::SetText( 8, 2, min, m_svUI->x_min_input ); + QtUtils::SetText( 8, 2, max, m_svUI->x_max_input ); + QtUtils::SetText( 8, 6, step, m_svUI->step_input ); } } // namespace SpectrumView -} // namespace MantidQt +} // namespace MantidQt diff --git a/Code/Mantid/MantidQt/SpectrumViewer/src/SVConnections.cpp b/Code/Mantid/MantidQt/SpectrumViewer/src/SVConnections.cpp index 0523d1559a02..da2401a047dc 100644 --- a/Code/Mantid/MantidQt/SpectrumViewer/src/SVConnections.cpp +++ b/Code/Mantid/MantidQt/SpectrumViewer/src/SVConnections.cpp @@ -1,4 +1,3 @@ - #include #include @@ -20,264 +19,266 @@ namespace SpectrumView * The objects passed in must be constructed elsewhere and must be deleted * elsewhere, when the SpectrumViewer is closed. * - * @param ui The object containing the gui components for - * the SpectrumView viewer. - * @param spectrum_view The main window. - * @param spectrum_display The SpectrumDisplay object that will display the - * image - * @param h_graph_display The GraphDisplay object that will display - * horizontal cuts through the image - * @param v_graph_display The GraphDisplay object that will display - * vertical cuts through the image + * @param ui The object containing the gui components for + * the SpectrumView viewer. + * @param spectrumView The main window. + * @param spectrumDisplay The SpectrumDisplay object that will display the + * image + * @param hGraphDisplay The GraphDisplay object that will display + * horizontal cuts through the image + * @param vGraphDisplay The GraphDisplay object that will display + * vertical cuts through the image * */ -SVConnections::SVConnections( Ui_SpectrumViewer* ui, - SpectrumView* spectrum_view, - SpectrumDisplay* spectrum_display, - GraphDisplay* h_graph_display, - GraphDisplay* v_graph_display ) +SVConnections::SVConnections( Ui_SpectrumViewer* ui, + SpectrumView* spectrumView, + SpectrumDisplay* spectrumDisplay, + GraphDisplay* hGraphDisplay, + GraphDisplay* vGraphDisplay ) : + m_svUI(ui), + m_svMainWindow(spectrumView), + m_spectrumDisplay(spectrumDisplay), + m_hGraphDisplay(hGraphDisplay), + m_vGraphDisplay(vGraphDisplay), + m_pickerX(-1), m_pickerY(-1) { - sv_ui = ui; - // first disable a few un-implemented controls - sv_ui->menuGraph_Selected->setDisabled(true); - sv_ui->actionClear_Selections->setDisabled(true); - sv_ui->actionOverlaid->setDisabled(true); - sv_ui->actionOffset_Vertically->setDisabled(true); - sv_ui->actionOffset_Diagonally->setDisabled(true); - sv_ui->actionGraph_Rebinned_Data->setDisabled(true); - sv_ui->menuHelp->setDisabled(false); - - this->sv_main_window = spectrum_view; - QObject::connect( sv_ui->actionClose, SIGNAL(triggered()), - this, SLOT(close_viewer()) ); - - // now set up the gui components - this->spectrum_display = spectrum_display; - this->h_graph_display = h_graph_display; - this->v_graph_display = v_graph_display; - + // First disable a few un-implemented controls + m_svUI->menuGraph_Selected->setDisabled(true); + m_svUI->actionClear_Selections->setDisabled(true); + m_svUI->actionOverlaid->setDisabled(true); + m_svUI->actionOffset_Vertically->setDisabled(true); + m_svUI->actionOffset_Diagonally->setDisabled(true); + m_svUI->actionGraph_Rebinned_Data->setDisabled(true); + m_svUI->menuHelp->setDisabled(false); + + QObject::connect( m_svUI->actionClose, SIGNAL(triggered()), + this, SLOT(closeViewer()) ); + + // Now set up the GUI components QList image_sizes; image_sizes.append( 500 ); image_sizes.append( 250 ); - sv_ui->imageSplitter->setSizes( image_sizes ); + m_svUI->imageSplitter->setSizes( image_sizes ); QList vgraph_sizes; vgraph_sizes.append( 500 ); vgraph_sizes.append( 30 ); vgraph_sizes.append( 220 ); - sv_ui->vgraphSplitter->setSizes( vgraph_sizes ); + m_svUI->vgraphSplitter->setSizes( vgraph_sizes ); QList horiz_sizes; horiz_sizes.append( 250 ); horiz_sizes.append( 750 ); horiz_sizes.append( 150 ); - sv_ui->left_right_splitter->setSizes( horiz_sizes ); - - sv_ui->imageHorizontalScrollBar->setFocusPolicy( Qt::StrongFocus ); - sv_ui->imageHorizontalScrollBar->setMouseTracking(true); - sv_ui->imageHorizontalScrollBar->setMinimum(20); - sv_ui->imageHorizontalScrollBar->setMaximum(2000); - sv_ui->imageHorizontalScrollBar->setPageStep(30); - sv_ui->imageHorizontalScrollBar->setSingleStep(30/2); - - sv_ui->imageVerticalScrollBar->setFocusPolicy( Qt::StrongFocus ); - sv_ui->imageVerticalScrollBar->setMouseTracking(true); - sv_ui->imageVerticalScrollBar->setMinimum(0); - sv_ui->imageVerticalScrollBar->setMaximum(10000000); - sv_ui->imageVerticalScrollBar->setPageStep(500); - sv_ui->imageVerticalScrollBar->setSingleStep(500/2); + m_svUI->left_right_splitter->setSizes( horiz_sizes ); + + m_svUI->imageHorizontalScrollBar->setFocusPolicy( Qt::StrongFocus ); + m_svUI->imageHorizontalScrollBar->setMouseTracking(true); + m_svUI->imageHorizontalScrollBar->setMinimum(20); + m_svUI->imageHorizontalScrollBar->setMaximum(2000); + m_svUI->imageHorizontalScrollBar->setPageStep(30); + m_svUI->imageHorizontalScrollBar->setSingleStep(30/2); + + m_svUI->imageVerticalScrollBar->setFocusPolicy( Qt::StrongFocus ); + m_svUI->imageVerticalScrollBar->setMouseTracking(true); + m_svUI->imageVerticalScrollBar->setMinimum(0); + m_svUI->imageVerticalScrollBar->setMaximum(10000000); + m_svUI->imageVerticalScrollBar->setPageStep(500); + m_svUI->imageVerticalScrollBar->setSingleStep(500/2); // for forwarding scroll wheel events - sv_ui->spectrumPlot->canvas()->installEventFilter(this); + m_svUI->spectrumPlot->canvas()->installEventFilter(this); - sv_ui->action_Hscroll->setCheckable(true); - sv_ui->action_Hscroll->setChecked(false); - sv_ui->imageHorizontalScrollBar->hide(); - sv_ui->imageHorizontalScrollBar->setEnabled(false); + m_svUI->action_Hscroll->setCheckable(true); + m_svUI->action_Hscroll->setChecked(false); + m_svUI->imageHorizontalScrollBar->hide(); + m_svUI->imageHorizontalScrollBar->setEnabled(false); - sv_ui->action_Vscroll->setCheckable(true); - sv_ui->action_Vscroll->setChecked(true); - sv_ui->imageVerticalScrollBar->show(); - sv_ui->imageVerticalScrollBar->setEnabled(true); + m_svUI->action_Vscroll->setCheckable(true); + m_svUI->action_Vscroll->setChecked(true); + m_svUI->imageVerticalScrollBar->show(); + m_svUI->imageVerticalScrollBar->setEnabled(true); - sv_ui->intensity_slider->setTickInterval(10); - sv_ui->intensity_slider->setTickPosition(QSlider::TicksBelow); - sv_ui->intensity_slider->setSliderPosition(30); + m_svUI->intensity_slider->setTickInterval(10); + m_svUI->intensity_slider->setTickPosition(QSlider::TicksBelow); + m_svUI->intensity_slider->setSliderPosition(30); - sv_ui->graph_max_slider->setTickInterval(10); - sv_ui->graph_max_slider->setTickPosition(QSlider::TicksBelow); - sv_ui->graph_max_slider->setSliderPosition(100); + m_svUI->graph_max_slider->setTickInterval(10); + m_svUI->graph_max_slider->setTickPosition(QSlider::TicksBelow); + m_svUI->graph_max_slider->setSliderPosition(100); - image_picker = new TrackingPicker( sv_ui->spectrumPlot->canvas() ); - image_picker->setMousePattern(QwtPicker::MouseSelect1, Qt::LeftButton); - image_picker->setTrackerMode(QwtPicker::ActiveOnly); - image_picker->setRubberBandPen(QColor(Qt::gray)); + m_imagePicker = new TrackingPicker( m_svUI->spectrumPlot->canvas() ); + m_imagePicker->setMousePattern(QwtPicker::MouseSelect1, Qt::LeftButton); + m_imagePicker->setTrackerMode(QwtPicker::ActiveOnly); + m_imagePicker->setRubberBandPen(QColor(Qt::gray)); /* // point selections & connection works on mouse release */ - image_picker->setRubberBand(QwtPicker::CrossRubberBand); - image_picker->setSelectionFlags(QwtPicker::PointSelection | + m_imagePicker->setRubberBand(QwtPicker::CrossRubberBand); + m_imagePicker->setSelectionFlags(QwtPicker::PointSelection | QwtPicker::DragSelection ); /* - QObject::connect( image_picker, SIGNAL(selected(const QwtPolygon &)), + QObject::connect( m_imagePicker, SIGNAL(selected(const QwtPolygon &)), this, SLOT(imagePickerSelectedPoint()) ); */ /* // point selection works on mouse click, NO CROSSHAIRS... - image_picker->setRubberBand(QwtPicker::CrossRubberBand); - image_picker->setSelectionFlags(QwtPicker::PointSelection | + m_imagePicker->setRubberBand(QwtPicker::CrossRubberBand); + m_imagePicker->setSelectionFlags(QwtPicker::PointSelection | QwtPicker::ClickSelection ); - QObject::connect( image_picker, SIGNAL(selected(const QwtPolygon &)), + QObject::connect( m_imagePicker, SIGNAL(selected(const QwtPolygon &)), this, SLOT(imagePickerSelectedPoint()) ); */ /* // rect selection calls SLOT on mouse release - - image_picker->setMousePattern(QwtPicker::MouseSelect1, Qt::MidButton); - image_picker->setRubberBand(QwtPicker::RectRubberBand); - image_picker->setSelectionFlags(QwtPicker::RectSelection | + + m_imagePicker->setMousePattern(QwtPicker::MouseSelect1, Qt::MidButton); + m_imagePicker->setRubberBand(QwtPicker::RectRubberBand); + m_imagePicker->setSelectionFlags(QwtPicker::RectSelection | QwtPicker::DragSelection ); - QObject::connect( image_picker, SIGNAL(selected(const QwtPolygon &)), + QObject::connect( m_imagePicker, SIGNAL(selected(const QwtPolygon &)), this, SLOT(imagePickerSelectedPoint()) ); */ /* - image_picker->setRubberBand(QwtPicker::CrossRubberBand); - image_picker->setSelectionFlags(QwtPicker::PointSelection | + m_imagePicker->setRubberBand(QwtPicker::CrossRubberBand); + m_imagePicker->setSelectionFlags(QwtPicker::PointSelection | QwtPicker::ClickSelection ); */ - QObject::connect( image_picker, SIGNAL(mouseMoved()), - this, SLOT(imagePicker_moved()) ); + QObject::connect( m_imagePicker, SIGNAL(mouseMoved(const QPoint &)), + this, SLOT(imagePickerMoved(const QPoint &)) ); - QObject::connect(sv_ui->imageSplitter, SIGNAL(splitterMoved(int,int)), - this, SLOT(imageSplitter_moved()) ); + QObject::connect(m_svUI->imageSplitter, SIGNAL(splitterMoved(int, int)), + this, SLOT(imageSplitterMoved()) ); - QObject::connect(sv_ui->x_min_input, SIGNAL( returnPressed() ), - this, SLOT(image_horizontal_range_changed()) ); + QObject::connect(m_svUI->vgraphSplitter, SIGNAL(splitterMoved(int, int)), + this, SLOT(vgraphSplitterMoved()) ); - QObject::connect(sv_ui->x_max_input, SIGNAL( returnPressed() ), - this, SLOT(image_horizontal_range_changed()) ); + QObject::connect(m_svUI->x_min_input, SIGNAL( returnPressed() ), + this, SLOT(imageHorizontalRangeChanged()) ); - QObject::connect(sv_ui->step_input, SIGNAL( returnPressed() ), - this, SLOT(image_horizontal_range_changed()) ); + QObject::connect(m_svUI->x_max_input, SIGNAL( returnPressed() ), + this, SLOT(imageHorizontalRangeChanged()) ); - QObject::connect(sv_ui->imageVerticalScrollBar, SIGNAL(valueChanged(int)), - this, SLOT(v_scroll_bar_moved()) ); + QObject::connect(m_svUI->step_input, SIGNAL( returnPressed() ), + this, SLOT(imageHorizontalRangeChanged()) ); - QObject::connect(sv_ui->imageHorizontalScrollBar, SIGNAL(valueChanged(int)), - this, SLOT(h_scroll_bar_moved()) ); + QObject::connect(m_svUI->imageVerticalScrollBar, SIGNAL(valueChanged(int)), + this, SLOT(scrollBarMoved()) ); - QObject::connect(sv_ui->action_Hscroll, SIGNAL(changed()), - this, SLOT(toggle_Hscroll()) ); + QObject::connect(m_svUI->imageHorizontalScrollBar, SIGNAL(valueChanged(int)), + this, SLOT(scrollBarMoved()) ); - QObject::connect(sv_ui->action_Vscroll, SIGNAL(changed()), - this, SLOT(toggle_Vscroll()) ); + QObject::connect(m_svUI->action_Hscroll, SIGNAL(changed()), + this, SLOT(toggleHScroll()) ); - QObject::connect(sv_ui->intensity_slider, SIGNAL(valueChanged(int)), - this, SLOT(intensity_slider_moved()) ); + QObject::connect(m_svUI->action_Vscroll, SIGNAL(changed()), + this, SLOT(toggleVScroll()) ); - QObject::connect(sv_ui->graph_max_slider, SIGNAL(valueChanged(int)), - this, SLOT(graph_range_changed()) ); + QObject::connect(m_svUI->intensity_slider, SIGNAL(valueChanged(int)), + this, SLOT(intensitySliderMoved()) ); - // color scale selections - sv_ui->actionHeat->setCheckable(true); - sv_ui->actionHeat->setChecked(true); - sv_ui->actionGray->setCheckable(true); - sv_ui->actionNegative_Gray->setCheckable(true); - sv_ui->actionGreen_Yellow->setCheckable(true); - sv_ui->actionRainbow->setCheckable(true); - sv_ui->actionOptimal->setCheckable(true); - sv_ui->actionMulti->setCheckable(true); - sv_ui->actionSpectrum->setCheckable(true); - sv_ui->actionLoadColormap->setCheckable(true); + QObject::connect(m_svUI->graph_max_slider, SIGNAL(valueChanged(int)), + this, SLOT(graphRangeChanged()) ); + + // Color scale selections + m_svUI->actionHeat->setCheckable(true); + m_svUI->actionHeat->setChecked(true); + m_svUI->actionGray->setCheckable(true); + m_svUI->actionNegative_Gray->setCheckable(true); + m_svUI->actionGreen_Yellow->setCheckable(true); + m_svUI->actionRainbow->setCheckable(true); + m_svUI->actionOptimal->setCheckable(true); + m_svUI->actionMulti->setCheckable(true); + m_svUI->actionSpectrum->setCheckable(true); + m_svUI->actionLoadColormap->setCheckable(true); // set up initial color // scale display - sv_ui->color_scale->setScaledContents(true); - sv_ui->color_scale->setMinimumHeight(15); - sv_ui->color_scale->setMinimumWidth(15); + m_svUI->color_scale->setScaledContents(true); + m_svUI->color_scale->setMinimumHeight(15); + m_svUI->color_scale->setMinimumWidth(15); std::vector positive_color_table; ColorMaps::GetColorMap( ColorMaps::HEAT, 256, positive_color_table ); std::vector negative_color_table; ColorMaps::GetColorMap( ColorMaps::GRAY, 256, negative_color_table ); - ShowColorScale( positive_color_table, negative_color_table ); + showColorScale( positive_color_table, negative_color_table ); - color_group = new QActionGroup(this); - color_group->addAction(sv_ui->actionHeat); - color_group->addAction(sv_ui->actionGray); - color_group->addAction(sv_ui->actionNegative_Gray); - color_group->addAction(sv_ui->actionGreen_Yellow); - color_group->addAction(sv_ui->actionRainbow); - color_group->addAction(sv_ui->actionOptimal); - color_group->addAction(sv_ui->actionMulti); - color_group->addAction(sv_ui->actionSpectrum); - color_group->addAction(sv_ui->actionLoadColormap); + m_colorGroup = new QActionGroup(this); + m_colorGroup->addAction(m_svUI->actionHeat); + m_colorGroup->addAction(m_svUI->actionGray); + m_colorGroup->addAction(m_svUI->actionNegative_Gray); + m_colorGroup->addAction(m_svUI->actionGreen_Yellow); + m_colorGroup->addAction(m_svUI->actionRainbow); + m_colorGroup->addAction(m_svUI->actionOptimal); + m_colorGroup->addAction(m_svUI->actionMulti); + m_colorGroup->addAction(m_svUI->actionSpectrum); + m_colorGroup->addAction(m_svUI->actionLoadColormap); - QObject::connect(sv_ui->actionHeat, SIGNAL(triggered()), - this, SLOT(heat_color_scale()) ); + QObject::connect(m_svUI->actionHeat, SIGNAL(triggered()), + this, SLOT(heatColorScale()) ); - QObject::connect(sv_ui->actionGray, SIGNAL(triggered()), - this, SLOT(gray_color_scale()) ); + QObject::connect(m_svUI->actionGray, SIGNAL(triggered()), + this, SLOT(grayColorScale()) ); - QObject::connect(sv_ui->actionNegative_Gray, SIGNAL(triggered()), - this, SLOT(negative_gray_color_scale()) ); + QObject::connect(m_svUI->actionNegative_Gray, SIGNAL(triggered()), + this, SLOT(negativeGrayColorScale()) ); - QObject::connect(sv_ui->actionGreen_Yellow, SIGNAL(triggered()), - this, SLOT(green_yellow_color_scale()) ); + QObject::connect(m_svUI->actionGreen_Yellow, SIGNAL(triggered()), + this, SLOT(greenYellowColorScale()) ); - QObject::connect(sv_ui->actionRainbow, SIGNAL(triggered()), - this, SLOT(rainbow_color_scale()) ); + QObject::connect(m_svUI->actionRainbow, SIGNAL(triggered()), + this, SLOT(rainbowColorScale()) ); - QObject::connect(sv_ui->actionOptimal, SIGNAL(triggered()), - this, SLOT(optimal_color_scale()) ); + QObject::connect(m_svUI->actionOptimal, SIGNAL(triggered()), + this, SLOT(optimalColorScale()) ); - QObject::connect(sv_ui->actionMulti, SIGNAL(triggered()), - this, SLOT(multi_color_scale()) ); + QObject::connect(m_svUI->actionMulti, SIGNAL(triggered()), + this, SLOT(multiColorScale()) ); - QObject::connect(sv_ui->actionSpectrum, SIGNAL(triggered()), - this, SLOT(spectrum_color_scale()) ); + QObject::connect(m_svUI->actionSpectrum, SIGNAL(triggered()), + this, SLOT(spectrumColorScale()) ); - QObject::connect(sv_ui->actionLoadColormap, SIGNAL(triggered()), - this, SLOT(load_color_map()) ); + QObject::connect(m_svUI->actionLoadColormap, SIGNAL(triggered()), + this, SLOT(loadColorMap()) ); - h_graph_picker = new TrackingPicker( sv_ui->h_graphPlot->canvas() ); - h_graph_picker->setMousePattern(QwtPicker::MouseSelect1, Qt::LeftButton); - h_graph_picker->setTrackerMode(QwtPicker::ActiveOnly); - h_graph_picker->setRubberBandPen(QColor(Qt::gray)); - h_graph_picker->setRubberBand(QwtPicker::CrossRubberBand); - h_graph_picker->setSelectionFlags(QwtPicker::PointSelection | + m_hGraphPicker = new TrackingPicker( m_svUI->h_graphPlot->canvas() ); + m_hGraphPicker->setMousePattern(QwtPicker::MouseSelect1, Qt::LeftButton); + m_hGraphPicker->setTrackerMode(QwtPicker::ActiveOnly); + m_hGraphPicker->setRubberBandPen(QColor(Qt::gray)); + m_hGraphPicker->setRubberBand(QwtPicker::CrossRubberBand); + m_hGraphPicker->setSelectionFlags(QwtPicker::PointSelection | QwtPicker::DragSelection ); - QObject::connect( h_graph_picker, SIGNAL(mouseMoved()), - this, SLOT(h_graphPicker_moved()) ); + QObject::connect( m_hGraphPicker, SIGNAL(mouseMoved(const QPoint &)), + this, SLOT(hGraphPickerMoved(const QPoint &)) ); // NOTE: This initialization could be a (static?) method in TrackingPicker - v_graph_picker = new TrackingPicker( sv_ui->v_graphPlot->canvas() ); - v_graph_picker->setMousePattern(QwtPicker::MouseSelect1, Qt::LeftButton); - v_graph_picker->setTrackerMode(QwtPicker::ActiveOnly); - v_graph_picker->setRubberBandPen(QColor(Qt::gray)); - v_graph_picker->setRubberBand(QwtPicker::CrossRubberBand); - v_graph_picker->setSelectionFlags(QwtPicker::PointSelection | + m_vGraphPicker = new TrackingPicker( m_svUI->v_graphPlot->canvas() ); + m_vGraphPicker->setMousePattern(QwtPicker::MouseSelect1, Qt::LeftButton); + m_vGraphPicker->setTrackerMode(QwtPicker::ActiveOnly); + m_vGraphPicker->setRubberBandPen(QColor(Qt::gray)); + m_vGraphPicker->setRubberBand(QwtPicker::CrossRubberBand); + m_vGraphPicker->setSelectionFlags(QwtPicker::PointSelection | QwtPicker::DragSelection ); - QObject::connect( v_graph_picker, SIGNAL(mouseMoved()), - this, SLOT(v_graphPicker_moved()) ); + QObject::connect( m_vGraphPicker, SIGNAL(mouseMoved(const QPoint &)), + this, SLOT(vGraphPickerMoved(const QPoint &)) ); - QObject::connect( sv_ui->actionOnline_Help_Page, SIGNAL(triggered()), - this, SLOT(online_help_slot()) ); + QObject::connect( m_svUI->actionOnline_Help_Page, SIGNAL(triggered()), + this, SLOT(openOnlineHelp()) ); } SVConnections::~SVConnections() { - delete image_picker; - delete h_graph_picker; - delete v_graph_picker; - delete color_group; } + /** + * Handle events. + * * @param object Object that the event came from. * @param event The event being filtered. * @return true if the event was consumed. @@ -293,130 +294,244 @@ bool SVConnections::eventFilter(QObject *object, QEvent *event) { if (wheelEvent->orientation() == Qt::Orientation::Vertical) { - return sv_ui->imageVerticalScrollBar->event(wheelEvent); + return m_svUI->imageVerticalScrollBar->event(wheelEvent); } else if (wheelEvent->orientation() == Qt::Orientation::Horizontal) { - return sv_ui->imageHorizontalScrollBar->event(wheelEvent); + return m_svUI->imageHorizontalScrollBar->event(wheelEvent); } } } + else if (event->type() == QEvent::KeyPress) + { + // don't bother if the values aren't set + if (m_pickerX < 0) return false; + if (m_pickerY < 0) return false; + + // Convert Y position to values so that a change of 1 corresponds to a change in spec. no by 1 + int newX = m_pickerX; + double lastY = m_spectrumDisplay->getPointedAtY(); + + QKeyEvent *keyEvent = dynamic_cast(event); + int key = keyEvent->key(); + switch (key) + { + case Qt::Key_Up: + lastY += 1.0; + break; + case Qt::Key_Down: + lastY -= 1.0; + break; + case Qt::Key_Left: + newX--; + break; + case Qt::Key_Right: + newX++; + break; + default: + // this is not the event we were looking for + return false; + } + + // Convert Y position back to unsigned pixel position + QPoint newPoint = m_spectrumDisplay->getPlotTransform(qMakePair(0.0, lastY)); + int newY = newPoint.y(); + + // Ignore the event if the position is outside of the plot area + if (newX < 0) return false; + if (newY < 0) return false; + const QSize canvasSize = m_svUI->spectrumPlot->canvas()->size(); + if (newX > canvasSize.width()) return false; + if (newY > canvasSize.height()) return false; + + // make the changes real + m_pickerX = newX; + m_pickerY = newY; + + // determine where the canvas is in global coords + QPoint canvasPos = m_svUI->spectrumPlot->canvas()->mapToGlobal(QPoint(0,0)); + // move the cursor to the correct position + m_svUI->spectrumPlot->canvas()->cursor().setPos(QPoint(canvasPos.x()+m_pickerX, canvasPos.y()+m_pickerY)); + + QPair transPoints = m_spectrumDisplay->getPlotInvTransform(QPoint(newX, newY)); + + m_spectrumDisplay->setHGraph( lastY ); + m_spectrumDisplay->setVGraph( transPoints.first ); + + m_spectrumDisplay->showInfoList( transPoints.first, lastY ); + + // consume the event + return true; + } + + // don't filter the event return false; } -void SVConnections::close_viewer() +/** + * Slot to handle closing the window. + */ +void SVConnections::closeViewer() { - this->sv_main_window->close(); + m_svMainWindow->close(); } -void SVConnections::toggle_Hscroll() +/** + * Toggles the horizontal scroll bar. + */ +void SVConnections::toggleHScroll() { - bool is_on = sv_ui->action_Hscroll->isChecked(); - sv_ui->imageHorizontalScrollBar->setVisible( is_on ); - sv_ui->imageHorizontalScrollBar->setEnabled( is_on ); - spectrum_display->UpdateImage(); + bool is_on = m_svUI->action_Hscroll->isChecked(); + m_svUI->imageHorizontalScrollBar->setVisible( is_on ); + m_svUI->imageHorizontalScrollBar->setEnabled( is_on ); + m_spectrumDisplay->updateImage(); + m_spectrumDisplay->handleResize(); } -void SVConnections::toggle_Vscroll() +/** + * Toggles the vertical scroll bar. + */ +void SVConnections::toggleVScroll() { - bool is_on = sv_ui->action_Vscroll->isChecked(); - sv_ui->imageVerticalScrollBar->setVisible( is_on ); - sv_ui->imageVerticalScrollBar->setEnabled( is_on ); - spectrum_display->UpdateImage(); + bool is_on = m_svUI->action_Vscroll->isChecked(); + m_svUI->imageVerticalScrollBar->setVisible( is_on ); + m_svUI->imageVerticalScrollBar->setEnabled( is_on ); + m_spectrumDisplay->updateImage(); + m_spectrumDisplay->handleResize(); } -void SVConnections::image_horizontal_range_changed() +/** + * Update X range when range selection changed. + */ +void SVConnections::imageHorizontalRangeChanged() { - spectrum_display->UpdateRange(); + m_spectrumDisplay->updateRange(); } -void SVConnections::graph_range_changed() +void SVConnections::graphRangeChanged() { - double value = (double)sv_ui->graph_max_slider->value(); - double min = (double)sv_ui->graph_max_slider->minimum(); - double max = (double)sv_ui->graph_max_slider->maximum(); + double value = (double)m_svUI->graph_max_slider->value(); + double min = (double)m_svUI->graph_max_slider->minimum(); + double max = (double)m_svUI->graph_max_slider->maximum(); double range_scale = (value - min)/(max - min); if ( range_scale < 0.01 ) range_scale = 0.01; - h_graph_display->SetRangeScale( range_scale ); - v_graph_display->SetRangeScale( range_scale ); + m_hGraphDisplay->setRangeScale( range_scale ); + m_vGraphDisplay->setRangeScale( range_scale ); } -void SVConnections::v_scroll_bar_moved() +/** + * Handles updating the image when a scroll bar is moved. + */ +void SVConnections::scrollBarMoved() { - spectrum_display->UpdateImage(); + m_spectrumDisplay->updateImage(); } -void SVConnections::h_scroll_bar_moved() +/** + * Handle the image splitter being moved. + * + * This moves the vertical graph slitter to the same position + * in ordetr to keep the graphs in alignment. + */ +void SVConnections::imageSplitterMoved() { - spectrum_display->UpdateImage(); + QList sizes = m_svUI->imageSplitter->sizes(); + + QList vgraph_sizes; + vgraph_sizes.append( sizes[0] ); + vgraph_sizes.append( sizes[1] ); + + m_svUI->vgraphSplitter->setSizes( vgraph_sizes ); + + m_spectrumDisplay->updateImage(); + m_spectrumDisplay->handleResize(); } -void SVConnections::imageSplitter_moved() +/** + * Handle the vertical graph splitter being moved. + * + * This moves the image slitter to the same position + * in ordetr to keep the graphs in alignment. + */ +void SVConnections::vgraphSplitterMoved() { - QList sizes = sv_ui->imageSplitter->sizes(); + QList sizes = m_svUI->vgraphSplitter->sizes(); + QList vgraph_sizes; vgraph_sizes.append( sizes[0] ); - vgraph_sizes.append( 30 ); vgraph_sizes.append( sizes[1] ); - sv_ui->vgraphSplitter->setSizes( vgraph_sizes ); - spectrum_display->UpdateImage(); + + m_svUI->imageSplitter->setSizes( vgraph_sizes ); + + m_spectrumDisplay->updateImage(); + m_spectrumDisplay->handleResize(); } -void SVConnections::imagePicker_moved() +/** + * Update the pointed at position for the m_imagePicker. + * + * @param point The position moved to. + */ +void SVConnections::imagePickerMoved(const QPoint & point) { - QwtPolygon selected_points = image_picker->selection(); - if ( selected_points.size() >= 1 ) - { - int index = selected_points.size() - 1; - spectrum_display->SetPointedAtPoint( selected_points[index] ); - } + m_pickerX = point.x(); + m_pickerY = point.y(); + m_spectrumDisplay->setPointedAtPoint( point ); } -void SVConnections::h_graphPicker_moved() +/** + * Update the pointed at position for the m_hGraphDisplay. + * + * @param point The position moved to. + */ +void SVConnections::hGraphPickerMoved(const QPoint & point) { - QwtPolygon selected_points = h_graph_picker->selection(); - if ( selected_points.size() >= 1 ) - { - int index = selected_points.size() - 1; - h_graph_display->SetPointedAtPoint( selected_points[index] ); - } + m_hGraphDisplay->setPointedAtPoint(point); } -void SVConnections::v_graphPicker_moved() +/** + * Update the pointed at position for the m_vGraphDisplay. + * + * @param point The position moved to. + */ +void SVConnections::vGraphPickerMoved(const QPoint & point) { - QwtPolygon selected_points = v_graph_picker->selection(); - if ( selected_points.size() >= 1 ) - { - int index = selected_points.size() - 1; - v_graph_display->SetPointedAtPoint( selected_points[index] ); - } + m_vGraphDisplay->setPointedAtPoint(point); } -void SVConnections::intensity_slider_moved() + +/** + * Slot to handle the intensity slider being moved. + */ +void SVConnections::intensitySliderMoved() { - double value = (double)sv_ui->intensity_slider->value(); - double min = (double)sv_ui->intensity_slider->minimum(); - double max = (double)sv_ui->intensity_slider->maximum(); + double value = (double)m_svUI->intensity_slider->value(); + double min = (double)m_svUI->intensity_slider->minimum(); + double max = (double)m_svUI->intensity_slider->maximum(); double scaled_value = 100.0*(value - min)/(max - min); - spectrum_display->SetIntensity( scaled_value ); + m_spectrumDisplay->setIntensity( scaled_value ); } -void SVConnections::heat_color_scale() + +/** + * Set the heat color scale. + */ +void SVConnections::heatColorScale() { std::vector positive_color_table; ColorMaps::GetColorMap( ColorMaps::HEAT, 256, positive_color_table ); @@ -424,11 +539,15 @@ void SVConnections::heat_color_scale() std::vector negative_color_table; ColorMaps::GetColorMap( ColorMaps::GRAY, 256, negative_color_table ); - spectrum_display->SetColorScales( positive_color_table, negative_color_table ); - ShowColorScale( positive_color_table, negative_color_table ); + m_spectrumDisplay->setColorScales( positive_color_table, negative_color_table ); + showColorScale( positive_color_table, negative_color_table ); } -void SVConnections::gray_color_scale() + +/** + * Set the gray color scale. + */ +void SVConnections::grayColorScale() { std::vector positive_color_table; ColorMaps::GetColorMap( ColorMaps::GRAY, 256, positive_color_table ); @@ -436,11 +555,15 @@ void SVConnections::gray_color_scale() std::vector negative_color_table; ColorMaps::GetColorMap( ColorMaps::HEAT, 256, negative_color_table ); - spectrum_display->SetColorScales( positive_color_table, negative_color_table ); - ShowColorScale( positive_color_table, negative_color_table ); + m_spectrumDisplay->setColorScales( positive_color_table, negative_color_table ); + showColorScale( positive_color_table, negative_color_table ); } -void SVConnections::negative_gray_color_scale() + +/** + * Set the inverse gray color scale. + */ +void SVConnections::negativeGrayColorScale() { std::vector positive_color_table; ColorMaps::GetColorMap( ColorMaps::NEGATIVE_GRAY,256, positive_color_table); @@ -448,11 +571,15 @@ void SVConnections::negative_gray_color_scale() std::vector negative_color_table; ColorMaps::GetColorMap( ColorMaps::HEAT, 256, negative_color_table ); - spectrum_display->SetColorScales( positive_color_table, negative_color_table ); - ShowColorScale( positive_color_table, negative_color_table ); + m_spectrumDisplay->setColorScales( positive_color_table, negative_color_table ); + showColorScale( positive_color_table, negative_color_table ); } -void SVConnections::green_yellow_color_scale() + +/** + * Set the green and yellow color scale. + */ +void SVConnections::greenYellowColorScale() { std::vector positive_color_table; ColorMaps::GetColorMap( ColorMaps::GREEN_YELLOW, 256, positive_color_table); @@ -460,11 +587,15 @@ void SVConnections::green_yellow_color_scale() std::vector negative_color_table; ColorMaps::GetColorMap( ColorMaps::GRAY, 256, negative_color_table ); - spectrum_display->SetColorScales( positive_color_table, negative_color_table ); - ShowColorScale( positive_color_table, negative_color_table ); + m_spectrumDisplay->setColorScales( positive_color_table, negative_color_table ); + showColorScale( positive_color_table, negative_color_table ); } -void SVConnections::rainbow_color_scale() + +/** + * Set the rainbow color scale. + */ +void SVConnections::rainbowColorScale() { std::vector positive_color_table; ColorMaps::GetColorMap( ColorMaps::RAINBOW, 256, positive_color_table ); @@ -472,11 +603,15 @@ void SVConnections::rainbow_color_scale() std::vector negative_color_table; ColorMaps::GetColorMap( ColorMaps::GRAY, 256, negative_color_table ); - spectrum_display->SetColorScales( positive_color_table, negative_color_table ); - ShowColorScale( positive_color_table, negative_color_table ); + m_spectrumDisplay->setColorScales( positive_color_table, negative_color_table ); + showColorScale( positive_color_table, negative_color_table ); } -void SVConnections::optimal_color_scale() + +/** + * Set the optimal color scale. + */ +void SVConnections::optimalColorScale() { std::vector positive_color_table; ColorMaps::GetColorMap( ColorMaps::OPTIMAL, 256, positive_color_table ); @@ -484,11 +619,15 @@ void SVConnections::optimal_color_scale() std::vector negative_color_table; ColorMaps::GetColorMap( ColorMaps::GRAY, 256, negative_color_table ); - spectrum_display->SetColorScales( positive_color_table, negative_color_table ); - ShowColorScale( positive_color_table, negative_color_table ); + m_spectrumDisplay->setColorScales( positive_color_table, negative_color_table ); + showColorScale( positive_color_table, negative_color_table ); } -void SVConnections::multi_color_scale() + +/** + * Set the multi color scale. + */ +void SVConnections::multiColorScale() { std::vector positive_color_table; ColorMaps::GetColorMap( ColorMaps::MULTI, 256, positive_color_table ); @@ -496,11 +635,15 @@ void SVConnections::multi_color_scale() std::vector negative_color_table; ColorMaps::GetColorMap( ColorMaps::GRAY, 256, negative_color_table ); - spectrum_display->SetColorScales( positive_color_table, negative_color_table ); - ShowColorScale( positive_color_table, negative_color_table ); + m_spectrumDisplay->setColorScales( positive_color_table, negative_color_table ); + showColorScale( positive_color_table, negative_color_table ); } -void SVConnections::spectrum_color_scale() + +/** + * Set the spectrum color scale. + */ +void SVConnections::spectrumColorScale() { std::vector positive_color_table; ColorMaps::GetColorMap( ColorMaps::SPECTRUM, 256, positive_color_table ); @@ -508,14 +651,17 @@ void SVConnections::spectrum_color_scale() std::vector negative_color_table; ColorMaps::GetColorMap( ColorMaps::GRAY, 256, negative_color_table ); - spectrum_display->SetColorScales( positive_color_table, negative_color_table ); - ShowColorScale( positive_color_table, negative_color_table ); + m_spectrumDisplay->setColorScales( positive_color_table, negative_color_table ); + showColorScale( positive_color_table, negative_color_table ); } -void SVConnections::load_color_map() +/** + * Slot to handle loading a color map from file. + */ +void SVConnections::loadColorMap() { - QString file_name = MantidColorMap::loadMapDialog( "", this->sv_main_window ); + QString file_name = MantidColorMap::loadMapDialog( "", m_svMainWindow ); MantidColorMap* mantid_color_map = new MantidColorMap( file_name, GraphOptions::Linear ); @@ -533,8 +679,8 @@ void SVConnections::load_color_map() std::vector negative_color_table; ColorMaps::GetColorMap( ColorMaps::GRAY, n_colors, negative_color_table ); - spectrum_display->SetColorScales( positive_color_table, negative_color_table ); - ShowColorScale( positive_color_table, negative_color_table ); + m_spectrumDisplay->setColorScales( positive_color_table, negative_color_table ); + showColorScale( positive_color_table, negative_color_table ); } @@ -542,50 +688,49 @@ void SVConnections::load_color_map() * Set the pix map that shows the color scale from the specified positive * and negative color tables. * - * @param positive_color_table The new color table used to map positive data - * values to an RGB color. - * @param negative_color_table The new color table used to map negative data - * values to an RGB color. This must have the - * same number of entries as the positive - * color table. + * @param positiveColorTable The new color table used to map positive data + * values to an RGB color. + * @param negativeColorTable The new color table used to map negative data + * values to an RGB color. This must have the + * same number of entries as the positive + * color table. */ -void SVConnections::ShowColorScale( std::vector & positive_color_table, - std::vector & negative_color_table ) +void SVConnections::showColorScale( std::vector & positiveColorTable, + std::vector & negativeColorTable ) { - size_t total_colors = positive_color_table.size() + - negative_color_table.size(); + size_t totalColors = positiveColorTable.size() + negativeColorTable.size(); - unsigned int *rgb_data = new unsigned int[ total_colors ]; + QImage image((int)totalColors, 1, QImage::Format_RGB32); + int index = 0; - size_t index = 0; - size_t n_colors = negative_color_table.size(); - for ( size_t i = 0; i < n_colors; i++ ) + size_t numColors = negativeColorTable.size(); + for(size_t i = 0; i < numColors; i++) { - rgb_data[index] = negative_color_table[ n_colors - 1 - i ]; + unsigned int pixel = static_cast(negativeColorTable[numColors - 1 - i]); + image.setPixel(index, 0, pixel); index++; } - n_colors = positive_color_table.size(); - for ( size_t i = 0; i < n_colors; i++ ) + numColors = positiveColorTable.size(); + for(size_t i = 0; i < numColors; i++) { - rgb_data[index] = positive_color_table[i]; + unsigned int pixel = static_cast(positiveColorTable[i]); + image.setPixel(index, 0, pixel); index++; } - uchar *buffer = (uchar*)rgb_data; - QImage image( buffer, (int)total_colors, 1, QImage::Format_RGB32 ); QPixmap pixmap = QPixmap::fromImage(image); - sv_ui->color_scale->setPixmap( pixmap ); - - delete[] rgb_data; + m_svUI->color_scale->setPixmap( pixmap ); } -void SVConnections::online_help_slot() +/** + * Slot to open the online help webapge for the interface. + */ +void SVConnections::openOnlineHelp() { QDesktopServices::openUrl(QUrl("http://www.mantidproject.org/MantidPlot:_ImageViewer")); - } } // namespace SpectrumView -} // namespace MantidQt +} // namespace MantidQt diff --git a/Code/Mantid/MantidQt/SpectrumViewer/src/SVUtils.cpp b/Code/Mantid/MantidQt/SpectrumViewer/src/SVUtils.cpp index 81926bcb02d0..e8a2528a8e36 100644 --- a/Code/Mantid/MantidQt/SpectrumViewer/src/SVUtils.cpp +++ b/Code/Mantid/MantidQt/SpectrumViewer/src/SVUtils.cpp @@ -9,33 +9,12 @@ namespace MantidQt namespace SpectrumView { -/** - * Extract a double from the specified string, if possible. - * - * @param text The string containing a double value - * @param value Set to the value from the string if the conversion - * worked. - * @return true if the string could be successfully converted to a double, - * and return false otherwise. - */ -bool SVUtils::StringToDouble( std::string text, - double &value ) -{ - std::istringstream strs(text); - if ( strs >> value ) - { - return true; - } - return false; -} - - /** * Get a formatted string form of the specified double precision value. * - * @param width The total number of characters to be used in the + * @param width The total number of characters to be used in the * formatted string - * @param precision The number of significant figures to use + * @param precision The number of significant figures to use * @param value The double precsion number to be formatted * @param str String that will be set to the formatted number */ @@ -60,7 +39,7 @@ void SVUtils::Format( int width, * to a string using the specified width and precision. * * @param name String name that is first pushed on the list - * @param width The total number of characters to be used when formatting + * @param width The total number of characters to be used when formatting * the value * @param precision The number of significant figures to use * @param value The double precsion number to be formatted and pushed on @@ -83,7 +62,7 @@ void SVUtils::PushNameValue( const std::string & name, /** * Find a non-degenerate interval containing all the specified values. - * If there are more than one values in the list, min will be set to + * If there are more than one values in the list, min will be set to * the smallest value and max will be set to the largest value. If there * is only on value in the list, min will be set to 90% of that value and * max will be set to 110% of that value. If the only value in the list @@ -117,11 +96,11 @@ bool SVUtils::FindValidInterval( const QVector & values, /** * Adjust min and max so that min is strictly less than max. If min > max - * the values are swapped. If min = max != 0, they will be shifted off from + * the values are swapped. If min = max != 0, they will be shifted off from * their initial common value by 10%. If min = max = 0, they will be set * to -1 and 1, respectively. * - * @param min Set to be strictly less than max. + * @param min Set to be strictly less than max. * @param max Set to be strictly greater than min. * * @return true if the original values were OK and are unchanged, return @@ -130,11 +109,11 @@ bool SVUtils::FindValidInterval( const QVector & values, bool SVUtils::FindValidInterval( double & min, double & max ) { - bool values_OK = true; + bool valuesOK = true; - if ( max == min ) // adjust values so they are not equal + if ( max == min ) // adjust values so they are not equal { - values_OK = false; + valuesOK = false; if ( min == 0 ) { min = -1, @@ -147,25 +126,25 @@ bool SVUtils::FindValidInterval( double & min, } } - if ( min > max ) // fix the order + if ( min > max ) // fix the order { - values_OK = false; + valuesOK = false; double temp = min; min = max; max = temp; } - return values_OK; + return valuesOK; } /** * Adjust min and max so that min is strictly less than max, and both are - * greater than 0. If min > max the values are swapped. If min = max > 0, - * they will be shifted off from their initial common value by factors of 10. + * greater than 0. If min > max the values are swapped. If min = max > 0, + * they will be shifted off from their initial common value by factors of 10. * If min = max = 0, they will be set to 0.1 and 10, respectively. * - * @param min Set to be strictly less than max and more than 0. + * @param min Set to be strictly less than max and more than 0. * @param max Set to be strictly greater than min. * * @return true if the original values were OK and are unchanged, return @@ -174,39 +153,40 @@ bool SVUtils::FindValidInterval( double & min, bool SVUtils::FindValidLogInterval( double & min, double & max ) { - bool values_OK = true; + bool valuesOK = true; if ( min < 0 ) { std::cout << "min < 0 " << min << std::endl; - values_OK = false; + valuesOK = false; min = -min; } if ( max < 0 ) { std::cout << "max < 0 " << max << std::endl; - values_OK = false; + valuesOK = false; max = -max; } - if ( min > max ) // fix the order + if ( min > max ) // Fix the order { std::cout << "min > max " << min << " > " << max << std::endl; - values_OK = false; + valuesOK = false; double temp = min; min = max; max = temp; } - if ( min == 0 && max > 0 ) // raise min, so the interval covers 2 orders - { // of magnitude + // Raise min, so the interval covers 2 orders of magnitude + if ( min == 0 && max > 0 ) + { std::cout << "min == 0, max > 0 " << min << ", " << max << std::endl; - values_OK = false; + valuesOK = false; min = 0.01 * max; } - else if ( max == min ) // adjust values so they are not equal + else if ( max == min ) // Adjust values so they are not equal { - values_OK = false; + valuesOK = false; std::cout << "min == max " << min << " == " << max << std::endl; if ( min == 0 ) { @@ -220,7 +200,7 @@ bool SVUtils::FindValidLogInterval( double & min, } } - return values_OK; + return valuesOK; } @@ -240,7 +220,7 @@ bool SVUtils::FindValidLogInterval( double & min, */ int SVUtils::NumSteps( double min, double max, double step ) { - int n_bins = 0; + int numBins = 0; if ( step == 0 || (max-min) <= 0 || (step < 0 && min <= 0) ) { @@ -249,54 +229,54 @@ int SVUtils::NumSteps( double min, double max, double step ) if ( step > 0 ) // uniform steps { - n_bins = (int)(( max - min ) / step); + numBins = (int)(( max - min ) / step); } else if ( step < 0 ) // log steps { -// -// Interpret step as the negative of the fractional increase in the -// first bin boundary, relative to the zeroth bin boundary (min). -// This is the convention followed by the Rebin() algorithm in Mantid. -// - n_bins = (int)ceil( (log(max) - log(min))/log(1 - step) ); - if ( n_bins < 1 ) - n_bins = 1; -// -// This formula assumes a negative step indicates a log scale with -// the size of the first bin specified by |step|. This is not the -// convention used in the Rebin() algorithm, so we have commented -// this out and use the Mantid convention. -// -// n_bins = (int)ceil( (log(max) - log(min))/log(1 - step/min) ); + + /* Interpret step as the negative of the fractional increase in the */ + /* first bin boundary, relative to the zeroth bin boundary (min). */ + /* This is the convention followed by the Rebin() algorithm in Mantid. */ + + numBins = (int)ceil( (log(max) - log(min))/log(1 - step) ); + if ( numBins < 1 ) + numBins = 1; + + /* This formula assumes a negative step indicates a log scale with */ + /* the size of the first bin specified by |step|. This is not the */ + /* convention used in the Rebin algorithm, so we have commented */ + /* this out and use the Mantid convention. */ + + //numBins = (int)ceil( (log(max) - log(min))/log(1 - step/min) ); } - return n_bins; + return numBins; } /** - * Calculate a point in [new_min,new_max] by linear interpolation, and - * clamp the result to be in the interval [new_min,new_max]. + * Calculate a point in [newMin,newMax] by linear interpolation, and + * clamp the result to be in the interval [newMin,newMax]. * @param min Left endpoint of original interval * @param max Right endpoint of original interval * @param val Reference point in orignal interval - * @param new_min Left endpoint of new interval - * @param new_max Right endpoint of new interval - * @param new_val Point in new interval that is placed in [new_min,new_max] - * in the same proportion as val is in [min,max]. - * @return true if the calculated value is in [new_min,new_max] and false + * @param newMin Left endpoint of new interval + * @param newMax Right endpoint of new interval + * @param newVal Point in new interval that is placed in [newMin,newMax] + * in the same proportion as val is in [min,max]. + * @return true if the calculated value is in [newMin,newMax] and false * if it is outside of the interval. */ bool SVUtils::Interpolate( double min, double max, double val, - double new_min, - double new_max, - double & new_val ) + double newMin, + double newMax, + double & newVal ) { - new_val = (val - min)/( max - min ) * (new_max - new_min) + new_min; + newVal = (val - min)/( max - min ) * (newMax - newMin) + newMin; - if ( new_val < new_min || new_val > new_max ) + if ( newVal < newMin || newVal > newMax ) return false; else return true; @@ -304,32 +284,32 @@ bool SVUtils::Interpolate( double min, /** - * Calculate the value in [new_min,new_max] on a logarithmic scale that + * Calculate the value in [newMin,newMax] on a logarithmic scale that * would correspond to the point val on a linear scale on [min,max]. * For example, if val was half way from min to max, and the log scale - * extended from new_min = 1 to new_max = 100, then new_val would return 10, + * extended from newMin = 1 to newMax = 100, then newVal would return 10, * since 10 is half way along a log scale from 1 to 100. - * Clamp the result to be in the interval [new_min,new_max]. + * Clamp the result to be in the interval [newMin,newMax]. * @param min Left endpoint of original interval with linear scale * @param max Right endpoint of original interval with linear scale * @param val Reference point in orignal interval - * @param new_min Left endpoint of new interval with log scale - * @param new_max Right endpoint of new interval with log scale - * @param new_val Point in new interval that is placed in [new_min,new_max] + * @param newMin Left endpoint of new interval with log scale + * @param newMax Right endpoint of new interval with log scale + * @param newVal Point in new interval that is placed in [newMin,newMax] * in the same proportion as val is in [min,max]. - * @return true if the calculated value is in [new_min,new_max] and false + * @return true if the calculated value is in [newMin,newMax] and false * if it is outside of the interval. */ bool SVUtils::LogInterpolate( double min, double max, double val, - double new_min, - double new_max, - double & new_val ) + double newMin, + double newMax, + double & newVal ) { - new_val = new_min * exp( (val-min)/(max-min) * log ( new_max/new_min )); + newVal = newMin * exp( (val-min)/(max-min) * log ( newMax/newMin )); - if ( new_val < new_min || new_val > new_max ) + if ( newVal < newMin || newVal > newMax ) return false; else return true; @@ -338,68 +318,71 @@ bool SVUtils::LogInterpolate( double min, /** * Find a new interval [min,max] with boundaries aligned with the underlying - * data bin boundaries, then set first_index to the index of the bin, + * data bin boundaries, then set firstIndex to the index of the bin, * corresponding to the min value and set the number of steps to the smaller * of the number of steps in the data, and the initial value of the number * of steps. NOTE: This calculation is needed for displaying a fixed array * of data that should not be rebinned. * - * @param global_min Smallest value covered by the underlying data - * @param global_max Largest value covered by the underlying data - * @param global_steps Number of uniform bins the underlying data is - * divided into on the interval [global_min,global_max]. - * @param first_index This will be set to the bin number containing the + * @param globalMin Smallest value covered by the underlying data + * @param globalMax Largest value covered by the underlying data + * @param globalSteps Number of uniform bins the underlying data is + * divided into on the interval [globalMin,globalMax]. + * @param firstIndex This will be set to the bin number containing the * specified min value. - * @param min On input this should be smallest value of interest - * in the interval. This will be adjusted to be the + * @param min On input this should be smallest value of interest + * in the interval. This will be adjusted to be the * left bin boundary of the bin containing the specified * min value. - * @param max On input this should be largest value of interest - * in the interval. This will be adjusted to be the + * @param max On input this should be largest value of interest + * in the interval. This will be adjusted to be the * right bin boundary of the bin containing the specified * max value, if max is in the interior of a bin. * @param steps On input this should be the number of bins desired * between the min and max values. This will be adjusted * to be no more than the number of steps available. */ -bool SVUtils::CalculateInterval( double global_min, - double global_max, - size_t global_steps, - size_t & first_index, +bool SVUtils::CalculateInterval( double globalMin, + double globalMax, + size_t globalSteps, + size_t & firstIndex, double & min, double & max, size_t & steps ) { - double d_index; - // find bin containing min....... - Interpolate( global_min, global_max, min, - 0.0, (double)global_steps, d_index ); + double index; + + // Find bin containing min + Interpolate( globalMin, globalMax, min, + 0.0, (double)globalSteps, index ); + + // min_index is the number of the bin containing min + int min_index = (int)floor(index); - int min_index = (int)floor(d_index); // min_index is the number of the bin - // containing min if ( min_index < 0 ) min_index = 0; - // now set min to the value at the - // left edge of bin at min_index - Interpolate( 0.0, (double)global_steps, (double)min_index, - global_min, global_max, min ); - // find bin containing max........ - Interpolate( global_min, global_max, max, - 0.0, (double)global_steps, d_index ); + // Now set min to the value at the left edge of bin at min_index + Interpolate( 0.0, (double)globalSteps, (double)min_index, + globalMin, globalMax, min ); + + // Find bin containing max + Interpolate( globalMin, globalMax, max, + 0.0, (double)globalSteps, index ); + + /* max_index is the number of the bin */ + /* containing max, or with max as */ + /* right hand endpoint */ + int max_index = (int)ceil(index) - 1; - int max_index = (int)ceil(d_index) - 1;// max index is the number of the bin - // containing max, or with max as - // right hand endpoint - if ( max_index >= (int)global_steps ) - max_index = (int)global_steps - 1; + if ( max_index >= (int)globalSteps ) + max_index = (int)globalSteps - 1; - // now set max to the value at the - // right edge of bin max_index - Interpolate( 0, (double)global_steps, (double)(max_index + 1), - global_min, global_max, max ); + // Now set max to the value at the right edge of bin max_index + Interpolate( 0, (double)globalSteps, (double)(max_index + 1), + globalMin, globalMax, max ); - first_index = min_index; + firstIndex = min_index; size_t source_steps = max_index - min_index + 1; if ( steps > source_steps ) @@ -409,4 +392,4 @@ bool SVUtils::CalculateInterval( double global_min, } } // namespace SpectrumView -} // namespace MantidQt +} // namespace MantidQt diff --git a/Code/Mantid/MantidQt/SpectrumViewer/src/SliderHandler.cpp b/Code/Mantid/MantidQt/SpectrumViewer/src/SliderHandler.cpp index e2ce4353c19e..d5fec750d75f 100644 --- a/Code/Mantid/MantidQt/SpectrumViewer/src/SliderHandler.cpp +++ b/Code/Mantid/MantidQt/SpectrumViewer/src/SliderHandler.cpp @@ -1,8 +1,8 @@ - #include #include #include "MantidQtSpectrumViewer/SliderHandler.h" +#include "MantidQtSpectrumViewer/SVUtils.h" namespace MantidQt { @@ -10,114 +10,129 @@ namespace SpectrumView { /** - * Construct a SliderHandler object to manage the image scrollbars from the + * Construct a SliderHandler object to manage the image scrollbars from the * specified UI. */ -SliderHandler::SliderHandler( Ui_SpectrumViewer* sv_ui ) : ISliderHandler() +SliderHandler::SliderHandler( Ui_SpectrumViewer* svUI ) + : ISliderHandler(), m_svUI(svUI) +{ +} + + +/** + * Reconfigure the image scrollbars for the specified data and drawing area. + * + * Used when the size of the plot area has changed. + * + * @param drawArea Rectangle specifiying the region where the image will + * be drawn + * @param dataSource SpectrumDataSource that provides the data to be drawn + */ +void SliderHandler::reConfigureSliders( QRect drawArea, + SpectrumDataSource_sptr dataSource ) { - this->sv_ui = sv_ui; + QScrollBar* vScroll = m_svUI->imageVerticalScrollBar; + + int oldVValue = vScroll->value(); + int numRows = (int)dataSource->getNRows(); + int step = vScroll->pageStep(); + + configureSlider( vScroll, numRows, drawArea.height(), oldVValue ); + + vScroll->setValue(oldVValue + (step / 2)); } /** * Configure the image scrollbars for the specified data and drawing area. * - * @param draw_area Rectangle specifiying the region where the image will - * be drawn - * @param data_source SpectrumDataSource that provides the data to be drawn + * @param drawArea Rectangle specifiying the region where the image will + * be drawn + * @param dataSource SpectrumDataSource that provides the data to be drawn */ -void SliderHandler::ConfigureSliders( QRect draw_area, - SpectrumDataSource* data_source ) +void SliderHandler::configureSliders( QRect drawArea, + SpectrumDataSource_sptr dataSource ) { - QScrollBar* v_scroll = sv_ui->imageVerticalScrollBar; - int n_rows = (int)data_source->GetNRows(); - ConfigureSlider( v_scroll, n_rows, draw_area.height(), n_rows ); + QScrollBar* vScroll = m_svUI->imageVerticalScrollBar; + int numRows = (int)dataSource->getNRows(); + configureSlider( vScroll, numRows, drawArea.height(), numRows ); - ConfigureHSlider( 2000, draw_area.width() ); // initial default, 2000 bins + configureHSlider( 2000, drawArea.width() ); // initial default, 2000 bins } /** - * Public method to configure the horizontal scrollbar to cover the + * Public method to configure the horizontal scrollbar to cover the * specified range of data columns, displayed in the specified number of - * pixels. + * pixels. * - * @param n_data_steps The number of columns in the data that should be + * @param numDataSetps The number of columns in the data that should be * displayed - * @param n_pixels The number of pixels avaliable to show the data + * @param numPixels The number of pixels avaliable to show the data */ -void SliderHandler::ConfigureHSlider( int n_data_steps, - int n_pixels ) +void SliderHandler::configureHSlider( int numDataSetps, + int numPixels ) { - QScrollBar* h_scroll = sv_ui->imageHorizontalScrollBar; - ConfigureSlider( h_scroll, n_data_steps, n_pixels, 0 ); + QScrollBar* hScroll = m_svUI->imageHorizontalScrollBar; + configureSlider( hScroll, numDataSetps, numPixels, 0 ); } /** * Configure the specified scrollbar to cover the specified range of data - * steps, displayed in the specified number of pixels. + * steps, displayed in the specified number of pixels. * - * @param scroll_bar The scroll bar that will be configured - * @param n_data_steps The number of bins in the data that should be + * @param scrollBar The scroll bar that will be configured + * @param numDataSetps The number of bins in the data that should be * displayed - * @param n_pixels The number of pixels avaliable to show the data + * @param numPixels The number of pixels avaliable to show the data * @param val The initial position of the scrollbar, between 0 and - * n_data_steps. + * numDataSetps. */ -void SliderHandler::ConfigureSlider( QScrollBar* scroll_bar, - int n_data_steps, - int n_pixels, +void SliderHandler::configureSlider( QScrollBar* scrollBar, + int numDataSetps, + int numPixels, int val ) { - int step = n_pixels; - if ( step > n_data_steps ) - { - step = n_data_steps; - } + int step = numPixels; + if ( step > numDataSetps ) + step = numDataSetps; + if ( step <= 0 ) - { step = 1; - } - int max = n_data_steps - step; + int max = numDataSetps - step; if ( max <= 0 ) - { max = 0; - } if ( val < 0 ) - { val = 0; - } if ( val > max ) - { val = max; - } - scroll_bar->setMinimum( 0 ); - scroll_bar->setMaximum( max ); - scroll_bar->setPageStep( step ); - scroll_bar->setValue( val ); + scrollBar->setMinimum( 0 ); + scrollBar->setMaximum( max ); + scrollBar->setPageStep( step ); + scrollBar->setValue( val ); } /** * Return true if the image horizontal scrollbar is enabled. */ -bool SliderHandler::HSliderOn() +bool SliderHandler::hSliderOn() { - return sv_ui->imageHorizontalScrollBar->isEnabled(); + return m_svUI->imageHorizontalScrollBar->isEnabled(); } /** * Return true if the image vertical scrollbar is enabled. */ -bool SliderHandler::VSliderOn() +bool SliderHandler::vSliderOn() { - return sv_ui->imageVerticalScrollBar->isEnabled(); + return m_svUI->imageVerticalScrollBar->isEnabled(); } @@ -131,14 +146,14 @@ bool SliderHandler::VSliderOn() * @param x_max This will be set to the last bin number to display in the * x direction */ -void SliderHandler::GetHSliderInterval( int &x_min, int &x_max ) +void SliderHandler::getHSliderInterval( int &x_min, int &x_max ) { - QScrollBar* h_scroll = sv_ui->imageHorizontalScrollBar; - int step = h_scroll->pageStep(); - int value = h_scroll->value(); + QScrollBar* hScroll = m_svUI->imageHorizontalScrollBar; + int step = hScroll->pageStep(); + int value = hScroll->value(); - x_min = value; - x_max = x_min + step; + x_min = value; + x_max = x_min + step; } @@ -152,18 +167,18 @@ void SliderHandler::GetHSliderInterval( int &x_min, int &x_max ) * @param y_max This will be set to the last bin number to display in the * y direction */ -void SliderHandler::GetVSliderInterval( int &y_min, int &y_max ) +void SliderHandler::getVSliderInterval( int &y_min, int &y_max ) { - QScrollBar* v_scroll = sv_ui->imageVerticalScrollBar; - int max = v_scroll->maximum(); - int step = v_scroll->pageStep(); - int value = v_scroll->value(); - - y_min = max - value; // invert value since scale increases from + QScrollBar* vScroll = m_svUI->imageVerticalScrollBar; + int max = vScroll->maximum(); + int step = vScroll->pageStep(); + int value = vScroll->value(); + + y_min = max - value; // invert value since scale increases from y_max = y_min + step; // bottom to top, but scroll bar increases // the other way. } } // namespace SpectrumView -} // namespace MantidQt +} // namespace MantidQt diff --git a/Code/Mantid/MantidQt/SpectrumViewer/src/SpectrumDataSource.cpp b/Code/Mantid/MantidQt/SpectrumViewer/src/SpectrumDataSource.cpp index 4cff6ce44d02..510b583f2d4b 100644 --- a/Code/Mantid/MantidQt/SpectrumViewer/src/SpectrumDataSource.cpp +++ b/Code/Mantid/MantidQt/SpectrumViewer/src/SpectrumDataSource.cpp @@ -9,27 +9,23 @@ namespace MantidQt namespace SpectrumView { - /** * Construct data source with specified total range and data size. * - * @param total_xmin The smallest 'x' value covered by the data - * @param total_xmax The largest 'x' value covered by the data - * @param total_ymin The smallest 'y' value covered by the data - * @param total_ymax The largest 'y' value covered by the data - * @param total_rows The total number of rows the data is divided into - * @param total_cols The total number of columns the data is divided into + * @param totalXMin The smallest 'x' value covered by the data + * @param totalXMax The largest 'x' value covered by the data + * @param totalYMin The smallest 'y' value covered by the data + * @param totalYMax The largest 'y' value covered by the data + * @param totalRows The total number of rows the data is divided into + * @param totalCols The total number of columns the data is divided into */ -SpectrumDataSource::SpectrumDataSource( double total_xmin, double total_xmax, - double total_ymin, double total_ymax, - size_t total_rows, size_t total_cols ) +SpectrumDataSource::SpectrumDataSource( double totalXMin, double totalXMax, + double totalYMin, double totalYMax, + size_t totalRows, size_t totalCols ) : + m_totalXMin(totalXMin), m_totalXMax(totalXMax), + m_totalYMin(totalYMin), m_totalYMax(totalYMax), + m_totalRows(totalRows), m_totalCols(totalCols) { - this->total_xmin = total_xmin; - this->total_xmax = total_xmax; - this->total_ymin = total_ymin; - this->total_ymax = total_ymax; - this->total_rows = total_rows; - this->total_cols = total_cols; } @@ -41,90 +37,84 @@ SpectrumDataSource::~SpectrumDataSource() /** * Get the smallest 'x' value covered by the data. */ -double SpectrumDataSource::GetXMin() +double SpectrumDataSource::getXMin() { - return total_xmin; + return m_totalXMin; } /** * Get the largest 'x' value covered by the data. */ -double SpectrumDataSource::GetXMax() +double SpectrumDataSource::getXMax() { - return total_xmax; + return m_totalXMax; } /** * Get the smallest 'y' value covered by the data. */ -double SpectrumDataSource::GetYMin() +double SpectrumDataSource::getYMin() { - return total_ymin; + return m_totalYMin; } /** * Get the largest 'y' value covered by the data. */ -double SpectrumDataSource::GetYMax() +double SpectrumDataSource::getYMax() { - return total_ymax; + return m_totalYMax; } /** * Get the total number of rows the data is divided into */ -size_t SpectrumDataSource::GetNRows() +size_t SpectrumDataSource::getNRows() { - return total_rows; + return m_totalRows; } /** * Get the total number of columns the data is divided into */ -size_t SpectrumDataSource::GetNCols() +size_t SpectrumDataSource::getNCols() { - return total_cols; + return m_totalCols; } /** * Clamp x to the interval of x-values covered by this DataSource - * @param x If x is more than xmax it will be set to xmax. If x is less + * @param x If x is more than xmax it will be set to xmax. If x is less * than xmin, it will be set to xmin. */ -void SpectrumDataSource::RestrictX( double & x ) +void SpectrumDataSource::restrictX( double & x ) { - if ( x > total_xmax ) - { - x = total_xmax; - } - else if ( x < total_xmin ) - { - x = total_xmin; - } + if ( x > m_totalXMax ) + x = m_totalXMax; + + else if ( x < m_totalXMin ) + x = m_totalXMin; } /** * Clamp y to the interval of y-values covered by this DataSource. - * @param y If y is more than ymax it will be set to ymax. If y is less + * @param y If y is more than ymax it will be set to ymax. If y is less * than ymin, it will be set to ymin. */ -void SpectrumDataSource::RestrictY( double & y ) +void SpectrumDataSource::restrictY( double & y ) { - if ( y > total_ymax ) - { - y = total_ymax; - } - else if ( y < total_ymin ) - { - y = total_ymin; - } + if ( y > m_totalYMax ) + y = m_totalYMax; + + else if ( y < m_totalYMin ) + y = m_totalYMin; } @@ -133,16 +123,13 @@ void SpectrumDataSource::RestrictY( double & y ) * @param row If row is more than n_rows-1, it is set to n_rows-1. If * row < 0 it is set to zero. */ -void SpectrumDataSource::RestrictRow( int & row ) +void SpectrumDataSource::restrictRow( int & row ) { - if ( row >= (int)total_rows ) - { - row = (int)total_rows - 1; - } + if ( row >= (int)m_totalRows ) + row = (int)m_totalRows - 1; + else if ( row < 0 ) - { row = 0; - } } @@ -151,27 +138,24 @@ void SpectrumDataSource::RestrictRow( int & row ) * @param col If col is more than n_cols-1, it is set to n_cols-1. If * col < 0 it is set to zero. */ -void SpectrumDataSource::RestrictCol( int & col ) +void SpectrumDataSource::restrictCol( int & col ) { - if ( col >= (int)total_cols ) - { - col = (int)total_cols - 1; - } + if ( col >= (int)m_totalCols ) + col = (int)m_totalCols - 1; + else if ( col < 0 ) - { col = 0; - } } /** * Convenience method to get all the data at the maximum resolution. */ -DataArray* SpectrumDataSource::GetDataArray( bool is_log_x ) +DataArray_const_sptr SpectrumDataSource::getDataArray( bool isLogX ) { - return GetDataArray( total_xmin, total_xmax, total_ymin, total_ymax, - total_rows, total_cols, is_log_x ); + return getDataArray( m_totalXMin, m_totalXMax, m_totalYMin, m_totalYMax, + m_totalRows, m_totalCols, isLogX ); } } // namespace SpectrumView -} // namespace MantidQt +} // namespace MantidQt diff --git a/Code/Mantid/MantidQt/SpectrumViewer/src/SpectrumDisplay.cpp b/Code/Mantid/MantidQt/SpectrumViewer/src/SpectrumDisplay.cpp index 0b5caea9fdbf..70fdbcea414c 100644 --- a/Code/Mantid/MantidQt/SpectrumViewer/src/SpectrumDisplay.cpp +++ b/Code/Mantid/MantidQt/SpectrumViewer/src/SpectrumDisplay.cpp @@ -14,6 +14,7 @@ #include "MantidQtSpectrumViewer/ColorMaps.h" #include "MantidQtSpectrumViewer/QtUtils.h" #include "MantidQtSpectrumViewer/SVUtils.h" +#include "MantidQtSpectrumViewer/SliderHandler.h" namespace MantidQt { @@ -23,178 +24,194 @@ namespace SpectrumView /** * Make an SpectrumDisplay to display with the given widgets and controls. * - * @param spectrum_plot The QwtPlot that will hold the image - * @param slider_handler The object that manages interaction with the - * horizontal and vertical scroll bars - * @param range_handler The object that manages interaction with the range. - * @param h_graph The GraphDisplay for the graph showing horizontal - * cuts through the image at the bottom of the image. - * @param v_graph The GraphDisplay for the graph showing vertical - * cuts through the image at the left side of the image. - * @param table_widget The widget where the information about a pointed - * at location will be displayed. + * @param spectrumPlot The QwtPlot that will hold the image + * @param sliderHandler The object that manages interaction with the + * horizontal and vertical scroll bars + * @param rangeHander The object that manages interaction with the range. + * @param hGraph The GraphDisplay for the graph showing horizontal + * cuts through the image at the bottom of the image. + * @param vGraph The GraphDisplay for the graph showing vertical + * cuts through the image at the left side of the image. + * @param tableWidget The widget where the information about a pointed + * at location will be displayed. */ -SpectrumDisplay::SpectrumDisplay( QwtPlot* spectrum_plot, - ISliderHandler* slider_handler, - IRangeHandler* range_handler, - GraphDisplay* h_graph, - GraphDisplay* v_graph, - QTableWidget* table_widget ) - : data_source(0), spectrum_plot(spectrum_plot), slider_handler(slider_handler), - range_handler(range_handler), h_graph_display(h_graph), v_graph_display(v_graph), - image_table(table_widget) +SpectrumDisplay::SpectrumDisplay( QwtPlot* spectrumPlot, + ISliderHandler* sliderHandler, + IRangeHandler* rangeHander, + GraphDisplay* hGraph, + GraphDisplay* vGraph, + QTableWidget* tableWidget ) : + m_spectrumPlot(spectrumPlot), + m_sliderHandler(sliderHandler), + m_rangeHandler(rangeHander), + m_hGraphDisplay(hGraph), + m_vGraphDisplay(vGraph), + m_imageTable(tableWidget) { ColorMaps::GetColorMap( ColorMaps::HEAT, 256, - positive_color_table ); + m_positiveColorTable ); ColorMaps::GetColorMap( ColorMaps::GRAY, 256, - negative_color_table ); + m_negativeColorTable ); - spectrum_plot_item = new SpectrumPlotItem; + m_spectrumPlotItem = new SpectrumPlotItem; setupSpectrumPlotItem(); } SpectrumDisplay::~SpectrumDisplay() { - // std::cout << "SpectrumDisplay destructor called" << std::endl; - delete spectrum_plot_item; + delete m_spectrumPlotItem; } + bool SpectrumDisplay::hasData(const std::string& wsName, const boost::shared_ptr ws) { - return this->data_source->hasData(wsName, ws); + return m_dataSource->hasData(wsName, ws); } + /// Set some properties of the SpectrumPlotItem object void SpectrumDisplay::setupSpectrumPlotItem() { - spectrum_plot_item->setXAxis( QwtPlot::xBottom ); - spectrum_plot_item->setYAxis( QwtPlot::yLeft ); + m_spectrumPlotItem->setXAxis( QwtPlot::xBottom ); + m_spectrumPlotItem->setYAxis( QwtPlot::yLeft ); - spectrum_plot_item->attach( spectrum_plot ); + m_spectrumPlotItem->attach( m_spectrumPlot ); double DEFAULT_INTENSITY = 30; - SetIntensity( DEFAULT_INTENSITY ); + setIntensity( DEFAULT_INTENSITY ); } + /** * Set the data source from which the image and data table information will * be obtained. * - * @param data_source The SpectrumDataSource that provides the array of values + * @param dataSource The SpectrumDataSource that provides the array of values * and information for the table. */ -void SpectrumDisplay::SetDataSource( SpectrumDataSource* data_source ) +void SpectrumDisplay::setDataSource( SpectrumDataSource_sptr dataSource ) { - this->data_source = data_source; - h_graph_display->SetDataSource( data_source ); - v_graph_display->SetDataSource( data_source ); - - total_y_min = data_source->GetYMin(); - total_y_max = data_source->GetYMax(); - - total_x_min = data_source->GetXMin(); - total_x_max = data_source->GetXMax(); - - pointed_at_x = DBL_MAX; - pointed_at_y = DBL_MAX; - - int n_rows = 500; // get reasonable size initial image data - int n_cols = 500; - // data_array is deleted in the SpectrumPlotItem - data_array = data_source->GetDataArray( total_x_min, total_x_max, - total_y_min, total_y_max, - n_rows, n_cols, - false ); - - spectrum_plot->setAxisScale( QwtPlot::xBottom, data_array->GetXMin(), - data_array->GetXMax() ); - spectrum_plot->setAxisScale( QwtPlot::yLeft, data_array->GetYMin(), - data_array->GetYMax() ); - - spectrum_plot_item->SetData( data_array, - &positive_color_table, - &negative_color_table ); - - range_handler->ConfigureRangeControls( data_source ); + m_dataSource = dataSource; - QRect draw_area; - GetDisplayRectangle( draw_area ); - slider_handler->ConfigureSliders( draw_area, data_source ); + m_hGraphDisplay->setDataSource( m_dataSource ); + m_vGraphDisplay->setDataSource( m_dataSource ); + + m_totalYMin = m_dataSource->getYMin(); + m_totalYMax = m_dataSource->getYMax(); + + m_totalXMin = m_dataSource->getXMin(); + m_totalXMax = m_dataSource->getXMax(); + + m_pointedAtX = DBL_MAX; + m_pointedAtY = DBL_MAX; + + int n_rows = static_cast(m_totalYMax - m_totalYMin); // get reasonable size initial image data + int n_cols = 500; + + // m_dataArray is deleted in the SpectrumPlotItem + m_dataArray = m_dataSource->getDataArray( m_totalXMin, m_totalXMax, + m_totalYMin, m_totalYMax, + n_rows, n_cols, + false ); + + m_spectrumPlot->setAxisScale( QwtPlot::xBottom, m_dataArray->getXMin(), m_dataArray->getXMax() ); + m_spectrumPlot->setAxisScale( QwtPlot::yLeft, m_dataArray->getYMin(), m_dataArray->getYMax() ); + + m_spectrumPlotItem->setData( m_dataArray, + &m_positiveColorTable, + &m_negativeColorTable ); + + m_rangeHandler->configureRangeControls( m_dataSource ); + + QRect drawArea; + getDisplayRectangle( drawArea ); + m_sliderHandler->configureSliders( drawArea, m_dataSource ); } + /** * Rebuild the scrollbars and image due to a change in the range xmin, xmax * or step size. It should be invoked when the user changes the values in * the xmin, xmax or step controls. It should not be called directly from * other threads. */ -void SpectrumDisplay::UpdateRange() +void SpectrumDisplay::updateRange() { - if ( data_source == 0 ) - { - return; // no image data to update - } + if ( m_dataSource == 0 ) + return; // No image data to update - if ( DataSourceRangeChanged() ) - { - SetDataSource( data_source ); // re-initialize with the altered source - } + if ( dataSourceRangeChanged() ) + setDataSource( m_dataSource ); // Re-initialize with the altered source - QRect display_rect; - GetDisplayRectangle( display_rect ); - // range controls now determine - // the number of bins - double min = total_x_min; - double max = total_x_max; - double step = (total_x_max - total_x_min)/2000; - range_handler->GetRange( min, max, step ); - - int n_bins = SVUtils::NumSteps( min, max, step ); - if ( n_bins == 0 ) - { + QRect displayRect; + getDisplayRectangle( displayRect ); + // Range controls now determine the number of bins + + double min = m_totalXMin; + double max = m_totalXMax; + double step = (m_totalXMax - m_totalXMin) / 2000; + m_rangeHandler->getRange( min, max, step ); + + int numBins = SVUtils::NumSteps( min, max, step ); + if ( numBins == 0 ) return; - } - slider_handler->ConfigureHSlider( n_bins, display_rect.width() ); + m_sliderHandler->configureHSlider( numBins, displayRect.width() ); - UpdateImage(); + updateImage(); } + +/** + * Updates the rnages of the scroll bars when the window is resized. + */ +void SpectrumDisplay::handleResize() +{ + QRect draw_area; + getDisplayRectangle( draw_area ); + + // Notify the sliders of the resize + SliderHandler * sliderHandler = dynamic_cast(m_sliderHandler); + if(sliderHandler) + sliderHandler->reConfigureSliders(draw_area, m_dataSource); +} + + /** * This will rebuild the image from the data source. It should be invoked * when the scroll bar is moved, the plot area is resize or the color or * intensity tables are changed. It should not be called directly from * other threads. */ -void SpectrumDisplay::UpdateImage() +void SpectrumDisplay::updateImage() { - if ( data_source == 0 ) + if ( m_dataSource == 0 ) { return; // no image data to update } - if ( DataSourceRangeChanged() ) + if ( dataSourceRangeChanged() ) { - SetDataSource( data_source ); // re-initialize with the altered source + setDataSource( m_dataSource ); // re-initialize with the altered source } QRect display_rect; - GetDisplayRectangle( display_rect ); + getDisplayRectangle( display_rect ); - double scale_y_min = data_source->GetYMin(); - double scale_y_max = data_source->GetYMax(); + double scale_y_min = m_dataSource->getYMin(); + double scale_y_max = m_dataSource->getYMax(); - double scale_x_min = total_x_min; - double scale_x_max = total_x_max; - double x_step = (total_x_max - total_x_min)/2000; + double scale_x_min = m_totalXMin; + double scale_x_max = m_totalXMax; + double x_step = (m_totalXMax - m_totalXMin)/2000; - range_handler->GetRange( scale_x_min, scale_x_max, x_step ); + m_rangeHandler->getRange( scale_x_min, scale_x_max, x_step ); - int n_rows = (int)data_source->GetNRows(); + int n_rows = (int)m_dataSource->getNRows(); int n_cols = SVUtils::NumSteps( scale_x_min, scale_x_max, x_step ); // This works for linear or log scales @@ -203,32 +220,32 @@ void SpectrumDisplay::UpdateImage() return; // can't draw empty image } - if ( slider_handler->VSliderOn() ) + if ( m_sliderHandler->vSliderOn() ) { int y_min; int y_max; - slider_handler->GetVSliderInterval( y_min, y_max ); + m_sliderHandler->getVSliderInterval( y_min, y_max ); double new_y_min = 0; double new_y_max = 0; - SVUtils::Interpolate( 0, n_rows, y_min, + SVUtils::Interpolate( 0, n_rows, y_min, scale_y_min, scale_y_max, new_y_min ); - SVUtils::Interpolate( 0, n_rows, y_max, + SVUtils::Interpolate( 0, n_rows, y_max, scale_y_min, scale_y_max, new_y_max ); scale_y_min = new_y_min; scale_y_max = new_y_max; } - if ( slider_handler->HSliderOn() ) + if ( m_sliderHandler->hSliderOn() ) { int x_min; int x_max; - slider_handler->GetHSliderInterval( x_min, x_max ); + m_sliderHandler->getHSliderInterval( x_min, x_max ); // NOTE: The interval [xmin,xmax] is always // found linearly. For log_x, we need to adjust it - + double new_x_min = 0; double new_x_max = 0; @@ -263,38 +280,39 @@ void SpectrumDisplay::UpdateImage() bool is_log_x = ( x_step < 0 ); // NOTE: The DataArray is deleted - data_array = data_source->GetDataArray( scale_x_min, scale_x_max, - scale_y_min, scale_y_max, - n_rows, n_cols, - is_log_x ); + m_dataArray = m_dataSource->getDataArray( scale_x_min, scale_x_max, + scale_y_min, scale_y_max, + n_rows, n_cols, + is_log_x ); - is_log_x = data_array->IsLogX(); // Data source might not be able to + is_log_x = m_dataArray->isLogX(); // Data source might not be able to // provide log binned data, so check // if log binned data was returned. - spectrum_plot->setAxisScale( QwtPlot::xBottom, data_array->GetXMin(), - data_array->GetXMax() ); + m_spectrumPlot->setAxisScale( QwtPlot::xBottom, m_dataArray->getXMin(), + m_dataArray->getXMax() ); + if ( is_log_x ) { QwtLog10ScaleEngine* log_engine = new QwtLog10ScaleEngine(); - spectrum_plot->setAxisScaleEngine( QwtPlot::xBottom, log_engine ); + m_spectrumPlot->setAxisScaleEngine( QwtPlot::xBottom, log_engine ); } else { QwtLinearScaleEngine* linear_engine = new QwtLinearScaleEngine(); - spectrum_plot->setAxisScaleEngine( QwtPlot::xBottom, linear_engine ); + m_spectrumPlot->setAxisScaleEngine( QwtPlot::xBottom, linear_engine ); } - spectrum_plot->setAxisScale( QwtPlot::yLeft, data_array->GetYMin(), - data_array->GetYMax() ); + m_spectrumPlot->setAxisScale( QwtPlot::yLeft, m_dataArray->getYMin(), + m_dataArray->getYMax() ); - spectrum_plot_item->SetData( data_array, - &positive_color_table, - &negative_color_table ); - spectrum_plot->replot(); + m_spectrumPlotItem->setData( m_dataArray, + &m_positiveColorTable, + &m_negativeColorTable ); + m_spectrumPlot->replot(); - SetVGraph( pointed_at_x ); - SetHGraph( pointed_at_y ); + setVGraph( m_pointedAtX ); + setHGraph( m_pointedAtY ); } @@ -305,50 +323,64 @@ void SpectrumDisplay::UpdateImage() * scale, the negative color table should be a gray scale to easily * distinguish between positive and negative values. * - * @param positive_color_table The new color table used to map positive data - * values to an RGB color. This can have any - * positive number of values, but will typically - * have 256 entries. - * @param negative_color_table The new color table used to map negative data - * values to an RGB color. This must have the - * same number of entries as the positive - * color table. + * @param positiveColorTable The new color table used to map positive data + * values to an RGB color. This can have any + * positive number of values, but will typically + * have 256 entries. + * @param negativeColorTable The new color table used to map negative data + * values to an RGB color. This must have the + * same number of entries as the positive + * color table. */ -void SpectrumDisplay::SetColorScales( std::vector & positive_color_table, - std::vector & negative_color_table ) +void SpectrumDisplay::setColorScales( std::vector & positiveColorTable, + std::vector & negativeColorTable ) { - this->positive_color_table.resize( positive_color_table.size() ); - for ( size_t i = 0; i < positive_color_table.size(); i++ ) - { - this->positive_color_table[i] = positive_color_table[i]; - } + m_positiveColorTable.resize( positiveColorTable.size() ); + for ( size_t i = 0; i < positiveColorTable.size(); i++ ) + m_positiveColorTable[i] = positiveColorTable[i]; - this->negative_color_table.resize( negative_color_table.size() ); - for ( size_t i = 0; i < negative_color_table.size(); i++ ) - { - this->negative_color_table[i] = negative_color_table[i]; - } - - UpdateImage(); + this->m_negativeColorTable.resize( negativeColorTable.size() ); + for ( size_t i = 0; i < negativeColorTable.size(); i++ ) + m_negativeColorTable[i] = negativeColorTable[i]; + + updateImage(); } /** * Change the control parameter (0...100) used to brighten the image. * If the control parameter is 0, the mapping from data values to color - * table index will be linear. As the control parameter is increased + * table index will be linear. As the control parameter is increased * the mapping becomes more and more non-linear in a way that emphasizes * the lower level values. This is similar to a log intensity scale. - * - * @param control_parameter This is clamped between 0 (linear) and - * 100 (most emphasis on low intensity values) + * + * @param controlParameter This is clamped between 0 (linear) and + * 100 (most emphasis on low intensity values) */ -void SpectrumDisplay::SetIntensity( double control_parameter ) +void SpectrumDisplay::setIntensity( double controlParameter ) { size_t DEFAULT_SIZE = 100000; - ColorMaps::GetIntensityMap( control_parameter, DEFAULT_SIZE, intensity_table); - spectrum_plot_item->SetIntensityTable( &intensity_table ); - UpdateImage(); + ColorMaps::GetIntensityMap( controlParameter, DEFAULT_SIZE, m_intensityTable); + m_spectrumPlotItem->setIntensityTable( &m_intensityTable ); + updateImage(); +} + + +QPoint SpectrumDisplay::getPlotTransform( QPair values ) +{ + double x = m_spectrumPlot->transform( QwtPlot::xBottom, values.first ); + double y = m_spectrumPlot->transform( QwtPlot::yLeft, values.second ); + + return QPoint((int)x, (int)y); +} + + +QPair SpectrumDisplay::getPlotInvTransform( QPoint point ) +{ + double x = m_spectrumPlot->invTransform( QwtPlot::xBottom, point.x() ); + double y = m_spectrumPlot->invTransform( QwtPlot::yLeft, point.y() ); + + return qMakePair(x,y); } @@ -357,29 +389,27 @@ void SpectrumDisplay::SetIntensity( double control_parameter ) * show those as graphs in the horizontal and vertical graphs and show * information about the specified point. * - * @param point The point that the user is currently pointing at with + * @param point The point that the user is currently pointing at with * the mouse. * @param mouseClick Which mouse button was clicked (used by derived class) * @return A pair containing the (x,y) values in the graph of the point */ -QPair SpectrumDisplay::SetPointedAtPoint( QPoint point, int /*mouseClick*/ ) +QPair SpectrumDisplay::setPointedAtPoint( QPoint point, int /*mouseClick*/ ) { - if ( data_source == 0 || data_array == 0 ) - { - return qMakePair(0.0,0.0); - } + if ( m_dataSource == 0 || m_dataArray == 0 ) + return qMakePair(0.0, 0.0); - double x = spectrum_plot->invTransform( QwtPlot::xBottom, point.x() ); - double y = spectrum_plot->invTransform( QwtPlot::yLeft, point.y() ); + QPair transPoints = getPlotInvTransform(point); - SetHGraph( y ); - SetVGraph( x ); + setHGraph( transPoints.second ); + setVGraph( transPoints.first ); - ShowInfoList( x, y ); + showInfoList( transPoints.first, transPoints.second ); - return qMakePair(x,y); + return transPoints; } + /* * Extract data for Horizontal graph from the image at the specified y value. * If the y value is NOT in the y-interval covered by the data array, just @@ -387,24 +417,24 @@ QPair SpectrumDisplay::SetPointedAtPoint( QPoint point, int /*mou * * @param y The y-value of the horizontal cut through the image. */ -void SpectrumDisplay::SetHGraph( double y ) +void SpectrumDisplay::setHGraph( double y ) { - if ( y < data_array->GetYMin() || y > data_array->GetYMax() ) + if ( y < m_dataArray->getYMin() || y > m_dataArray->getYMax() ) { - h_graph_display->Clear(); + m_hGraphDisplay->clear(); return; } - pointed_at_y = y; + m_pointedAtY = y; - float *data = data_array->GetData(); + std::vectordata = m_dataArray->getData(); - size_t n_cols = data_array->GetNCols(); + size_t n_cols = m_dataArray->getNCols(); - double x_min = data_array->GetXMin(); - double x_max = data_array->GetXMax(); + double x_min = m_dataArray->getXMin(); + double x_max = m_dataArray->getXMax(); - size_t row = data_array->RowOfY( y ); + size_t row = m_dataArray->rowOfY( y ); QVector xData; QVector yData; @@ -413,15 +443,15 @@ void SpectrumDisplay::SetHGraph( double y ) yData.push_back( data[ row * n_cols ] ); for ( size_t col = 0; col < n_cols; col++ ) { - double x_val = data_array->XOfColumn( col ); + double x_val = m_dataArray->xOfColumn( col ); xData.push_back( x_val ); // mark data at col yData.push_back( data[ row * n_cols + col ] ); // centers } xData.push_back( x_max ); // end at x_max yData.push_back( data[ row * n_cols + n_cols-1 ] ); - h_graph_display->SetLogX( data_array->IsLogX() ); - h_graph_display->SetData( xData, yData, y ); + m_hGraphDisplay->setLogX( m_dataArray->isLogX() ); + m_hGraphDisplay->setData( xData, yData, y ); } @@ -432,25 +462,25 @@ void SpectrumDisplay::SetHGraph( double y ) * * @param x The x-value of the vertical cut through the image. */ -void SpectrumDisplay::SetVGraph( double x ) +void SpectrumDisplay::setVGraph( double x ) { - if ( x < data_array->GetXMin() || x > data_array->GetXMax() ) + if ( x < m_dataArray->getXMin() || x > m_dataArray->getXMax() ) { - v_graph_display->Clear(); + m_vGraphDisplay->clear(); return; } - pointed_at_x = x; + m_pointedAtX = x; - float *data = data_array->GetData(); + std::vector data = m_dataArray->getData(); - size_t n_rows = data_array->GetNRows(); - size_t n_cols = data_array->GetNCols(); + size_t n_rows = m_dataArray->getNRows(); + size_t n_cols = m_dataArray->getNCols(); - double y_min = data_array->GetYMin(); - double y_max = data_array->GetYMax(); + double y_min = m_dataArray->getYMin(); + double y_max = m_dataArray->getYMax(); - size_t col = data_array->ColumnOfX( x ); + size_t col = m_dataArray->columnOfX( x ); QVector v_xData; QVector v_yData; @@ -460,49 +490,73 @@ void SpectrumDisplay::SetVGraph( double x ) v_xData.push_back( data[col] ); for ( size_t row = 0; row < n_rows; row++ ) // mark data at row centres { - double y_val = data_array->YOfRow( row ); + double y_val = m_dataArray->yOfRow( row ); v_yData.push_back( y_val ); v_xData.push_back( data[ row * n_cols + col ] ); } v_yData.push_back( y_max ); // end at y_max v_xData.push_back( data[ (n_rows-1) * n_cols + col] ); - v_graph_display->SetData( v_xData, v_yData, x ); + m_vGraphDisplay->setData( v_xData, v_yData, x ); } /** * Get the information about a pointed at location and show it in the - * table. + * table. * * @param x The x coordinate of the pointed at location on the image. * @param y The y coordinate of the pointed at location on the image. */ -void SpectrumDisplay::ShowInfoList( double x, double y ) +std::vector SpectrumDisplay::showInfoList( double x, double y ) { std::vector info_list; - data_source->GetInfoList( x, y, info_list ); + m_dataSource->getInfoList( x, y, info_list ); int n_infos = (int)info_list.size() / 2; - image_table->setRowCount(n_infos + 1); - image_table->setColumnCount(2); - image_table->verticalHeader()->hide(); - image_table->horizontalHeader()->hide(); + m_imageTable->setRowCount(n_infos + 1); + m_imageTable->setColumnCount(2); + m_imageTable->verticalHeader()->hide(); + m_imageTable->horizontalHeader()->hide(); int width = 9; int prec = 3; - double value = data_array->GetValue( x, y ); - QtUtils::SetTableEntry( 0, 0, "Value", image_table ); - QtUtils::SetTableEntry( 0, 1, width, prec, value, image_table ); + double value = m_dataArray->getValue( x, y ); + QtUtils::SetTableEntry( 0, 0, "Value", m_imageTable ); + QtUtils::SetTableEntry( 0, 1, width, prec, value, m_imageTable ); for ( int i = 0; i < n_infos; i++ ) { - QtUtils::SetTableEntry( i+1, 0, info_list[2*i], image_table ); - QtUtils::SetTableEntry( i+1, 1, info_list[2*i+1], image_table ); + QtUtils::SetTableEntry( i+1, 0, info_list[2*i], m_imageTable ); + QtUtils::SetTableEntry( i+1, 1, info_list[2*i+1], m_imageTable ); } - image_table->resizeColumnsToContents(); + m_imageTable->resizeColumnsToContents(); + + return info_list; +} + + +/** + * Gets the X value being pointed at. + * + * @returns X value + */ +double SpectrumDisplay::getPointedAtX() +{ + return m_pointedAtX; +} + + +/** + * Gets the Y value being pointed at. + * + * @returns Y value + */ +double SpectrumDisplay::getPointedAtY() +{ + return m_pointedAtY; } @@ -512,15 +566,15 @@ void SpectrumDisplay::ShowInfoList( double x, double y ) * @param rect A QRect object that will be filled out with position, width * and height of the pixel region covered by the image. */ -void SpectrumDisplay::GetDisplayRectangle( QRect &rect ) +void SpectrumDisplay::getDisplayRectangle( QRect &rect ) { - QwtScaleMap xMap = spectrum_plot->canvasMap( QwtPlot::xBottom ); - QwtScaleMap yMap = spectrum_plot->canvasMap( QwtPlot::yLeft ); + QwtScaleMap xMap = m_spectrumPlot->canvasMap( QwtPlot::xBottom ); + QwtScaleMap yMap = m_spectrumPlot->canvasMap( QwtPlot::yLeft ); - double x_min = data_array->GetXMin(); - double x_max = data_array->GetXMax(); - double y_min = data_array->GetYMin(); - double y_max = data_array->GetYMax(); + double x_min = m_dataArray->getXMin(); + double x_max = m_dataArray->getXMax(); + double y_min = m_dataArray->getYMin(); + double y_max = m_dataArray->getYMax(); int pix_x_min = (int)xMap.transform( x_min ); int pix_x_max = (int)xMap.transform( x_max ); @@ -543,21 +597,14 @@ void SpectrumDisplay::GetDisplayRectangle( QRect &rect ) } -bool SpectrumDisplay::DataSourceRangeChanged() +bool SpectrumDisplay::dataSourceRangeChanged() { - if ( total_y_min != data_source->GetYMin() || - total_y_max != data_source->GetYMax() || - total_x_min != data_source->GetXMin() || - total_x_max != data_source->GetXMax() ) - { - return true; - } - else - { - return false; - } + return ( m_totalYMin != m_dataSource->getYMin() || + m_totalYMax != m_dataSource->getYMax() || + m_totalXMin != m_dataSource->getXMin() || + m_totalXMax != m_dataSource->getXMax() ); } } // namespace SpectrumView -} // namespace MantidQt +} // namespace MantidQt diff --git a/Code/Mantid/MantidQt/SpectrumViewer/src/SpectrumPlotItem.cpp b/Code/Mantid/MantidQt/SpectrumViewer/src/SpectrumPlotItem.cpp index ca5832bcd4b3..1ae3028c5dee 100644 --- a/Code/Mantid/MantidQt/SpectrumViewer/src/SpectrumPlotItem.cpp +++ b/Code/Mantid/MantidQt/SpectrumViewer/src/SpectrumPlotItem.cpp @@ -1,4 +1,3 @@ - #include #include #include "MantidQtSpectrumViewer/SpectrumPlotItem.h" @@ -7,78 +6,61 @@ namespace MantidQt { namespace SpectrumView { - + /** * Construct basic plot item with NO data to plot. */ -SpectrumPlotItem::SpectrumPlotItem() +SpectrumPlotItem::SpectrumPlotItem() : + m_bufferID(0), + /* m_dataArray0(NULL), */ + /* m_dataArray1(NULL), */ + m_positiveColorTable(NULL), + m_negativeColorTable(NULL), + m_intensityTable(NULL) { - buffer_ID = 0; - data_array_0 = 0; - data_array_1 = 0; - positive_color_table = 0; - negative_color_table = 0; - intensity_table = 0; } SpectrumPlotItem::~SpectrumPlotItem() { - //std::cout << "SpectrumPlotItem destructor called" << std::endl; - - if ( data_array_0 ) - { - delete data_array_0; - } - if ( data_array_1 ) - { - delete data_array_1; - } } /** * Specify the data to be plotted and the color table to use. * - * @param data_array The DataArray object containing the data to - * plot along with information about the array - * size and the region covered by the data. - * @param positive_color_table Vector of RGB colors that determine the mapping - * from a positive data value to a color. - * @param negative_color_table Vector of RGB colors that determine the mapping - * from a negative data value to a color. This - * must have the same number of entries as the - * positive color table. + * @param dataArray The DataArray object containing the data to + * plot along with information about the array + * size and the region covered by the data. + * @param positiveColorTable Vector of RGB colors that determine the mapping + * from a positive data value to a color. + * @param negativeColorTable Vector of RGB colors that determine the mapping + * from a negative data value to a color. This + * must have the same number of entries as the + * positive color table. */ -void SpectrumPlotItem::SetData( DataArray* data_array, - std::vector* positive_color_table, - std::vector* negative_color_table ) +void SpectrumPlotItem::setData( DataArray_const_sptr dataArray, + std::vector* positiveColorTable, + std::vector* negativeColorTable ) { - if ( buffer_ID == 0 ) + if ( m_bufferID == 0 ) { - if ( data_array_1 ) // we must be done using array 1, so delete it - { - delete data_array_1; - } - data_array_1 = data_array; // put new data in array 1, and switch to it - // leaving array 0 intact for now, in case it's - // being drawn. - buffer_ID = 1; + m_dataArray1 = dataArray; // put new data in array 1, and switch to it + // leaving array 0 intact for now, in case it's + // being drawn. + m_bufferID = 1; } else { - if ( data_array_0 ) // we must be done using array 0, so delete it - { - delete data_array_0; - } - data_array_0 = data_array; // put new data in array 0, and switch to it - // leaving array 1 intact for now, in case it's - // being drawn. - buffer_ID = 0; + m_dataArray0 = dataArray; // put new data in array 0, and switch to it + // leaving array 1 intact for now, in case it's + // being drawn. + m_bufferID = 0; } - this->positive_color_table = positive_color_table; - this->negative_color_table = negative_color_table; + + m_positiveColorTable = positiveColorTable; + m_negativeColorTable = negativeColorTable; } @@ -87,13 +69,13 @@ void SpectrumPlotItem::SetData( DataArray* data_array, * they are mapped to a color. This is typically used to apply a log type * scaling so lower level values can be seen better. * - * @param intensity_table Look up table containing values between 0 and 1 - * that will be used to scale the corresponding - * image values before mappign to a color index. + * @param intensityTable Look up table containing values between 0 and 1 + * that will be used to scale the corresponding + * image values before mappign to a color index. */ -void SpectrumPlotItem::SetIntensityTable( std::vector* intensity_table ) +void SpectrumPlotItem::setIntensityTable( std::vector* intensityTable ) { - this->intensity_table = intensity_table; + m_intensityTable = intensityTable; } @@ -105,50 +87,45 @@ void SpectrumPlotItem::SetIntensityTable( std::vector* intensity_table ) * columns in the actual displayed image * @param yMap The QwtScaleMap used by QWT to map y-values to pixel * rows in the actual displayed image - * @param canvasRect rectangle containing the pixel region where QWT will + * @param canvasRect rectangle containing the pixel region where QWT will * draw the image. This rectangle is slightly larger * than the actual rectangle used for the image. This * parameter is NOT USED by the SpectrumPlotItem, but is - * passed in when QWT calls this method. + * passed in when QWT calls this method. */ void SpectrumPlotItem::draw(QPainter * painter, - const QwtScaleMap & xMap, - const QwtScaleMap & yMap, - const QRect & ) const + const QwtScaleMap & xMap, + const QwtScaleMap & yMap, + const QRect & ) const { - if ( !positive_color_table ) // if no color table, the data is not yet - { // set, so just return + // If no color table, the data is not yet set, so just return + if(!m_positiveColorTable) return; - } - DataArray* data_array; - if ( buffer_ID == 0 ) - { - data_array = data_array_0; - } + DataArray_const_sptr dataArray; + if ( m_bufferID == 0 ) + dataArray = m_dataArray0; else - { - data_array = data_array_1; - } + dataArray = m_dataArray1; - size_t n_rows = data_array->GetNRows(); - size_t n_cols = data_array->GetNCols(); + size_t n_rows = dataArray->getNRows(); + size_t n_cols = dataArray->getNCols(); if ( n_rows == 0 || n_cols == 0 ) { return; // can't draw degenerate image } - const double min = data_array->GetDataMin(); - const double max = data_array->GetDataMax(); - const double x_min = data_array->GetXMin(); - const double x_max = data_array->GetXMax(); - const double y_min = data_array->GetYMin(); - const double y_max = data_array->GetYMax(); + const double min = dataArray->getDataMin(); + const double max = dataArray->getDataMax(); + const double x_min = dataArray->getXMin(); + const double x_max = dataArray->getXMax(); + const double y_min = dataArray->getYMin(); + const double y_max = dataArray->getYMax(); - float *data = data_array->GetData(); + std::vector data = dataArray->getData(); // find the actual plot region - // using the scale maps. + // using the scale maps. const int pix_x_min = (int)xMap.transform( x_min ); const int pix_x_max = (int)xMap.transform( x_max ); const int pix_y_min = (int)yMap.transform( y_min ); @@ -166,13 +143,13 @@ void SpectrumPlotItem::draw(QPainter * painter, zc_max = 1; } - double scale = ((double)positive_color_table->size()-1)/zc_max; - double ct_scale = ((double)positive_color_table->size()-1); - if ( intensity_table != 0 ) + double scale = ((double)m_positiveColorTable->size()-1)/zc_max; + double ct_scale = ((double)m_positiveColorTable->size()-1); + if ( m_intensityTable != 0 ) { - size_t lut_size = intensity_table->size(); + size_t lut_size = m_intensityTable->size(); scale = ((double)lut_size-1.0) / zc_max; - ct_scale = ((double)positive_color_table->size()-1); + ct_scale = ((double)m_positiveColorTable->size()-1); } size_t color_index; @@ -184,20 +161,20 @@ void SpectrumPlotItem::draw(QPainter * painter, for ( int row = (int)n_rows-1; row >= 0; row-- ) { size_t data_index = row * n_cols; - if (intensity_table == 0 ) // use color tables directly + if (m_intensityTable == 0 ) // use color tables directly { for ( int col = 0; col < (int)n_cols; col++ ) { - val = data[data_index] * scale; + val = data[data_index] * scale; if ( val >= 0 ) // use positive color table { color_index = (uint)val; - rgb_buffer[image_index] = (*positive_color_table)[ color_index ]; + rgb_buffer[image_index] = (*m_positiveColorTable)[ color_index ]; } else // use negative color table { color_index = (uint)(-val); - rgb_buffer[image_index] = (*negative_color_table)[ color_index ]; + rgb_buffer[image_index] = (*m_negativeColorTable)[ color_index ]; } image_index++; data_index++; @@ -211,14 +188,14 @@ void SpectrumPlotItem::draw(QPainter * painter, if ( val >= 0 ) { lut_index = (uint)val; - color_index = (uint)((*intensity_table)[lut_index] * ct_scale ); - rgb_buffer[image_index] = (*positive_color_table)[ color_index ]; + color_index = (uint)((*m_intensityTable)[lut_index] * ct_scale ); + rgb_buffer[image_index] = (*m_positiveColorTable)[ color_index ]; } else { lut_index = (uint)(-val); - color_index = (uint)((*intensity_table)[lut_index] * ct_scale ); - rgb_buffer[image_index] = (*negative_color_table)[ color_index ]; + color_index = (uint)((*m_intensityTable)[lut_index] * ct_scale ); + rgb_buffer[image_index] = (*m_negativeColorTable)[ color_index ]; } image_index++; data_index++; @@ -233,7 +210,7 @@ void SpectrumPlotItem::draw(QPainter * painter, int width = pix_x_max - pix_x_min + 1; int height = pix_y_min - pix_y_max + 1; // y-axis is inverted for image - QPixmap scaled_pixmap = pixmap.scaled( width, height, + QPixmap scaled_pixmap = pixmap.scaled( width, height, Qt::IgnoreAspectRatio, Qt::FastTransformation); @@ -246,4 +223,4 @@ void SpectrumPlotItem::draw(QPainter * painter, } // namespace SpectrumView -} // namespace MantidQt +} // namespace MantidQt diff --git a/Code/Mantid/MantidQt/SpectrumViewer/src/SpectrumView.cpp b/Code/Mantid/MantidQt/SpectrumViewer/src/SpectrumView.cpp index 12297305815a..8c7b192b66c1 100644 --- a/Code/Mantid/MantidQt/SpectrumViewer/src/SpectrumView.cpp +++ b/Code/Mantid/MantidQt/SpectrumViewer/src/SpectrumView.cpp @@ -1,9 +1,7 @@ - #include -#include "MantidQtSpectrumViewer/SpectrumView.h" -#include "MantidQtSpectrumViewer/ColorMaps.h" +#include "MantidQtSpectrumViewer/SpectrumView.h" +#include "MantidQtSpectrumViewer/ColorMaps.h" -#include "ui_SpectrumView.h" #include "MantidQtSpectrumViewer/SVConnections.h" #include "MantidQtSpectrumViewer/SpectrumDisplay.h" #include "MantidQtSpectrumViewer/SliderHandler.h" @@ -16,7 +14,6 @@ namespace MantidQt namespace SpectrumView { - /** * Construct an SpectrumView to display data from the specified data source. * The specified SpectrumDataSource must be constructed elsewhere and passed @@ -30,32 +27,40 @@ namespace SpectrumView SpectrumView::SpectrumView(QWidget *parent) : QMainWindow(parent, 0), WorkspaceObserver(), - m_ui(new Ui::SpectrumViewer()) + m_ui(new Ui::SpectrumViewer()), + m_sliderHandler(NULL), + m_rangeHandler(NULL), + m_spectrumDisplay(NULL), + m_svConnections(NULL), + m_emodeHandler(NULL) { m_ui->setupUi(this); } + SpectrumView::~SpectrumView() { -// std::cout << "SpectrumView destructor called" << std::endl; + delete m_spectrumDisplay; + delete m_svConnections; - delete h_graph; - delete v_graph; + if(m_emodeHandler) + delete m_emodeHandler; +} - delete m_ui; - delete m_slider_handler; - delete m_range_handler; - delete m_spectrum_display; - delete m_sv_connections; - if ( m_emode_handler) - { - delete m_emode_handler; - } + +void SpectrumView::resizeEvent(QResizeEvent * event) +{ + QMainWindow::resizeEvent(event); + + if(m_svConnections) + m_svConnections->imageSplitterMoved(); } + + void SpectrumView::renderWorkspace(Mantid::API::MatrixWorkspace_const_sptr wksp) { - MatrixWSDataSource* data_source = new MatrixWSDataSource(wksp); - this->updateHandlers(data_source); + m_dataSource = MatrixWSDataSource_sptr(new MatrixWSDataSource(wksp)); + updateHandlers(m_dataSource); // Watch for the deletion of the associated workspace observeAfterReplace(); @@ -67,84 +72,85 @@ void SpectrumView::renderWorkspace(Mantid::API::MatrixWorkspace_const_sptr wksp) connect(this, SIGNAL(needToUpdate()), this, SLOT(updateWorkspace())); // set the window title - std::string title = std::string("SpectrumView (") + - wksp->getTitle() + - std::string(")"); - this->setWindowTitle(QString::fromStdString(title)); + std::string title = "SpectrumView (" + wksp->getTitle() + ")"; + this->setWindowTitle(QString::fromStdString(title).simplified()); - h_graph = new GraphDisplay( m_ui->h_graphPlot, m_ui->h_graph_table, false ); - v_graph = new GraphDisplay( m_ui->v_graphPlot, m_ui->v_graph_table, true ); + m_hGraph = new GraphDisplay( m_ui->h_graphPlot, m_ui->h_graph_table, false ); + m_vGraph = new GraphDisplay( m_ui->v_graphPlot, m_ui->v_graph_table, true ); - m_spectrum_display = new SpectrumDisplay( m_ui->spectrumPlot, - m_slider_handler, - m_range_handler, - h_graph, v_graph, - m_ui->image_table ); + m_spectrumDisplay = new SpectrumDisplay( m_ui->spectrumPlot, + m_sliderHandler, + m_rangeHandler, + m_hGraph, m_vGraph, + m_ui->image_table); - m_sv_connections = new SVConnections( m_ui, this, m_spectrum_display, - h_graph, v_graph ); + m_svConnections = new SVConnections( m_ui, this, m_spectrumDisplay, + m_hGraph, m_vGraph ); - m_spectrum_display->SetDataSource( data_source ); + m_spectrumDisplay->setDataSource( m_dataSource ); } + /// Setup the various handlers (energy-mode, slider, range) -void SpectrumView::updateHandlers(SpectrumDataSource* data_source) +void SpectrumView::updateHandlers(SpectrumDataSource_sptr dataSource) { - // IF we have a MatrixWSDataSource give it the handler for the + // If we have a MatrixWSDataSource give it the handler for the // EMode, so the user can set EMode and EFixed. NOTE: we could avoid // this type checking if we made the ui in the calling code and passed // it in. We would need a common base class for this class and // the ref-viewer UI. - MatrixWSDataSource* matrix_ws_data_source = - dynamic_cast( data_source ); - if ( matrix_ws_data_source != 0 ) + MatrixWSDataSource_sptr matrixWsDataSource = boost::dynamic_pointer_cast( dataSource ); + + if ( matrixWsDataSource != NULL ) { - m_emode_handler = new EModeHandler( m_ui ); - matrix_ws_data_source -> SetEModeHandler( m_emode_handler ); + m_emodeHandler = new EModeHandler( m_ui ); + matrixWsDataSource -> setEModeHandler( m_emodeHandler ); } else { - m_emode_handler = 0; + m_emodeHandler = NULL; } - m_slider_handler = new SliderHandler( m_ui ); - m_range_handler = new RangeHandler( m_ui ); - + m_sliderHandler = new SliderHandler( m_ui ); + m_rangeHandler = new RangeHandler( m_ui ); } + /** Slot to close the window */ void SpectrumView::closeWindow() { close(); } + /** Slot to replace the workspace being looked at. */ void SpectrumView::updateWorkspace() { close(); // TODO the right thing } + /** Signal to close this window if the workspace has just been deleted */ void SpectrumView::preDeleteHandle(const std::string& wsName,const boost::shared_ptr ws) { - if (m_spectrum_display->hasData(wsName, ws)) + if (m_spectrumDisplay->hasData(wsName, ws)) { emit needToClose(); } } + /** Signal that the workspace being looked at was just replaced with a different one */ void SpectrumView::afterReplaceHandle(const std::string& wsName,const boost::shared_ptr ws) { - std::cout << "afterReplaceHandle" << std::endl; - if (m_spectrum_display->hasData(wsName, ws)) + if (m_spectrumDisplay->hasData(wsName, ws)) { // MatrixWSDataSource* matrix_ws_data_source = new Matrix // dynamic_cast( ws ); -// saved_spectrum_display->SetDataSource(ws); // TODO implement the right thing +// m_spectrumDisplay->setDataSource(ws); // TODO implement the right thing emit needToUpdate(); } } } // namespace SpectrumView -} // namespace MantidQt +} // namespace MantidQt diff --git a/Code/Mantid/MantidQt/SpectrumViewer/src/SpectrumViewDemo.cpp b/Code/Mantid/MantidQt/SpectrumViewer/src/SpectrumViewDemo.cpp deleted file mode 100644 index d7ef8c5f8701..000000000000 --- a/Code/Mantid/MantidQt/SpectrumViewer/src/SpectrumViewDemo.cpp +++ /dev/null @@ -1,91 +0,0 @@ - -#include - -#include -#include -#include - -#include "MantidQtSpectrumViewer/SVUtils.h" -#include "MantidQtSpectrumViewer/SpectrumView.h" -#include "MantidQtSpectrumViewer/ArrayDataSource.h" - -using namespace MantidQt; -using namespace SpectrumView; - -/** - * Construct an array of test data over the specified region with the - * specified region using the specified number of rows and columns. - * - * @param total_xmin The x-coordinate at the left edge of the data region - * @param total_xmax The x-coordinate at the right edge of the data region - * @param total_ymin The y-coordinate at the bottom edge of the data region - * @param total_ymax The y-coordinate at the top edge of the data region - * @param total_rows The number of rows the test data should be divided into - * @param total_cols The number of columns the test data should be divided - * into - */ -float * MakeTestData( double total_xmin, double total_xmax, - double total_ymin, double total_ymax, - size_t total_rows, size_t total_cols ) -{ - // make some test data in array data[] - double x; - double y; - float* data = new float[total_rows*total_cols]; - for ( size_t row = 0; row < total_rows; row++ ) - for ( size_t col = 0; col < total_cols; col++ ) - { - x = ((double)col - (double)total_cols/2.0)/(double)total_cols; - y = ((double)row - (double)total_rows/2.0)/(double)total_rows; - data[ row * total_cols + col ] = - (float)(1000.0 * cos( (x*x + y*y)*20.0 )); - } - // mark a row 1/4 way up - double point = (total_ymax - total_ymin)/4 + total_ymin; - double mark_row = 0; - SVUtils::Interpolate( total_ymin, total_ymax, point, - 0.0, (double)total_rows, mark_row ); - - size_t row_offset = (int)(mark_row) * total_cols; - for ( size_t col = 0; col < total_cols; col++ ) - { - data[ row_offset-total_cols + col ] = 0; - data[ row_offset + col ] = 0; - data[ row_offset+total_cols + col ] = 0; - } - // mark a col 1/10 way over - point = (total_xmax - total_xmin)/10 + total_xmin; - double mark_col = 0; - SVUtils::Interpolate( total_xmin, total_xmax, point, - 0.0, (double)total_cols, mark_col ); - - size_t col_offset = (int)( mark_col ); - for ( size_t row = 0; row < total_rows; row++ ) - { - data[ row * total_cols + col_offset-1 ] = 0; - data[ row * total_cols + col_offset ] = 0; - data[ row * total_cols + col_offset+1 ] = 0; - } - - return data; -} - - -int main( int argc, char **argv ) -{ - QApplication a( argc, argv ); - - float * data = MakeTestData( 10, 110, 220, 320, 2000, 2000 ); - - ArrayDataSource* source = - new ArrayDataSource( 10, 110, 220, 320, 2000, 2000, data ); - - MantidQt::SpectrumView::SpectrumView spectrum_view( source ); - - // Don't delete on close in this case, since image_view - // will be deleted when the application ends - spectrum_view.setAttribute(Qt::WA_DeleteOnClose,false); - - return a.exec(); -} - diff --git a/Code/Mantid/MantidQt/SpectrumViewer/src/SpectrumViewNxEventFile.cpp b/Code/Mantid/MantidQt/SpectrumViewer/src/SpectrumViewNxEventFile.cpp deleted file mode 100644 index 5fe938deb3b4..000000000000 --- a/Code/Mantid/MantidQt/SpectrumViewer/src/SpectrumViewNxEventFile.cpp +++ /dev/null @@ -1,59 +0,0 @@ - -#include - -#include -#include -#include - -#include "MantidAPI/FrameworkManager.h" -#include "MantidAPI/AlgorithmManager.h" -#include "MantidKernel/System.h" -#include "MantidGeometry/IDTypes.h" -#include "MantidNexusCPP/NeXusFile.hpp" -#include "MantidAPI/IEventWorkspace.h" - -#include "MantidQtSpectrumViewer/MatrixWSImageView.h" - -using namespace MantidQt; -using namespace SpectrumView; -using namespace Mantid::Kernel; -using namespace Mantid::API; - -int main( int argc, char** argv ) -{ - std::cout << "Start of SpectrumViewNxEventFile..." << std::endl; - if ( argc < 2 ) - { - std::cout << "Please enter a NeXus event file name on the command line!" - << std::endl; - return 0; - } - std::string file_name(argv[1]); - - QApplication a( argc, argv ); - - Mantid::API::FrameworkManager::Instance(); - IAlgorithm_sptr ld = AlgorithmManager::Instance().createUnmanaged("LoadEventNexus"); - ld->initialize(); - - ld->setPropertyValue("Filename", file_name ); - std::string outws_name = "EventWS"; - ld->setPropertyValue("OutputWorkspace",outws_name); - ld->setPropertyValue("Precount", "0"); - - std::cout << "Loading file: " << file_name << std::endl; - ld->execute(); - ld->isExecuted(); - - std::cout << "File Loaded, getting workspace. " << std::endl; - - IEventWorkspace_sptr WS; - WS = AnalysisDataService::Instance().retrieveWS(outws_name); - - std::cout << "Got EventWorkspace, making EventWSDataSource..." << std::endl; - - MantidQt::SpectrumView::MatrixWSImageView spectrum_view( WS ); - - return a.exec(); -} - diff --git a/Code/Mantid/MantidQt/SpectrumViewer/src/TrackingPicker.cpp b/Code/Mantid/MantidQt/SpectrumViewer/src/TrackingPicker.cpp index 6fc06a2eb711..28a1f2f4b45d 100644 --- a/Code/Mantid/MantidQt/SpectrumViewer/src/TrackingPicker.cpp +++ b/Code/Mantid/MantidQt/SpectrumViewer/src/TrackingPicker.cpp @@ -1,21 +1,18 @@ - -#include "MantidQtSpectrumViewer/TrackingPicker.h" +#include "MantidQtSpectrumViewer/TrackingPicker.h" namespace MantidQt { namespace SpectrumView { - /** * Construct a tracking picker to work with the specified canvas * * @param canvas Pointer to the QwtPlotCanvas this picker will work with */ TrackingPicker::TrackingPicker( QwtPlotCanvas* canvas ) - :QwtPlotPicker( canvas ) + : QwtPlotPicker( canvas ), m_hideReadout(true) { - hide_readout = true; } @@ -26,9 +23,9 @@ TrackingPicker::TrackingPicker( QwtPlotCanvas* canvas ) * @param hide If true, the position readout at the mouse position will * be turned off. */ -void TrackingPicker::HideReadout( bool hide ) +void TrackingPicker::hideReadout( bool hide ) { - this->hide_readout = hide; + m_hideReadout = hide; } @@ -40,8 +37,8 @@ void TrackingPicker::HideReadout( bool hide ) */ QwtText TrackingPicker::trackerText( const QPoint & point ) const { - emit mouseMoved(); - if ( hide_readout ) + emit mouseMoved(point); + if ( m_hideReadout ) { return QwtText(); } @@ -60,8 +57,8 @@ QwtText TrackingPicker::trackerText( const QPoint & point ) const */ QwtText TrackingPicker::trackerText( const QwtDoublePoint & pos ) const { - emit mouseMoved(); - if ( hide_readout ) + emit mouseMoved(pos.toPoint()); + if ( m_hideReadout ) { return QwtText(); } @@ -72,4 +69,4 @@ QwtText TrackingPicker::trackerText( const QwtDoublePoint & pos ) const } } // namespace SpectrumView -} // namespace MantidQt +} // namespace MantidQt diff --git a/Code/Mantid/Vates/VatesAPI/test/SQWLoadingPresenterTest.h b/Code/Mantid/Vates/VatesAPI/test/SQWLoadingPresenterTest.h index 784fa2edb019..bcac5e5db461 100644 --- a/Code/Mantid/Vates/VatesAPI/test/SQWLoadingPresenterTest.h +++ b/Code/Mantid/Vates/VatesAPI/test/SQWLoadingPresenterTest.h @@ -192,7 +192,7 @@ void testTimeLabel() presenter.executeLoadMetadata(); vtkDataSet* product = presenter.execute(&factory, mockLoadingProgressAction, mockDrawingProgressAction); TSM_ASSERT_EQUALS("Time label should be exact.", - presenter.getTimeStepLabel(), "en (mEv)"); + presenter.getTimeStepLabel(), "en (meV)"); TS_ASSERT(Mock::VerifyAndClearExpectations(view)); TS_ASSERT(Mock::VerifyAndClearExpectations(&factory)); diff --git a/Code/Mantid/docs/source/algorithms/AnnularRingAbsorption-v1.rst b/Code/Mantid/docs/source/algorithms/AnnularRingAbsorption-v1.rst new file mode 100644 index 000000000000..6d0a822f06ef --- /dev/null +++ b/Code/Mantid/docs/source/algorithms/AnnularRingAbsorption-v1.rst @@ -0,0 +1,51 @@ + +.. algorithm:: + +.. summary:: + +.. alias:: + +.. properties:: + +Description +----------- + +Sets up a hollow sample shape, along with the required material properties, and runs +the :ref:`MonteCarloAbsorption ` algorithm. This algorithm merely +serves as a simpler interface to define the shape & material of the sample without having +to resort to the more complex :ref:`CreateSampleShape ` & :ref:`SetSampleMaterial ` +algorithms. The computational part is all taken care of by :ref:`MonteCarloAbsorption `. Please see that +documentation for more details. + +Assumptions +########### + +The algorithm currently assumes that the can wall is sufficiently thin & a weak absorber so that it can be ignored. + + +Usage +----- + +**Example** + +.. testcode:: AnnularRingAbsorptionExample + + sample_ws = CreateSampleWorkspace("Histogram",NumBanks=1) # fake some data in TOF + sample_ws = ConvertUnits(sample_ws, Target="Wavelength") + factors = \ + AnnularRingAbsorption(sample_ws, + SampleHeight=3.8, SampleThickness=0.05, CanOuterRadius=1.1,CanInnerRadius=0.92, + SampleChemicalFormula="Li2-Ir-O3",SampleNumberDensity=0.004813, + EventsPerPoint=300) + + print "The created workspace has one entry for each spectra: %i" % factors.getNumberHistograms() + print "Just divide your data by the correction to correct for absorption." + +Output: + +.. testoutput:: AnnularRingAbsorptionExample + + The created workspace has one entry for each spectra: 100 + Just divide your data by the correction to correct for absorption. + +.. categories:: diff --git a/Code/Mantid/docs/source/algorithms/AnvredCorrection-v1.rst b/Code/Mantid/docs/source/algorithms/AnvredCorrection-v1.rst index e489e5afe7d1..a3fb3e4024d2 100644 --- a/Code/Mantid/docs/source/algorithms/AnvredCorrection-v1.rst +++ b/Code/Mantid/docs/source/algorithms/AnvredCorrection-v1.rst @@ -42,6 +42,8 @@ The pixel efficiency and incident spectrum correction are NOT CURRENTLY USED. The absorption correction, trans, depends on both lamda and the pixel, Which is a fairly expensive calulation when done for each event. +Also see :ref:`algm-LorentzCorrection` + Usage ----- diff --git a/Code/Mantid/docs/source/algorithms/CalculateMSVesuvio-v1.rst b/Code/Mantid/docs/source/algorithms/CalculateMSVesuvio-v1.rst new file mode 100644 index 000000000000..8eddae38cace --- /dev/null +++ b/Code/Mantid/docs/source/algorithms/CalculateMSVesuvio-v1.rst @@ -0,0 +1,59 @@ +.. algorithm:: + +.. summary:: + +.. alias:: + +.. properties:: + +Description +----------- + +Calculates the multiple scattering contribution for deep inelastic neutron scattering on +the `Vesuvio `__ instrument at +ISIS. The algorithm follows the procedures defined by J. Mayers et al. [1]_. + + +Usage +----- + +.. code-block:: python + + runs = "" # fill in run numbers here + ip_file = "" # fill in IP file here + data = LoadVesuvio(Filename=, SpectrumList=spectra, + Mode="SingleDifference", InstrumentParFile=ip_file) + # Cut it down to the typical range + data = CropWorkspace(raw_ws,XMin=50.0,XMax=562.0) + # Coarser binning + data = Rebin(raw_ws, Params=[49.5, 1.0, 562.5]) + + # Create sample shape + height = 0.1 # y-dir (m) + width = 0.1 # x-dir (m) + thick = 0.005 # z-dir (m) + + half_height, half_width, half_thick = 0.5*height, 0.5*width, 0.5*thick + xml_str = \ + " " \ + + " " % (half_width,-half_height,half_thick) \ + + " " % (half_width, half_height, half_thick) \ + + " " % (half_width, -half_height, -half_thick) \ + + " " % (-half_width, -half_height, half_thick) \ + + "" + CreateSampleShape(data, xml_str) + atom_props = [1.007900, 0.9272392, 5.003738, + 16.00000, 3.2587662E-02, 13.92299, + 27.50000, 4.0172841E-02, 15.07701] + tot_scatter, ms_scatter = \ + CalculateMSVesuvio(data, NoOfMasses=3, SampleDensity=241, AtomicProperties=atom_props, + BeamRadius=2.5) + +References +---------- + +.. [1] J. Mayers, A.L. Fielding and R. Senesi, `Nucl. Inst Methods A 481, 454(2002) `__ + + + +.. categories:: diff --git a/Code/Mantid/docs/source/algorithms/ConvertMDHistoToMatrixWorkspace-v1.rst b/Code/Mantid/docs/source/algorithms/ConvertMDHistoToMatrixWorkspace-v1.rst index 600561a1f032..9810cb87c197 100644 --- a/Code/Mantid/docs/source/algorithms/ConvertMDHistoToMatrixWorkspace-v1.rst +++ b/Code/Mantid/docs/source/algorithms/ConvertMDHistoToMatrixWorkspace-v1.rst @@ -9,15 +9,15 @@ Description ----------- -Creates a single spectrum Workspace2D with X,Y, and E copied from an -first non-integrated dimension of a IMDHistoWorkspace. +Creates a Workspace2D with X,Y, and E copied from an IMDHistoWorkspace. +The MD workspace must have at most 2 non-integrated dimensions. Usage ----- -**Example** +**Example 1** -.. testcode:: ExHasUB +.. testcode:: ExHasUB1 ws = CreateMDHistoWorkspace(SignalInput='1,2,3,4,5,6,7,8,9', ErrorInput='1,1,1,1,1,1,1,1,1', Dimensionality='2', @@ -31,7 +31,29 @@ Usage Output: -.. testoutput:: ExHasUB +.. testoutput:: ExHasUB1 + + ws is a MDHistoWorkspace + wsOut is a Workspace2D with 3 histograms and 3 bins + + +**Example 2** + +.. testcode:: ExHasUB2 + + ws = CreateMDHistoWorkspace(SignalInput='1,2,3', + ErrorInput='1,1,1', Dimensionality='2', + Extents='-1,1,-1,1', NumberOfBins='1,3', Names='A,B', Units='U,T') + + print "%s is a %s" % (ws, ws.id()) + + wsOut=ConvertMDHistoToMatrixWorkspace(ws) + + print "%s is a %s with %i histograms and %i bins" % (wsOut, wsOut.id(), wsOut.getNumberHistograms(), wsOut.blocksize()) + +Output: + +.. testoutput:: ExHasUB2 ws is a MDHistoWorkspace wsOut is a Workspace2D with 1 histograms and 3 bins diff --git a/Code/Mantid/docs/source/algorithms/ConvertToDiffractionMDWorkspace-v1.rst b/Code/Mantid/docs/source/algorithms/ConvertToDiffractionMDWorkspace-v1.rst index f814ae34f586..21a59d9438ee 100644 --- a/Code/Mantid/docs/source/algorithms/ConvertToDiffractionMDWorkspace-v1.rst +++ b/Code/Mantid/docs/source/algorithms/ConvertToDiffractionMDWorkspace-v1.rst @@ -11,7 +11,7 @@ Description This algorithm converts from a `MatrixWorkspace `__ (in detector/time-of-flight space) to a -`MDEventWorkspace `__ containing events in reciprocal +`MDEventWorkspace `__ containing events in reciprocal space. The calculations apply only to elastic diffraction experiments. The @@ -20,7 +20,7 @@ to HKL of the crystal. If the OutputWorkspace does NOT already exist, a default one is created. In order to define more precisely the parameters of the -`MDEventWorkspace `__, use the +`MDEventWorkspace `__, use the :ref:`algm-CreateMDWorkspace` algorithm first. Types of Conversion @@ -100,11 +100,14 @@ Usage # A way to look at these results as a text: print "Resulting MD workspace has {0} events and {1} dimensions".format(md.getNEvents(),md.getNumDims()) + print "Workspace Type is: ",md.id() + **Output:** .. testoutput:: ExConvertToDiffractionMDWorkspace Resulting MD workspace has 520128 events and 3 dimensions - + Workspace Type is: MDEventWorkspace + .. categories:: diff --git a/Code/Mantid/docs/source/algorithms/ConvertToDiffractionMDWorkspace-v2.rst b/Code/Mantid/docs/source/algorithms/ConvertToDiffractionMDWorkspace-v2.rst index eaf25f37fbd5..3527b1f8684d 100644 --- a/Code/Mantid/docs/source/algorithms/ConvertToDiffractionMDWorkspace-v2.rst +++ b/Code/Mantid/docs/source/algorithms/ConvertToDiffractionMDWorkspace-v2.rst @@ -9,19 +9,30 @@ Description ----------- -This algorithm converts from a `MatrixWorkspace `__ (in -detector/time-of-flight space) to a -`MDEventWorkspace `__ containing events in reciprocal -space. +The algorithm converts from a `MatrixWorkspace `__ (in +any input units) into `MDWorkspace `__ containing +3D events in reciprocal space. The calculations apply only to elastic diffraction experiments. The conversion can be done either to Q-space in the lab or sample frame, or to HKL of the crystal. -If the OutputWorkspace does NOT already exist, a default one is created. -In order to define more precisely the parameters of the -`MDEventWorkspace `__, use the -:ref:`algm-CreateMDWorkspace` algorithm first. +Version 2 of the algorithm is the wrapper around :ref:`algm-ConvertToMD` algorithm, used for +diffraction workflow and for supporting the interface of the previous specialized version of this +algorithm. Old specialized version of this algorithm also exists. + +See the :ref:`algm-ConvertToDiffractionMDWorkspace-v1` for details of the old and :ref:`algm-ConvertToMD` for this algorithms implementations. + +The main difference between the results produced by the version one and two of this algorithm +is the type of the workspace, produced by default. +Version one is producing `MDLeanEvent<3> `__-s workspace +and this version generates `MDEvent<3> `__-s workspace. + +To obtain a workspace containing `MDLeanEvent<3> `__-s, +and fine-tune the output workspace properties, +one has to create OutputWorkspace using :ref:`algm-CreateMDWorkspace` algorithm first. + + Types of Conversion ################### @@ -52,41 +63,6 @@ This correction is also done by the :ref:`algm-AnvredCorrection` algorithm, and will be set to false if that algorithm has been run on the input workspace. -OneEventPerBin option -##################### - -If you specify *OneEventPerBin*, then the **histogram** representation -of the input workspace is used, with one MDEvent generated for each bin -of the workspace, **including zeros**. - -This can be useful in cases where the experimental coverage needs to be -tracked. With one MDEvent for each bin, you can count which regions in -Q-space have been measured. The `SliceViewer `__ has an -option to view normalized by number of events. This means that, for -example, areas with overlap from two runs will appear scaled down. - -A significant drawback to this is that the output MDEventWorkspace will -be *significantly* larger than the events alone would be. It currently -must be created in physical memory (it cannot yet be cached to disk). -One way to limit the memory used is to limit the OutputExtents to a -smaller region and only convert part of the space. - -Also, the :ref:`algm-FindPeaksMD` algorithm may not work optimally -because it depends partly on higher density of events causing more -finely split boxes. - -If your input is a `Workspace2D `__ and you do NOT check -*OneEventPerBin*, then the workspace is converted to an -`EventWorkspace `__ but with no events for empty bins. - -Performance Notes -################# - -- 8-core Intel Xeon 3.2 GHz computer: measured between 4 and 5.5 - million events per second (100-200 million event workspace). -- 32-core AMD Opteron 2.7 GHz computer: measured between 8 and 9 - million events per second (400-1000 million event workspaces). - Usage **Example - Convert re-binned MARI 2D workspace to 3D MD workspace for further analysis/merging with data at different temperatures :** @@ -100,11 +76,14 @@ Usage # A way to look at these results as a text: print "Resulting MD workspace has {0} events and {1} dimensions".format(md.getNEvents(),md.getNumDims()) + print "Workspace Type is: ",md.id() **Output:** .. testoutput:: ExConvertToDiffractionMDWorkspace Resulting MD workspace has 520128 events and 3 dimensions + Workspace Type is: MDEventWorkspace + .. categories:: diff --git a/Code/Mantid/docs/source/algorithms/CopyLogs-v1.rst b/Code/Mantid/docs/source/algorithms/CopyLogs-v1.rst index dadd158570fe..6a94de02a671 100644 --- a/Code/Mantid/docs/source/algorithms/CopyLogs-v1.rst +++ b/Code/Mantid/docs/source/algorithms/CopyLogs-v1.rst @@ -17,12 +17,199 @@ the output workspace using one of three merge strategies. the same name. - MergeKeepExisting: Keep the existing logs in the output workspace and don't modify them, but append any new ones from the input workspace. - -Note that this will not concatenate values or ranges. The algorithm will -choose to keep the value of any the log already present in the output -workspace, leaving it untouched. + Note that this will not concatenate values or ranges. The algorithm will + choose to keep the value of any the log already present in the output + workspace, leaving it unchanged. - WipeExisting: Dump any logs that are in the output workspace and replace them with the logs from the input workspace. +Usage +----- + +**Example - Copy Logs with default merge strategy** + +.. testcode:: ExCopyLogsSimple + + # Create two workspaces + demo_ws1 = CreateWorkspace(DataX=range(0,3), DataY=(0,2)) + demo_ws2 = CreateWorkspace(DataX=range(0,3), DataY=(0,2)) + + # Add logs to first workspace + AddSampleLog(Workspace=demo_ws1, LogName='x', LogText='hello world', LogType='String') + AddSampleLog(Workspace=demo_ws1, LogName='y', LogText='1', LogType='Number') + AddSampleLog(Workspace=demo_ws1, LogName='z', LogText='2', LogType='Number Series') + + # Add logs to second workspace + AddSampleLog(Workspace=demo_ws2, LogName='x', LogText='hello universe', LogType='String') + AddSampleLog(Workspace=demo_ws2, LogName='w', LogText='3', LogType='Number') + + # Fetch the generated logs + run1 = demo_ws1.getRun() + log_x1 = run1.getLogData('x') + log_y = run1.getLogData('y') + log_z = run1.getLogData('z') + run2 = demo_ws2.getRun() + log_x2 = run2.getLogData('x') + log_w = run2.getLogData('w') + + # Print the log values + print "Before CopyLog" + print "1st workspace log values x =",log_x1.value,", y =", log_y.value,", z =", log_z.value + print "2nd workspace log values x =",log_x2.value,", w =", log_w.value + + # Copy logs of 1st workspace to 2nd workspace + CopyLogs( demo_ws1, demo_ws2) + + # Fetch the new logs + run1 = demo_ws1.getRun() + log_x1 = run1.getLogData('x') + log_y = run1.getLogData('y') + log_z = run1.getLogData('z') + run2 = demo_ws2.getRun() + log_x2 = run2.getLogData('x') + log_w = run2.getLogData('w') + log_y2 = run2.getLogData('y') + log_z2 = run2.getLogData('z') + + # Print the log values + print "After CopyLog" + print "1st workspace log values x =",log_x1.value,", y =", log_y.value,", z =", log_z.value + print "2nd workspace log values x =",log_x2.value,", w =", log_w.value,", y =", log_y2.value,", z =", log_z2.value + +Output: + +.. testoutput:: ExCopyLogsSimple + + Before CopyLog + 1st workspace log values x = hello world , y = 1 , z = [2] + 2nd workspace log values x = hello universe , w = 3 + After CopyLog + 1st workspace log values x = hello world , y = 1 , z = [2] + 2nd workspace log values x = hello world , w = 3 , y = 1 , z = [2] + + +**Example - Copy Logs with MergeKeepExisting merge strategy** + +.. testcode:: ExCopyLogsKeepExisting + + # Create two workspaces + demo_ws1 = CreateWorkspace(DataX=range(0,3), DataY=(0,2)) + demo_ws2 = CreateWorkspace(DataX=range(0,3), DataY=(0,2)) + + # Add logs to first workspace + AddSampleLog(Workspace=demo_ws1, LogName='x', LogText='hello world', LogType='String') + AddSampleLog(Workspace=demo_ws1, LogName='y', LogText='1', LogType='Number') + AddSampleLog(Workspace=demo_ws1, LogName='z', LogText='2', LogType='Number Series') + + # Add logs to second workspace + AddSampleLog(Workspace=demo_ws2, LogName='x', LogText='hello universe', LogType='String') + AddSampleLog(Workspace=demo_ws2, LogName='w', LogText='3', LogType='Number') + + # Fetch the generated logs + run1 = demo_ws1.getRun() + log_x1 = run1.getLogData('x') + log_y = run1.getLogData('y') + log_z = run1.getLogData('z') + run2 = demo_ws2.getRun() + log_x2 = run2.getLogData('x') + log_w = run2.getLogData('w') + + # Print the log values + print "Before CopyLog" + print "1st workspace log values x =",log_x1.value,", y =", log_y.value,", z =", log_z.value + print "2nd workspace log values x =",log_x2.value,", w =", log_w.value + + # Copy logs of 1st workspace to 2nd workspace + CopyLogs( demo_ws1, demo_ws2, MergeStrategy='MergeKeepExisting') + + # Fetch the new logs + run1 = demo_ws1.getRun() + log_x1 = run1.getLogData('x') + log_y = run1.getLogData('y') + log_z = run1.getLogData('z') + run2 = demo_ws2.getRun() + log_x2 = run2.getLogData('x') + log_w = run2.getLogData('w') + log_y2 = run2.getLogData('y') + log_z2 = run2.getLogData('z') + + # Print the log values + print "After CopyLog" + print "1st workspace log values x =",log_x1.value,", y =", log_y.value,", z =", log_z.value + print "2nd workspace log values x =",log_x2.value,", w =", log_w.value,", y =", log_y2.value,", z =", log_z2.value + +Output: + +.. testoutput:: ExCopyLogsKeepExisting + + Before CopyLog + 1st workspace log values x = hello world , y = 1 , z = [2] + 2nd workspace log values x = hello universe , w = 3 + After CopyLog + 1st workspace log values x = hello world , y = 1 , z = [2] + 2nd workspace log values x = hello universe , w = 3 , y = 1 , z = [2] + + +**Example - Copy Logs with WipeExisting merge strategy** + +.. testcode:: ExCopyLogsWipeExisting + + # Create two workspaces + demo_ws1 = CreateWorkspace(DataX=range(0,3), DataY=(0,2)) + demo_ws2 = CreateWorkspace(DataX=range(0,3), DataY=(0,2)) + + # Add sample logs first workspace + AddSampleLog(Workspace=demo_ws1, LogName='x', LogText='hello world', LogType='String') + AddSampleLog(Workspace=demo_ws1, LogName='y', LogText='1', LogType='Number') + AddSampleLog(Workspace=demo_ws1, LogName='z', LogText='2', LogType='Number Series') + + # Add sample logs second workspace + AddSampleLog(Workspace=demo_ws2, LogName='x', LogText='hello universe', LogType='String') + AddSampleLog(Workspace=demo_ws2, LogName='w', LogText='3', LogType='Number') + + # Fetch the generated logs + run1 = demo_ws1.getRun() + log_x1 = run1.getLogData('x') + log_y = run1.getLogData('y') + log_z = run1.getLogData('z') + run2 = demo_ws2.getRun() + log_x2 = run2.getLogData('x') + log_w = run2.getLogData('w') + + # Print the log values + print "Before CopyLog" + print "1st workspace log values x =",log_x1.value,", y =", log_y.value,", z =", log_z.value + print "2nd workspace log values x =",log_x2.value,", w =", log_w.value + + # Copy logs of 1st workspace to 2nd workspace + CopyLogs( demo_ws1, demo_ws2, MergeStrategy='WipeExisting') + + # Fetch the new logs + run1 = demo_ws1.getRun() + log_x1 = run1.getLogData('x') + log_y = run1.getLogData('y') + log_z = run1.getLogData('z') + run2 = demo_ws2.getRun() + log_x2 = run2.getLogData('x') + log_y2 = run2.getLogData('y') + log_z2 = run2.getLogData('z') + + # Print the log values + print "After CopyLog" + print "1st workspace log values x =",log_x1.value,", y =", log_y.value,", z =", log_z.value + print "2nd workspace log values x =",log_x2.value,", y =", log_y2.value,", z =", log_z2.value + + +Output: + +.. testoutput:: ExCopyLogsWipeExisting + + Before CopyLog + 1st workspace log values x = hello world , y = 1 , z = [2] + 2nd workspace log values x = hello universe , w = 3 + After CopyLog + 1st workspace log values x = hello world , y = 1 , z = [2] + 2nd workspace log values x = hello world , y = 1 , z = [2] + .. categories:: diff --git a/Code/Mantid/docs/source/algorithms/CorelliCrossCorrelate-v1.rst b/Code/Mantid/docs/source/algorithms/CorelliCrossCorrelate-v1.rst new file mode 100644 index 000000000000..44d77859cb3d --- /dev/null +++ b/Code/Mantid/docs/source/algorithms/CorelliCrossCorrelate-v1.rst @@ -0,0 +1,50 @@ + +.. algorithm:: + +.. summary:: + +.. alias:: + +.. properties:: + +Description +----------- + +The algorithm calculates the elastic signal for the Corelli diffractometer. This is done by calculating the cross-correlation with the correlation chopper. The correlation chopper modulates the incident neutron beam with a pseudo-random sequence. The calculated signal is applied the each event in the form of a weight. + +The algorithm requires the timing offset of the TDC signal from the correlation chopper to run. The timing offset is dependent on the frequency of the chopper and should not change if the frequency has not changed. + +Usage +----- +.. Try not to use files in your examples, + but if you cannot avoid it then the (small) files must be added to + autotestdata\UsageData and the following tag unindented + .. include:: ../usagedata-note.txt + +**Example - CorelliCrossCorrelate** + +.. testcode:: CorelliCrossCorrelateExample + + # Load a Corelli data file. + ws = Load('CORELLI_2100') + + # You will need to load the instrument if the one in the NeXus file doesn't contain the chopper sequence. + LoadInstrument(ws, MonitorList='-1,-2,-3', InstrumentName='CORELLI') + + # Run the cross-correlation. This is using a TDC timing offset of 56000ns. + wsOut = CorelliCrossCorrelate(ws,56000) + + print 'The detector 172305 has ' + str(ws.getEventList(172305).getNumberEvents()) + ' events.' + print 'The event weights before cross-correlation are ' + str(ws.getEventList(172305).getWeights()) + print 'The event weights after cross-correlation are ' + str(wsOut.getEventList(172305).getWeights()) + +Output: + +.. testoutput:: CorelliCrossCorrelateExample + + The detector 172305 has 3 events. + The event weights before cross-correlation are [ 1. 1. 1.] + The event weights after cross-correlation are [-1.99391854 2.00611877 2.00611877] + +.. categories:: + diff --git a/Code/Mantid/docs/source/algorithms/CreateCalibrationWorkspace-v1.rst b/Code/Mantid/docs/source/algorithms/CreateCalibrationWorkspace-v1.rst new file mode 100644 index 000000000000..a4e5a0fe2af5 --- /dev/null +++ b/Code/Mantid/docs/source/algorithms/CreateCalibrationWorkspace-v1.rst @@ -0,0 +1,49 @@ +.. 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/CreateGroupingWorkspace-v1.rst b/Code/Mantid/docs/source/algorithms/CreateGroupingWorkspace-v1.rst index 24597cffdb6a..29873ac41d94 100644 --- a/Code/Mantid/docs/source/algorithms/CreateGroupingWorkspace-v1.rst +++ b/Code/Mantid/docs/source/algorithms/CreateGroupingWorkspace-v1.rst @@ -24,10 +24,15 @@ If the GroupNames parameter is given, the names of banks matching the comma-separated strings in the parameter will be used to sequentially number the groups in the output. +If both the FixedGroupCount and ComponentName parameter are given then +the detectors for the given component will be grouped into the number +of groups specified, detectors will be left ungrouped in the event that +the number of detectors does not divide equally into the number of groups. + Usage ----- -**Example - CreateGoupingWorkspace for MUSR Instrument** +**Example - CreateGroupingWorkspace for MUSR Instrument** .. include:: ../usagedata-note.txt @@ -48,7 +53,7 @@ Output: Instrument name = MUSR -**Example - CreateGoupingWorkspace from MUSR workspace** +**Example - CreateGroupingWorkspace from MUSR workspace** .. testcode:: ExCreateGroupingWorkspaceFromWorkspace @@ -72,7 +77,7 @@ Output: Instrument name = MUSR -**Example - CreateGoupingWorkspace from GEM Instrument Definition** +**Example - CreateGroupingWorkspace from GEM Instrument Definition** .. testcode:: ExCreateGroupingWorkspaceFromIDF @@ -91,4 +96,20 @@ Output: Instrument name = GEM +**Example - CreateGroupingWorkspace for IRIS graphite component** + +.. testcode:: ExCreateGroupingWorkspaceFromComponent + + grouping_ws, spectra_count, group_count = CreateGroupingWorkspace(InstrumentName='IRIS', ComponentName='graphite', FixedGroupCount=5) + + print "Number of grouped spectra:",spectra_count + print "Number of groups:",group_count + +Output: + +.. testoutput:: ExCreateGroupingWorkspaceFromComponent + + Number of grouped spectra: 50 + Number of groups: 5 + .. categories:: diff --git a/Code/Mantid/docs/source/algorithms/FakeISISHistoDAE-v1.rst b/Code/Mantid/docs/source/algorithms/FakeISISHistoDAE-v1.rst index 961187ce3c48..2e0438300b23 100644 --- a/Code/Mantid/docs/source/algorithms/FakeISISHistoDAE-v1.rst +++ b/Code/Mantid/docs/source/algorithms/FakeISISHistoDAE-v1.rst @@ -13,6 +13,8 @@ Simulates ISIS histogram DAE. It runs continuously until canceled and listens to port 6789 for ISIS DAE commands. Data is generated starting at 10000 microseconds Time of flight, and each bin requested covers 100 microseconds. +The algorithm silently defines three additional spectra with numbers NSpectra+1, NSpectra+2 and NSpectra+3 in a +different time regime (they have different binning to the rest of the spectra). Usage ----- diff --git a/Code/Mantid/docs/source/algorithms/FilterEvents-v1.rst b/Code/Mantid/docs/source/algorithms/FilterEvents-v1.rst index bdaa11f3444a..f5d1123a894f 100644 --- a/Code/Mantid/docs/source/algorithms/FilterEvents-v1.rst +++ b/Code/Mantid/docs/source/algorithms/FilterEvents-v1.rst @@ -66,4 +66,122 @@ Comparing with other event filtering algorithms Wiki page `EventFiltering `__ has a detailed introduction on event filtering in MantidPlot. +Usage +----- + +**Example - Filtering event without correction on TOF** + +.. testcode:: FilterEventNoCorrection + + ws = Load(Filename='CNCS_7860_event.nxs') + splitws, infows = GenerateEventsFilter(InputWorkspace=ws, UnitOfTime='Nanoseconds', LogName='SampleTemp', + MinimumLogValue=279.9, MaximumLogValue=279.98, LogValueInterval=0.01) + + FilterEvents(InputWorkspace=ws, SplitterWorkspace=splitws, InformationWorkspace=infows, + OutputWorkspaceBaseName='tempsplitws', GroupWorkspaces=True, + FilterByPulseTime = False, OutputWorkspaceIndexedFrom1 = False, + CorrectionToSample = "None", SpectrumWithoutDetector = "Skip", SplitSampleLogs = False, + OutputTOFCorrectionWorkspace='mock') + + # Print result + wsgroup = mtd["tempsplitws"] + wsnames = wsgroup.getNames() + for name in sorted(wsnames): + tmpws = mtd[name] + print "workspace %s has %d events" % (name, tmpws.getNumberEvents()) + + +Output: + +.. testoutput:: FilterEventNoCorrection + + workspace tempsplitws_0 has 124 events + workspace tempsplitws_1 has 16915 events + workspace tempsplitws_2 has 10009 events + workspace tempsplitws_3 has 6962 events + workspace tempsplitws_4 has 22520 events + workspace tempsplitws_5 has 5133 events + workspace tempsplitws_unfiltered has 50603 events + + +**Example - Filtering event by pulse time** + +.. testcode:: FilterEventByPulseTime + + ws = Load(Filename='CNCS_7860_event.nxs') + splitws, infows = GenerateEventsFilter(InputWorkspace=ws, UnitOfTime='Nanoseconds', LogName='SampleTemp', + MinimumLogValue=279.9, MaximumLogValue=279.98, LogValueInterval=0.01) + + FilterEvents(InputWorkspace=ws, + SplitterWorkspace=splitws, + InformationWorkspace=infows, + OutputWorkspaceBaseName='tempsplitws', + GroupWorkspaces=True, + FilterByPulseTime = True, + OutputWorkspaceIndexedFrom1 = True, + CorrectionToSample = "None", + SpectrumWithoutDetector = "Skip", + SplitSampleLogs = False, + OutputTOFCorrectionWorkspace='mock') + + # Print result + wsgroup = mtd["tempsplitws"] + wsnames = wsgroup.getNames() + for name in sorted(wsnames): + tmpws = mtd[name] + print "workspace %s has %d events" % (name, tmpws.getNumberEvents()) + + +Output: + +.. testoutput:: FilterEventByPulseTime + + workspace tempsplitws_1 has 123 events + workspace tempsplitws_2 has 16951 events + workspace tempsplitws_3 has 9972 events + workspace tempsplitws_4 has 7019 events + workspace tempsplitws_5 has 22529 events + workspace tempsplitws_6 has 5067 events + + +**Example - Filtering event with correction on TOF** + +.. testcode:: FilterEventTOFCorrection + + ws = Load(Filename='CNCS_7860_event.nxs') + splitws, infows = GenerateEventsFilter(InputWorkspace=ws, UnitOfTime='Nanoseconds', LogName='SampleTemp', + MinimumLogValue=279.9, MaximumLogValue=279.98, LogValueInterval=0.01) + + FilterEvents(InputWorkspace=ws, SplitterWorkspace=splitws, InformationWorkspace=infows, + OutputWorkspaceBaseName='tempsplitws', + GroupWorkspaces=True, + FilterByPulseTime = False, + OutputWorkspaceIndexedFrom1 = False, + CorrectionToSample = "Direct", + IncidentEnergy=3, + SpectrumWithoutDetector = "Skip", + SplitSampleLogs = False, + OutputTOFCorrectionWorkspace='mock') + + # Print result + wsgroup = mtd["tempsplitws"] + wsnames = wsgroup.getNames() + for name in sorted(wsnames): + tmpws = mtd[name] + print "workspace %s has %d events" % (name, tmpws.getNumberEvents()) + + +Output: + +.. testoutput:: FilterEventTOFCorrection + + workspace tempsplitws_0 has 124 events + workspace tempsplitws_1 has 16937 events + workspace tempsplitws_2 has 9987 events + workspace tempsplitws_3 has 6962 events + workspace tempsplitws_4 has 22529 events + workspace tempsplitws_5 has 5124 events + workspace tempsplitws_unfiltered has 50603 events + + .. categories:: diff --git a/Code/Mantid/docs/source/algorithms/FindPeaks-v1.rst b/Code/Mantid/docs/source/algorithms/FindPeaks-v1.rst index 65804b22354b..c7e6cc50cf99 100644 --- a/Code/Mantid/docs/source/algorithms/FindPeaks-v1.rst +++ b/Code/Mantid/docs/source/algorithms/FindPeaks-v1.rst @@ -86,4 +86,29 @@ References #. M.A.Mariscotti, *A method for automatic identification of peaks in the presence of background and its application to spectrum analysis , NIM 50 (1967) 309.* +Usage +----- + +**Example - Find a single peak:** + +.. testcode:: ExFindPeakSingle + + ws = CreateSampleWorkspace(Function="User Defined", UserDefinedFunction="name=LinearBackground, \ + A0=0.3;name=Gaussian, PeakCentre=5, Height=10, Sigma=0.7", NumBanks=1, BankPixelWidth=1, XMin=0, XMax=10, BinWidth=0.1) + + table = FindPeaks(InputWorkspace='ws', FWHM='20') + + row = table.row(0) + + #print row + print "Peak 1 {Centre: %.3f, width: %.3f, height: %.3f }" % ( row["centre"], row["width"], row["height"]) + + +Output: + +.. testoutput:: ExFindPeakSingle + + Peak 1 {Centre: 5.050, width: 1.648, height: 10.000 } + + .. categories:: diff --git a/Code/Mantid/docs/source/algorithms/Fury-v1.rst b/Code/Mantid/docs/source/algorithms/Fury-v1.rst new file mode 100644 index 000000000000..a82a566e5ec7 --- /dev/null +++ b/Code/Mantid/docs/source/algorithms/Fury-v1.rst @@ -0,0 +1,24 @@ +.. 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/GeneralisedSecondDifference-v1.rst b/Code/Mantid/docs/source/algorithms/GeneralisedSecondDifference-v1.rst index 37011608dfbb..a17dcbebb7cb 100644 --- a/Code/Mantid/docs/source/algorithms/GeneralisedSecondDifference-v1.rst +++ b/Code/Mantid/docs/source/algorithms/GeneralisedSecondDifference-v1.rst @@ -16,4 +16,28 @@ Instruments and Methods 50, 309 (1967). Given a spectrum with value yi difference curve, smoothed by averaging each point in the interval [-m,+m], and applying this procedure z times. +Usage +----- + +**Example - Use on a single peak** + +.. testcode:: ExGeneralisedSecondDifferenceSimple + + # Create Workspace with peak around x=15.0 + ws = CreateSampleWorkspace(BankPixelWidth=1, Xmax=30, BinWidth=1) + + # Apply algorithm. + wsD = GeneralisedSecondDifference(ws,M=2,Z=2) + + # Show values around the peak + print "%.2f, %.2f, %.2f, %.2f, %.2f" % (wsD.readY(0)[8], wsD.readY(0)[9], wsD.readY(0)[10], wsD.readY(0)[11], wsD.readY(0)[12]) + print "Peak at", wsD.readX(0)[10] + +Output: + +.. testoutput:: ExGeneralisedSecondDifferenceSimple + + -0.34, -7.21, -20.00, -7.21, -0.34 + Peak at 15.0 + .. categories:: diff --git a/Code/Mantid/docs/source/algorithms/GeneratePythonScript-v1.rst b/Code/Mantid/docs/source/algorithms/GeneratePythonScript-v1.rst index ce804c7410ca..a65f4d025222 100644 --- a/Code/Mantid/docs/source/algorithms/GeneratePythonScript-v1.rst +++ b/Code/Mantid/docs/source/algorithms/GeneratePythonScript-v1.rst @@ -12,6 +12,14 @@ Description Retrieves the algorithm history of the workspace and saves it to a Python script file or Python variable. +A time range can be specified which will restrict the algorithms in +the scrit to those which were executed between the given times, +if no end time was specified then algorithms from the start time up +to the current time will be included in the generated script. + +Start and end times are given in ISO8601 format: YYYY-MM-DD HH:mm:ss, +for example 3:25 PM on July the 4th 2014 would be 2014-07-04 15:25:00. + Usage ----- @@ -53,6 +61,51 @@ Output: removeFiles(['myscript.py']) +**Example - generate a python script giving a range of start times:** + +.. testcode:: ExGeneratePythonScriptWithTimeRanges + + import time + + # Do some operations on the workspace with a pause between them + ws = CreateSampleWorkspace() + ws = CropWorkspace(ws, XMin=7828.162291, XMax=11980.906921) + time.sleep(2) + ws = Power(ws, Exponent=1.5) + ws = RenameWorkspace(ws, OutputWorkspace="MyTestWorkspace") + + # Get the execution time of the last algorithm and subtract 1 second + history = mtd['MyTestWorkspace'].getHistory() + last = history.getAlgorithmHistory(history.size() - 1) + from_time = last.executionDate() - int(1e9) + + # Generate a script with a given start time + script_text = GeneratePythonScript(ws, StartTimestamp=str(from_time)) + print script_text.strip() + +Output: + +.. testoutput:: ExGeneratePythonScriptWithTimeRanges + + ###################################################################### + #Python Script Generated by GeneratePythonScript Algorithm + ###################################################################### + Power(InputWorkspace='ws', OutputWorkspace='ws', Exponent=1.5) + RenameWorkspace(InputWorkspace='ws', OutputWorkspace='MyTestWorkspace') + +.. testcleanup:: ExGeneratePythonScriptWithTimeRanges + + import os + def removeFiles(files): + for ws in files: + try: + path = os.path.join(os.path.expanduser("~"), ws) + os.remove(path) + except: + pass + + removeFiles(['myscript.py']) + **Example - generate a python script and save it to file:** diff --git a/Code/Mantid/docs/source/algorithms/GetTimeSeriesLogInformation-v1.rst b/Code/Mantid/docs/source/algorithms/GetTimeSeriesLogInformation-v1.rst index a75627ed86d0..d60729bc5106 100644 --- a/Code/Mantid/docs/source/algorithms/GetTimeSeriesLogInformation-v1.rst +++ b/Code/Mantid/docs/source/algorithms/GetTimeSeriesLogInformation-v1.rst @@ -11,4 +11,30 @@ Description Get information from a TimeSeriesProperty log. +Usage +----- +.. include:: ../usagedata-note.txt + +**Example - Get Information from One Log** + +.. testcode:: exGetTimeSeriesLogInformationSimple + + w=Load('CNCS_7860') + + result = GetTimeSeriesLogInformation(InputWorkspace=w,LogName='Speed5',InformationWorkspace='info') + + for i in [0,5,6,7,8]: + row = result[1].row(i) + print row['Name'], " %.3f" % row['Value'] + +Output: + +.. testoutput:: exGetTimeSeriesLogInformationSimple + + Items 4.000 + Average(dT) 39.239 + Max(dT) 53.984 + Min(dT) 29.953 + Sigma(dt) 10.543 + .. categories:: diff --git a/Code/Mantid/docs/source/algorithms/IndirectResolution-v1.rst b/Code/Mantid/docs/source/algorithms/IndirectResolution-v1.rst new file mode 100644 index 000000000000..27efd1d06062 --- /dev/null +++ b/Code/Mantid/docs/source/algorithms/IndirectResolution-v1.rst @@ -0,0 +1,39 @@ +.. algorithm:: + +.. summary:: + +.. alias:: + +.. properties:: + +Description +----------- + +Creates a resolution workspace for an inelastic indirect sample run. + +See `Indirect:Calibration `_. + +Usage +----- + +**Example - Running IndirectResolution.** + +.. testcode:: ExIndirectResolutionSimple + + resolution = IndirectResolution(InputFiles='IRS26173.raw', + Instrument='IRIS', + Analyser='graphite', + Reflection='002', + DetectorRange=[3, 53], + BackgroundRange=[-0.16, -0.14], + RebinParam='-0.175,0.002,0.175') + + print mtd.doesExist('resolution') + +Output: + +.. testoutput:: ExIndirectResolutionSimple + + True + +.. categories:: diff --git a/Code/Mantid/docs/source/algorithms/IndirectTransmissionMonitor-v1.rst b/Code/Mantid/docs/source/algorithms/IndirectTransmissionMonitor-v1.rst new file mode 100644 index 000000000000..572e9a207449 --- /dev/null +++ b/Code/Mantid/docs/source/algorithms/IndirectTransmissionMonitor-v1.rst @@ -0,0 +1,41 @@ +.. algorithm:: + +.. summary:: + +.. alias:: + +.. properties:: + +Description +----------- + +Calculates the sample transmission using the raw data files of the sample and its background or container. + +For more details, see `Indirect:Transmission `_. + +Output workspace will default to [instument][run number]_[analyser][reflection]_Transmission if not set. + +Usage +----- + +**Example - Create mapping file for IRIS** + +.. testcode:: exIRISTransmission + + sample_file = 'IRS26176.RAW' + can_file = 'IRS26173.RAW' + + sample_ws = Load(sample_file) + can_ws = Load(can_file) + + transmission_ws = IndirectTransmissionMonitor(SampleWorkspace=sample_ws, CanWorkspace=can_ws) + + print transmission_ws.getNames() + +**Output:** + +.. testoutput:: exIRISTransmission + + ['sample_ws_Sam','sample_ws_Can','sample_ws_Trans'] + +.. categories:: diff --git a/Code/Mantid/docs/source/algorithms/InelasticIndirectReduction-v1.rst b/Code/Mantid/docs/source/algorithms/InelasticIndirectReduction-v1.rst new file mode 100644 index 000000000000..f21cb07071a9 --- /dev/null +++ b/Code/Mantid/docs/source/algorithms/InelasticIndirectReduction-v1.rst @@ -0,0 +1,42 @@ +.. algorithm:: + +.. summary:: + +.. alias:: + +.. properties:: + +Description +----------- + +Performs a reduction for an inelastic indirect geometry instrument. + +Usage +----- + +.. include:: ../usagedata-note.txt + +**Example - IRIS energy conversion:** + +.. testcode:: ExIRISReduction + + InelasticIndirectReduction(InputFiles='IRS21360.raw', + OutputWorkspaceGroup='IndirectReductions', + Instrument='IRIS', + Analyser='graphite', + Reflection='002', + DetectorRange=[3, 53], + SaveFormats=['nxs']) + + reduction_workspace_names = mtd['IndirectReductions'].getNames() + + for workspace_name in reduction_workspace_names: + print workspace_name + +Output: + +.. testoutput:: ExIRISReduction + + irs21360_graphite002_red + +.. categories:: diff --git a/Code/Mantid/docs/source/algorithms/IntegrateEllipsoids-v1.rst b/Code/Mantid/docs/source/algorithms/IntegrateEllipsoids-v1.rst index 713c57f5c5ab..ef8e0f5483f0 100644 --- a/Code/Mantid/docs/source/algorithms/IntegrateEllipsoids-v1.rst +++ b/Code/Mantid/docs/source/algorithms/IntegrateEllipsoids-v1.rst @@ -13,7 +13,7 @@ Overview and similar algorithms ############################### This algorithm will integrate disjoint single crystal Bragg peaks by -summing the number of raw events in a 3D ellipsoidal peak region in +summing the number of raw or weighted events in a 3D ellipsoidal peak region in reciprocal space and subtracting an estimate of the background obtained from an ellipsoidal shell. In some ways it is similar to the :ref:`algm-IntegratePeaksMD` algorithm. In particular the size parameters to @@ -22,7 +22,7 @@ background subtraction is done in the same way for both the intensity and the estimated standard deviations. However, this algorithm differs from :ref:`algm-IntegratePeaksMD` in several critical ways. -- This algorithm works directly with raw, un-weighted events +- This algorithm works directly with raw or weighted events while :ref:`algm-IntegratePeaksMD` uses **MDEvents** from `MDEventWorkspace `_. - This algorithm uses 3D ellipsoidal regions with aspect ratios that diff --git a/Code/Mantid/docs/source/algorithms/IntegrateFlux-v1.rst b/Code/Mantid/docs/source/algorithms/IntegrateFlux-v1.rst new file mode 100644 index 000000000000..82124878d83e --- /dev/null +++ b/Code/Mantid/docs/source/algorithms/IntegrateFlux-v1.rst @@ -0,0 +1,47 @@ + +.. algorithm:: + +.. summary:: + +.. alias:: + +.. properties:: + +Description +----------- + +If a spectrum in the input workspace contains function :math:`f(x)` then the corresponding spectrum in +the output workspace has its indefinite integral: + +:math:`\int_{x_0}^x f(\xi)d\xi`. + +The input workspace is expected to be an event workspace with weighted-no-time events. + + +Usage +----- + +**Example - IntegrateFlux** + +.. testcode:: IntegrateFluxExample + + # Create an event workspace + ws = CreateSampleWorkspace("Event") + # Make evet type weighted-no-time. + ws = CompressEvents( ws ) + # Integrate all spectra. + wsOut = IntegrateFlux( ws ) + + # Print the result + print "The input workspace has %i spectra" % ws.getNumberHistograms() + print "The output workspace has %i spectra" % wsOut.getNumberHistograms() + +Output: + +.. testoutput:: IntegrateFluxExample + + The input workspace has 200 spectra + The output workspace has 200 spectra + +.. categories:: + diff --git a/Code/Mantid/docs/source/algorithms/IntegratePeaksMD-v2.rst b/Code/Mantid/docs/source/algorithms/IntegratePeaksMD-v2.rst index 58662ef954ac..24b8726a32f6 100644 --- a/Code/Mantid/docs/source/algorithms/IntegratePeaksMD-v2.rst +++ b/Code/Mantid/docs/source/algorithms/IntegratePeaksMD-v2.rst @@ -93,6 +93,36 @@ If BackgroundInnerRadius is left blank, then **BackgroundInnerRadius** = IntegratePeaksMD\_graph2.png +IntegrateIfOnEdge option +################################### + +Edges for each bank or pack of tubes of the instrument are defined by masking the edges in the PeaksWorkspace instrument. +e.g. For CORELLI, tubes 1 and 16, and pixels 0 and 255. +Q in the lab frame for every peak is calculated, call it C +For every point on the edge, the trajectory in reciprocal space is a straight line, going through: + +:math:`\vec{O}=(0,0,0)` + +Calculate a point at a fixed momentum, say k=1. +Q in the lab frame: + +:math:`\vec{E}=(-k*sin(\theta)*cos(\phi),-k*sin(\theta)*sin(\phi),k-k*cos(\phi))` + +Normalize E to 1: + +:math:`\vec{E}=\vec{E}*(1./\left|\vec{E}\right|)` + +The distance from C to OE is given by: + +:math:`dv=\vec{C}-\vec{E}*(\vec{C} \cdot \vec{E})` + +If: + +:math:`\left|dv\right|`_. + +.. categories:: diff --git a/Code/Mantid/docs/source/algorithms/LoadFITS-v1.rst b/Code/Mantid/docs/source/algorithms/LoadFITS-v1.rst new file mode 100644 index 000000000000..557447bc10fd --- /dev/null +++ b/Code/Mantid/docs/source/algorithms/LoadFITS-v1.rst @@ -0,0 +1,14 @@ +.. algorithm:: + +.. summary:: + +.. alias:: + +.. properties:: + +Description +----------- + +Load data from FITS files + +.. categories:: diff --git a/Code/Mantid/docs/source/algorithms/LoadGSS-v1.rst b/Code/Mantid/docs/source/algorithms/LoadGSS-v1.rst index 0f857af315c4..4dbacfd89201 100644 --- a/Code/Mantid/docs/source/algorithms/LoadGSS-v1.rst +++ b/Code/Mantid/docs/source/algorithms/LoadGSS-v1.rst @@ -11,7 +11,7 @@ Description Loads a GSS file such as that saved by :ref:`algm-SaveGSS`. -Two types of GSAS files are supported +Two types of GSAS files (.fxye) are supported | ``* RALF`` | ``* SLOG`` diff --git a/Code/Mantid/docs/source/algorithms/LoadMD-v1.rst b/Code/Mantid/docs/source/algorithms/LoadMD-v1.rst index ff226cb1c527..b91d3f6d9d72 100644 --- a/Code/Mantid/docs/source/algorithms/LoadMD-v1.rst +++ b/Code/Mantid/docs/source/algorithms/LoadMD-v1.rst @@ -19,7 +19,7 @@ MDWorkspace `__ by checking the FileBackEnd option. This will load the box structure (allowing for some visualization with no speed penalty) but leave the events on disk until requested. Processing file-backed MDWorkspaces is significantly slower -than in-memory workspaces due to frequency file access! +than in-memory workspaces due to frequent file access! For file-backed workspaces, the Memory option allows you to specify a cache size, in MB, to keep events in memory before caching to disk. @@ -28,4 +28,26 @@ Finally, the BoxStructureOnly and MetadataOnly options are for special situations and used by other algorithms, they should not be needed in daily use. +Usage +----- +.. include:: ../usagedata-note.txt + +**Example - Load MD workspace.** + +.. testcode:: ExLoadMD + + # Load sample MDEvent workspace, present in Mantid unit tests + mdws = LoadMD('MAPS_MDEW.nxs'); + + # Check results + print "Workspace type is: ",type(mdws) + print "Workspace has:{0:2} dimensions and contains: {1:4} MD events".format(mdws.getNumDims(),mdws.getNEvents()) + +Output: + +.. testoutput:: ExLoadMD + + Workspace type is: + Workspace has: 4 dimensions and contains: 0 MD events + .. categories:: diff --git a/Code/Mantid/docs/source/algorithms/LoadNXSPE-v1.rst b/Code/Mantid/docs/source/algorithms/LoadNXSPE-v1.rst index b6731fd3578d..39b9704aed8b 100644 --- a/Code/Mantid/docs/source/algorithms/LoadNXSPE-v1.rst +++ b/Code/Mantid/docs/source/algorithms/LoadNXSPE-v1.rst @@ -16,4 +16,9 @@ algorithm. **NOTE:** In the current implementation, the rendering of the NXSPE instrument is VERY memory intensive. +Usage +----- + +See :ref:`algm-SaveNXSPE` usage examples where Save and Load NXSPE operations are tested together. + .. categories:: diff --git a/Code/Mantid/docs/source/algorithms/LoadSQW-v1.rst b/Code/Mantid/docs/source/algorithms/LoadSQW-v1.rst index 057e1744c9bd..941c6fd8c768 100644 --- a/Code/Mantid/docs/source/algorithms/LoadSQW-v1.rst +++ b/Code/Mantid/docs/source/algorithms/LoadSQW-v1.rst @@ -159,8 +159,35 @@ functionality at a later stage. However, we can now assume that: - requires that all sqw files that are to be combined have #. each been created from only one spe file #. the same lattice parameters and pixel projection axes as held in the header block - #. the same projection axes and offsets, as held in the data block + #. the same projection axes and offsets, as held in the data block #. the same plot and integration axes, with same bins and integration ranges - the display axes will be taken from the first sqw object in the list to be combined +Usage +----- +.. include:: ../usagedata-note.txt + +**Example - Load 4D workspace form sample SQW file.** + +.. testcode:: ExLoadSQW + + # Delete existing workspace if it is already in Mantid as LoadSQW does not support overwriting + # existig workspaces by desighn + if 'mdws' in mtd: + DeleteWorkspace('mdws') + # + # Load sample sqw file, present in Mantid unit tests as MD workspace + mdws = LoadSQW('test_horace_reader.sqw'); + + # Check results + print "Workspace type is: ",type(mdws) + print "Workspace has:{0:2} dimensions and contains: {1:4} MD events".format(mdws.getNumDims(),mdws.getNEvents()) + +Output: + +.. testoutput:: ExLoadSQW + + Workspace type is: + Workspace has: 4 dimensions and contains: 580 MD events + .. categories:: diff --git a/Code/Mantid/docs/source/algorithms/LorentzCorrection-v1.rst b/Code/Mantid/docs/source/algorithms/LorentzCorrection-v1.rst new file mode 100644 index 000000000000..8022a4b00d23 --- /dev/null +++ b/Code/Mantid/docs/source/algorithms/LorentzCorrection-v1.rst @@ -0,0 +1,48 @@ + +.. algorithm:: + +.. summary:: + +.. alias:: + +.. properties:: + +Description +----------- + +Calculates and applies the lorentz correction weights to a workspace. The Lorentz correction *L* is calculated according to: + +.. math:: + L = \sin(\theta)^{2}/\lambda^{4} + +Where :math:`\theta` is the scattering angle. + +The calculations performed in this Algorithm are a subset of those performed by the :ref:`algm-AnvredCorrection` + +Usage +----- + +**Example - LorentzCorrection** + +.. testcode:: LorentzCorrectionExample + + tof = Load(Filename='HRP39180.RAW') + lam = ConvertUnits(InputWorkspace=tof, Target='Wavelength') + corrected = LorentzCorrection(InputWorkspace=lam) + + y = corrected.readY(2) + e = corrected.readE(2) + # print first corrected yvalues + print y[1:5] + # print first corrected evalues + print e[1:5] + +Output: + +.. testoutput:: LorentzCorrectionExample + + [ 0.84604876 0.4213364 1.67862035 0. ] + [ 0.59824681 0.4213364 0.83931018 0. ] + +.. categories:: + diff --git a/Code/Mantid/docs/source/algorithms/MDNormSXD-v1.rst b/Code/Mantid/docs/source/algorithms/MDNormSXD-v1.rst new file mode 100644 index 000000000000..1f4af4aaf557 --- /dev/null +++ b/Code/Mantid/docs/source/algorithms/MDNormSXD-v1.rst @@ -0,0 +1,90 @@ + +.. algorithm:: + +.. summary:: + +.. alias:: + +.. properties:: + +Description +----------- + +The algorithm calculates a normalization MD workspace for single crystal diffraction experiments. +Trajectories of each detector in reciprocal space are calculated, and the flux is integrated between intersections with each +MDBox. + + +Usage +----- +.. Try not to use files in your examples, + but if you cannot avoid it then the (small) files must be added to + autotestdata\UsageData and the following tag unindented + .. include:: ../usagedata-note.txt + +**Example - MDNormSXD** + +.. testcode:: MDNormSXDExample + + try: + # Setting up the workspaces containing information about the flux and the solid angle (from a vanadium run) + rawVan=Load(Filename=r'TOPAZ_7892_event.nxs') + rawVan=ConvertUnits(InputWorkspace=rawVan,Target='Momentum') + MaskBTP(Workspace=rawVan,Bank="10-16,19-21,23-25,29-35,40-46,49-57,59") + MaskBTP(Workspace=rawVan,Pixel="0-9,246-255") + MaskBTP(Workspace=rawVan,Tube="0-9,246-255") + rawVan=CropWorkspace(InputWorkspace=rawVan,XMin='1.85',XMax='10') + + #Solid angle + sa=Rebin(InputWorkspace=rawVan,Params='1.85,10,10',PreserveEvents='0') + SaveNexus(InputWorkspace=sa, Filename="/home/3y9/Desktop/TOPAZ/solidAngle.nxs") + + #flux + flux=GroupDetectors(InputWorkspace=rawVan,MapFile=r'/home/3y9/Desktop/TOPAZ/grouping.xml') + DeleteWorkspace(rawVan) + flux=CompressEvents(InputWorkspace=flux,Tolerance=1e-4) + flux=Rebin(InputWorkspace=flux,Params='1.85,10,10') + for i in range(flux.getNumberHistograms()): + el=flux.getEventList(i) + el.divide(flux.readY(i)[0],0) + flux=Rebin(InputWorkspace=flux,Params='1.85,10,10') + flux=IntegrateFlux(flux) + SaveNexus(InputWorkspace=flux, Filename="/home/3y9/Desktop/TOPAZ/spectra.nxs") + + #data + data=Load(Filename=r'TOPAZ_7985_event.nxs') + data=ConvertUnits(InputWorkspace=data,Target='Momentum') + MaskBTP(Workspace=data,Bank="10-16,19-21,23-25,29-35,40-46,49-57,59") + MaskBTP(Workspace=data,Pixel="0-9,246-255") + MaskBTP(Workspace=data,Tube="0-9,246-255") + data=CropWorkspace(InputWorkspace=data,XMin='1.85',XMax='10') + data=Rebin(InputWorkspace=data,Params='1.85,10,10') + LoadIsawUB(InputWorkspace=data,Filename=r'7995.mat') + MDdata=ConvertToMD(InputWorkspace=data,QDimensions="Q3D",dEAnalysisMode="Elastic", + Q3DFrames="HKL",QConversionScales="HKL", + MinValues="-10,-10,-10",Maxvalues="10,10,10") + SaveMD(InputWorkspace=MDdata, Filename="/home/3y9/Desktop/TOPAZ/MDdata.nxs") + + #running the algorithm + MDNormSXD(InputWorkspace='MDdata', + AlignedDim0='[H,0,0],-8,8,100', + AlignedDim1='[0,K,0],-8,8,100', + AlignedDim2='[0,0,L],-8,8,100', + FluxWorkspace=flux, + SolidAngleWorkspace=sa, + OutputWorkspace='mdout', + OutputNormalizationWorkspace='mdnorm') + + #If you have multiple workspaces, add separately the output workspaces, and separately the + #output normalization workspaces, then divide the two sums + normalized=DivideMD('mdout','mdnorm') + except: + pass + +.. testoutput:: SXDMDNormExample + + + + +.. categories:: + diff --git a/Code/Mantid/docs/source/algorithms/MSGDiffractionReduction-v1.rst b/Code/Mantid/docs/source/algorithms/MSGDiffractionReduction-v1.rst new file mode 100644 index 000000000000..9f0c82741e1a --- /dev/null +++ b/Code/Mantid/docs/source/algorithms/MSGDiffractionReduction-v1.rst @@ -0,0 +1,41 @@ +.. algorithm:: + +.. summary:: + +.. alias:: + +.. properties:: + +Description +----------- + +The generic routine used to reduce diffraction runs from indirect inelastic geometry instruments at ISIS. + +Usage +----- + +**Example - Running MSGDiffractionReduction.** + +.. testcode:: ExMSGDiffractionReductionSimple + + MSGDiffractionReduction(InputFiles='IRS21360.raw', + OutputWorkspaceGroup='DiffOut', + Instrument='IRIS', + Mode='diffspec', + DetectorRange=[105,112]) + + ws = mtd['DiffOut'].getItem(0) + + print 'Workspace name: %s' % ws.getName() + print 'Number of spectra: %d' % ws.getNumberHistograms() + print 'Number of bins: %s' % ws.blocksize() + +Output: + +.. testoutput:: ExMSGDiffractionReductionSimple + + Workspace name: irs21360_diffspec_red + Number of spectra: 1 + Number of bins: 1935 + +.. categories:: diff --git a/Code/Mantid/docs/source/algorithms/MaskBins-v1.rst b/Code/Mantid/docs/source/algorithms/MaskBins-v1.rst index 8699c79e06e3..48fb101d43af 100644 --- a/Code/Mantid/docs/source/algorithms/MaskBins-v1.rst +++ b/Code/Mantid/docs/source/algorithms/MaskBins-v1.rst @@ -23,6 +23,33 @@ downstream algorithms. Only algorithms (e.g. :ref:`algm-Rebin`, :ref:`algm-CropWorkspace`) have been modified to properly propagate the masking. + +Usage +----- + +**Masking of a small workspace** + +.. testcode:: exMaskBinsSimple + + # Create workspace with 10 bins of width 10 + ws = CreateSampleWorkspace(BankPixelWidth=1, Xmax=100, BinWidth=10) + + # Mask a range of X-values + wsMasked = MaskBins(ws,XMin=16,XMax=32) + + # Show Y values in workspaces + print "Before masking:", ws.readY(0) + print "After masking:",wsMasked.readY(0) + + +Output: + +.. testoutput:: exMaskBinsSimple + + Before masking: [ 0.3 0.3 0.3 0.3 0.3 10.3 0.3 0.3 0.3 0.3] + After masking: [ 0.3 0. 0. 0. 0.3 10.3 0.3 0.3 0.3 0.3] + + Related Algorithms ------------------ diff --git a/Code/Mantid/docs/source/algorithms/MaskBinsFromTable-v1.rst b/Code/Mantid/docs/source/algorithms/MaskBinsFromTable-v1.rst index 9dc00c0420cf..95b0252badaf 100644 --- a/Code/Mantid/docs/source/algorithms/MaskBinsFromTable-v1.rst +++ b/Code/Mantid/docs/source/algorithms/MaskBinsFromTable-v1.rst @@ -10,9 +10,49 @@ Description ----------- Masks bins in a workspace. The user specified masking parameters, -including spectra, xmin and xmax are given via a TableWorkspace. +such as spectra, xmin and xmax are given via a TableWorkspace. + +It calls algorithm MaskBins underneath. +If DetectorIDsList column exists it will convert this list to a list of spectra before calling MaskBins. + +The table may have several rows, in which case it calls Maskbins for each row. + + +Usage +----- + +**Masking of a small workspace** + +.. testcode:: exMaskBinsFromTableSimple + + # Create workspace with 10 bins of width 10 + ws = CreateSampleWorkspace(BankPixelWidth=1, Xmax=100, BinWidth=10) + + # Create table workspace with masking information in it + mask_info = CreateEmptyTableWorkspace() + mask_info.addColumn("str", "SpectraList") + mask_info.addColumn("double", "XMin") + mask_info.addColumn("double", "XMax") + mask_info.addRow(["", 16.0, 32.0]) # 1st mask: SpectraList=ALL, Xmin=16, XMax=32 + mask_info.addRow(["", 71.5, 79.0]) # 2nd mask: SpectraList=ALL, Xmin=71.5, XMax=79 + + + # Mask a range of X-values + wsMasked = MaskBinsFromTable(ws,MaskingInformation=mask_info) + + # Show Y values in workspaces + print "Before masking:", ws.readY(0) + print "After masking:",wsMasked.readY(0) + + +Output: + +.. testoutput:: exMaskBinsFromTableSimple + + Before masking: [ 0.3 0.3 0.3 0.3 0.3 10.3 0.3 0.3 0.3 0.3] + After masking: [ 0.3 0. 0. 0. 0.3 10.3 0.3 0. 0.3 0.3] + -It calls algorithm MaskBins underneath. Related Algorithms ------------------ diff --git a/Code/Mantid/docs/source/algorithms/MaskDetectors-v1.rst b/Code/Mantid/docs/source/algorithms/MaskDetectors-v1.rst index ed54c71650a6..4f0fc656a5ce 100644 --- a/Code/Mantid/docs/source/algorithms/MaskDetectors-v1.rst +++ b/Code/Mantid/docs/source/algorithms/MaskDetectors-v1.rst @@ -11,7 +11,8 @@ Description This algorithm will flag the detectors listed as masked(\ `IDetector `__::isMasked() method) and will zero the -data in the spectra related to those detectors. +data in the spectra for MatrixWorkspaces related to those detectors. For PeaksWorkspaces, only the +detectors listed are masked and the mask must be specified by a DetectorList or MaskedWorkspace. All but the first property are optional and at least one of them must be set. If several are set, the first will be used. diff --git a/Code/Mantid/docs/source/algorithms/MergeMD-v1.rst b/Code/Mantid/docs/source/algorithms/MergeMD-v1.rst index 7847a044b08c..f8ed3e5798b8 100644 --- a/Code/Mantid/docs/source/algorithms/MergeMD-v1.rst +++ b/Code/Mantid/docs/source/algorithms/MergeMD-v1.rst @@ -69,13 +69,12 @@ Usage **************************************************************** workspace 1 has 2 dimensions with 18231 points and 18231 events with d1 min_max=0.0:5.0, d2 min_max=-10.0:10.0 - workspace 2 has 2 dimensions with 15606 points and 15606 events + workspace 2 has 2 dimensions with 18360 points and 18360 events with d1 min_max=0.0:10.0, d2 min_max=-5.0:15.0 **************************************************************** - Merged WS has 2 dimensions with 33837 points and 33837 events + Merged WS has 2 dimensions with 36591 points and 36591 events with d1 min_max=0.0:10.0, d2 min_max=-10.0:15.0 **************************************************************** - .. categories:: diff --git a/Code/Mantid/docs/source/algorithms/MolDyn-v1.rst b/Code/Mantid/docs/source/algorithms/MolDyn-v1.rst new file mode 100644 index 000000000000..53dcbf959f26 --- /dev/null +++ b/Code/Mantid/docs/source/algorithms/MolDyn-v1.rst @@ -0,0 +1,44 @@ +.. algorithm:: + +.. summary:: + +.. alias:: + +.. properties:: + +Description +----------- + +This algorithm is a loader from simulation data from the nMOLDYN software, +simulations can be loaded form either a plain ASCII file or CDL file. + +When loading from a CDL file one or multiple functions can be loaded, when +loading a single function an instrument resolution workspace can be provided +which the loaded function is convoluted with to allow comparison with actual +instrument data. + +When loading from ASCII function selection and convolution with an instrument +resolution are unavailable. + +Usage +----- + +.. include:: ../usagedata-note.txt + +**Example - Loading a simulation from a CDL file..** + +.. testcode:: ExLoadCDLFile + + out_ws_group = MolDyn(Filename='NaF_DISF.cdl', Functions=['Fqt-total', 'Sqw-total']) + + for ws_name in out_ws_group.getNames(): + print ws_name + +Output: + +.. testoutput:: ExLoadCDLFile + + NaF_DISF_Fqt-total + NaF_DISF_Sqw-total + +.. categories:: diff --git a/Code/Mantid/docs/source/algorithms/NormaliseByCurrent-v1.rst b/Code/Mantid/docs/source/algorithms/NormaliseByCurrent-v1.rst index 9b04cc2624e2..7b30052e0953 100644 --- a/Code/Mantid/docs/source/algorithms/NormaliseByCurrent-v1.rst +++ b/Code/Mantid/docs/source/algorithms/NormaliseByCurrent-v1.rst @@ -17,7 +17,7 @@ by that number. ISIS Calculation Details ------------------------ -The good proton charge **gd\_ptrn\_chrg** is an summed value that +The good proton charge **gd\_prtn\_chrg** is an summed value that applies across all periods. It is therefore suitable to run NormaliseByProtonCharge for single-period workspaces, but gives incorrect normalisation for multi-period workspaces. If the algorithm @@ -34,4 +34,41 @@ the output will be as well. Weighted events are used to scale by the current (see the :ref:`algm-Divide` algorithm, which is a child algorithm being used). +Usage +----- + +**Example - Normalise by Current simple workspace** + +.. testcode:: exNormaliseByCurrentSimple + + # Create two workspaces + ws = CreateWorkspace(DataX=range(0,3), DataY=(17,12)) + + # Add Good Proton Charge Log + AddSampleLog(Workspace=ws, LogName='gd_prtn_chrg', LogText='10.0', LogType='Number') + + # Fetch the generated logs + run1 = ws.getRun() + log_p = run1.getLogData('gd_prtn_chrg') + + # Print the log value + print "Good Proton Charge =",log_p.value + + #Run the Algorithm + wsN = NormaliseByCurrent(ws) + + #Print results + print "Before normalisation", ws.readY(0); + print "After normalisation ", wsN.readY(0); + + +Output: + +.. testoutput:: exNormaliseByCurrentSimple + + Good Proton Charge = 10.0 + Before normalisation [ 17. 12.] + After normalisation [ 1.7 1.2] + + .. categories:: diff --git a/Code/Mantid/docs/source/algorithms/NormaliseToMonitor-v1.rst b/Code/Mantid/docs/source/algorithms/NormaliseToMonitor-v1.rst index 35559ffa94dc..ae37918a283e 100644 --- a/Code/Mantid/docs/source/algorithms/NormaliseToMonitor-v1.rst +++ b/Code/Mantid/docs/source/algorithms/NormaliseToMonitor-v1.rst @@ -62,4 +62,35 @@ spectrum. In both cases, the :ref:`algm-Divide` algorithm is used to perform the normalisation. +Usage +----- +.. include:: ../usagedata-note.txt + +**Example - Normalise to Monitor ID=1** + +.. testcode:: exNormaliseToMonitorSimple + + ws =Load('IRS26173.raw') + + wsN = NormaliseToMonitor( ws, MonitorID=1 ) + + print "Without normalisation" + print "Monitor ID=1 %.3f, %.3f" % ( ws.readY(0)[0], ws.readY(0)[1] ) + print "Selected data %.6f, %.6f" % ( ws.readY(6)[0], ws.readY(3)[1] ) + + print "With Normalisation" + print "Monitor ID=1 %.3f, %.3f" % ( wsN.readY(0)[0], wsN.readY(0)[1] ) + print "Selected data %.6f, %.6f" % ( wsN.readY(6)[0], wsN.readY(3)[1] ) + +Output: + +.. testoutput:: exNormaliseToMonitorSimple + + Without normalisation + Monitor ID=1 626034.000, 626681.000 + Selected data 2.000000, 1.000000 + With Normalisation + Monitor ID=1 464872.441, 464872.441 + Selected data 1.485135, 0.741801 + .. categories:: diff --git a/Code/Mantid/docs/source/algorithms/PerformIndexOperations-v1.rst b/Code/Mantid/docs/source/algorithms/PerformIndexOperations-v1.rst index c4554e52ebb2..7634090f37c1 100644 --- a/Code/Mantid/docs/source/algorithms/PerformIndexOperations-v1.rst +++ b/Code/Mantid/docs/source/algorithms/PerformIndexOperations-v1.rst @@ -9,6 +9,47 @@ Description ----------- +This algorithm can be used to arrange the spectra of a workspace. It can add two spectra and to remove spectra or do a combination of these. +The processing instructions give the details of this. +Instructions +############ + +The processing instructions consist of a list of numbers that refer to spectra 0 to n-1 and various operators ',',':','+' and '-'. + +To remove spectra, list those you want to keep. The ':' symbol indicates a continuous range of spectra, sparing you the need to list every spectrum. +For example if you have 100 spectra (0 to 99) and want to remove the first and last 10 spectra along with spectrum 12, +you would use processing instructions '10,13:89'. This says keep spectrum 10 along with spectra 13 to 89 inclusive. + +To add spectra, use '+' to add two spectra or '-' to add a range. For example you may with to add spectrum 10 to 12 and ignore the rest, you would use '10+12'. +If you were adding five groups of 20, you would use '0-19,20-39,40-59,60-79,80-99'. + +One could combine the two, for example '10+12,13:89' would list the sum of spectra 10 and 12 followed by spectra 13 to 89. + +Usage +----- + +**Example - Get Sum of First Two spectra followed by Last Two spectra** + +.. testcode:: ExPerformIndexOperationsSimple + + # Create Workspace of 5 spectra each with two entries. + ws = CreateWorkspace(DataX=[1,2], DataY=[11,12,21,22,31,32,41,42,51,52], NSpec=5) + + # Run algorithm adding first two spectra and then keeping last two spectra + ws2 = PerformIndexOperations( ws, "0+1,3,4") + + #print result + print ws2.readY(0) + print ws2.readY(1) + print ws2.readY(2) + +Output: + +.. testoutput:: ExPerformIndexOperationsSimple + + [ 32. 34.] + [ 41. 42.] + [ 51. 52.] .. categories:: diff --git a/Code/Mantid/docs/source/algorithms/ReadGroupsFromFile-v1.rst b/Code/Mantid/docs/source/algorithms/ReadGroupsFromFile-v1.rst index 61156ff91109..a469cdabb161 100644 --- a/Code/Mantid/docs/source/algorithms/ReadGroupsFromFile-v1.rst +++ b/Code/Mantid/docs/source/algorithms/ReadGroupsFromFile-v1.rst @@ -19,4 +19,39 @@ The instrumentView is the best way to visualize the grouping using the .. |Instrument view of grouping using ReadFromFile with ShowUnselected=True| image:: /images/ReadFromFile-Grouping.png + +Usage +----- + +.. include:: ../usagedata-note.txt + +**Example - Read 9 groups for INES instrument:** + +.. testcode:: ExReadGroupsFromFileSimple + + # Create workspace with INES instrument in it + ws1 = Load("INES_Definition.xml") + + # Run algorithm + ws2 = ReadGroupsFromFile( ws1, "INES_example.cal") + + # Print the value of selected sprectra. Each corresponds to the group of the corresponding detector. + for i in [0,1,2,3,4,5,6,7,8]: + print ws2.readY(16*i), ws2.readY(16*i+5), ws2.readY(16*i+10), ws2.readY(16*i+15) + +Output: + +.. testoutput:: ExReadGroupsFromFileSimple + + [ 1.] [ 1.] [ 1.] [ 1.] + [ 2.] [ 2.] [ 2.] [ 2.] + [ 3.] [ 3.] [ 3.] [ 3.] + [ 4.] [ 4.] [ 4.] [ 4.] + [ 5.] [ 5.] [ 5.] [ 5.] + [ 6.] [ 6.] [ 6.] [ 6.] + [ 7.] [ 7.] [ 7.] [ 7.] + [ 8.] [ 8.] [ 8.] [ 8.] + [ 9.] [ 9.] [ 9.] [ 9.] + + .. categories:: diff --git a/Code/Mantid/docs/source/algorithms/ReflectometryReductionOne-v1.rst b/Code/Mantid/docs/source/algorithms/ReflectometryReductionOne-v1.rst index 1e76c3e3e2b5..f26ee5471611 100644 --- a/Code/Mantid/docs/source/algorithms/ReflectometryReductionOne-v1.rst +++ b/Code/Mantid/docs/source/algorithms/ReflectometryReductionOne-v1.rst @@ -46,4 +46,32 @@ parameters associated with the transmission runs will also be required. If a single Transmission run is provided, then no stitching parameters will be needed. +Usage +----- + +**Example - Reduce a Run** + +.. testcode:: ExReflRedOneSimple + + run = Load(Filename='INTER00013460.nxs') + # Basic reduction with no transmission run + IvsQ, IvsLam, thetaOut = ReflectometryReductionOne(InputWorkspace=run, ThetaIn=0.7, I0MonitorIndex=2, ProcessingInstructions='3:4', + WavelengthMin=1.0, WavelengthMax=17.0, + MonitorBackgroundWavelengthMin=15.0, MonitorBackgroundWavelengthMax=17.0, + MonitorIntegrationWavelengthMin=4.0, MonitorIntegrationWavelengthMax=10.0 ) + + print "The first four IvsLam Y values are: [", str(IvsLam.readY(0)[0]),",", str(IvsLam.readY(0)[1]),",", str(IvsLam.readY(0)[2]),",", str(IvsLam.readY(0)[3]),"]" + print "The first four IvsQ Y values are: [", str(IvsQ.readY(0)[0]),",", str(IvsQ.readY(0)[1]),",", str(IvsQ.readY(0)[2]),",", str(IvsQ.readY(0)[3]),"]" + print "Theta out is the same as theta in:",thetaOut + + +Output: + +.. testoutput:: ExReflRedOneSimple + + The first four IvsLam Y values are: [ 0.0 , 0.0 , 0.0 , 1.19084981351e-06 ] + The first four IvsQ Y values are: [ 3.26638386884e-05 , 5.41802219385e-05 , 4.89364938612e-05 , 5.50890537024e-05 ] + Theta out is the same as theta in: 0.7 + + .. categories:: diff --git a/Code/Mantid/docs/source/algorithms/SaveNXSPE-v1.rst b/Code/Mantid/docs/source/algorithms/SaveNXSPE-v1.rst index 2efb679ca6a3..f1c424864294 100644 --- a/Code/Mantid/docs/source/algorithms/SaveNXSPE-v1.rst +++ b/Code/Mantid/docs/source/algorithms/SaveNXSPE-v1.rst @@ -34,18 +34,31 @@ Usage import os import numpy - + # Create dummy workspace. out_ws = CreateSimulationWorkspace(Instrument="IRIS", BinParams="0,500,2000") out_ws.setY(0, numpy.array([10.0, 50.0, 30.0, 60.0])) - - file_path = os.path.join(config["defaultsave.directory"], "NXSPEData.nxsps") - + AddSampleLog(out_ws, 'Ei', LogText='321', LogType='Number') + + file_path = os.path.join(config["defaultsave.directory"], "NXSPEData.nxspe") + # Do a "roundtrip" of the data. - SaveNXSPE(out_ws, file_path) + SaveNXSPE(out_ws, file_path,Psi=32) + + # By desigghn, SaveMXSPE does not store detector's ID-s. LoadNXSPE sets detector's ID-s to defaults. + # To compare loaded and saved workspaces here, one needs to set-up default detector's ID-s to the source workspace. + nSpec = out_ws.getNumberHistograms() + for i in xrange(0,nSpec): + sp=out_ws.getSpectrum(i); + sp.setDetectorID(i+1); in_ws = LoadNXSPE(file_path) - + + ws_comparison_rez = CheckWorkspacesMatch(out_ws,in_ws,1.e-9,CheckInstrument=False) print "Contents of the first spectrum = " + str(in_ws.readY(0)) + "." + print "Initial and loaded workspaces comparison is: ",ws_comparison_rez + run = in_ws.getRun(); + print "Loaded workspace has attached incident energy Ei={0:5} and rotation angle Psi={1:5}deg".format(run.getLogData('Ei').value,run.getLogData('psi').value) + .. testcleanup:: ExSimpleSavingRoundtrip @@ -56,5 +69,8 @@ Output: .. testoutput:: ExSimpleSavingRoundtrip Contents of the first spectrum = [ 10. 50. 30. 60.]. + Initial and loaded workspaces comparison is: Success! + Loaded workspace has attached incident energy Ei=321.0 and rotation angle Psi= 32.0deg + .. categories:: diff --git a/Code/Mantid/docs/source/algorithms/SavePDFGui-v1.rst b/Code/Mantid/docs/source/algorithms/SavePDFGui-v1.rst new file mode 100644 index 000000000000..f81febe8d360 --- /dev/null +++ b/Code/Mantid/docs/source/algorithms/SavePDFGui-v1.rst @@ -0,0 +1,57 @@ + +.. algorithm:: + +.. summary:: + +.. alias:: + +.. properties:: + +Description +----------- + +This algorithm saves G(r) files consistent with `PDFGui `_. +The body of the file is of the form ``r Gr dr dGr``. + +Usage +----- +.. Try not to use files in your examples, + but if you cannot avoid it then the (small) files must be added to + autotestdata\UsageData and the following tag unindented + .. include:: ../usagedata-note.txt + +**Example - SavePDFGui** + +.. testcode:: SavePDFGuiExample + + # Create a host workspace + ws = CreateWorkspace(DataX=range(0,3), DataY=range(0,3), UnitX="Angstrom") + + # Create a filename + import os + path = os.path.join(os.path.expanduser("~"), "savepdfgui.gr") + + # Save as G(r) file + SavePDFGui(ws, path) + + # Check that the file exists + print os.path.isfile(path) + +Output: + +.. testoutput:: SavePDFGuiExample + + True + +.. testcleanup:: SavePDFGuiExample + + DeleteWorkspace(ws) + import os + try: + path = os.path.join(os.path.expanduser("~"), "savepdfgui.gr") + os.remove(path) + except: + pass + +.. categories:: + diff --git a/Code/Mantid/docs/source/algorithms/SaveParameterFile-v1.rst b/Code/Mantid/docs/source/algorithms/SaveParameterFile-v1.rst index 5df213db0e16..c8de626682f4 100644 --- a/Code/Mantid/docs/source/algorithms/SaveParameterFile-v1.rst +++ b/Code/Mantid/docs/source/algorithms/SaveParameterFile-v1.rst @@ -15,8 +15,9 @@ The parameter file can then be inspected and or modified. It can also be loaded Mantid using the `LoadParameterFile `__ algorithm. The LocationParameters property specifies whether or not to save any calibration parameters -used to adjust the location of any components. Specifically, it will skip "x", "y", "z", -"r-position", "t-position", "p-position", "rotx", "roty", and "rotz" parameters. +used to adjust the location of any components. If enabled, SaveParameterFile may also output +"x", "y", "z", "rotx", "roty", and "rotz" parameters when necessary to update the position and +rotation of the components. Usage ----- diff --git a/Code/Mantid/docs/source/algorithms/SetSampleMaterial-v1.rst b/Code/Mantid/docs/source/algorithms/SetSampleMaterial-v1.rst index 0d7ca7c07f8e..4f4d227297d6 100644 --- a/Code/Mantid/docs/source/algorithms/SetSampleMaterial-v1.rst +++ b/Code/Mantid/docs/source/algorithms/SetSampleMaterial-v1.rst @@ -44,4 +44,30 @@ Also Note that for isotopes specified in a molecular expression, the isotope must be enclosed by parenthesis, except for two special cases, ``D`` and ``T``, which stand for ``H2`` and ``H3``, respectively. +Cross Section Calculations +########################## + +Each of the cross sections (:math:`\sigma`) are calculated according to + +.. math:: \sigma = \frac{1}{N_{atoms}}\sum_{i}\sigma_{i}n_{i} + +where :math:`N_{atoms} = \sum_{i}n_{i}`. A concrete example for the total +cross section of ``D2 O`` + +.. math:: \sigma = \frac{1}{2+1}\left( 7.64*2 + 4.232*1\right) = 6.504\ barns + +Number Density +############## + +The number density is defined as + +.. math:: \rho_n = \frac{ZParameter}{UnitCellVolume} + +It can can be generated in one of two ways: + +1. Specifying it directly with ``SampleNumberDensity`` +2. Specifying the ``ZParameter`` and the ``UnitCellVolume`` (or letting + the algorithm calculate it from the OrientedLattice on the + ``InputWorkspace``). + .. categories:: diff --git a/Code/Mantid/docs/source/algorithms/Symmetrise-v1.rst b/Code/Mantid/docs/source/algorithms/Symmetrise-v1.rst index bc93a312b7dc..58b6fafe03fc 100644 --- a/Code/Mantid/docs/source/algorithms/Symmetrise-v1.rst +++ b/Code/Mantid/docs/source/algorithms/Symmetrise-v1.rst @@ -10,9 +10,13 @@ Description ----------- Symmetrise takes an asymmetric :math:`S(Q,w)` - i.e. one in which the -moduli of xmin & xmax are different. Typically xmax is > mod(xmin). A -negative value of x is chosen (Xcut) so that the curve for mod(Xcut) to -xmax is reflected and inserted for x less than the Xcut. +moduli of xmin & xmax are different. Typically xmax is > mod(xmin). + +Two values, XMin and XMax, are chosen to specify the section of the positive +side of the curve to be reflected onto the negative side, the sample curve +is cropped at XMax ensuring that the symmetrised curve has a symmetrical X +range. + Usage ----- @@ -23,17 +27,16 @@ Usage import numpy as np - #create an asymmetric line shape + # create an asymmetric line shape def rayleigh(x, sigma): - return (x / sigma**2) * np.exp( -x**2 / (2*sigma**2)) + return (x / sigma ** 2) * np.exp(-x ** 2 / (2 * sigma ** 2)) - dataX = np.arange(0, 10, 0.01) - dataY = rayleigh(dataX, 1) + data_x = np.arange(0, 10, 0.01) + data_y = rayleigh(data_x, 1) - ws = CreateWorkspace(dataX, dataY) - ws = ScaleX(ws, -1, "Add") #centre the peak over 0 + sample_ws = CreateWorkspace(data_x, data_y) + sample_ws = ScaleX(sample_ws, -1, "Add") # centre the peak over 0 - ws = RenameWorkspace(ws, OutputWorkspace="iris00001_graphite002_red") - Symmetrise('00001', '-0.001', InputType='Workspace') + symm_ws = Symmetrise(Sample=sample_ws, XMin=0.05, XMax=8.0) .. categories:: diff --git a/Code/Mantid/docs/source/algorithms/TimeSlice-v1.rst b/Code/Mantid/docs/source/algorithms/TimeSlice-v1.rst new file mode 100644 index 000000000000..fa9cad85fb99 --- /dev/null +++ b/Code/Mantid/docs/source/algorithms/TimeSlice-v1.rst @@ -0,0 +1,47 @@ +.. algorithm:: + +.. summary:: + +.. alias:: + +.. properties:: + +Description +----------- + +Used to perform integration over a given time of flight data from an +indirect inelastic geometry instrument. + +The peak range will be integrated to give the result over the given +spectra range, the output workspace will contain the result of the +integration against the spectrum number. + +Optionally a calibration workspace can be provided which will be +applied to the raw data before the integration is performed. + +A background range can also be provided which will first calculate +and subtract a flat background from the raw data before the +integration is performed. + +Usage +----- + +.. include:: ../usagedata-note.txt + +**Example - Running TimeSlice** + +.. testcode:: ExIndirectTransmissionSimple + + TimeSlice(InputFiles=['IRS26173.raw'], + SpectraRange=[3, 53], + PeakRange=[62500, 65000]) + + print mtd.doesExist('irs26173_slice') + +Output: + +.. testoutput:: ExIndirectTransmissionSimple + + True + +.. categories:: diff --git a/Code/Mantid/docs/source/algorithms/WienerSmooth-v1.rst b/Code/Mantid/docs/source/algorithms/WienerSmooth-v1.rst new file mode 100644 index 000000000000..37ce0d70a1ef --- /dev/null +++ b/Code/Mantid/docs/source/algorithms/WienerSmooth-v1.rst @@ -0,0 +1,50 @@ + +.. algorithm:: + +.. summary:: + +.. alias:: + +.. properties:: + +Description +----------- + +This algorithm smooths the data in a histogram using the Wiener filter method. + +Usage +----- + +**Example - Smooth noisy data** + +.. testcode:: + + import random + import math + + # Define a function + def fun(x): + return math.sin(x) + x /10 + + # Create a workspace with noisy data. + + # Size of the data set + n = 200 + + # Define the x-values + interval = (-10.0,10.0) + dx = (interval[1] - interval[0]) / (n - 1) + x = [interval[0] + dx * i for i in range(n)] + + # Define the y-values as a function fun(x) + random noise + noise = 0.1 + y = [fun(x[i]) + random.normalvariate(0.0,noise) for i in range(n)] + + # Create a workspace + ws = CreateWorkspace(x,y) + + # Smooth the data using the Wiener filter + smooth = WienerSmooth(ws,0) + +.. categories:: + diff --git a/Code/Mantid/docs/source/concepts/Point_groups.rst b/Code/Mantid/docs/source/concepts/Point_groups.rst new file mode 100644 index 000000000000..c00da6633605 --- /dev/null +++ b/Code/Mantid/docs/source/concepts/Point_groups.rst @@ -0,0 +1,215 @@ +.. _Point groups: + +Point groups +============ + +This document explains how crystallographic point groups are used in Mantid. + +Introduction +------------ + +Point groups can be used to describe the symmetry of an object or a lattice, as commonly used in the context of diffraction techniques. According to the definition given in the International Tables for Crystallography A, a "point group is a group of symmetry operations all of which leave at least one point unmoved" [ITA6]_. This means that only symmetry operations without a translational component are allowed, which leaves only rotations :math:`1`, :math:`2`, :math:`3`, :math:`4`, :math:`6` and roto-inversions :math:`\bar{1}`, :math:`\bar{3}`, :math:`\bar{4}`, :math:`\bar{6}` and mirror planes :math:`m`. In space groups, translational symmetry is present as well (for example in the form of screw axes and glide planes). + +In three dimensions there are 32 crystallographic point groups and in 11 of these an inversion center (:math:`\bar{1}`) is present. These so called Laue classes are important for diffraction experiments because Friedel's law defines that diffraction patterns always show a center of symmetry if anomalous dispersion is not taken into account. + +Through the presence of certain symmetry operations in certain directions, the Laue classes can be categorized into seven crystal systems (see table below). This information is included in the Hermann-Mauguin symbol, which describes symmetry along different directions, depending on the crystal system. + +.. table:: The seven crystal systems and how they relate to the 11 Laue classes. + + +----------------+-------------------------------------+ + | Crystal system | Laue classes | + +================+=====================================+ + | Cubic | :math:`m\bar{3}`, :math:`m\bar{3}m` | + +----------------+-------------------------------------+ + | Hexagonal | :math:`6/m`, :math:`6/mmm` | + +----------------+-------------------------------------+ + | Trigonal | :math:`\bar{3}`, :math:`\bar{3}m` | + +----------------+-------------------------------------+ + | Tetragonal | :math:`4/m`, :math:`4/mmm` | + +----------------+-------------------------------------+ + | Orthorhombic | :math:`mmm` | + +----------------+-------------------------------------+ + | Monoclinic | :math:`2/m` | + +----------------+-------------------------------------+ + | Triclinic | :math:`\bar{1}` | + +----------------+-------------------------------------+ + +As mentioned before, point groups can describe the symmetry of a lattice, including the reciprocal lattice. When working with diffraction data, which are often described in terms of reciprocal lattice vectors with their Miller indices :math:`hkl` (since it's a vector it can be written shortly as :math:`\mathbf{h}`), this is particularly useful. Each symmetry operation :math:`S_i` of the point group transforms a vector :math:`\mathbf{h}` into a new vector :math:`\mathbf{h}'`: + +.. math:: + \mathbf{h}' = \mathbf{S}_i \cdot \mathbf{h} + +To describe the rotational and translational components of the symmetry operation, a matrix :math:`M_i` and a vector :math:`v_i` are used. In three dimensions :math:`\mathbf{h}` has three elements, so :math:`\mathbf{M_i}` is a :math:`3\times3`-matrix and the symmetry operation is applied like this: + +.. math:: + \mathbf{h}' = \mathbf{M}_i \cdot \mathbf{h} + \mathbf{v_i} + +A point group is an ensemble of symmetry operations. The number of operations present in this collection is the so called order :math:`N` of the corresponding point group. Applying all symmetry operations of a point group to a given vector :math:`\mathbf{h}` results in :math:`N` new vectors :math:`\mathbf{h}'`, some of which may be identical (this depends on the symmetry and also on the vectors, e.g. if one or more index is 0). This means that the symmetry operations of a point group generate a set of :math:`N'` (where :math:`N' < N`) non-identical vectors :math:`\mathbf{h}'` for a given vector :math:`\mathbf{h}` - these vectors are called symmetry equivalents. + +A very common representation of symmetry operations is the Jones faithful notation, which is very concise and used throughout the International Tables. Some examples of the notation are given in the following table. + +.. table:: Examples for symmetry operations in Jones faithful notation. + + =============== =================== + Symbol Symmetry operation + =============== =================== + ``x,y,z`` Identity + ``-x,-y,-z`` Inversion + ``-x,-y,z`` 2-fold rotation around :math:`z` + ``x,y,-z`` Mirror plane perpendicular to :math:`z` + ``-x,-y,z+1/2`` :math:`2_1` screw axis along :math:`z` + =============== =================== + + +Using symmetry operations +------------------------- + +As explained above, point groups are represented as a collection of symmetry operations, which in turn are described by a :math:`3\times3`-matrix for the rotational part and a :math:`3\times1`-vector for the translational component. + +Using these identifiers, ``SymmetryOperation``-objects can be created through a factory and then used to transform vectors. The following code sample shows how to do that in Python: + +.. testcode :: ExSymmetryOperation + + from mantid.geometry import SymmetryOperation, SymmetryOperationFactoryImpl + + symOp = SymmetryOperationFactoryImpl.Instance().createSymOp("x,y,-z") + + hkl = [1, -1, 3] + hklPrime = symOp.apply(hkl) + + print "Mirrored hkl:", hklPrime + +The above code will print the mirrored index: + +.. testoutput :: ExSymmetryOperation + + Mirrored hkl: [1,-1,-3] + +The corresponding code in C++ looks very similar and usage examples can be found in the code base, mainly in the implementation of ``PointGroup``, which will be the next topic. + +Using point groups +------------------ + +Point groups are represented in Mantid by the ``PointGroup``-interface, which is then implemented for each actual point group. The interface consists of two parts, one for providing information about the point group and one for working with :math:`hkl`-indices. Just as in the case of ``SymmetryOperation``, ``PointGroup``-objects are created using a factory, this time by supplying the short Hermann-Mauguin symbol [#f1]_ : + +.. testcode :: ExInformation + + from mantid.geometry import PointGroup, PointGroupFactoryImpl + + pg = PointGroupFactoryImpl.Instance().createPointGroup("-1") + + print "Name:", pg.getName() + print "Hermann-Mauguin symbol:", pg.getSymbol() + print "Crystal system:", pg.crystalSystem() + +When this code is executed, some information about the point group is printed: + +.. testoutput :: ExInformation + + Name: -1 (Triclinic) + Hermann-Mauguin symbol: -1 + Crystal system: Triclinic + +It's possible to query the factory about available point groups. One option returns a list of all available groups, while another possibility is to get only groups from a certain crystal system: + +.. testcode :: ExQueryPointGroups + + from mantid.geometry import PointGroup, PointGroupFactoryImpl + + print "All point groups:", PointGroupFactoryImpl.Instance().getAllPointGroupSymbols() + print "Cubic point groups:", PointGroupFactoryImpl.Instance().getPointGroupSymbols(PointGroup.CrystalSystem.Cubic) + print "Tetragonal point groups:", PointGroupFactoryImpl.Instance().getPointGroupSymbols(PointGroup.CrystalSystem.Tetragonal) + +Which results in the following output: + +.. testoutput :: ExQueryPointGroups + + All point groups: ['-1','-3','-31m','-3m1','112/m','2/m','4/m','4/mmm','6/m','6/mmm','m-3','m-3m','mmm'] + Cubic point groups: ['m-3','m-3m'] + Tetragonal point groups: ['4/m','4/mmm'] + +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 + + from mantid.geometry import PointGroup, PointGroupFactoryImpl + + pg = PointGroupFactoryImpl.Instance().createPointGroup("m-3m") + + hkl1 = [2, 0, 0] + hkl2 = [0, 0, -2] + hkl3 = [0, 1, 2] + + print "Are [2,0,0] and [0,0,-2] equivalent?", pg.isEquivalent(hkl1, hkl2) + print "Are [2,0,0] and [0,1,2] equivalent?", pg.isEquivalent(hkl1, hkl3) + +.. testoutput :: ExIsEquivalent + + Are [2,0,0] and [0,0,-2] equivalent? True + Are [2,0,0] and [0,1,2] equivalent? False + +Another common task is to find all symmetry equivalents of a reflection, for example to determine its multiplicity. ``PointGroup`` has a method for this purpose which returns the set of non-identical symmetry equivalents for a given :math:`hkl` (including :math:`hkl` itself): + +.. testcode :: ExGetEquivalents + + from mantid.geometry import PointGroup, PointGroupFactoryImpl + + pg = PointGroupFactoryImpl.Instance().createPointGroup("m-3m") + + hkl1 = [2, 0, 0] + equivalents1 = pg.getEquivalents(hkl1) + + print "Number of reflections equivalent to [2,0,0]:", len(equivalents1) + print "Equivalents:", equivalents1 + print + + hkl2 = [1, 1, 1] + equivalents2 = pg.getEquivalents(hkl2) + + print "Number of reflections equivalent to [1,1,1]:", len(equivalents2) + print "Equivalents:", equivalents2 + +Executing this code results in the following output: + +.. testoutput :: ExGetEquivalents + + Number of reflections equivalent to [2,0,0]: 6 + Equivalents: [[2,0,0], [0,2,0], [0,0,2], [0,0,-2], [0,-2,0], [-2,0,0]] + + Number of reflections equivalent to [1,1,1]: 8 + Equivalents: [[1,1,1], [1,1,-1], [1,-1,1], [1,-1,-1], [-1,1,1], [-1,1,-1], [-1,-1,1], [-1,-1,-1]] + +Sometimes, a list of reflections needs to be reduced to a set of symmetry independent reflections only. That means it should not contain any two reflections that are symmetry equivalents according to the point group symmetry. To achieve this, ``PointGroup`` offers a method that returns the same :math:`hkl'` for all symmetry equivalents. + +.. testcode :: ExIndependentReflections + + from mantid.geometry import PointGroup, PointGroupFactoryImpl + + pg = PointGroupFactoryImpl.Instance().createPointGroup("m-3m") + + hklList = [[1, 0, 0], [0, 1, 0], [-1, 0, 0], # Equivalent to [1,0,0] + [1, 1, 1], [-1, 1, 1], # Equivalent to [1,1,1] + [-3, 1, 1], [1, -3, 1], [-1, 1, 3]] # Equivalent to [3,1,1] + + independent = set() + + for hkl in hklList: + independent.add(pg.getReflectionFamily(hkl)) # getReflectionFamily returns the same hkl for all symmetry equivalents + + print "Number of independent reflections:", len(independent) + print "Reflections:", list(independent) + +This example code produces the output below upon execution: + +.. testoutput:: ExIndependentReflections + + Number of independent reflections: 3 + Reflections: [[1,1,1], [1,0,0], [3,1,1]] + +Again, as in the case of ``SymmetryOperation``, the usage of ``PointGroup`` and the corresponding factory is very similar in C++. + +.. [ITA6] International Tables for Crystallography (2006). Vol. A, ch. 10.1, p. 762 + +.. [#f1] In the case of the monoclinic Laue class :math:`2/m` it's a bit more complicated, because there are two conventions regarding the unique axis. According to current crystallographic standards, the :math:`b`-axis is used, but in some cases one may find the :math:`c`-axis for this purpose. To resolve this, both options are offered in Mantid. When using the symbol ``2/m``, the :math:`b`-axis convention is used, for :math:`c` one has to explicitly provide the symbol as ``112/m``. + +.. categories:: Concepts \ No newline at end of file diff --git a/Code/Mantid/docs/source/fitfunctions/EndErfc.rst b/Code/Mantid/docs/source/fitfunctions/EndErfc.rst new file mode 100644 index 000000000000..5fb5bd408ac7 --- /dev/null +++ b/Code/Mantid/docs/source/fitfunctions/EndErfc.rst @@ -0,0 +1,20 @@ +.. _func-EndErfc: + +======= +EndErfc +======= + +.. index:: EndErfc + +Description +----------- + +This is a fitting function for the complementary error function. + +The function is A*erfc((B-x)/C) + D for positive A and the same minus 2A for negative A. + +.. attributes:: + +.. properties:: + +.. categories:: diff --git a/Code/Mantid/docs/source/fitfunctions/TabulatedFunction.rst b/Code/Mantid/docs/source/fitfunctions/TabulatedFunction.rst new file mode 100644 index 000000000000..86b0138edbd2 --- /dev/null +++ b/Code/Mantid/docs/source/fitfunctions/TabulatedFunction.rst @@ -0,0 +1,62 @@ +.. _func-TabulatedFunction: + +================= +TabulatedFunction +================= + +.. index:: TabulatedFunction + +Description +----------- + +A function which takes its values from a file or a workspace. The values are tabulated as +x,y pairs. Liear interpolation is used for points between the tabulated values. The function +returns zero for points outside the tabulated values. + +The files can be either ascii text files or nexus files. The ascii files must contain two column +of real numbers separated by spaces. The first column are the x-values and the second one is for y. + +If a nexus file is used its first spectrum provides the data for the function. The same is true for +a workspace which must be a MatrixWorkspace. + +.. attributes:: + +.. properties:: + +Usage +----- + +.. include:: ../usagedata-note.txt + +**Example - Fit two structure factors that are shifted and scaled with respect to each other:** + +.. testcode:: Ex + + ws1=LoadNexus('tabulatedFunctionExample.nxs') + + # Clone the workspace by rescaling and shift + ws2=CloneWorkspace(ws1) + ws2=Scale(ws2, Factor=1.34, Operation='Multiply') + ws2=ScaleX(ws2, Factor=0.002, Operation='Add') + + # Call the Fit algorithm and perform the fit + myFunc='name=TabulatedFunction,Workspace=ws1,WorkspaceIndex=0,Scaling=1.0,Shift=0.0' + fitStatus, chiSq, covarianceTable, paramTable, fitWorkspace =\ + Fit(Function=myFunc, InputWorkspace=ws2, Output='fit') + + print "The fit was: " + fitStatus + print("Fitted Scaling value is: %.2f" % paramTable.column(1)[0]) + print("Fitted Shift value is: %.3f" % abs(paramTable.column(1)[1])) + # fitWorkspace contains the data, the calculated and the difference patterns + print "Number of spectra in fitWorkspace is: " + str(fitWorkspace.getNumberHistograms()) + +Output: + +.. testoutput:: Ex + + The fit was: success + Fitted Scaling value is: 1.34 + Fitted Shift value is: 0.002 + Number of spectra in fitWorkspace is: 3 + +.. categories:: diff --git a/Code/Mantid/instrument/ALF_Definition.xml b/Code/Mantid/instrument/ALF_Definition.xml index 418a1d5b19d5..331f26d6a83d 100644 --- a/Code/Mantid/instrument/ALF_Definition.xml +++ b/Code/Mantid/instrument/ALF_Definition.xml @@ -1,7 +1,9 @@ - diff --git a/Code/Mantid/instrument/ARCS_Definition_19000000-20121010.xml b/Code/Mantid/instrument/ARCS_Definition_19000000-20121010.xml index cd75dac024b3..01b0a5a702a1 100644 --- a/Code/Mantid/instrument/ARCS_Definition_19000000-20121010.xml +++ b/Code/Mantid/instrument/ARCS_Definition_19000000-20121010.xml @@ -1,7 +1,9 @@ - diff --git a/Code/Mantid/instrument/ARCS_Definition_20121010-20121011.xml b/Code/Mantid/instrument/ARCS_Definition_20121010-20121011.xml index b0f30d998c1d..7a3aa25582ec 100644 --- a/Code/Mantid/instrument/ARCS_Definition_20121010-20121011.xml +++ b/Code/Mantid/instrument/ARCS_Definition_20121010-20121011.xml @@ -1,7 +1,9 @@ - diff --git a/Code/Mantid/instrument/ARCS_Definition_20121011-.xml b/Code/Mantid/instrument/ARCS_Definition_20121011-.xml index d7136c4962d0..3eba4da4776a 100644 --- a/Code/Mantid/instrument/ARCS_Definition_20121011-.xml +++ b/Code/Mantid/instrument/ARCS_Definition_20121011-.xml @@ -1,7 +1,9 @@ - diff --git a/Code/Mantid/instrument/ARGUS_Definition.xml b/Code/Mantid/instrument/ARGUS_Definition.xml index 6c20cfda9360..af0ba59852d8 100644 --- a/Code/Mantid/instrument/ARGUS_Definition.xml +++ b/Code/Mantid/instrument/ARGUS_Definition.xml @@ -1,7 +1,9 @@ - diff --git a/Code/Mantid/instrument/BASIS_Definition.xml b/Code/Mantid/instrument/BASIS_Definition.xml index e7c863270d73..82684ef3a9f2 100644 --- a/Code/Mantid/instrument/BASIS_Definition.xml +++ b/Code/Mantid/instrument/BASIS_Definition.xml @@ -1,5 +1,5 @@ - + @@ -28,10 +28,25 @@
- + + - + + + + + + + + + + + + + + + @@ -22715,9 +22730,6 @@ - - - @@ -45402,9 +45414,6 @@ - - - @@ -68089,9 +68098,6 @@ - - - diff --git a/Code/Mantid/instrument/BASIS_Definition_0-20130119.xml b/Code/Mantid/instrument/BASIS_Definition_0-20130119.xml index ffbee38da87f..bc0573b5b69a 100644 --- a/Code/Mantid/instrument/BASIS_Definition_0-20130119.xml +++ b/Code/Mantid/instrument/BASIS_Definition_0-20130119.xml @@ -1,5 +1,7 @@ - diff --git a/Code/Mantid/instrument/BASIS_silicon_111_Parameters.xml b/Code/Mantid/instrument/BASIS_silicon_111_Parameters.xml index f4ca952eead0..c3f972fadbb9 100644 --- a/Code/Mantid/instrument/BASIS_silicon_111_Parameters.xml +++ b/Code/Mantid/instrument/BASIS_silicon_111_Parameters.xml @@ -36,7 +36,6 @@ - @@ -47,31 +46,13 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + diff --git a/Code/Mantid/instrument/BIOSANS_Definition.xml b/Code/Mantid/instrument/BIOSANS_Definition.xml index 0656336dd07f..07034d2d4861 100644 --- a/Code/Mantid/instrument/BIOSANS_Definition.xml +++ b/Code/Mantid/instrument/BIOSANS_Definition.xml @@ -1,7 +1,9 @@ - diff --git a/Code/Mantid/instrument/BIOSANS_Definition_2012.xml b/Code/Mantid/instrument/BIOSANS_Definition_2012.xml index 67d4fbf8c1ab..ba0ecbeef8ec 100644 --- a/Code/Mantid/instrument/BIOSANS_Definition_2012.xml +++ b/Code/Mantid/instrument/BIOSANS_Definition_2012.xml @@ -1,5 +1,7 @@ - diff --git a/Code/Mantid/instrument/CHRONUS_Definition.xml b/Code/Mantid/instrument/CHRONUS_Definition.xml index 366ad81ab0a8..2798396347c2 100644 --- a/Code/Mantid/instrument/CHRONUS_Definition.xml +++ b/Code/Mantid/instrument/CHRONUS_Definition.xml @@ -3,7 +3,7 @@ see http://www.mantidproject.org/IDF --> - + diff --git a/Code/Mantid/instrument/CNCS_Definition_1-35154.xml b/Code/Mantid/instrument/CNCS_Definition_1-35154.xml index ee6f552bcd65..dd42e9ae800c 100644 --- a/Code/Mantid/instrument/CNCS_Definition_1-35154.xml +++ b/Code/Mantid/instrument/CNCS_Definition_1-35154.xml @@ -1,7 +1,9 @@ - diff --git a/Code/Mantid/instrument/CNCS_Definition_20120215-20120313.xml b/Code/Mantid/instrument/CNCS_Definition_20120215-20120313.xml index 254b9111a40e..057117bcbf93 100644 --- a/Code/Mantid/instrument/CNCS_Definition_20120215-20120313.xml +++ b/Code/Mantid/instrument/CNCS_Definition_20120215-20120313.xml @@ -1,5 +1,7 @@ - diff --git a/Code/Mantid/instrument/CNCS_Definition_20120314_20120816.xml b/Code/Mantid/instrument/CNCS_Definition_20120314_20120816.xml index 86a8bc1343f0..01a141c05a71 100644 --- a/Code/Mantid/instrument/CNCS_Definition_20120314_20120816.xml +++ b/Code/Mantid/instrument/CNCS_Definition_20120314_20120816.xml @@ -1,5 +1,7 @@ - diff --git a/Code/Mantid/instrument/CNCS_Definition_20120817_20130814.xml b/Code/Mantid/instrument/CNCS_Definition_20120817_20130814.xml index 87b69ed32f10..770416855d77 100644 --- a/Code/Mantid/instrument/CNCS_Definition_20120817_20130814.xml +++ b/Code/Mantid/instrument/CNCS_Definition_20120817_20130814.xml @@ -1,5 +1,7 @@ - diff --git a/Code/Mantid/instrument/CNCS_Definition_20130814_20140131.xml b/Code/Mantid/instrument/CNCS_Definition_20130814_20140131.xml index 6f5d5d1b90d7..a1e61c061120 100644 --- a/Code/Mantid/instrument/CNCS_Definition_20130814_20140131.xml +++ b/Code/Mantid/instrument/CNCS_Definition_20130814_20140131.xml @@ -1,5 +1,7 @@ - diff --git a/Code/Mantid/instrument/CNCS_Definition_20140201_20140807.xml b/Code/Mantid/instrument/CNCS_Definition_20140201_20140807.xml index 27bc6251c8d7..7124e7c28996 100644 --- a/Code/Mantid/instrument/CNCS_Definition_20140201_20140807.xml +++ b/Code/Mantid/instrument/CNCS_Definition_20140201_20140807.xml @@ -1,5 +1,5 @@ - + diff --git a/Code/Mantid/instrument/CNCS_Definition_35155-44929.xml b/Code/Mantid/instrument/CNCS_Definition_35155-44929.xml index 3ed2b9cbe438..4c4708a2bec8 100644 --- a/Code/Mantid/instrument/CNCS_Definition_35155-44929.xml +++ b/Code/Mantid/instrument/CNCS_Definition_35155-44929.xml @@ -1,5 +1,7 @@ - diff --git a/Code/Mantid/instrument/CORELLI_Definition.xml b/Code/Mantid/instrument/CORELLI_Definition.xml index 78f3e1c01d1e..83b539b45c5d 100644 --- a/Code/Mantid/instrument/CORELLI_Definition.xml +++ b/Code/Mantid/instrument/CORELLI_Definition.xml @@ -1,5 +1,5 @@ - + @@ -15,7 +15,15 @@ - + + + + + + + + + @@ -31,6 +39,711 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -1342,7 +2055,7 @@ - + @@ -1604,7 +2317,7 @@ - + diff --git a/Code/Mantid/instrument/CORELLI_Parameters.xml b/Code/Mantid/instrument/CORELLI_Parameters.xml new file mode 100644 index 000000000000..e9cf3f940d4e --- /dev/null +++ b/Code/Mantid/instrument/CORELLI_Parameters.xml @@ -0,0 +1,19 @@ + + + + + + + + + + + + + + + + + + + diff --git a/Code/Mantid/instrument/CRISP_Definition.xml b/Code/Mantid/instrument/CRISP_Definition.xml index e6c8349e8036..8afc97e4bfd9 100644 --- a/Code/Mantid/instrument/CRISP_Definition.xml +++ b/Code/Mantid/instrument/CRISP_Definition.xml @@ -1,5 +1,7 @@ - diff --git a/Code/Mantid/instrument/CRISP_Parameters.xml b/Code/Mantid/instrument/CRISP_Parameters.xml index 8b05b80de698..785baa525ded 100644 --- a/Code/Mantid/instrument/CRISP_Parameters.xml +++ b/Code/Mantid/instrument/CRISP_Parameters.xml @@ -36,10 +36,14 @@ + + diff --git a/Code/Mantid/instrument/D17_Definition.xml b/Code/Mantid/instrument/D17_Definition.xml index 7103cf3ae01e..087d024f91d9 100644 --- a/Code/Mantid/instrument/D17_Definition.xml +++ b/Code/Mantid/instrument/D17_Definition.xml @@ -1,6 +1,9 @@ - @@ -54,13 +57,14 @@ valid-to="2100-01-31 23:59:59" last-modified="2014-05-26 14:06:31"> - - + + - - + diff --git a/Code/Mantid/instrument/D2B_Definition.xml b/Code/Mantid/instrument/D2B_Definition.xml index 0e0dd567811d..ff72228f997a 100644 --- a/Code/Mantid/instrument/D2B_Definition.xml +++ b/Code/Mantid/instrument/D2B_Definition.xml @@ -1,6 +1,6 @@ - diff --git a/Code/Mantid/instrument/D33_Definition.xml b/Code/Mantid/instrument/D33_Definition.xml index c5bd81fc41bd..3bc659ec75e2 100644 --- a/Code/Mantid/instrument/D33_Definition.xml +++ b/Code/Mantid/instrument/D33_Definition.xml @@ -2,7 +2,7 @@ diff --git a/Code/Mantid/instrument/EMU_Definition_32detectors.xml b/Code/Mantid/instrument/EMU_Definition_32detectors.xml index 43a532d4d37e..d74a6dac0856 100644 --- a/Code/Mantid/instrument/EMU_Definition_32detectors.xml +++ b/Code/Mantid/instrument/EMU_Definition_32detectors.xml @@ -1,7 +1,9 @@ - diff --git a/Code/Mantid/instrument/EMU_Definition_96detectors.xml b/Code/Mantid/instrument/EMU_Definition_96detectors.xml index cfcd20558912..03ffbf68daf1 100644 --- a/Code/Mantid/instrument/EMU_Definition_96detectors.xml +++ b/Code/Mantid/instrument/EMU_Definition_96detectors.xml @@ -1,7 +1,9 @@ - diff --git a/Code/Mantid/instrument/ENGIN-X_Definition.xml b/Code/Mantid/instrument/ENGIN-X_Definition.xml index 0e1be1ba3886..8f931e0d5816 100644 --- a/Code/Mantid/instrument/ENGIN-X_Definition.xml +++ b/Code/Mantid/instrument/ENGIN-X_Definition.xml @@ -1,7 +1,9 @@ - diff --git a/Code/Mantid/instrument/EQ-SANS_Definition.xml b/Code/Mantid/instrument/EQ-SANS_Definition.xml index fb1005bbd915..411822031fbe 100644 --- a/Code/Mantid/instrument/EQ-SANS_Definition.xml +++ b/Code/Mantid/instrument/EQ-SANS_Definition.xml @@ -1,7 +1,9 @@ - diff --git a/Code/Mantid/instrument/FOCUS_Definition.xml b/Code/Mantid/instrument/FOCUS_Definition.xml index 52a519946320..0d5b5c40c4ad 100644 --- a/Code/Mantid/instrument/FOCUS_Definition.xml +++ b/Code/Mantid/instrument/FOCUS_Definition.xml @@ -1,6 +1,8 @@ - diff --git a/Code/Mantid/instrument/Facilities.xml b/Code/Mantid/instrument/Facilities.xml index d5be1187b46e..25d30bd20967 100644 --- a/Code/Mantid/instrument/Facilities.xml +++ b/Code/Mantid/instrument/Facilities.xml @@ -320,7 +320,6 @@ - diff --git a/Code/Mantid/instrument/GEM_Definition.xml b/Code/Mantid/instrument/GEM_Definition.xml index 25128523ed3e..b7b3a66e808e 100644 --- a/Code/Mantid/instrument/GEM_Definition.xml +++ b/Code/Mantid/instrument/GEM_Definition.xml @@ -1,7 +1,9 @@ - diff --git a/Code/Mantid/instrument/GPD_Definition_2detectors.xml b/Code/Mantid/instrument/GPD_Definition_2detectors.xml index 28b80f25a5e0..a0c946e00b5e 100644 --- a/Code/Mantid/instrument/GPD_Definition_2detectors.xml +++ b/Code/Mantid/instrument/GPD_Definition_2detectors.xml @@ -1,7 +1,9 @@ - diff --git a/Code/Mantid/instrument/GPSANS_Definition.xml b/Code/Mantid/instrument/GPSANS_Definition.xml index 04abc87f0563..eaf2ad16b535 100644 --- a/Code/Mantid/instrument/GPSANS_Definition.xml +++ b/Code/Mantid/instrument/GPSANS_Definition.xml @@ -1,7 +1,9 @@ - diff --git a/Code/Mantid/instrument/GPS_Definition_5detectors.xml b/Code/Mantid/instrument/GPS_Definition_5detectors.xml index 13c99260e01f..7594636cc117 100644 --- a/Code/Mantid/instrument/GPS_Definition_5detectors.xml +++ b/Code/Mantid/instrument/GPS_Definition_5detectors.xml @@ -1,7 +1,9 @@ - diff --git a/Code/Mantid/instrument/Grouping/REFL_Detector_Grouping_Sum_X_rot.xml b/Code/Mantid/instrument/Grouping/REFL_Detector_Grouping_Sum_X_rot.xml new file mode 100644 index 000000000000..3a884fe2a035 --- /dev/null +++ b/Code/Mantid/instrument/Grouping/REFL_Detector_Grouping_Sum_X_rot.xml @@ -0,0 +1,914 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Code/Mantid/instrument/Grouping/REFL_Detector_Grouping_Sum_Y_rot.xml b/Code/Mantid/instrument/Grouping/REFL_Detector_Grouping_Sum_Y_rot.xml new file mode 100644 index 000000000000..d159bb2edfd9 --- /dev/null +++ b/Code/Mantid/instrument/Grouping/REFL_Detector_Grouping_Sum_Y_rot.xml @@ -0,0 +1,770 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Code/Mantid/instrument/HET_Definition.xml b/Code/Mantid/instrument/HET_Definition.xml index a3607f43db6d..0ac98520335e 100644 --- a/Code/Mantid/instrument/HET_Definition.xml +++ b/Code/Mantid/instrument/HET_Definition.xml @@ -1,7 +1,9 @@ - diff --git a/Code/Mantid/instrument/HIFI_Definition.xml b/Code/Mantid/instrument/HIFI_Definition.xml index 25dd0d64e72c..7652dd7bc415 100644 --- a/Code/Mantid/instrument/HIFI_Definition.xml +++ b/Code/Mantid/instrument/HIFI_Definition.xml @@ -1,7 +1,9 @@ - diff --git a/Code/Mantid/instrument/HIRESSANS_Definition.xml b/Code/Mantid/instrument/HIRESSANS_Definition.xml index 9623d8e108ec..ddb3ddb660fa 100644 --- a/Code/Mantid/instrument/HIRESSANS_Definition.xml +++ b/Code/Mantid/instrument/HIRESSANS_Definition.xml @@ -1,5 +1,7 @@ - diff --git a/Code/Mantid/instrument/HRPD_Definition.xml b/Code/Mantid/instrument/HRPD_Definition.xml index 3cb1c19e929f..10480bc8ba27 100644 --- a/Code/Mantid/instrument/HRPD_Definition.xml +++ b/Code/Mantid/instrument/HRPD_Definition.xml @@ -1,7 +1,9 @@ - diff --git a/Code/Mantid/instrument/HYSPEC_Definition.xml b/Code/Mantid/instrument/HYSPEC_Definition.xml index e281d4071883..c3fe985030ce 100644 --- a/Code/Mantid/instrument/HYSPEC_Definition.xml +++ b/Code/Mantid/instrument/HYSPEC_Definition.xml @@ -1,5 +1,7 @@ - diff --git a/Code/Mantid/instrument/IMAT_Definition.xml b/Code/Mantid/instrument/IMAT_Definition.xml new file mode 100644 index 000000000000..c150ddcb1a8a --- /dev/null +++ b/Code/Mantid/instrument/IMAT_Definition.xml @@ -0,0 +1,71 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Code/Mantid/instrument/IN10_Definition.xml b/Code/Mantid/instrument/IN10_Definition.xml index dcfec200ceee..809db8d93899 100644 --- a/Code/Mantid/instrument/IN10_Definition.xml +++ b/Code/Mantid/instrument/IN10_Definition.xml @@ -1,7 +1,9 @@ - diff --git a/Code/Mantid/instrument/IN13_Definition.xml b/Code/Mantid/instrument/IN13_Definition.xml index 9d5f914b6f4e..ef5bb4e1f672 100644 --- a/Code/Mantid/instrument/IN13_Definition.xml +++ b/Code/Mantid/instrument/IN13_Definition.xml @@ -1,7 +1,9 @@ - diff --git a/Code/Mantid/instrument/IN16B_Definition.xml b/Code/Mantid/instrument/IN16B_Definition.xml index 92a12ba26c83..832d594df69e 100644 --- a/Code/Mantid/instrument/IN16B_Definition.xml +++ b/Code/Mantid/instrument/IN16B_Definition.xml @@ -1,6 +1,9 @@ - diff --git a/Code/Mantid/instrument/IN16_Definition.xml b/Code/Mantid/instrument/IN16_Definition.xml index bad78baed12d..77b43629a07f 100644 --- a/Code/Mantid/instrument/IN16_Definition.xml +++ b/Code/Mantid/instrument/IN16_Definition.xml @@ -1,7 +1,9 @@ - diff --git a/Code/Mantid/instrument/IN4_Definition.xml b/Code/Mantid/instrument/IN4_Definition.xml index 3e47614f94a3..3cd93ab4767e 100644 --- a/Code/Mantid/instrument/IN4_Definition.xml +++ b/Code/Mantid/instrument/IN4_Definition.xml @@ -1,7 +1,10 @@ - + diff --git a/Code/Mantid/instrument/IN5_Definition.xml b/Code/Mantid/instrument/IN5_Definition.xml index 9903b0400fbd..b652240d1259 100644 --- a/Code/Mantid/instrument/IN5_Definition.xml +++ b/Code/Mantid/instrument/IN5_Definition.xml @@ -1,6 +1,9 @@ - diff --git a/Code/Mantid/instrument/IN6_Definition.xml b/Code/Mantid/instrument/IN6_Definition.xml index 6476d285e711..3456e5b9064a 100644 --- a/Code/Mantid/instrument/IN6_Definition.xml +++ b/Code/Mantid/instrument/IN6_Definition.xml @@ -1,7 +1,10 @@ - + diff --git a/Code/Mantid/instrument/INES_Definition.xml b/Code/Mantid/instrument/INES_Definition.xml index 0f5c29da5d46..d1eb6d6d22f2 100644 --- a/Code/Mantid/instrument/INES_Definition.xml +++ b/Code/Mantid/instrument/INES_Definition.xml @@ -1,7 +1,9 @@ - diff --git a/Code/Mantid/instrument/INTER_Definition.xml b/Code/Mantid/instrument/INTER_Definition.xml index a8513f55f9df..28db9dfbd2a5 100644 --- a/Code/Mantid/instrument/INTER_Definition.xml +++ b/Code/Mantid/instrument/INTER_Definition.xml @@ -1,5 +1,7 @@ - diff --git a/Code/Mantid/instrument/INTER_Parameters.xml b/Code/Mantid/instrument/INTER_Parameters.xml index 96216d6a8c2a..43671c19f03c 100644 --- a/Code/Mantid/instrument/INTER_Parameters.xml +++ b/Code/Mantid/instrument/INTER_Parameters.xml @@ -33,10 +33,14 @@ + + diff --git a/Code/Mantid/instrument/IRIS_Definition.xml b/Code/Mantid/instrument/IRIS_Definition.xml index 1f5736c7408a..a0be3ec3e4c3 100644 --- a/Code/Mantid/instrument/IRIS_Definition.xml +++ b/Code/Mantid/instrument/IRIS_Definition.xml @@ -1,7 +1,9 @@ - diff --git a/Code/Mantid/instrument/LARMOR_Definition.xml b/Code/Mantid/instrument/LARMOR_Definition.xml index 64c984237b5c..85ce441f1a9a 100644 --- a/Code/Mantid/instrument/LARMOR_Definition.xml +++ b/Code/Mantid/instrument/LARMOR_Definition.xml @@ -1,7 +1,9 @@ - diff --git a/Code/Mantid/instrument/LET_Definition.xml b/Code/Mantid/instrument/LET_Definition.xml index b67cf567f6c6..f54ab3fd09a8 100644 --- a/Code/Mantid/instrument/LET_Definition.xml +++ b/Code/Mantid/instrument/LET_Definition.xml @@ -1,7 +1,9 @@ - diff --git a/Code/Mantid/instrument/LET_Definition_dr2to9.xml b/Code/Mantid/instrument/LET_Definition_dr2to9.xml index e6ac42070c29..d480ca3eb474 100644 --- a/Code/Mantid/instrument/LET_Definition_dr2to9.xml +++ b/Code/Mantid/instrument/LET_Definition_dr2to9.xml @@ -1,7 +1,9 @@ - diff --git a/Code/Mantid/instrument/LET_Definition_dr3to10.xml b/Code/Mantid/instrument/LET_Definition_dr3to10.xml index b904ce60b66e..9cd7fd1b83d8 100644 --- a/Code/Mantid/instrument/LET_Definition_dr3to10.xml +++ b/Code/Mantid/instrument/LET_Definition_dr3to10.xml @@ -1,7 +1,9 @@ - diff --git a/Code/Mantid/instrument/LET_Definition_dr3to11.xml b/Code/Mantid/instrument/LET_Definition_dr3to11.xml index 3cc255530c56..15c624c00272 100644 --- a/Code/Mantid/instrument/LET_Definition_dr3to11.xml +++ b/Code/Mantid/instrument/LET_Definition_dr3to11.xml @@ -1,7 +1,9 @@ - diff --git a/Code/Mantid/instrument/LOQ_Definition_20010430-20020226.xml b/Code/Mantid/instrument/LOQ_Definition_20010430-20020226.xml index 6ec433c131c4..02a14ff51966 100644 --- a/Code/Mantid/instrument/LOQ_Definition_20010430-20020226.xml +++ b/Code/Mantid/instrument/LOQ_Definition_20010430-20020226.xml @@ -1,7 +1,9 @@ - diff --git a/Code/Mantid/instrument/LOQ_Definition_20020226-.xml b/Code/Mantid/instrument/LOQ_Definition_20020226-.xml index 3d7735146482..7f32050beb6f 100644 --- a/Code/Mantid/instrument/LOQ_Definition_20020226-.xml +++ b/Code/Mantid/instrument/LOQ_Definition_20020226-.xml @@ -1,7 +1,9 @@ - diff --git a/Code/Mantid/instrument/LOQ_Definition_20121016-.xml b/Code/Mantid/instrument/LOQ_Definition_20121016-.xml index c7c546c05b67..f93cc3637940 100644 --- a/Code/Mantid/instrument/LOQ_Definition_20121016-.xml +++ b/Code/Mantid/instrument/LOQ_Definition_20121016-.xml @@ -1,7 +1,9 @@ - diff --git a/Code/Mantid/instrument/LOQ_trans_Definition.xml b/Code/Mantid/instrument/LOQ_trans_Definition.xml index 91178d5cea51..69196e66c7c1 100644 --- a/Code/Mantid/instrument/LOQ_trans_Definition.xml +++ b/Code/Mantid/instrument/LOQ_trans_Definition.xml @@ -1,7 +1,9 @@ - diff --git a/Code/Mantid/instrument/MANDI_Definition_2012.xml b/Code/Mantid/instrument/MANDI_Definition_2012.xml index 60583cec86be..8d11b7308455 100644 --- a/Code/Mantid/instrument/MANDI_Definition_2012.xml +++ b/Code/Mantid/instrument/MANDI_Definition_2012.xml @@ -1,7 +1,9 @@ - diff --git a/Code/Mantid/instrument/MANDI_Definition_2013_03_15.xml b/Code/Mantid/instrument/MANDI_Definition_2013_03_15.xml index d95889a575c6..299c4d96296c 100644 --- a/Code/Mantid/instrument/MANDI_Definition_2013_03_15.xml +++ b/Code/Mantid/instrument/MANDI_Definition_2013_03_15.xml @@ -1,7 +1,9 @@ - diff --git a/Code/Mantid/instrument/MANDI_Definition_2013_08_01.xml b/Code/Mantid/instrument/MANDI_Definition_2013_08_01.xml index 8aa17675d054..8025821306bc 100644 --- a/Code/Mantid/instrument/MANDI_Definition_2013_08_01.xml +++ b/Code/Mantid/instrument/MANDI_Definition_2013_08_01.xml @@ -1,7 +1,9 @@ - diff --git a/Code/Mantid/instrument/MANDI_Definition_2014_08_01.xml b/Code/Mantid/instrument/MANDI_Definition_2014_08_01.xml index ff3947ba2174..281024a9208b 100644 --- a/Code/Mantid/instrument/MANDI_Definition_2014_08_01.xml +++ b/Code/Mantid/instrument/MANDI_Definition_2014_08_01.xml @@ -1,7 +1,9 @@ - diff --git a/Code/Mantid/instrument/MAPS_Definition.xml b/Code/Mantid/instrument/MAPS_Definition.xml index b53c70ae578a..5bef2b032e4e 100644 --- a/Code/Mantid/instrument/MAPS_Definition.xml +++ b/Code/Mantid/instrument/MAPS_Definition.xml @@ -1,7 +1,9 @@ - diff --git a/Code/Mantid/instrument/MARI_Definition.xml b/Code/Mantid/instrument/MARI_Definition.xml index db207c84f73d..8f4aa117c173 100644 --- a/Code/Mantid/instrument/MARI_Definition.xml +++ b/Code/Mantid/instrument/MARI_Definition.xml @@ -1,7 +1,9 @@ - diff --git a/Code/Mantid/instrument/MERLIN_Definition.xml b/Code/Mantid/instrument/MERLIN_Definition.xml index 7400a5c1c0bd..12ecfb090152 100644 --- a/Code/Mantid/instrument/MERLIN_Definition.xml +++ b/Code/Mantid/instrument/MERLIN_Definition.xml @@ -1,7 +1,9 @@ - diff --git a/Code/Mantid/instrument/MERLIN_Definition_after2013_4.xml b/Code/Mantid/instrument/MERLIN_Definition_after2013_4.xml index 16048581dd1a..c87581b895a8 100644 --- a/Code/Mantid/instrument/MERLIN_Definition_after2013_4.xml +++ b/Code/Mantid/instrument/MERLIN_Definition_after2013_4.xml @@ -1,7 +1,9 @@ - diff --git a/Code/Mantid/instrument/MIBEMOL_Definition.xml b/Code/Mantid/instrument/MIBEMOL_Definition.xml index fa3f052a16c8..abcc15879689 100644 --- a/Code/Mantid/instrument/MIBEMOL_Definition.xml +++ b/Code/Mantid/instrument/MIBEMOL_Definition.xml @@ -1,6 +1,8 @@ - diff --git a/Code/Mantid/instrument/MUSR_Definition.xml b/Code/Mantid/instrument/MUSR_Definition.xml index 34a34f977d87..337d6019973c 100644 --- a/Code/Mantid/instrument/MUSR_Definition.xml +++ b/Code/Mantid/instrument/MUSR_Definition.xml @@ -1,7 +1,9 @@ - diff --git a/Code/Mantid/instrument/MUT_Definition_32_detectors.xml b/Code/Mantid/instrument/MUT_Definition_32_detectors.xml index 1f18fd9dfe90..4d040b8cef43 100644 --- a/Code/Mantid/instrument/MUT_Definition_32_detectors.xml +++ b/Code/Mantid/instrument/MUT_Definition_32_detectors.xml @@ -3,7 +3,7 @@ see http://www.mantidproject.org/IDF --> - diff --git a/Code/Mantid/instrument/NGSANS_Definition.xml b/Code/Mantid/instrument/NGSANS_Definition.xml index 2766142107d7..7774a347bc7d 100644 --- a/Code/Mantid/instrument/NGSANS_Definition.xml +++ b/Code/Mantid/instrument/NGSANS_Definition.xml @@ -1,7 +1,9 @@ - diff --git a/Code/Mantid/instrument/NIM_Definition.xml b/Code/Mantid/instrument/NIM_Definition.xml index 320100baf2e7..9161d98d2779 100644 --- a/Code/Mantid/instrument/NIM_Definition.xml +++ b/Code/Mantid/instrument/NIM_Definition.xml @@ -1,7 +1,9 @@ - diff --git a/Code/Mantid/instrument/NOMAD_Definition.xml b/Code/Mantid/instrument/NOMAD_Definition.xml index 05bd72494d61..c536ff632286 100644 --- a/Code/Mantid/instrument/NOMAD_Definition.xml +++ b/Code/Mantid/instrument/NOMAD_Definition.xml @@ -1,5 +1,7 @@ - diff --git a/Code/Mantid/instrument/NOMAD_Definition_19000000-20120630.xml b/Code/Mantid/instrument/NOMAD_Definition_19000000-20120630.xml index a13060e4f1ef..176aa025cbec 100644 --- a/Code/Mantid/instrument/NOMAD_Definition_19000000-20120630.xml +++ b/Code/Mantid/instrument/NOMAD_Definition_19000000-20120630.xml @@ -1,7 +1,9 @@ - diff --git a/Code/Mantid/instrument/NOMAD_Definition_20120701-20120731.xml b/Code/Mantid/instrument/NOMAD_Definition_20120701-20120731.xml index b3738b68103a..f0ce316037c1 100644 --- a/Code/Mantid/instrument/NOMAD_Definition_20120701-20120731.xml +++ b/Code/Mantid/instrument/NOMAD_Definition_20120701-20120731.xml @@ -1,5 +1,7 @@ - diff --git a/Code/Mantid/instrument/OFFSPEC_Definition.xml b/Code/Mantid/instrument/OFFSPEC_Definition.xml index 020b7b538999..2fd5b70b117d 100644 --- a/Code/Mantid/instrument/OFFSPEC_Definition.xml +++ b/Code/Mantid/instrument/OFFSPEC_Definition.xml @@ -1,7 +1,9 @@ - diff --git a/Code/Mantid/instrument/OFFSPEC_Definition_pre11_7_2012.xml b/Code/Mantid/instrument/OFFSPEC_Definition_pre11_7_2012.xml index 12bfeadab331..b607508c9b06 100644 --- a/Code/Mantid/instrument/OFFSPEC_Definition_pre11_7_2012.xml +++ b/Code/Mantid/instrument/OFFSPEC_Definition_pre11_7_2012.xml @@ -1,7 +1,9 @@ - diff --git a/Code/Mantid/instrument/OSIRIS_Definition.xml b/Code/Mantid/instrument/OSIRIS_Definition.xml index 712b3b252998..defb5c255fd5 100644 --- a/Code/Mantid/instrument/OSIRIS_Definition.xml +++ b/Code/Mantid/instrument/OSIRIS_Definition.xml @@ -1,7 +1,9 @@ - diff --git a/Code/Mantid/instrument/PEARL_Definition.xml b/Code/Mantid/instrument/PEARL_Definition.xml index 0f315b0ed818..4a1bc1b16a64 100644 --- a/Code/Mantid/instrument/PEARL_Definition.xml +++ b/Code/Mantid/instrument/PEARL_Definition.xml @@ -1,7 +1,9 @@ - diff --git a/Code/Mantid/instrument/PEARL_Definition_new.xml b/Code/Mantid/instrument/PEARL_Definition_new.xml index 5df8ac6ea4b2..c5a9f299d893 100644 --- a/Code/Mantid/instrument/PEARL_Definition_new.xml +++ b/Code/Mantid/instrument/PEARL_Definition_new.xml @@ -1,7 +1,9 @@ - diff --git a/Code/Mantid/instrument/PEARL_Definition_new_lowangle.xml b/Code/Mantid/instrument/PEARL_Definition_new_lowangle.xml index 67deeba507db..3a29982b9792 100644 --- a/Code/Mantid/instrument/PEARL_Definition_new_lowangle.xml +++ b/Code/Mantid/instrument/PEARL_Definition_new_lowangle.xml @@ -1,7 +1,9 @@ - diff --git a/Code/Mantid/instrument/POLARIS_Definition_115.xml b/Code/Mantid/instrument/POLARIS_Definition_115.xml index 27fafcb2da32..a08612b93ee1 100644 --- a/Code/Mantid/instrument/POLARIS_Definition_115.xml +++ b/Code/Mantid/instrument/POLARIS_Definition_115.xml @@ -1,7 +1,9 @@ - - - diff --git a/Code/Mantid/instrument/POLDI_Definition400.xml b/Code/Mantid/instrument/POLDI_Definition400.xml index 3b3ff9e7c246..41a7d6982253 100644 --- a/Code/Mantid/instrument/POLDI_Definition400.xml +++ b/Code/Mantid/instrument/POLDI_Definition400.xml @@ -1,7 +1,9 @@ - diff --git a/Code/Mantid/instrument/POLDI_Definition_2013.xml b/Code/Mantid/instrument/POLDI_Definition_2013.xml index 3c2abadcb573..621e2dc671c2 100644 --- a/Code/Mantid/instrument/POLDI_Definition_2013.xml +++ b/Code/Mantid/instrument/POLDI_Definition_2013.xml @@ -1,7 +1,7 @@ diff --git a/Code/Mantid/instrument/POLDI_Definition_2014b.xml b/Code/Mantid/instrument/POLDI_Definition_2014b.xml new file mode 100644 index 000000000000..c79f61504ea8 --- /dev/null +++ b/Code/Mantid/instrument/POLDI_Definition_2014b.xml @@ -0,0 +1,278 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Code/Mantid/instrument/POLDI_Definition_ipp10.xml b/Code/Mantid/instrument/POLDI_Definition_ipp10.xml index d70343e2e21e..fb95cf5a0db9 100644 --- a/Code/Mantid/instrument/POLDI_Definition_ipp10.xml +++ b/Code/Mantid/instrument/POLDI_Definition_ipp10.xml @@ -1,7 +1,9 @@ - diff --git a/Code/Mantid/instrument/POLDI_Definition_ipp11.xml b/Code/Mantid/instrument/POLDI_Definition_ipp11.xml index 430e7aad005f..214c5b9d8dd4 100644 --- a/Code/Mantid/instrument/POLDI_Definition_ipp11.xml +++ b/Code/Mantid/instrument/POLDI_Definition_ipp11.xml @@ -1,7 +1,9 @@ - diff --git a/Code/Mantid/instrument/POLDI_Definition_ipp12.xml b/Code/Mantid/instrument/POLDI_Definition_ipp12.xml index ab9e07e55b48..3e17670a7681 100644 --- a/Code/Mantid/instrument/POLDI_Definition_ipp12.xml +++ b/Code/Mantid/instrument/POLDI_Definition_ipp12.xml @@ -1,7 +1,9 @@ - diff --git a/Code/Mantid/instrument/POLDI_Definition_ipp13.xml b/Code/Mantid/instrument/POLDI_Definition_ipp13.xml index d41be04f4bd6..95a282313ffd 100644 --- a/Code/Mantid/instrument/POLDI_Definition_ipp13.xml +++ b/Code/Mantid/instrument/POLDI_Definition_ipp13.xml @@ -1,7 +1,9 @@ - diff --git a/Code/Mantid/instrument/POLDI_Definition_ipp9.xml b/Code/Mantid/instrument/POLDI_Definition_ipp9.xml index 7f427ecce082..5dc01d00abfb 100644 --- a/Code/Mantid/instrument/POLDI_Definition_ipp9.xml +++ b/Code/Mantid/instrument/POLDI_Definition_ipp9.xml @@ -1,7 +1,9 @@ - diff --git a/Code/Mantid/instrument/POLDI_Parameters_2014b.xml b/Code/Mantid/instrument/POLDI_Parameters_2014b.xml new file mode 100644 index 000000000000..f26d7516f981 --- /dev/null +++ b/Code/Mantid/instrument/POLDI_Parameters_2014b.xml @@ -0,0 +1,260 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Code/Mantid/instrument/POLREF_Definition.xml b/Code/Mantid/instrument/POLREF_Definition.xml index df4c31795dd4..e1e23c7730a0 100644 --- a/Code/Mantid/instrument/POLREF_Definition.xml +++ b/Code/Mantid/instrument/POLREF_Definition.xml @@ -1,7 +1,9 @@ - diff --git a/Code/Mantid/instrument/POLREF_Parameters.xml b/Code/Mantid/instrument/POLREF_Parameters.xml index fa461e5f257b..537b14c666c8 100644 --- a/Code/Mantid/instrument/POLREF_Parameters.xml +++ b/Code/Mantid/instrument/POLREF_Parameters.xml @@ -39,10 +39,14 @@ + + diff --git a/Code/Mantid/instrument/POWGEN_Definition_2010.xml b/Code/Mantid/instrument/POWGEN_Definition_2010.xml index 9778c8c0d430..79d9bdb2e764 100644 --- a/Code/Mantid/instrument/POWGEN_Definition_2010.xml +++ b/Code/Mantid/instrument/POWGEN_Definition_2010.xml @@ -1,7 +1,9 @@ - diff --git a/Code/Mantid/instrument/POWGEN_Definition_2011-02-25.xml b/Code/Mantid/instrument/POWGEN_Definition_2011-02-25.xml index b9601e784414..1e0921bba195 100644 --- a/Code/Mantid/instrument/POWGEN_Definition_2011-02-25.xml +++ b/Code/Mantid/instrument/POWGEN_Definition_2011-02-25.xml @@ -1,7 +1,9 @@ - diff --git a/Code/Mantid/instrument/POWGEN_Definition_2012-08-20.xml b/Code/Mantid/instrument/POWGEN_Definition_2012-08-20.xml index d6b4b76fe88d..77b4b2b7089b 100644 --- a/Code/Mantid/instrument/POWGEN_Definition_2012-08-20.xml +++ b/Code/Mantid/instrument/POWGEN_Definition_2012-08-20.xml @@ -1,7 +1,9 @@ - diff --git a/Code/Mantid/instrument/POWGEN_Definition_2012-11-27.xml b/Code/Mantid/instrument/POWGEN_Definition_2012-11-27.xml index f1132c837a4d..001594f05bf5 100644 --- a/Code/Mantid/instrument/POWGEN_Definition_2012-11-27.xml +++ b/Code/Mantid/instrument/POWGEN_Definition_2012-11-27.xml @@ -1,7 +1,9 @@ - diff --git a/Code/Mantid/instrument/POWGEN_Definition_2013-06-01.xml b/Code/Mantid/instrument/POWGEN_Definition_2013-06-01.xml index 98b72e4479db..6e7d6d71c79a 100644 --- a/Code/Mantid/instrument/POWGEN_Definition_2013-06-01.xml +++ b/Code/Mantid/instrument/POWGEN_Definition_2013-06-01.xml @@ -1,5 +1,7 @@ - diff --git a/Code/Mantid/instrument/POWGEN_Definition_2013-08-01.xml b/Code/Mantid/instrument/POWGEN_Definition_2013-08-01.xml index c311a6773ca9..cec00dd8c576 100644 --- a/Code/Mantid/instrument/POWGEN_Definition_2013-08-01.xml +++ b/Code/Mantid/instrument/POWGEN_Definition_2013-08-01.xml @@ -1,5 +1,7 @@ - diff --git a/Code/Mantid/instrument/POWGEN_Definition_2014-02-01.xml b/Code/Mantid/instrument/POWGEN_Definition_2014-02-01.xml index e32f25078773..4d248c96bb43 100644 --- a/Code/Mantid/instrument/POWGEN_Definition_2014-02-01.xml +++ b/Code/Mantid/instrument/POWGEN_Definition_2014-02-01.xml @@ -1,5 +1,5 @@ - + diff --git a/Code/Mantid/instrument/POWGEN_Definition_2014-03-10.xml b/Code/Mantid/instrument/POWGEN_Definition_2014-03-10.xml index ba62f5e8b7e4..4b2f38724165 100644 --- a/Code/Mantid/instrument/POWGEN_Definition_2014-03-10.xml +++ b/Code/Mantid/instrument/POWGEN_Definition_2014-03-10.xml @@ -1,5 +1,5 @@ - + diff --git a/Code/Mantid/instrument/REF_L_Definition.xml b/Code/Mantid/instrument/REF_L_Definition.xml index 008148e8a1f1..6195eb6fdfbe 100644 --- a/Code/Mantid/instrument/REF_L_Definition.xml +++ b/Code/Mantid/instrument/REF_L_Definition.xml @@ -1,4 +1,6 @@ - diff --git a/Code/Mantid/instrument/REF_M_Definition.xml b/Code/Mantid/instrument/REF_M_Definition.xml index 735f22661fee..de651421d49d 100644 --- a/Code/Mantid/instrument/REF_M_Definition.xml +++ b/Code/Mantid/instrument/REF_M_Definition.xml @@ -1,4 +1,6 @@ - diff --git a/Code/Mantid/instrument/SANDALS_Definition.xml b/Code/Mantid/instrument/SANDALS_Definition.xml index 4d3c10504408..b0651d1afaec 100644 --- a/Code/Mantid/instrument/SANDALS_Definition.xml +++ b/Code/Mantid/instrument/SANDALS_Definition.xml @@ -1,7 +1,9 @@ - diff --git a/Code/Mantid/instrument/SANS2D_Definition.xml b/Code/Mantid/instrument/SANS2D_Definition.xml index caca3f87bb92..f1c80a0e1d30 100644 --- a/Code/Mantid/instrument/SANS2D_Definition.xml +++ b/Code/Mantid/instrument/SANS2D_Definition.xml @@ -1,7 +1,9 @@ - diff --git a/Code/Mantid/instrument/SANS2D_Definition_Tubes.xml b/Code/Mantid/instrument/SANS2D_Definition_Tubes.xml index fc3d5935d806..4ed3f6e5bf55 100644 --- a/Code/Mantid/instrument/SANS2D_Definition_Tubes.xml +++ b/Code/Mantid/instrument/SANS2D_Definition_Tubes.xml @@ -1,7 +1,9 @@ - diff --git a/Code/Mantid/instrument/SANS_Definition.xml b/Code/Mantid/instrument/SANS_Definition.xml index 5b3fefc604fb..52852ca82ebc 100644 --- a/Code/Mantid/instrument/SANS_Definition.xml +++ b/Code/Mantid/instrument/SANS_Definition.xml @@ -1,7 +1,9 @@ - diff --git a/Code/Mantid/instrument/SEQUOIA_Definition.xml b/Code/Mantid/instrument/SEQUOIA_Definition.xml index cc35e7563aa5..ae0a7cf31608 100644 --- a/Code/Mantid/instrument/SEQUOIA_Definition.xml +++ b/Code/Mantid/instrument/SEQUOIA_Definition.xml @@ -1,7 +1,9 @@ - diff --git a/Code/Mantid/instrument/SEQUOIA_Definition_upto_19889.xml b/Code/Mantid/instrument/SEQUOIA_Definition_upto_19889.xml index 6330873ace5a..c5d888c38b4c 100644 --- a/Code/Mantid/instrument/SEQUOIA_Definition_upto_19889.xml +++ b/Code/Mantid/instrument/SEQUOIA_Definition_upto_19889.xml @@ -1,7 +1,9 @@ - diff --git a/Code/Mantid/instrument/SNAP_Definition.xml b/Code/Mantid/instrument/SNAP_Definition.xml index d6e5dcdbc130..eca323e39d92 100644 --- a/Code/Mantid/instrument/SNAP_Definition.xml +++ b/Code/Mantid/instrument/SNAP_Definition.xml @@ -1,7 +1,9 @@ - diff --git a/Code/Mantid/instrument/SURF_Definition.xml b/Code/Mantid/instrument/SURF_Definition.xml index 7af1a1a59540..41da6e138099 100644 --- a/Code/Mantid/instrument/SURF_Definition.xml +++ b/Code/Mantid/instrument/SURF_Definition.xml @@ -1,5 +1,7 @@ - diff --git a/Code/Mantid/instrument/SURF_Parameters.xml b/Code/Mantid/instrument/SURF_Parameters.xml index 7b90a98646dc..6c443dcccd97 100644 --- a/Code/Mantid/instrument/SURF_Parameters.xml +++ b/Code/Mantid/instrument/SURF_Parameters.xml @@ -33,10 +33,14 @@ + + diff --git a/Code/Mantid/instrument/SXD_Definition.xml b/Code/Mantid/instrument/SXD_Definition.xml index 8a3fcc8b40b3..c6b3ba7a1ce1 100644 --- a/Code/Mantid/instrument/SXD_Definition.xml +++ b/Code/Mantid/instrument/SXD_Definition.xml @@ -1,7 +1,9 @@ - diff --git a/Code/Mantid/instrument/Schema/FacilitiesSchema.xsd b/Code/Mantid/instrument/Schema/Facilities/1.0/FacilitiesSchema.xsd similarity index 100% rename from Code/Mantid/instrument/Schema/FacilitiesSchema.xsd rename to Code/Mantid/instrument/Schema/Facilities/1.0/FacilitiesSchema.xsd diff --git a/Code/Mantid/instrument/Schema/GroupingSchema.xsd b/Code/Mantid/instrument/Schema/Grouping/1.0/GroupingSchema.xsd similarity index 100% rename from Code/Mantid/instrument/Schema/GroupingSchema.xsd rename to Code/Mantid/instrument/Schema/Grouping/1.0/GroupingSchema.xsd diff --git a/Code/Mantid/instrument/Schema/IDFSchema.xsd b/Code/Mantid/instrument/Schema/IDF/1.0/IDFSchema.xsd similarity index 100% rename from Code/Mantid/instrument/Schema/IDFSchema.xsd rename to Code/Mantid/instrument/Schema/IDF/1.0/IDFSchema.xsd diff --git a/Code/Mantid/instrument/Schema/ParameterFileSchema.xsd b/Code/Mantid/instrument/Schema/ParameterFile/1.0/ParameterFileSchema.xsd similarity index 100% rename from Code/Mantid/instrument/Schema/ParameterFileSchema.xsd rename to Code/Mantid/instrument/Schema/ParameterFile/1.0/ParameterFileSchema.xsd diff --git a/Code/Mantid/instrument/TOPAZ_Definition_2010.xml b/Code/Mantid/instrument/TOPAZ_Definition_2010.xml index 97421ddcd9a6..e4c091d3cafa 100644 --- a/Code/Mantid/instrument/TOPAZ_Definition_2010.xml +++ b/Code/Mantid/instrument/TOPAZ_Definition_2010.xml @@ -1,7 +1,9 @@ - diff --git a/Code/Mantid/instrument/TOPAZ_Definition_2011-01-01.xml b/Code/Mantid/instrument/TOPAZ_Definition_2011-01-01.xml index c8faa3902d6f..7065264c9663 100644 --- a/Code/Mantid/instrument/TOPAZ_Definition_2011-01-01.xml +++ b/Code/Mantid/instrument/TOPAZ_Definition_2011-01-01.xml @@ -1,7 +1,9 @@ - diff --git a/Code/Mantid/instrument/TOPAZ_Definition_2011-10-03.xml b/Code/Mantid/instrument/TOPAZ_Definition_2011-10-03.xml index 8640a7e45628..d8545cd0ded5 100644 --- a/Code/Mantid/instrument/TOPAZ_Definition_2011-10-03.xml +++ b/Code/Mantid/instrument/TOPAZ_Definition_2011-10-03.xml @@ -1,7 +1,9 @@ - diff --git a/Code/Mantid/instrument/TOPAZ_Definition_2011-10-21.xml b/Code/Mantid/instrument/TOPAZ_Definition_2011-10-21.xml index 63cfdce3b53f..74779672cb9a 100644 --- a/Code/Mantid/instrument/TOPAZ_Definition_2011-10-21.xml +++ b/Code/Mantid/instrument/TOPAZ_Definition_2011-10-21.xml @@ -1,7 +1,9 @@ - diff --git a/Code/Mantid/instrument/TOPAZ_Definition_2012-05-25.xml b/Code/Mantid/instrument/TOPAZ_Definition_2012-05-25.xml index cfa7405fe93e..7fee7c64b3df 100644 --- a/Code/Mantid/instrument/TOPAZ_Definition_2012-05-25.xml +++ b/Code/Mantid/instrument/TOPAZ_Definition_2012-05-25.xml @@ -1,7 +1,9 @@ - diff --git a/Code/Mantid/instrument/TOPAZ_Definition_2012-08-23.xml b/Code/Mantid/instrument/TOPAZ_Definition_2012-08-23.xml index cd779d046ec4..20f0157b7caa 100644 --- a/Code/Mantid/instrument/TOPAZ_Definition_2012-08-23.xml +++ b/Code/Mantid/instrument/TOPAZ_Definition_2012-08-23.xml @@ -1,7 +1,9 @@ - diff --git a/Code/Mantid/instrument/TOPAZ_Definition_2013-05-03.xml b/Code/Mantid/instrument/TOPAZ_Definition_2013-05-03.xml index d4b48d74ea42..6d401bf3d185 100644 --- a/Code/Mantid/instrument/TOPAZ_Definition_2013-05-03.xml +++ b/Code/Mantid/instrument/TOPAZ_Definition_2013-05-03.xml @@ -1,7 +1,9 @@ - diff --git a/Code/Mantid/instrument/TOPAZ_Definition_2014-01-01.xml b/Code/Mantid/instrument/TOPAZ_Definition_2014-01-01.xml index 75491496f8ac..168aa0f789f7 100644 --- a/Code/Mantid/instrument/TOPAZ_Definition_2014-01-01.xml +++ b/Code/Mantid/instrument/TOPAZ_Definition_2014-01-01.xml @@ -1,7 +1,9 @@ - diff --git a/Code/Mantid/instrument/TOPAZ_Definition_2014-08-01.xml b/Code/Mantid/instrument/TOPAZ_Definition_2014-08-01.xml index aa255726b25f..70adb99ffca6 100644 --- a/Code/Mantid/instrument/TOPAZ_Definition_2014-08-01.xml +++ b/Code/Mantid/instrument/TOPAZ_Definition_2014-08-01.xml @@ -1,7 +1,9 @@ - diff --git a/Code/Mantid/instrument/TOPAZ_Parameters.xml b/Code/Mantid/instrument/TOPAZ_Parameters.xml index 053043a51078..a8df1922e51d 100644 --- a/Code/Mantid/instrument/TOPAZ_Parameters.xml +++ b/Code/Mantid/instrument/TOPAZ_Parameters.xml @@ -2,12 +2,10 @@ - - + - diff --git a/Code/Mantid/instrument/TOSCA_Definition.xml b/Code/Mantid/instrument/TOSCA_Definition.xml index c55209ebdec1..a70e2c9e35c8 100644 --- a/Code/Mantid/instrument/TOSCA_Definition.xml +++ b/Code/Mantid/instrument/TOSCA_Definition.xml @@ -1,11 +1,13 @@ - + diff --git a/Code/Mantid/instrument/TOSCA_DefinitionDAE1.xml b/Code/Mantid/instrument/TOSCA_DefinitionDAE1.xml index ca3a9f384d40..611882f96759 100644 --- a/Code/Mantid/instrument/TOSCA_DefinitionDAE1.xml +++ b/Code/Mantid/instrument/TOSCA_DefinitionDAE1.xml @@ -1,7 +1,9 @@ - - diff --git a/Code/Mantid/instrument/VESUVIO_Definition.xml b/Code/Mantid/instrument/VESUVIO_Definition.xml index f760a8f2faa8..f2094e0a82d8 100644 --- a/Code/Mantid/instrument/VESUVIO_Definition.xml +++ b/Code/Mantid/instrument/VESUVIO_Definition.xml @@ -1,7 +1,9 @@ - - - - - + + + + - - - - - + + + + + - + @@ -355,4 +357,4 @@ - \ No newline at end of file + diff --git a/Code/Mantid/instrument/VESUVIO_Parameters.xml b/Code/Mantid/instrument/VESUVIO_Parameters.xml index d1fcdc31ad6a..f6d450471272 100644 --- a/Code/Mantid/instrument/VESUVIO_Parameters.xml +++ b/Code/Mantid/instrument/VESUVIO_Parameters.xml @@ -7,106 +7,111 @@ - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + + + + + + - + @@ -117,7 +122,7 @@ - @@ -132,7 +137,35 @@ - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -143,7 +176,7 @@ - @@ -156,8 +189,8 @@ - - diff --git a/Code/Mantid/instrument/VISION_Definition_00-20131021.xml b/Code/Mantid/instrument/VISION_Definition_00-20131021.xml index 73bf42632f99..6e08b3d8253f 100644 --- a/Code/Mantid/instrument/VISION_Definition_00-20131021.xml +++ b/Code/Mantid/instrument/VISION_Definition_00-20131021.xml @@ -1,5 +1,7 @@ - diff --git a/Code/Mantid/instrument/VISION_Definition_20131021-.xml b/Code/Mantid/instrument/VISION_Definition_20131021-.xml index 21fb59cdf00b..f858e03089e4 100644 --- a/Code/Mantid/instrument/VISION_Definition_20131021-.xml +++ b/Code/Mantid/instrument/VISION_Definition_20131021-.xml @@ -1,5 +1,7 @@ - diff --git a/Code/Mantid/instrument/VULCAN_Definition.xml b/Code/Mantid/instrument/VULCAN_Definition.xml index a9614d03c1f6..33d157dd28a4 100644 --- a/Code/Mantid/instrument/VULCAN_Definition.xml +++ b/Code/Mantid/instrument/VULCAN_Definition.xml @@ -1,7 +1,9 @@ - diff --git a/Code/Mantid/instrument/WISH_Definition.xml b/Code/Mantid/instrument/WISH_Definition.xml index c5ff1b5666e5..4fc9394d7a59 100644 --- a/Code/Mantid/instrument/WISH_Definition.xml +++ b/Code/Mantid/instrument/WISH_Definition.xml @@ -1,7 +1,9 @@ - diff --git a/Code/Mantid/instrument/WISH_Definition_10Panels.xml b/Code/Mantid/instrument/WISH_Definition_10Panels.xml index cccb01da09a3..f12682f765f0 100644 --- a/Code/Mantid/instrument/WISH_Definition_10Panels.xml +++ b/Code/Mantid/instrument/WISH_Definition_10Panels.xml @@ -1,7 +1,9 @@ - diff --git a/Code/Mantid/instrument/WISH_Definition_6Panel.xml b/Code/Mantid/instrument/WISH_Definition_6Panel.xml index f84b2a19838d..7efefcea1879 100644 --- a/Code/Mantid/instrument/WISH_Definition_6Panel.xml +++ b/Code/Mantid/instrument/WISH_Definition_6Panel.xml @@ -1,7 +1,9 @@ - diff --git a/Code/Mantid/instrument/WISH_Definition_9Panels.xml b/Code/Mantid/instrument/WISH_Definition_9Panels.xml index 6c2587283cc7..e3a2ec81ea0c 100644 --- a/Code/Mantid/instrument/WISH_Definition_9Panels.xml +++ b/Code/Mantid/instrument/WISH_Definition_9Panels.xml @@ -1,7 +1,9 @@ - diff --git a/Code/Mantid/instrument/nexusdictionaries/poldi.dic b/Code/Mantid/instrument/nexusdictionaries/poldi.dic index 83d526452114..d54f592483a7 100644 --- a/Code/Mantid/instrument/nexusdictionaries/poldi.dic +++ b/Code/Mantid/instrument/nexusdictionaries/poldi.dic @@ -49,6 +49,10 @@ Diaphragme2plus0=/entry1/POLDI/diaphragm2/zplus_zero ChopperName=/entry1/POLDI/chopper/name ChopperPhase=/entry1/POLDI/chopper/chopper_phase ChopperSpeed=/entry1/POLDI/chopper/rotation_speed + +# There seems to be an issue with this field in some data files. +# Once this is fixed, it can be reactivated. +#ChopperSpeedTarget=/entry1/POLDI/chopper/rotation_speed_target # SampleName=/entry1/POLDI/name # diff --git a/Code/Mantid/scripts/CMakeLists.txt b/Code/Mantid/scripts/CMakeLists.txt index 5fa83e35f01b..aa9cd9e0748a 100644 --- a/Code/Mantid/scripts/CMakeLists.txt +++ b/Code/Mantid/scripts/CMakeLists.txt @@ -4,6 +4,7 @@ set ( TEST_PY_FILES test/SettingsTest.py test/DgreduceTest.py test/DirectEnergyConversionTest.py + test/IndirectApplyCorrectionsTest.py test/IndirectCommonTests.py test/ReflectometryQuickAuxiliaryTest.py test/SansIsisGuiSettings.py diff --git a/Code/Mantid/scripts/FilterEvents.py b/Code/Mantid/scripts/FilterEvents.py new file mode 100644 index 000000000000..ef661b20f72e --- /dev/null +++ b/Code/Mantid/scripts/FilterEvents.py @@ -0,0 +1,16 @@ +from FilterEvents import eventFilterGUI +from PyQt4 import QtGui +import sys + +def qapp(): + if QtGui.QApplication.instance(): + app = QtGui.QApplication.instance() + else: + app = QtGui.QApplication(sys.argv) + return app + +app = qapp() + +reducer = eventFilterGUI.MainWindow() #the main ui class in this file is called MainWindow +reducer.show() +app.exec_() diff --git a/Code/Mantid/scripts/FilterEvents/MainWindow.ui b/Code/Mantid/scripts/FilterEvents/MainWindow.ui new file mode 100644 index 000000000000..424deac0a303 --- /dev/null +++ b/Code/Mantid/scripts/FilterEvents/MainWindow.ui @@ -0,0 +1,1028 @@ + + + MainWindow + + + + 0 + 0 + 823 + 1136 + + + + MainWindow + + + + + + 20 + 150 + 741 + 411 + + + + + + + 530 + 30 + 61 + 27 + + + + Browse + + + + + + 130 + 30 + 381 + 27 + + + + <html><head/><body><p>The name of the NeXus file or the run number to load. </p><p><br/></p><p>Run number should be InstrumentName_RunNumber (for example, NOM_11788)</p></body></html> + + + + + + 20 + 570 + 301 + 29 + + + + Qt::Horizontal + + + QSlider::TicksAbove + + + + + + 770 + 150 + 29 + 121 + + + + Qt::Vertical + + + QSlider::TicksAbove + + + + + + 130 + 80 + 461 + 27 + + + + + + + 610 + 80 + 98 + 27 + + + + Use + + + + + + 120 + 600 + 151 + 27 + + + + + + + 552 + 600 + 161 + 27 + + + + + + + 20 + 600 + 101 + 17 + + + + Starting Time + + + + + + 440 + 600 + 101 + 17 + + + + Stopping Time + + + + + + 460 + 570 + 301 + 29 + + + + Qt::Horizontal + + + QSlider::TicksAbove + + + + + + 770 + 440 + 29 + 121 + + + + Qt::Vertical + + + QSlider::TicksBelow + + + + + + 20 + 80 + 91 + 27 + + + + Refresh + + + + + + 280 + 600 + 41 + 27 + + + + Set + + + + + + 720 + 600 + 41 + 27 + + + + Set + + + + + + 160 + 130 + 101 + 17 + + + + ? + + + + + + 20 + 130 + 81 + 17 + + + + Log Name + + + + + + 20 + 690 + 741 + 391 + + + + 0 + + + + Filter By Log + + + + + 150 + 20 + 421 + 27 + + + + + + + 20 + 20 + 81 + 17 + + + + Sample Log + + + + + + 20 + 140 + 121 + 17 + + + + Minimum Value + + + + + + 390 + 140 + 111 + 17 + + + + Maximum Value + + + + + + 20 + 190 + 111 + 17 + + + + Log Step Size + + + + + + 350 + 190 + 161 + 17 + + + + Value Change Direction + + + + + + 600 + 20 + 98 + 27 + + + + Plot + + + + + + 10 + 240 + 151 + 17 + + + + Log Value Tolerance + + + + + + 40 + 290 + 111 + 17 + + + + Time Tolerance + + + + + + 420 + 240 + 101 + 17 + + + + Log Boundary + + + + + + 150 + 140 + 191 + 27 + + + + + + + 530 + 140 + 181 + 27 + + + + + + + 150 + 190 + 191 + 27 + + + + + + + 150 + 240 + 191 + 27 + + + + + + + 150 + 290 + 191 + 27 + + + + + + + 530 + 190 + 181 + 27 + + + + + + + 530 + 240 + 181 + 27 + + + + + + + 530 + 290 + 181 + 41 + + + + Filter + + + + + + 30 + 70 + 66 + 17 + + + + Mean + + + + + + 170 + 70 + 111 + 17 + + + + ? + + + + + + 390 + 70 + 101 + 17 + + + + Time Average + + + + + + 530 + 70 + 111 + 17 + + + + ? + + + + + + 30 + 100 + 81 + 17 + + + + Frequency + + + + + + 170 + 100 + 111 + 17 + + + + ? + + + + + + 390 + 100 + 101 + 17 + + + + Log Size + + + + + + 530 + 100 + 111 + 17 + + + + ? + + + + + + Filter By Time + + + + + 250 + 100 + 181 + 27 + + + + + + + 110 + 110 + 101 + 17 + + + + Time Interval + + + + + + 250 + 160 + 181 + 61 + + + + Filter + + + + + + Advanced Setup + + + + + 40 + 270 + 181 + 22 + + + + Filter By Pulse Time + + + + + + 40 + 310 + 211 + 22 + + + + Group Output Workspace + + + + + + 360 + 270 + 271 + 22 + + + + Output Workspace Indexed From 1 + + + + + + 360 + 310 + 271 + 22 + + + + Split Sample Logs + + + + + + 260 + 30 + 341 + 27 + + + + + None + + + + + Elastic + + + + + Direct + + + + + Indirect + + + + + Customized + + + + + + + 260 + 220 + 351 + 27 + + + + + Skip + + + + + Skip only if TOF correction + + + + + + + 40 + 40 + 181 + 20 + + + + TOF Correction To Sample + + + + + + 40 + 230 + 191 + 17 + + + + Spectrum without Detector + + + + + + 110 + 80 + 121 + 21 + + + + Incident Energy + + + + + + 260 + 80 + 341 + 27 + + + + + + + 40 + 110 + 191 + 21 + + + + TOF Correction Workspace + + + + + + 260 + 110 + 341 + 27 + + + + + + + 620 + 110 + 81 + 27 + + + + Refresh + + + + + + 90 + 170 + 97 + 22 + + + + + 75 + true + false + + + + Fast Log + + + + + + 260 + 170 + 231 + 22 + + + + + 75 + true + + + + Generate Filter In Parallel + + + + + + 0 + 140 + 741 + 21 + + + + Qt::Horizontal + + + + + + 0 + 200 + 741 + 16 + + + + Qt::Horizontal + + + + + + Error Message + + + + + 30 + 20 + 681 + 281 + + + + + + + 30 + 320 + 681 + 27 + + + + CLEAR + + + + + + + + 430 + 650 + 331 + 27 + + + + + + + 340 + 650 + 91 + 20 + + + + Splitter Title + + + + + + 20 + 650 + 101 + 20 + + + + Output Name + + + + + + 120 + 650 + 211 + 27 + + + + + + + 730 + 20 + 81 + 41 + + + + + 14 + 75 + true + true + + + + <html><head/><body><p><span style=" color:#ff0000;">ERROR!</span></p></body></html> + + + + + + 20 + 30 + 111 + 17 + + + + <html><head/><body><p>The name of the NeXus file or the run number to load</p></body></html> + + + <html><head/><body><p>Label for file name or run number</p></body></html> + + + File / Run + + + + + + 610 + 30 + 98 + 27 + + + + Load + + + + + + + 0 + 0 + 823 + 25 + + + + + + + + diff --git a/Code/Mantid/scripts/FilterEvents/Ui_MainWindow.py b/Code/Mantid/scripts/FilterEvents/Ui_MainWindow.py new file mode 100644 index 000000000000..8267389953cb --- /dev/null +++ b/Code/Mantid/scripts/FilterEvents/Ui_MainWindow.py @@ -0,0 +1,378 @@ +# -*- coding: utf-8 -*- + +# Form implementation generated from reading ui file 'MainWindow.ui' +# +# Created: Tue Nov 4 15:50:54 2014 +# by: PyQt4 UI code generator 4.9.1 +# +# WARNING! All changes made in this file will be lost! + +from PyQt4 import QtCore, QtGui + +import matplotlib +from matplotlib.backends.backend_qt4agg import FigureCanvasQTAgg as FigureCanvas +from matplotlib.backends.backend_qt4agg import NavigationToolbar2QTAgg as NavigationToolbar +from matplotlib.figure import Figure + +try: + _fromUtf8 = QtCore.QString.fromUtf8 +except AttributeError: + _fromUtf8 = lambda s: s + +class Ui_MainWindow(object): + def setupUi(self, MainWindow): + MainWindow.setObjectName(_fromUtf8("MainWindow")) + MainWindow.resize(823, 1136) + self.centralwidget = QtGui.QWidget(MainWindow) + self.centralwidget.setObjectName(_fromUtf8("centralwidget")) + self.graphicsView = QtGui.QGraphicsView(self.centralwidget) + self.graphicsView.setGeometry(QtCore.QRect(20, 150, 741, 411)) + self.graphicsView.setObjectName(_fromUtf8("graphicsView")) + self.pushButton_browse = QtGui.QPushButton(self.centralwidget) + self.pushButton_browse.setGeometry(QtCore.QRect(530, 30, 61, 27)) + self.pushButton_browse.setObjectName(_fromUtf8("pushButton_browse")) + self.lineEdit = QtGui.QLineEdit(self.centralwidget) + self.lineEdit.setGeometry(QtCore.QRect(130, 30, 381, 27)) + self.lineEdit.setObjectName(_fromUtf8("lineEdit")) + self.horizontalSlider = QtGui.QSlider(self.centralwidget) + self.horizontalSlider.setGeometry(QtCore.QRect(20, 570, 301, 29)) + self.horizontalSlider.setOrientation(QtCore.Qt.Horizontal) + self.horizontalSlider.setTickPosition(QtGui.QSlider.TicksAbove) + self.horizontalSlider.setObjectName(_fromUtf8("horizontalSlider")) + self.verticalSlider = QtGui.QSlider(self.centralwidget) + self.verticalSlider.setGeometry(QtCore.QRect(770, 150, 29, 121)) + self.verticalSlider.setOrientation(QtCore.Qt.Vertical) + self.verticalSlider.setTickPosition(QtGui.QSlider.TicksAbove) + self.verticalSlider.setObjectName(_fromUtf8("verticalSlider")) + self.comboBox = QtGui.QComboBox(self.centralwidget) + self.comboBox.setGeometry(QtCore.QRect(130, 80, 461, 27)) + self.comboBox.setObjectName(_fromUtf8("comboBox")) + self.pushButton_3 = QtGui.QPushButton(self.centralwidget) + self.pushButton_3.setGeometry(QtCore.QRect(610, 80, 98, 27)) + self.pushButton_3.setObjectName(_fromUtf8("pushButton_3")) + self.lineEdit_3 = QtGui.QLineEdit(self.centralwidget) + self.lineEdit_3.setGeometry(QtCore.QRect(120, 600, 151, 27)) + self.lineEdit_3.setObjectName(_fromUtf8("lineEdit_3")) + self.lineEdit_4 = QtGui.QLineEdit(self.centralwidget) + self.lineEdit_4.setGeometry(QtCore.QRect(552, 600, 161, 27)) + self.lineEdit_4.setObjectName(_fromUtf8("lineEdit_4")) + self.label_3 = QtGui.QLabel(self.centralwidget) + self.label_3.setGeometry(QtCore.QRect(20, 600, 101, 17)) + self.label_3.setObjectName(_fromUtf8("label_3")) + self.label_4 = QtGui.QLabel(self.centralwidget) + self.label_4.setGeometry(QtCore.QRect(440, 600, 101, 17)) + self.label_4.setObjectName(_fromUtf8("label_4")) + self.horizontalSlider_2 = QtGui.QSlider(self.centralwidget) + self.horizontalSlider_2.setGeometry(QtCore.QRect(460, 570, 301, 29)) + self.horizontalSlider_2.setOrientation(QtCore.Qt.Horizontal) + self.horizontalSlider_2.setTickPosition(QtGui.QSlider.TicksAbove) + self.horizontalSlider_2.setObjectName(_fromUtf8("horizontalSlider_2")) + self.verticalSlider_2 = QtGui.QSlider(self.centralwidget) + self.verticalSlider_2.setGeometry(QtCore.QRect(770, 440, 29, 121)) + self.verticalSlider_2.setOrientation(QtCore.Qt.Vertical) + self.verticalSlider_2.setTickPosition(QtGui.QSlider.TicksBelow) + self.verticalSlider_2.setObjectName(_fromUtf8("verticalSlider_2")) + self.pushButton_refreshWS = QtGui.QPushButton(self.centralwidget) + self.pushButton_refreshWS.setGeometry(QtCore.QRect(20, 80, 91, 27)) + self.pushButton_refreshWS.setObjectName(_fromUtf8("pushButton_refreshWS")) + self.pushButton_setT0 = QtGui.QPushButton(self.centralwidget) + self.pushButton_setT0.setGeometry(QtCore.QRect(280, 600, 41, 27)) + self.pushButton_setT0.setObjectName(_fromUtf8("pushButton_setT0")) + self.pushButton_setTf = QtGui.QPushButton(self.centralwidget) + self.pushButton_setTf.setGeometry(QtCore.QRect(720, 600, 41, 27)) + self.pushButton_setTf.setObjectName(_fromUtf8("pushButton_setTf")) + self.label_lognamevalue = QtGui.QLabel(self.centralwidget) + self.label_lognamevalue.setGeometry(QtCore.QRect(160, 130, 101, 17)) + self.label_lognamevalue.setObjectName(_fromUtf8("label_lognamevalue")) + self.label_logname = QtGui.QLabel(self.centralwidget) + self.label_logname.setGeometry(QtCore.QRect(20, 130, 81, 17)) + self.label_logname.setObjectName(_fromUtf8("label_logname")) + self.filterTab = QtGui.QTabWidget(self.centralwidget) + self.filterTab.setGeometry(QtCore.QRect(20, 690, 741, 391)) + self.filterTab.setObjectName(_fromUtf8("filterTab")) + self.tab = QtGui.QWidget() + self.tab.setObjectName(_fromUtf8("tab")) + self.comboBox_2 = QtGui.QComboBox(self.tab) + self.comboBox_2.setGeometry(QtCore.QRect(150, 20, 421, 27)) + self.comboBox_2.setObjectName(_fromUtf8("comboBox_2")) + self.label_7 = QtGui.QLabel(self.tab) + self.label_7.setGeometry(QtCore.QRect(20, 20, 81, 17)) + self.label_7.setObjectName(_fromUtf8("label_7")) + self.label_8 = QtGui.QLabel(self.tab) + self.label_8.setGeometry(QtCore.QRect(20, 140, 121, 17)) + self.label_8.setObjectName(_fromUtf8("label_8")) + self.label_9 = QtGui.QLabel(self.tab) + self.label_9.setGeometry(QtCore.QRect(390, 140, 111, 17)) + self.label_9.setObjectName(_fromUtf8("label_9")) + self.label_10 = QtGui.QLabel(self.tab) + self.label_10.setGeometry(QtCore.QRect(20, 190, 111, 17)) + self.label_10.setObjectName(_fromUtf8("label_10")) + self.label_11 = QtGui.QLabel(self.tab) + self.label_11.setGeometry(QtCore.QRect(350, 190, 161, 17)) + self.label_11.setObjectName(_fromUtf8("label_11")) + self.pushButton_4 = QtGui.QPushButton(self.tab) + self.pushButton_4.setGeometry(QtCore.QRect(600, 20, 98, 27)) + self.pushButton_4.setObjectName(_fromUtf8("pushButton_4")) + self.label_19 = QtGui.QLabel(self.tab) + self.label_19.setGeometry(QtCore.QRect(10, 240, 151, 17)) + self.label_19.setObjectName(_fromUtf8("label_19")) + self.label_20 = QtGui.QLabel(self.tab) + self.label_20.setGeometry(QtCore.QRect(40, 290, 111, 17)) + self.label_20.setObjectName(_fromUtf8("label_20")) + self.label_21 = QtGui.QLabel(self.tab) + self.label_21.setGeometry(QtCore.QRect(420, 240, 101, 17)) + self.label_21.setObjectName(_fromUtf8("label_21")) + self.lineEdit_5 = QtGui.QLineEdit(self.tab) + self.lineEdit_5.setGeometry(QtCore.QRect(150, 140, 191, 27)) + self.lineEdit_5.setObjectName(_fromUtf8("lineEdit_5")) + self.lineEdit_6 = QtGui.QLineEdit(self.tab) + self.lineEdit_6.setGeometry(QtCore.QRect(530, 140, 181, 27)) + self.lineEdit_6.setObjectName(_fromUtf8("lineEdit_6")) + self.lineEdit_7 = QtGui.QLineEdit(self.tab) + self.lineEdit_7.setGeometry(QtCore.QRect(150, 190, 191, 27)) + self.lineEdit_7.setObjectName(_fromUtf8("lineEdit_7")) + self.lineEdit_8 = QtGui.QLineEdit(self.tab) + self.lineEdit_8.setGeometry(QtCore.QRect(150, 240, 191, 27)) + self.lineEdit_8.setObjectName(_fromUtf8("lineEdit_8")) + self.lineEdit_9 = QtGui.QLineEdit(self.tab) + self.lineEdit_9.setGeometry(QtCore.QRect(150, 290, 191, 27)) + self.lineEdit_9.setObjectName(_fromUtf8("lineEdit_9")) + self.comboBox_4 = QtGui.QComboBox(self.tab) + self.comboBox_4.setGeometry(QtCore.QRect(530, 190, 181, 27)) + self.comboBox_4.setObjectName(_fromUtf8("comboBox_4")) + self.comboBox_5 = QtGui.QComboBox(self.tab) + self.comboBox_5.setGeometry(QtCore.QRect(530, 240, 181, 27)) + self.comboBox_5.setObjectName(_fromUtf8("comboBox_5")) + self.pushButton_filterLog = QtGui.QPushButton(self.tab) + self.pushButton_filterLog.setGeometry(QtCore.QRect(530, 290, 181, 41)) + self.pushButton_filterLog.setObjectName(_fromUtf8("pushButton_filterLog")) + self.label_mean = QtGui.QLabel(self.tab) + self.label_mean.setGeometry(QtCore.QRect(30, 70, 66, 17)) + self.label_mean.setObjectName(_fromUtf8("label_mean")) + self.label_meanvalue = QtGui.QLabel(self.tab) + self.label_meanvalue.setGeometry(QtCore.QRect(170, 70, 111, 17)) + self.label_meanvalue.setObjectName(_fromUtf8("label_meanvalue")) + self.label_avg = QtGui.QLabel(self.tab) + self.label_avg.setGeometry(QtCore.QRect(390, 70, 101, 17)) + self.label_avg.setObjectName(_fromUtf8("label_avg")) + self.label_timeAvgValue = QtGui.QLabel(self.tab) + self.label_timeAvgValue.setGeometry(QtCore.QRect(530, 70, 111, 17)) + self.label_timeAvgValue.setObjectName(_fromUtf8("label_timeAvgValue")) + self.label_freq = QtGui.QLabel(self.tab) + self.label_freq.setGeometry(QtCore.QRect(30, 100, 81, 17)) + self.label_freq.setObjectName(_fromUtf8("label_freq")) + self.label_freqValue = QtGui.QLabel(self.tab) + self.label_freqValue.setGeometry(QtCore.QRect(170, 100, 111, 17)) + self.label_freqValue.setObjectName(_fromUtf8("label_freqValue")) + self.label_logsize = QtGui.QLabel(self.tab) + self.label_logsize.setGeometry(QtCore.QRect(390, 100, 101, 17)) + self.label_logsize.setObjectName(_fromUtf8("label_logsize")) + self.label_logsizevalue = QtGui.QLabel(self.tab) + self.label_logsizevalue.setGeometry(QtCore.QRect(530, 100, 111, 17)) + self.label_logsizevalue.setObjectName(_fromUtf8("label_logsizevalue")) + self.filterTab.addTab(self.tab, _fromUtf8("")) + self.tab_2 = QtGui.QWidget() + self.tab_2.setObjectName(_fromUtf8("tab_2")) + self.lineEdit_timeInterval = QtGui.QLineEdit(self.tab_2) + self.lineEdit_timeInterval.setGeometry(QtCore.QRect(250, 100, 181, 27)) + self.lineEdit_timeInterval.setObjectName(_fromUtf8("lineEdit_timeInterval")) + self.label_6 = QtGui.QLabel(self.tab_2) + self.label_6.setGeometry(QtCore.QRect(110, 110, 101, 17)) + self.label_6.setObjectName(_fromUtf8("label_6")) + self.pushButton_filterTime = QtGui.QPushButton(self.tab_2) + self.pushButton_filterTime.setGeometry(QtCore.QRect(250, 160, 181, 61)) + self.pushButton_filterTime.setObjectName(_fromUtf8("pushButton_filterTime")) + self.filterTab.addTab(self.tab_2, _fromUtf8("")) + self.tab_3 = QtGui.QWidget() + self.tab_3.setObjectName(_fromUtf8("tab_3")) + self.checkBox_filterByPulse = QtGui.QCheckBox(self.tab_3) + self.checkBox_filterByPulse.setGeometry(QtCore.QRect(40, 270, 181, 22)) + self.checkBox_filterByPulse.setObjectName(_fromUtf8("checkBox_filterByPulse")) + self.checkBox_groupWS = QtGui.QCheckBox(self.tab_3) + self.checkBox_groupWS.setGeometry(QtCore.QRect(40, 310, 211, 22)) + self.checkBox_groupWS.setObjectName(_fromUtf8("checkBox_groupWS")) + self.checkBox_from1 = QtGui.QCheckBox(self.tab_3) + self.checkBox_from1.setGeometry(QtCore.QRect(360, 270, 271, 22)) + self.checkBox_from1.setObjectName(_fromUtf8("checkBox_from1")) + self.checkBox_splitLog = QtGui.QCheckBox(self.tab_3) + self.checkBox_splitLog.setGeometry(QtCore.QRect(360, 310, 271, 22)) + self.checkBox_splitLog.setObjectName(_fromUtf8("checkBox_splitLog")) + self.comboBox_tofCorr = QtGui.QComboBox(self.tab_3) + self.comboBox_tofCorr.setGeometry(QtCore.QRect(260, 30, 341, 27)) + self.comboBox_tofCorr.setObjectName(_fromUtf8("comboBox_tofCorr")) + self.comboBox_tofCorr.addItem(_fromUtf8("")) + self.comboBox_tofCorr.addItem(_fromUtf8("")) + self.comboBox_tofCorr.addItem(_fromUtf8("")) + self.comboBox_tofCorr.addItem(_fromUtf8("")) + self.comboBox_tofCorr.addItem(_fromUtf8("")) + self.comboBox_skipSpectrum = QtGui.QComboBox(self.tab_3) + self.comboBox_skipSpectrum.setGeometry(QtCore.QRect(260, 220, 351, 27)) + self.comboBox_skipSpectrum.setObjectName(_fromUtf8("comboBox_skipSpectrum")) + self.comboBox_skipSpectrum.addItem(_fromUtf8("")) + self.comboBox_skipSpectrum.addItem(_fromUtf8("")) + self.label_12 = QtGui.QLabel(self.tab_3) + self.label_12.setGeometry(QtCore.QRect(40, 40, 181, 20)) + self.label_12.setObjectName(_fromUtf8("label_12")) + self.label_13 = QtGui.QLabel(self.tab_3) + self.label_13.setGeometry(QtCore.QRect(40, 230, 191, 17)) + self.label_13.setObjectName(_fromUtf8("label_13")) + self.label_Ei = QtGui.QLabel(self.tab_3) + self.label_Ei.setGeometry(QtCore.QRect(110, 80, 121, 21)) + self.label_Ei.setObjectName(_fromUtf8("label_Ei")) + self.lineEdit_Ei = QtGui.QLineEdit(self.tab_3) + self.lineEdit_Ei.setGeometry(QtCore.QRect(260, 80, 341, 27)) + self.lineEdit_Ei.setObjectName(_fromUtf8("lineEdit_Ei")) + self.label_Ei_2 = QtGui.QLabel(self.tab_3) + self.label_Ei_2.setGeometry(QtCore.QRect(40, 110, 191, 21)) + self.label_Ei_2.setObjectName(_fromUtf8("label_Ei_2")) + self.comboBox_corrWS = QtGui.QComboBox(self.tab_3) + self.comboBox_corrWS.setGeometry(QtCore.QRect(260, 110, 341, 27)) + self.comboBox_corrWS.setObjectName(_fromUtf8("comboBox_corrWS")) + self.pushButton_refreshCorrWSList = QtGui.QPushButton(self.tab_3) + self.pushButton_refreshCorrWSList.setGeometry(QtCore.QRect(620, 110, 81, 27)) + self.pushButton_refreshCorrWSList.setObjectName(_fromUtf8("pushButton_refreshCorrWSList")) + self.checkBox_fastLog = QtGui.QCheckBox(self.tab_3) + self.checkBox_fastLog.setGeometry(QtCore.QRect(90, 170, 97, 22)) + font = QtGui.QFont() + font.setBold(True) + font.setWeight(75) + font.setStrikeOut(False) + self.checkBox_fastLog.setFont(font) + self.checkBox_fastLog.setObjectName(_fromUtf8("checkBox_fastLog")) + self.checkBox_doParallel = QtGui.QCheckBox(self.tab_3) + self.checkBox_doParallel.setGeometry(QtCore.QRect(260, 170, 231, 22)) + font = QtGui.QFont() + font.setBold(True) + font.setWeight(75) + self.checkBox_doParallel.setFont(font) + self.checkBox_doParallel.setObjectName(_fromUtf8("checkBox_doParallel")) + self.line = QtGui.QFrame(self.tab_3) + self.line.setGeometry(QtCore.QRect(0, 140, 741, 21)) + self.line.setFrameShape(QtGui.QFrame.HLine) + self.line.setFrameShadow(QtGui.QFrame.Sunken) + self.line.setObjectName(_fromUtf8("line")) + self.line_2 = QtGui.QFrame(self.tab_3) + self.line_2.setGeometry(QtCore.QRect(0, 200, 741, 16)) + self.line_2.setFrameShape(QtGui.QFrame.HLine) + self.line_2.setFrameShadow(QtGui.QFrame.Sunken) + self.line_2.setObjectName(_fromUtf8("line_2")) + self.filterTab.addTab(self.tab_3, _fromUtf8("")) + self.widget = QtGui.QWidget() + self.widget.setObjectName(_fromUtf8("widget")) + self.plainTextEdit_ErrorMsg = QtGui.QPlainTextEdit(self.widget) + self.plainTextEdit_ErrorMsg.setGeometry(QtCore.QRect(30, 20, 681, 281)) + self.plainTextEdit_ErrorMsg.setObjectName(_fromUtf8("plainTextEdit_ErrorMsg")) + self.pushButton_clearerror = QtGui.QPushButton(self.widget) + self.pushButton_clearerror.setGeometry(QtCore.QRect(30, 320, 681, 27)) + self.pushButton_clearerror.setObjectName(_fromUtf8("pushButton_clearerror")) + self.filterTab.addTab(self.widget, _fromUtf8("")) + self.lineEdit_title = QtGui.QLineEdit(self.centralwidget) + self.lineEdit_title.setGeometry(QtCore.QRect(430, 650, 331, 27)) + self.lineEdit_title.setObjectName(_fromUtf8("lineEdit_title")) + self.label_5 = QtGui.QLabel(self.centralwidget) + self.label_5.setGeometry(QtCore.QRect(340, 650, 91, 20)) + self.label_5.setObjectName(_fromUtf8("label_5")) + self.label_outwsname = QtGui.QLabel(self.centralwidget) + self.label_outwsname.setGeometry(QtCore.QRect(20, 650, 101, 20)) + self.label_outwsname.setObjectName(_fromUtf8("label_outwsname")) + self.lineEdit_outwsname = QtGui.QLineEdit(self.centralwidget) + self.lineEdit_outwsname.setGeometry(QtCore.QRect(120, 650, 211, 27)) + self.lineEdit_outwsname.setObjectName(_fromUtf8("lineEdit_outwsname")) + self.label_error = QtGui.QLabel(self.centralwidget) + self.label_error.setGeometry(QtCore.QRect(730, 20, 81, 41)) + font = QtGui.QFont() + font.setPointSize(14) + font.setBold(True) + font.setItalic(True) + font.setWeight(75) + self.label_error.setFont(font) + self.label_error.setObjectName(_fromUtf8("label_error")) + self.label_logname_2 = QtGui.QLabel(self.centralwidget) + self.label_logname_2.setGeometry(QtCore.QRect(20, 30, 111, 17)) + self.label_logname_2.setObjectName(_fromUtf8("label_logname_2")) + self.pushButton_load = QtGui.QPushButton(self.centralwidget) + self.pushButton_load.setGeometry(QtCore.QRect(610, 30, 98, 27)) + self.pushButton_load.setObjectName(_fromUtf8("pushButton_load")) + MainWindow.setCentralWidget(self.centralwidget) + self.menubar = QtGui.QMenuBar(MainWindow) + self.menubar.setGeometry(QtCore.QRect(0, 0, 823, 25)) + self.menubar.setObjectName(_fromUtf8("menubar")) + MainWindow.setMenuBar(self.menubar) + self.statusbar = QtGui.QStatusBar(MainWindow) + self.statusbar.setObjectName(_fromUtf8("statusbar")) + MainWindow.setStatusBar(self.statusbar) + + self.figure = Figure((4.0, 3.0), dpi=100) + self.theplot = self.figure.add_subplot(111) + self.graphicsView = FigureCanvas(self.figure) + self.graphicsView.setParent(self.centralwidget) + self.graphicsView.setGeometry(QtCore.QRect(20, 150, 741, 411)) + self.graphicsView.setObjectName(_fromUtf8("graphicsView")) + + self.retranslateUi(MainWindow) + self.filterTab.setCurrentIndex(0) + QtCore.QMetaObject.connectSlotsByName(MainWindow) + + def retranslateUi(self, MainWindow): + MainWindow.setWindowTitle(QtGui.QApplication.translate("MainWindow", "MainWindow", None, QtGui.QApplication.UnicodeUTF8)) + self.pushButton_browse.setText(QtGui.QApplication.translate("MainWindow", "Browse", None, QtGui.QApplication.UnicodeUTF8)) + self.lineEdit.setToolTip(QtGui.QApplication.translate("MainWindow", "

The name of the NeXus file or the run number to load.


Run number should be InstrumentName_RunNumber (for example, NOM_11788)

", None, QtGui.QApplication.UnicodeUTF8)) + self.pushButton_3.setText(QtGui.QApplication.translate("MainWindow", "Use", None, QtGui.QApplication.UnicodeUTF8)) + self.label_3.setText(QtGui.QApplication.translate("MainWindow", "Starting Time", None, QtGui.QApplication.UnicodeUTF8)) + self.label_4.setText(QtGui.QApplication.translate("MainWindow", "Stopping Time", None, QtGui.QApplication.UnicodeUTF8)) + self.pushButton_refreshWS.setText(QtGui.QApplication.translate("MainWindow", "Refresh", None, QtGui.QApplication.UnicodeUTF8)) + self.pushButton_setT0.setText(QtGui.QApplication.translate("MainWindow", "Set", None, QtGui.QApplication.UnicodeUTF8)) + self.pushButton_setTf.setText(QtGui.QApplication.translate("MainWindow", "Set", None, QtGui.QApplication.UnicodeUTF8)) + self.label_lognamevalue.setText(QtGui.QApplication.translate("MainWindow", "?", None, QtGui.QApplication.UnicodeUTF8)) + self.label_logname.setText(QtGui.QApplication.translate("MainWindow", "Log Name", None, QtGui.QApplication.UnicodeUTF8)) + self.label_7.setText(QtGui.QApplication.translate("MainWindow", "Sample Log", None, QtGui.QApplication.UnicodeUTF8)) + self.label_8.setText(QtGui.QApplication.translate("MainWindow", "Minimum Value", None, QtGui.QApplication.UnicodeUTF8)) + self.label_9.setText(QtGui.QApplication.translate("MainWindow", "Maximum Value", None, QtGui.QApplication.UnicodeUTF8)) + self.label_10.setText(QtGui.QApplication.translate("MainWindow", "Log Step Size", None, QtGui.QApplication.UnicodeUTF8)) + self.label_11.setText(QtGui.QApplication.translate("MainWindow", "Value Change Direction", None, QtGui.QApplication.UnicodeUTF8)) + self.pushButton_4.setText(QtGui.QApplication.translate("MainWindow", "Plot", None, QtGui.QApplication.UnicodeUTF8)) + self.label_19.setText(QtGui.QApplication.translate("MainWindow", "Log Value Tolerance", None, QtGui.QApplication.UnicodeUTF8)) + self.label_20.setText(QtGui.QApplication.translate("MainWindow", "Time Tolerance", None, QtGui.QApplication.UnicodeUTF8)) + self.label_21.setText(QtGui.QApplication.translate("MainWindow", "Log Boundary", None, QtGui.QApplication.UnicodeUTF8)) + self.pushButton_filterLog.setText(QtGui.QApplication.translate("MainWindow", "Filter", None, QtGui.QApplication.UnicodeUTF8)) + self.label_mean.setText(QtGui.QApplication.translate("MainWindow", "Mean", None, QtGui.QApplication.UnicodeUTF8)) + self.label_meanvalue.setText(QtGui.QApplication.translate("MainWindow", "?", None, QtGui.QApplication.UnicodeUTF8)) + self.label_avg.setText(QtGui.QApplication.translate("MainWindow", "Time Average", None, QtGui.QApplication.UnicodeUTF8)) + self.label_timeAvgValue.setText(QtGui.QApplication.translate("MainWindow", "?", None, QtGui.QApplication.UnicodeUTF8)) + self.label_freq.setText(QtGui.QApplication.translate("MainWindow", "Frequency", None, QtGui.QApplication.UnicodeUTF8)) + self.label_freqValue.setText(QtGui.QApplication.translate("MainWindow", "?", None, QtGui.QApplication.UnicodeUTF8)) + self.label_logsize.setText(QtGui.QApplication.translate("MainWindow", "Log Size", None, QtGui.QApplication.UnicodeUTF8)) + self.label_logsizevalue.setText(QtGui.QApplication.translate("MainWindow", "?", None, QtGui.QApplication.UnicodeUTF8)) + self.filterTab.setTabText(self.filterTab.indexOf(self.tab), QtGui.QApplication.translate("MainWindow", "Filter By Log", None, QtGui.QApplication.UnicodeUTF8)) + self.label_6.setText(QtGui.QApplication.translate("MainWindow", "Time Interval", None, QtGui.QApplication.UnicodeUTF8)) + self.pushButton_filterTime.setText(QtGui.QApplication.translate("MainWindow", "Filter", None, QtGui.QApplication.UnicodeUTF8)) + self.filterTab.setTabText(self.filterTab.indexOf(self.tab_2), QtGui.QApplication.translate("MainWindow", "Filter By Time", None, QtGui.QApplication.UnicodeUTF8)) + self.checkBox_filterByPulse.setText(QtGui.QApplication.translate("MainWindow", "Filter By Pulse Time", None, QtGui.QApplication.UnicodeUTF8)) + self.checkBox_groupWS.setText(QtGui.QApplication.translate("MainWindow", "Group Output Workspace", None, QtGui.QApplication.UnicodeUTF8)) + self.checkBox_from1.setText(QtGui.QApplication.translate("MainWindow", "Output Workspace Indexed From 1", None, QtGui.QApplication.UnicodeUTF8)) + self.checkBox_splitLog.setText(QtGui.QApplication.translate("MainWindow", "Split Sample Logs", None, QtGui.QApplication.UnicodeUTF8)) + self.comboBox_tofCorr.setItemText(0, QtGui.QApplication.translate("MainWindow", "None", None, QtGui.QApplication.UnicodeUTF8)) + self.comboBox_tofCorr.setItemText(1, QtGui.QApplication.translate("MainWindow", "Elastic", None, QtGui.QApplication.UnicodeUTF8)) + self.comboBox_tofCorr.setItemText(2, QtGui.QApplication.translate("MainWindow", "Direct", None, QtGui.QApplication.UnicodeUTF8)) + self.comboBox_tofCorr.setItemText(3, QtGui.QApplication.translate("MainWindow", "Indirect", None, QtGui.QApplication.UnicodeUTF8)) + self.comboBox_tofCorr.setItemText(4, QtGui.QApplication.translate("MainWindow", "Customized", None, QtGui.QApplication.UnicodeUTF8)) + self.comboBox_skipSpectrum.setItemText(0, QtGui.QApplication.translate("MainWindow", "Skip", None, QtGui.QApplication.UnicodeUTF8)) + self.comboBox_skipSpectrum.setItemText(1, QtGui.QApplication.translate("MainWindow", "Skip only if TOF correction", None, QtGui.QApplication.UnicodeUTF8)) + self.label_12.setText(QtGui.QApplication.translate("MainWindow", "TOF Correction To Sample", None, QtGui.QApplication.UnicodeUTF8)) + self.label_13.setText(QtGui.QApplication.translate("MainWindow", "Spectrum without Detector", None, QtGui.QApplication.UnicodeUTF8)) + self.label_Ei.setText(QtGui.QApplication.translate("MainWindow", "Incident Energy", None, QtGui.QApplication.UnicodeUTF8)) + self.label_Ei_2.setText(QtGui.QApplication.translate("MainWindow", "TOF Correction Workspace", None, QtGui.QApplication.UnicodeUTF8)) + self.pushButton_refreshCorrWSList.setText(QtGui.QApplication.translate("MainWindow", "Refresh", None, QtGui.QApplication.UnicodeUTF8)) + self.checkBox_fastLog.setText(QtGui.QApplication.translate("MainWindow", "Fast Log", None, QtGui.QApplication.UnicodeUTF8)) + self.checkBox_doParallel.setText(QtGui.QApplication.translate("MainWindow", "Generate Filter In Parallel", None, QtGui.QApplication.UnicodeUTF8)) + self.filterTab.setTabText(self.filterTab.indexOf(self.tab_3), QtGui.QApplication.translate("MainWindow", "Advanced Setup", None, QtGui.QApplication.UnicodeUTF8)) + self.pushButton_clearerror.setText(QtGui.QApplication.translate("MainWindow", "CLEAR", None, QtGui.QApplication.UnicodeUTF8)) + self.filterTab.setTabText(self.filterTab.indexOf(self.widget), QtGui.QApplication.translate("MainWindow", "Error Message", None, QtGui.QApplication.UnicodeUTF8)) + self.label_5.setText(QtGui.QApplication.translate("MainWindow", "Splitter Title", None, QtGui.QApplication.UnicodeUTF8)) + self.label_outwsname.setText(QtGui.QApplication.translate("MainWindow", "Output Name", None, QtGui.QApplication.UnicodeUTF8)) + self.label_error.setText(QtGui.QApplication.translate("MainWindow", "

ERROR!

", None, QtGui.QApplication.UnicodeUTF8)) + self.label_logname_2.setToolTip(QtGui.QApplication.translate("MainWindow", "

The name of the NeXus file or the run number to load

", None, QtGui.QApplication.UnicodeUTF8)) + self.label_logname_2.setWhatsThis(QtGui.QApplication.translate("MainWindow", "

Label for file name or run number

", None, QtGui.QApplication.UnicodeUTF8)) + self.label_logname_2.setText(QtGui.QApplication.translate("MainWindow", "File / Run ", None, QtGui.QApplication.UnicodeUTF8)) + self.pushButton_load.setText(QtGui.QApplication.translate("MainWindow", "Load", None, QtGui.QApplication.UnicodeUTF8)) + diff --git a/Code/Mantid/scripts/FilterEvents/__init__.py b/Code/Mantid/scripts/FilterEvents/__init__.py new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/Code/Mantid/scripts/FilterEvents/eventFilterGUI.py b/Code/Mantid/scripts/FilterEvents/eventFilterGUI.py new file mode 100644 index 000000000000..4a6b72acd6ef --- /dev/null +++ b/Code/Mantid/scripts/FilterEvents/eventFilterGUI.py @@ -0,0 +1,1122 @@ +import math +import numpy + +from Ui_MainWindow import Ui_MainWindow #import line for the UI python class +from PyQt4 import QtCore, QtGui +from PyQt4.QtCore import * +from PyQt4.QtGui import * + +import matplotlib +from matplotlib.backends.backend_qt4agg import FigureCanvasQTAgg as FigureCanvas +from matplotlib.backends.backend_qt4agg import NavigationToolbar2QTAgg as NavigationToolbar +from matplotlib.figure import Figure +from matplotlib.pyplot import gcf, setp + +import mantid +import mantid.simpleapi as api +import mantid.kernel +from mantid.simpleapi import AnalysisDataService + +from mantid.kernel import ConfigService + +import os + +HUGE_FAST = 10000 +HUGE_PARALLEL = 100000 +MAXTIMEBINSIZE = 20000 + +try: + _fromUtf8 = QtCore.QString.fromUtf8 +except AttributeError: + def _fromUtf8(s): + return s + +class MainWindow(QtGui.QMainWindow): + """ Class of Main Window (top) + + Move to ui.setupUI + Replacement is not a valid approach as the UI is setup at the end of self.ui.setupUI + self.dpi = 100 + self.fig = Figure((5.0, 4.0), dpi=self.dpi) + self.figure = Figure((4.0, 3.0), dpi=100) + self.theplot = self.figure.add_subplot(111) + self.ui.graphicsView = FigureCanvas(self.figure) + self.ui.graphicsView.setParent(self.centralwidget) + self.ui.graphicsView.setGeometry(QtCore.QRect(40, 230, 821, 411)) + self.ui.graphicsView.setObjectName(_fromUtf8("graphicsView")) + + + # Version 2.0 + Import + import matplotlib + from matplotlib.backends.backend_qt4agg import FigureCanvasQTAgg as FigureCanvas + from matplotlib.backends.backend_qt4agg import NavigationToolbar2QTAgg as NavigationToolbar + from matplotlib.figure import Figure + + self.figure = Figure((4.0, 3.0), dpi=100) + self.theplot = self.figure.add_subplot(111) + self.graphicsView = FigureCanvas(self.figure) + self.graphicsView.setParent(self.centralwidget) + self.graphicsView.setGeometry(QtCore.QRect(20, 150, 741, 411)) + self.graphicsView.setObjectName(_fromUtf8("graphicsView")) + + """ + + def __init__(self, parent=None): + """ Intialization and set up + """ + # Base class + QtGui.QMainWindow.__init__(self,parent) + + # Mantid configuration + config = ConfigService.Instance() + self._instrument = config["default.instrument"] + + # Central widget + self.centralwidget = QtGui.QWidget(self) + + # UI Window (from Qt Designer) + self.ui = Ui_MainWindow() + self.ui.setupUi(self) + + # Do initialize plotting + vecx, vecy, xlim, ylim = self.computeMock() + + self.mainline = self.ui.theplot.plot(vecx, vecy, 'r-') + + leftx = [xlim[0], xlim[0]] + lefty = [ylim[0], ylim[1]] + self.leftslideline = self.ui.theplot.plot(leftx, lefty, 'b--') + rightx = [xlim[1], xlim[1]] + righty = [ylim[0], ylim[1]] + self.rightslideline = self.ui.theplot.plot(rightx, righty, 'g--') + upperx = [xlim[0], xlim[1]] + uppery = [ylim[1], ylim[1]] + self.upperslideline = self.ui.theplot.plot(upperx, uppery, 'b--') + lowerx = [xlim[0], xlim[1]] + lowery = [ylim[0], ylim[0]] + self.lowerslideline = self.ui.theplot.plot(lowerx, lowery, 'g--') + + self.ui.graphicsView.mpl_connect('button_press_event', self.on_mouseDownEvent) + + # Set up horizontal slide (integer) and string value + self._leftSlideValue = 0 + self._rightSlideValue = 99 + + self.ui.horizontalSlider.setRange(0, 100) + self.ui.horizontalSlider.setValue(self._leftSlideValue) + self.ui.horizontalSlider.setTracking(True) + self.ui.horizontalSlider.setTickPosition(QSlider.TicksAbove) + self.connect(self.ui.horizontalSlider, SIGNAL('valueChanged(int)'), self.move_leftSlider) + + + self.ui.horizontalSlider_2.setRange(0, 100) + self.ui.horizontalSlider_2.setValue(self._rightSlideValue) + self.ui.horizontalSlider_2.setTracking(True) + self.ui.horizontalSlider_2.setTickPosition(QSlider.TicksAbove) + self.connect(self.ui.horizontalSlider_2, SIGNAL('valueChanged(int)'), self.move_rightSlider) + + # self.connect(self.ui.lineEdit_3, QtCore.SIGNAL("textChanged(QString)"), + # self.set_startTime) + self.ui.lineEdit_3.setValidator(QtGui.QDoubleValidator(self.ui.lineEdit_3)) + self.connect(self.ui.pushButton_setT0, QtCore.SIGNAL("clicked()"), self.set_startTime) + # self.connect(self.ui.lineEdit_4, QtCore.SIGNAL("textChanged(QString)"), + # self.set_stopTime) + self.ui.lineEdit_4.setValidator(QtGui.QDoubleValidator(self.ui.lineEdit_4)) + self.connect(self.ui.pushButton_setTf, QtCore.SIGNAL("clicked()"), self.set_stopTime) + + + # File loader + self.scanEventWorkspaces() + self.connect(self.ui.pushButton_refreshWS, SIGNAL('clicked()'), self.scanEventWorkspaces) + self.connect(self.ui.pushButton_browse, SIGNAL('clicked()'), self.browse_File) + self.connect(self.ui.pushButton_load, SIGNAL('clicked()'), self.load_File) + self.connect(self.ui.pushButton_3, SIGNAL('clicked()'), self.use_existWS) + + # Set up time + self.ui.lineEdit_3.setValidator(QtGui.QDoubleValidator(self.ui.lineEdit_3)) + self.ui.lineEdit_4.setValidator(QtGui.QDoubleValidator(self.ui.lineEdit_4)) + + # Filter by time + self.connect(self.ui.pushButton_filterTime, SIGNAL('clicked()'), self.filterByTime) + + # Filter by log value + self.ui.lineEdit_5.setValidator(QtGui.QDoubleValidator(self.ui.lineEdit_5)) + self.ui.lineEdit_6.setValidator(QtGui.QDoubleValidator(self.ui.lineEdit_6)) + self.ui.lineEdit_7.setValidator(QtGui.QDoubleValidator(self.ui.lineEdit_7)) + self.ui.lineEdit_8.setValidator(QtGui.QDoubleValidator(self.ui.lineEdit_8)) + self.ui.lineEdit_9.setValidator(QtGui.QDoubleValidator(self.ui.lineEdit_9)) + + self.connect(self.ui.lineEdit_5, QtCore.SIGNAL("textChanged(QString)"), + self.set_minLogValue) + self.connect(self.ui.lineEdit_6, QtCore.SIGNAL("textChanged(QString)"), + self.set_maxLogValue) + + dirchangeops = ["Both", "Increase", "Decrease"] + self.ui.comboBox_4.addItems(dirchangeops) + + logboundops = ["Centre", "Left"] + self.ui.comboBox_5.addItems(logboundops) + + self.connect(self.ui.pushButton_4, SIGNAL('clicked()'), self.plotLogValue) + + self.connect(self.ui.pushButton_filterLog, SIGNAL('clicked()'), self.filterByLogValue) + + # Set up vertical slide + self._upperSlideValue = 99 + self._lowerSlideValue = 0 + + self.ui.verticalSlider.setRange(0, 100) + self.ui.verticalSlider.setValue(self._upperSlideValue) + self.ui.verticalSlider.setTracking(True) + self.connect(self.ui.verticalSlider, SIGNAL('valueChanged(int)'), self.move_upperSlider) + + self.ui.verticalSlider_2.setRange(0, 100) + self.ui.verticalSlider_2.setValue(self._lowerSlideValue) + self.ui.verticalSlider_2.setTracking(True) + self.connect(self.ui.verticalSlider_2, SIGNAL('valueChanged(int)'), self.move_lowerSlider) + + # Set up for filtering (advanced setup) + self._tofcorrection = False + self.ui.checkBox_filterByPulse.setChecked(False) + self.ui.checkBox_from1.setChecked(False) + self.ui.checkBox_groupWS.setChecked(True) + + self.connect(self.ui.comboBox_tofCorr, SIGNAL('currentIndexChanged(int)'), self.showHideEi) + self.connect(self.ui.pushButton_refreshCorrWSList, SIGNAL('clicked()'), self._searchTableWorkspaces) + + self.ui.lineEdit_Ei.setValidator(QtGui.QDoubleValidator(self.ui.lineEdit_Ei)) + + self.ui.label_Ei.hide() + self.ui.lineEdit_Ei.hide() + self.ui.label_Ei_2.hide() + self.ui.comboBox_corrWS.hide() + self.ui.pushButton_refreshCorrWSList.hide() + + # Error message + self.connect(self.ui.pushButton_clearerror, SIGNAL('clicked()'), self._clearErrorMsg) + self.ui.plainTextEdit_ErrorMsg.setReadOnly(True) + self.ui.label_error.hide() + + # Set up for workspaces + self._dataWS = None + self._sampleLogNames = [] + self._sampleLog = None + + # Side information + self.ui.label_mean.hide() + self.ui.label_meanvalue.hide() + self.ui.label_avg.hide() + self.ui.label_timeAvgValue.hide() + self.ui.label_freq.hide() + self.ui.label_freqValue.hide() + self.ui.label_logname.hide() + self.ui.label_lognamevalue.hide() + self.ui.label_logsize.hide() + self.ui.label_logsizevalue.hide() + + # Default + self._defaultdir = os.getcwd() + + # self.ui.InputVal.setValidator(QtGui.QDoubleValidator(self.ui.InputVal)) + + # QtCore.QObject.connect(self.ui.convert, QtCore.SIGNAL("clicked()"), self.convert ) + # QtCore.QObject.connect(self.ui.inputUnits, QtCore.SIGNAL("currentIndexChanged(QString)"), self.setInstrumentInputs ) + # QtCore.QObject.connect(self.ui.outputUnits, QtCore.SIGNAL("currentIndexChanged(QString)"), self.setInstrumentInputs ) + # self.setInstrumentInputs() + + ##defaults + + return + + + def on_mouseDownEvent(self, event): + """ Respond to pick up a value with mouse down event + """ + x = event.xdata + y = event.ydata + + if x is not None and y is not None: + msg = "You've clicked on a bar with coords:\n %f, %f" % (x, y) + QMessageBox.information(self, "Click!", msg) + + return + + + def computeMock(self): + """ Compute vecx and vecy as mocking + """ + import random, math + + x0 = 0. + xf = 1. + dx = 0.1 + + vecx = [] + vecy = [] + + x = x0 + while x < xf: + y = 0.0 + vecx.append(x) + vecy.append(y) + x += dx + + xlim = [x0, xf] + ylim = [-1., 1] + + return (vecx, vecy, xlim, ylim) + + + def move_leftSlider(self): + """ Re-setup left range line in figure. + Triggered by a change in Qt Widget. NO EVENT is required. + """ + newx = self.ui.horizontalSlider.value() + if newx <= self._rightSlideValue and newx != self._leftSlideValue: + # Allowed value: move the value bar + self._leftSlideValue = newx + + # Move the vertical line + xlim = self.ui.theplot.get_xlim() + newx = xlim[0] + newx*(xlim[1] - xlim[0])*0.01 + leftx = [newx, newx] + lefty = self.ui.theplot.get_ylim() + setp(self.leftslideline, xdata=leftx, ydata=lefty) + + self.ui.graphicsView.draw() + + # Change value + self.ui.lineEdit_3.setText(str(newx)) + + else: + # Reset the value to original value + self.ui.horizontalSlider.setValue(self._leftSlideValue) + + return + + + def set_startTime(self): + """ Set the starting time and left slide bar + """ + inps = str(self.ui.lineEdit_3.text()) + print "Starting time = %s" % (inps) + + xlim = self.ui.theplot.get_xlim() + if inps == "": + # Empty. Use default + newtime0 = xlim[0] + else: + newtime0 = float(inps) + + # Convert to integer slide value + ileftvalue = int( (newtime0-xlim[0])/(xlim[1] - xlim[0])*100 ) + print "iLeftSlide = %d" % (ileftvalue) + + # Skip if same as origina + if ileftvalue == self._leftSlideValue: + return + + # Set the value if out of range + resetT = True + if ileftvalue < 0: + # Minimum value as 0 + ileftvalue = 0 + elif ileftvalue > self._rightSlideValue: + # Maximum value as right slide value + ileftvalue = self._rightSlideValue + else: + resetT = False + + if resetT is True: + newtime0 = xlim[0] + ileftvalue*(xlim[1]-xlim[0])*0.01 + print "Corrected iLeftSlide = %d (vs. right = %d)" % (ileftvalue, self._rightSlideValue) + + # Move the slide bar (left) + self._leftSlideValue = ileftvalue + + # Move the vertical line + leftx = [newtime0, newtime0] + lefty = self.ui.theplot.get_ylim() + setp(self.leftslideline, xdata=leftx, ydata=lefty) + + self.ui.graphicsView.draw() + + # Set the value to left slider + self.ui.horizontalSlider.setValue(self._leftSlideValue) + # Reset the value of line edit + if resetT is True: + self.ui.lineEdit_3.setText(str(newtime0)) + + return + + def move_rightSlider(self): + """ Re-setup left range line in figure. + Triggered by a change in Qt Widget. NO EVENT is required. + """ + newx = self.ui.horizontalSlider_2.value() + if newx >= self._leftSlideValue and newx != self._rightSlideValue: + # Allowed value: move the value bar + self._rightSlideValue = newx + + xlim = self.ui.theplot.get_xlim() + newx = xlim[0] + newx*(xlim[1] - xlim[0])*0.01 + leftx = [newx, newx] + lefty = self.ui.theplot.get_ylim() + setp(self.rightslideline, xdata=leftx, ydata=lefty) + + self.ui.graphicsView.draw() + + # Change value + self.ui.lineEdit_4.setText(str(newx)) + + else: + # Reset the value + self.ui.horizontalSlider_2.setValue(self._rightSlideValue) + + return + + + def set_stopTime(self): + """ Set the starting time and left slide bar + """ + inps = str(self.ui.lineEdit_4.text()) + print "Stopping time = %s" % (inps) + + xlim = self.ui.theplot.get_xlim() + if inps == "": + # Empty. Use default + newtimef = xlim[1] + else: + # Parse + newtimef = float(inps) + + # Convert to integer slide value + irightvalue = int( (newtimef-xlim[0])/(xlim[1] - xlim[0])*100 ) + print "iRightSlide = %d" % (irightvalue) + + # Return if no change + if irightvalue == self._rightSlideValue: + return + + # Correct value + resetT = True + if irightvalue >= 100: + irightvalue == 100 + elif irightvalue < self._leftSlideValue: + irightvalue = self._leftSlideValue + else: + resetT = False + + if resetT is True: + newtimef = xlim[0] + irightvalue*(xlim[1]-xlim[0])*0.01 + + # Move the slide bar (right) + self._rightSlideValue = irightvalue + + # Move the vertical line + rightx = [newtimef, newtimef] + righty = self.ui.theplot.get_ylim() + setp(self.rightslideline, xdata=rightx, ydata=righty) + + self.ui.graphicsView.draw() + + # Set the value to left slider + self.ui.horizontalSlider_2.setValue(self._rightSlideValue) + + # Reset to line edit + if resetT: + self.ui.lineEdit_4.setText(str(newtimef)) + + return + + def move_lowerSlider(self): + """ Re-setup upper range line in figure. + Triggered by a change in Qt Widget. NO EVENT is required. + """ + inewy = self.ui.verticalSlider_2.value() + print "LowerSlider is set with value %d vs. class variable %d" % (inewy, self._lowerSlideValue) + + # Return with no change + if inewy == self._lowerSlideValue: + # No change + return + + if inewy >= self._upperSlideValue: + # Out of upper range + inewy = self._upperSlideValue - 1 + + if inewy == 0 and self._lowerSlideValue < 0: + setLineEdit = False + else: + setLineEdit = True + + # Move the lower vertical bar + ylim = self.ui.theplot.get_ylim() + newy = ylim[0] + inewy*(ylim[1] - ylim[0])*0.01 + lowerx = self.ui.theplot.get_xlim() + lowery = [newy, newy] + setp(self.lowerslideline, xdata=lowerx, ydata=lowery) + + self.ui.graphicsView.draw() + + # Set line edit input + if setLineEdit is True: + # Change value to line edit (5) + self.ui.lineEdit_5.setText(str(newy)) + # Reset the class variable + self._lowerSlideValue = inewy + + return + + def set_minLogValue(self): + """ Set the starting time and left slide bar + """ + print "Minimum Log Value = %s" %(str(self.ui.lineEdit_5.text())) + + ylim = self.ui.theplot.get_ylim() + + if str(self.ui.lineEdit_5.text()) == "": + # Empty. Default to minY + newminY = ylim[0] + else: + # Non empty. Parse + newminY = float(self.ui.lineEdit_5.text()) + + # Convert to integer slide value + iminlogval = int( (newminY-ylim[0])/(ylim[1] - ylim[0])*100 ) + print "ilowerSlide = %d" % (iminlogval) + + # Return if no change + if iminlogval == self._lowerSlideValue: + return + + # Set value if out of range + resetL = True + if iminlogval >= self._upperSlideValue: + iminlogval = self._upperSlideValue - 1 + else: + resetL = False + + if resetL is True: + newminY = ylim[0] + iminlogval * (ylim[1]-ylim[0]) * 0.01 + + # Move the vertical line + lowerx = self.ui.theplot.get_xlim() + lowery = [newminY, newminY] + setp(self.lowerslideline, xdata=lowerx, ydata=lowery) + + self.ui.graphicsView.draw() + + # Move the slide bar (lower) + self._lowerSlideValue = iminlogval + print "LineEdit5 set slide to %d" % (self._lowerSlideValue) + self.ui.verticalSlider_2.setValue(self._lowerSlideValue) + + # Reset line Edit if using default + if resetL is True: + self.ui.lineEdit_5.setText(str(newminY)) + + return + + def move_upperSlider(self): + """ Re-setup upper range line in figure. + Triggered by a change in Qt Widget. NO EVENT is required. + """ + inewy = self.ui.verticalSlider.value() + + # Return w/o change + if inewy == self._upperSlideValue: + return + + # Set to boundary value + if inewy <= self._lowerSlideValue: + inewy = self._lowerSlideValue + 1 + + # Reset line editor? + if inewy == 100 and self._upperSlideValue > 100: + setLineEdit = False + else: + setLineEdit = True + + # Move the upper value bar + ylim = self.ui.theplot.get_ylim() + newy = ylim[0] + inewy*(ylim[1] - ylim[0])*0.01 + upperx = self.ui.theplot.get_xlim() + uppery = [newy, newy] + setp(self.upperslideline, xdata=upperx, ydata=uppery) + + self.ui.graphicsView.draw() + + # Change value + if setLineEdit is True: + self.ui.lineEdit_6.setText(str(newy)) + self._upperSlideValue = inewy + + return + + def set_maxLogValue(self): + """ Set maximum log value from line-edit + """ + inps = str(self.ui.lineEdit_6.text()) + print "Maximum Log Value = %s" %(inps) + + ylim = self.ui.theplot.get_ylim() + if inps == "": + # Empty. Default to minY + newmaxY = ylim[1] + else: + # Parse + newmaxY = float(inps) + + # Convert to integer slide value + imaxlogval = int( (newmaxY-ylim[0])/(ylim[1] - ylim[0])*100 ) + print "iUpperSlide = %d" % (imaxlogval) + + # Return if no change + if imaxlogval == self._upperSlideValue: + return + + # Set to default if out of range + resetL = True + # if imaxlogval >= 100: + # imaxlogval = 100 + if imaxlogval < self._lowerSlideValue: + imaxlogval = self._lowerSlideValue + 1 + else: + resetL = False + + # Set newmaxY if necessary + if resetL is True: + newmaxY = ylim[0] + imaxlogval * (ylim[1] - ylim[0]) * 0.01 + + # Move the vertical line + upperx = self.ui.theplot.get_xlim() + uppery = [newmaxY, newmaxY] + setp(self.upperslideline, xdata=upperx, ydata=uppery) + + self.ui.graphicsView.draw() + + # Set the value to upper slider + self._upperSlideValue = imaxlogval + self.ui.verticalSlider.setValue(self._upperSlideValue) + + # Set the value to editor if necessary + if resetL is True: + self.ui.lineEdit_6.setText(str(newmaxY)) + + return + + def browse_File(self): + """ Open a file dialog to get file + """ + filename = QtGui.QFileDialog.getOpenFileName(self, 'Input File Dialog', + self._defaultdir, "Data (*.nxs *.dat);;All files (*.*)") + + self.ui.lineEdit.setText(str(filename)) + + # print "Selected file: ", filename + + return + + def load_File(self): + """ Load the file by file name or run number + """ + # Get file name from line editor + filename = str(self.ui.lineEdit.text()) + + # Find out it is relative path or absolute path + if os.path.abspath(filename) == filename: + isabspath = True + else: + isabspath = False + + dataws = self._loadFile(str(filename)) + if dataws is None: + print "Unable to locate run %s in default directory %s." % (filename, self._defaultdir) + else: + self._importDataWorkspace(dataws) + self._defaultdir = os.path.dirname(str(filename)) + + return + + + def use_existWS(self): + """ Set up workspace to an existing one + """ + wsname = str(self.ui.comboBox.currentText()) + + try: + dataws = AnalysisDataService.retrieve(wsname) + self._importDataWorkspace(dataws) + except KeyError: + pass + + return + + + def plotLogValue(self): + """ Plot log value + """ + # Get log value + logname = str(self.ui.comboBox_2.currentText()) + if len(logname) == 0: + # return due to the empty one is chozen + return + + samplelog = self._dataWS.getRun().getProperty(logname) + vectimes = samplelog.times + vecvalue = samplelog.value + + # check + if len(vectimes) == 0: + print "Empty log!" + + # Convert absolute time to relative time in seconds + t0 = self._dataWS.getRun().getProperty("proton_charge").times[0] + t0ns = t0.totalNanoseconds() + + # append 1 more log if original log only has 1 value + tf = self._dataWS.getRun().getProperty("proton_charge").times[-1] + vectimes.append(tf) + vecvalue = numpy.append(vecvalue, vecvalue[-1]) + + vecreltimes = [] + for t in vectimes: + rt = float(t.totalNanoseconds() - t0ns) * 1.0E-9 + vecreltimes.append(rt) + + # Set to plot + xlim = [min(vecreltimes), max(vecreltimes)] + ylim = [min(vecvalue), max(vecvalue)] + self.ui.theplot.set_xlim(xlim[0], xlim[1]) + self.ui.theplot.set_ylim(ylim[0], ylim[1]) + + setp(self.mainline, xdata=vecreltimes, ydata=vecvalue) + + # assume that all logs are on almost same X-range. Only Y need to be reset + setp(self.leftslideline, ydata=ylim) + setp(self.rightslideline, ydata=ylim) + + # reset the log value limit as previous one does not make any sense + setp(self.lowerslideline, xdata=xlim, ydata=[ylim[0], ylim[0]]) + self._lowerSlideValue = 0 + self.ui.verticalSlider_2.setValue(self._lowerSlideValue) + self.ui.lineEdit_5.setText("") + + setp(self.upperslideline, xdata=xlim, ydata=[ylim[1], ylim[1]]) + self._upperSlideValue = 100 + self.ui.verticalSlider.setValue(self._upperSlideValue) + self.ui.lineEdit_6.setText("") + + self.ui.graphicsView.draw() + + # Load property's statistic and give suggestion on parallel and fast log + timeavg = samplelog.timeAverageValue() + numentries = samplelog.size() + stat = samplelog.getStatistics() + + duration = stat.duration + mean = stat.mean + freq = float(numentries)/float(duration) + + self.ui.label_mean.show() + self.ui.label_meanvalue.show() + self.ui.label_avg.show() + self.ui.label_timeAvgValue.show() + self.ui.label_freq.show() + self.ui.label_freqValue.show() + self.ui.label_logname.show() + self.ui.label_lognamevalue.show() + self.ui.label_logsize.show() + self.ui.label_logsizevalue.show() + + self.ui.label_meanvalue.setText("%.5e"%(mean)) + self.ui.label_timeAvgValue.setText("%.5e"%(timeavg)) + self.ui.label_freqValue.setText("%.5e"%(freq)) + self.ui.label_lognamevalue.setText(logname) + self.ui.label_logsizevalue.setText(str(numentries)) + + # Set suggested processing scheme + if numentries > HUGE_FAST: + self.ui.checkBox_fastLog.setCheckState(True) + if numentries > HUGE_PARALLEL: + self.ui.checkBox_doParallel.setCheckState(True) + else: + self.ui.checkBox_doParallel.setCheckState(False) + else: + self.ui.checkBox_fastLog.setCheckState(False) + self.ui.checkBox_doParallel.setCheckState(False) + + return + + + def _importDataWorkspace(self, dataws): + """ Import data workspace for filtering + """ + if dataws is None: + return + + # Plot time counts + errmsg = self._plotTimeCounts(dataws) + if errmsg is not None: + errmsg = "Workspace %s has invalid sample logs for splitting. Loading \ + failure! \n%s\n" % (str(dataws), errmsg) + self._setErrorMsg(errmsg) + return False + + # Import log + self._sampleLogNames = [""] + + run = dataws.getRun() + plist = run.getProperties() + for p in plist: + pv = p.value + if isinstance(pv, numpy.ndarray): + times = p.times + if len(times) > 1: + self._sampleLogNames.append(p.name) + # ENDFOR(p) + + # Set up sample log + self.ui.comboBox_2.clear() + self.ui.comboBox_2.addItems(self._sampleLogNames) + + # Side information + self.ui.label_mean.hide() + self.ui.label_meanvalue.hide() + self.ui.label_avg.hide() + self.ui.label_timeAvgValue.hide() + self.ui.label_freq.hide() + self.ui.label_freqValue.hide() + + # Set dataws to class variable + self._dataWS = dataws + + return True + + def scanEventWorkspaces(self): + """ + """ + wsnames = AnalysisDataService.getObjectNames() + + eventwsnames = [] + for wsname in wsnames: + wksp = AnalysisDataService.retrieve(wsname) + if wksp.__class__.__name__.count("Event") == 1: + eventwsnames.append(wsname) + # ENDFOR + + if len(eventwsnames) > 0: + self.ui.comboBox.clear() + self.ui.comboBox.addItems(eventwsnames) + + return + + + def _loadFile(self, filename): + """ Load file or run + File will be loaded to a workspace shown in MantidPlot + """ + config = ConfigService + + # Check input file name and output workspace name + if filename.isdigit() is True: + # Construct a file name from run number + runnumber = int(filename) + if runnumber <= 0: + print "Run number cannot be less or equal to zero. User gives %s. " % (filename) + return None + else: + ishort = config.getInstrument(self._instrument).shortName() + filename = "%s_%s" %(ishort, filename) + wsname = filename + "_event" + + elif filename.count(".") > 0: + # A proper file name + wsname = os.path.splitext(os.path.split(filename)[1])[0] + + elif filename.count("_") == 1: + # A short one as instrument_runnumber + iname = filename.split("_")[0] + str_runnumber = filename.split("_")[1] + if str_runnumber.isdigit() is True and int(str_runnumber) > 0: + # Acccepted format + ishort = config.getInstrument(iname).shortName() + wsname = "%s_%s_event" % (ishort, str_runnumber) + else: + # Non-supported + print "File name / run number in such format %s is not supported. " % (filename) + return None + + else: + # Unsupported format + print "File name / run number in such format %s is not supported. " % (filename) + return None + + # Load + try: + ws = api.Load(Filename=filename, OutputWorkspace=wsname) + except: + ws = None + + return ws + + + def _plotTimeCounts(self, wksp): + """ Plot time/counts + """ + import datetime + # Rebin events by pulse time + try: + # Get run start and run stop + if wksp.getRun().hasProperty("run_start"): + runstart = wksp.getRun().getProperty("run_start").value + else: + runstart = wksp.getRun().getProperty("proton_charge").times[0] + runstop = wksp.getRun().getProperty("proton_charge").times[-1] + + runstart = str(runstart).split(".")[0].strip() + runstop = str(runstop).split(".")[0].strip() + + t0 = datetime.datetime.strptime(runstart, "%Y-%m-%dT%H:%M:%S") + tf = datetime.datetime.strptime(runstop, "%Y-%m-%dT%H:%M:%S") + + # Calcualte + dt = tf-t0 + timeduration = dt.days*3600*24 + dt.seconds + + timeres = float(timeduration)/MAXTIMEBINSIZE + if timeres < 1.0: + timeres = 1.0 + + sumws = api.RebinByPulseTimes(InputWorkspace=wksp, OutputWorkspace = "Summed_%s"%(str(wksp)), + Params="0, %f, %d"%(timeres, timeduration)) + sumws = api.SumSpectra(InputWorkspace=sumws, OutputWorkspace=str(sumws)) + sumws = api.ConvertToPointData(InputWorkspace=sumws, OutputWorkspace=str(sumws)) + except Exception as e: + return str(e) + + vecx = sumws.readX(0) + vecy = sumws.readY(0) + + xmin = min(vecx) + xmax = max(vecx) + ymin = min(vecy) + ymax = max(vecy) + + # Reset graph + self.ui.theplot.set_xlim(xmin, xmax) + self.ui.theplot.set_ylim(ymin, ymax) + + # Set up main line + setp(self.mainline, xdata=vecx, ydata=vecy) + + # Reset slide + newslidery = [min(vecy), max(vecy)] + + newleftx = xmin + (xmax-xmin)*self._leftSlideValue*0.01 + setp(self.leftslideline, xdata=[newleftx, newleftx], ydata=newslidery) + + newrightx = xmin + (xmax-xmin)*self._rightSlideValue*0.01 + setp(self.rightslideline, xdata=[newrightx, newrightx], ydata=newslidery) + + self.ui.graphicsView.draw() + + return + + + def filterByTime(self): + """ Filter by time + """ + # Generate event filters + kwargs = {} + if self.ui.lineEdit_3.text() != "": + rel_starttime = float(self.ui.lineEdit_3.text()) + kwargs["StartTime"] = str(rel_starttime) + if self.ui.lineEdit_4.text() != "": + rel_stoptime = float(self.ui.lineEdit_4.text()) + kwargs["StopTime"] = str(rel_stoptime) + if self.ui.lineEdit_timeInterval.text() != "": + interval = float(self.ui.lineEdit_timeInterval.text()) + kwargs["TimeInterval"] = interval + + splitwsname = str(self._dataWS) + "_splitters" + splitinfowsname = str(self._dataWS) + "_info" + + title = str(self.ui.lineEdit_title.text()) + + """ Debug + for k in kwargs.keys(): + print k, kwargs[k], type(kwargs[k]) + print "Input workspace = ", str(self._dataWS) + END DB """ + + splitws, infows = api.GenerateEventsFilter( + InputWorkspace = self._dataWS, + UnitOfTime = "Seconds", + TitleOfSplitters = title, + OutputWorkspace = splitwsname, + InformationWorkspace = splitinfowsname, **kwargs) + + self.splitWksp(splitws, infows) + + return + + def filterByLogValue(self): + """ Filter by log value + """ + # Generate event filter + kwargs = {} + samplelog = str(self.ui.comboBox_2.currentText()) + if len(samplelog) == 0: + print "No sample log is selected!" + return + + + if self.ui.lineEdit_3.text() != "": + rel_starttime = float(self.ui.lineEdit_3.text()) + kwargs["StartTime"] = str(rel_starttime) + if self.ui.lineEdit_4.text() != "": + rel_stoptime = float(self.ui.lineEdit_4.text()) + kwargs["StopTime"] = str(rel_stoptime) + if self.ui.lineEdit_5.text() != "": + minlogvalue = float(self.ui.lineEdit_5.text()) + kwargs["MinimumLogValue"] = minlogvalue + if self.ui.lineEdit_6.text() != "": + maxlogvalue = float(self.ui.lineEdit_6.text()) + kwargs["MaximumLogValue"] = maxlogvalue + if self.ui.lineEdit_7.text() != "": + logvalueintv = float(self.ui.lineEdit_7.text()) + kwargs["LogValueInterval"] = logvalueintv + logvalchangedir = str(self.ui.comboBox_4.currentText()) + kwargs["FilterLogValueByChangingDirection"] = logvalchangedir + if self.ui.lineEdit_9.text() != "": + logvalueintv = float(self.ui.lineEdit_9.text()) + kwargs["TimeTolerance"] = logvalueintv + logboundtype = str(self.ui.comboBox_5.currentText()) + kwargs["LogBoundary"] = logboundtype + if self.ui.lineEdit_8.text() != "": + logvaluetol = float(self.ui.lineEdit_8.text()) + kwargs["LogValueTolerance"] = logvaluetol + + + splitwsname = str(self._dataWS) + "_splitters" + splitinfowsname = str(self._dataWS) + "_info" + + title = str(self.ui.lineEdit_title.text()) + + splitws, infows = api.GenerateEventsFilter( + InputWorkspace = self._dataWS, + UnitOfTime = "Seconds", + TitleOfSplitters = title, + OutputWorkspace = splitwsname, + LogName = samplelog, + InformationWorkspace = splitinfowsname, **kwargs) + + self.splitWksp(splitws, infows) + + return + + def splitWksp(self, splitws, infows): + """ Run FilterEvents + """ + dogroupws = self.ui.checkBox_groupWS.isChecked() + filterbypulse = self.ui.checkBox_filterByPulse.isChecked() + startfrom1 = self.ui.checkBox_from1.isChecked() + splitsamplelog = self.ui.checkBox_splitLog.isChecked() + + corr2sample = str(self.ui.comboBox_tofCorr.currentText()) + how2skip = str(self.ui.comboBox_skipSpectrum.currentText()) + + kwargs = {} + if corr2sample == "Direct": + ei = float(self.ui.lineEdit_Ei.text()) + kwargs["IncidentEnergy"] = ei + elif corr2sample == "Customized": + corrws = str(self.ui.comboBox_corrWS.currentText()) + kwargs["DetectorTOFCorrectionWorkspace"] = corrws + + # Output workspace name + outbasewsname = str(self.ui.lineEdit_outwsname.text()) + if len(outbasewsname) == 0: + outbasewsname = "tempsplitted" + self.ui.lineEdit_outwsname.setText(outbasewsname) + + api.FilterEvents( + InputWorkspace = self._dataWS, + SplitterWorkspace = splitws, + InformationWorkspace = infows, + OutputWorkspaceBaseName = outbasewsname, + GroupWorkspaces = dogroupws, + FilterByPulseTime = filterbypulse, + CorrectionToSample = corr2sample, + SpectrumWithoutDetector = how2skip, + SplitSampleLogs = splitsamplelog, + OutputWorkspaceIndexedFrom1 = startfrom1, + OutputTOFCorrectionWorkspace = 'TOFCorrTable', **kwargs) + + return + + def showHideEi(self): + """ + """ + corrtype = str(self.ui.comboBox_tofCorr.currentText()) + + # Incident energy + if corrtype == "Direct": + self.ui.label_Ei.show() + self.ui.lineEdit_Ei.show() + else: + self.ui.label_Ei.hide() + self.ui.lineEdit_Ei.hide() + + # Workspace + if corrtype == "Customized": + self.ui.label_Ei_2.show() + self.ui.comboBox_corrWS.show() + self.ui.pushButton_refreshCorrWSList.show() + + # Search for table workspace + self._searchTableWorkspaces() + + else: + self.ui.label_Ei_2.hide() + self.ui.comboBox_corrWS.hide() + self.ui.pushButton_refreshCorrWSList.hide() + + return + + + def _searchTableWorkspaces(self): + """ Search table workspaces and add to 'comboBox_corrWS' + """ + wsnames = AnalysisDataService.getObjectNames() + + tablewsnames = [] + for wsname in wsnames: + wksp = AnalysisDataService.retrieve(wsname) + if isinstance(wksp, mantid.api._api.ITableWorkspace): + tablewsnames.append(wsname) + # ENDFOR + + self.ui.comboBox_corrWS.clear() + if len(tablewsnames) > 0: + self.ui.comboBox_corrWS.addItems(tablewsnames) + + return + + def _clearErrorMsg(self): + """ Clear error message + """ + self.ui.plainTextEdit_ErrorMsg.setPlainText("") + self.ui.label_error.hide() + + return + + def _setErrorMsg(self, errmsg): + """ Clear error message + """ + self.ui.plainTextEdit_ErrorMsg.setPlainText(errmsg) + self.ui.label_error.show() + + return diff --git a/Code/Mantid/scripts/Inelastic/IndirectAbsCor.py b/Code/Mantid/scripts/Inelastic/IndirectAbsCor.py index ee93196dc196..8a930356a4a6 100644 --- a/Code/Mantid/scripts/Inelastic/IndirectAbsCor.py +++ b/Code/Mantid/scripts/Inelastic/IndirectAbsCor.py @@ -228,26 +228,26 @@ def plotAbs(workspaces, plotOpt): graph.activeLayer().setAxisTitle(mp.Layer.Bottom, 'Angle') -def AbsRunFeeder(inputWS, canWS, geom, ncan, size, avar, density, beam_width=None, sampleFormula=None, canFormula=None, sigs=None, siga=None, - plotOpt='None', Verbose=False,Save=False): +def AbsRunFeeder(input_ws, can_ws, geom, ncan, size, avar, density, beam_width=None, sample_formula=None, can_formula=None, sigs=None, siga=None, + plot_opt='None', verbose=False, save=False): """ Handles the feeding of input and plotting of output for the F2PY absorption correction routine. - @param inputWS - workspace to generate corrections for + @param input_ws - workspace to generate corrections for @param geom - type of geometry used (flat plate or cylinder) @param beam_width - width of the beam used. If None this will be taken from the IPF @param ncan - number of cans used. @param size - sample & can thickness - @param sampleFormula - optional, chemical formula for the sample - @param camFormula - optional, chemical formula for the can + @param sample_formula - optional, chemical formula for the sample + @param cam_formula - optional, chemical formula for the can @param density - density of the sample and cans(s) @param sigs - scattering for sample and can(s) @param siga - absorption for sample and can(s) @param avar - sample angle - @param plotOpt - whether to plot output - @param Verbose - whether to show extra verbose output - @param Save - whether to save the output to file + @param plot_opt - whether to plot output + @param verbose - whether to show extra verbose output + @param save - whether to save the output to file """ StartTime('CalculateCorrections') @@ -255,12 +255,12 @@ def AbsRunFeeder(inputWS, canWS, geom, ncan, size, avar, density, beam_width=Non #attempt to find beam width if none given if beam_width is None: - beam_width = getInstrumentParameter(inputWS, 'Workflow.beam-width') + beam_width = getInstrumentParameter(input_ws, 'Workflow.beam-width') beam_width = float(beam_width) #attempt to find beam height from parameter file try: - beam_height = getInstrumentParameter(inputWS, 'Workflow.beam-height') + beam_height = getInstrumentParameter(input_ws, 'Workflow.beam-height') beam_height = float(beam_height) except ValueError: # fall back on default value for beam height @@ -273,14 +273,14 @@ def AbsRunFeeder(inputWS, canWS, geom, ncan, size, avar, density, beam_width=Non # beam[7:8] hsdown,hsup bottom and top of scattered beam from sample b. beam = [beam_height, 0.5 * beam_width, -0.5 * beam_width, (beam_width / 2), -(beam_width / 2), 0.0, beam_height, 0.0, beam_height] - if sampleFormula is None and (sigs is None or siga is None): + if sample_formula is None and (sigs is None or siga is None): raise ValueError("Either a formula for the sample or values for the cross sections must be supplied.") #set sample material based on input or formula - if sampleFormula is not None: - SetSampleMaterial(InputWorkspace=inputWS, ChemicalFormula=sampleFormula, SampleNumberDensity=density[0]) + if sample_formula is not None: + SetSampleMaterial(InputWorkspace=input_ws, ChemicalFormula=sample_formula, SampleNumberDensity=density[0]) - sample = mtd[inputWS].sample() + sample = mtd[input_ws].sample() sam_mat = sample.getMaterial() # total scattering x-section @@ -288,11 +288,11 @@ def AbsRunFeeder(inputWS, canWS, geom, ncan, size, avar, density, beam_width=Non # absorption x-section siga[0] = sam_mat.absorbXSection() - if canFormula is not None and ncan == 2: + if can_formula is not None and ncan == 2: #set can material based on input or formula - SetSampleMaterial(InputWorkspace=canWS, ChemicalFormula=canFormula, SampleNumberDensity=density[1]) + SetSampleMaterial(InputWorkspace=can_ws, ChemicalFormula=can_formula, SampleNumberDensity=density[1]) - can_sample = mtd[canWS].sample() + can_sample = mtd[can_ws].sample() can_mat = can_sample.getMaterial() # total scattering x-section for can @@ -302,11 +302,11 @@ def AbsRunFeeder(inputWS, canWS, geom, ncan, size, avar, density, beam_width=Non siga[1] = can_mat.absorbXSection() siga[2] = can_mat.absorbXSection() - workspaces = AbsRun(inputWS, geom, beam, ncan, size, density, - sigs, siga, avar, Verbose, Save) + workspaces = AbsRun(input_ws, geom, beam, ncan, size, density, + sigs, siga, avar, verbose, save) EndTime('CalculateCorrections') - plotAbs(workspaces, plotOpt) + plotAbs(workspaces, plot_opt) def FlatAbs(ncan, thick, density, sigs, siga, angles, waves): @@ -444,4 +444,4 @@ def calcFlatAbsCan(ass, canXSection, canThickness1, canThickness2, sampleSec1, s acc = (acc1+acc2)/canThickness acsc = (acsc1+acsc2)/canThickness - return assc, acsc, acc \ No newline at end of file + return assc, acsc, acc diff --git a/Code/Mantid/scripts/Inelastic/IndirectDataAnalysis.py b/Code/Mantid/scripts/Inelastic/IndirectDataAnalysis.py index e827543c1c8d..36ebc9ff0a0f 100644 --- a/Code/Mantid/scripts/Inelastic/IndirectDataAnalysis.py +++ b/Code/Mantid/scripts/Inelastic/IndirectDataAnalysis.py @@ -74,7 +74,7 @@ def calculateEISF(params_table): ############################################################################## -def confitSeq(inputWS, func, startX, endX, ftype, bgd, temperature=None, specMin=0, specMax=None, Verbose=False, Plot='None', Save=False): +def confitSeq(inputWS, func, startX, endX, ftype, bgd, temperature=None, specMin=0, specMax=None, convolve=True, Verbose=False, Plot='None', Save=False): StartTime('ConvFit') bgd = bgd[:-2] @@ -91,7 +91,7 @@ def confitSeq(inputWS, func, startX, endX, ftype, bgd, temperature=None, specMin logger.notice('Fit type : Delta = ' + str(using_delta_func) + ' ; Lorentzians = ' + str(lorentzians)) logger.notice('Background type : ' + bgd) - output_workspace = getWSprefix(inputWS) + 'conv_' + ftype + bgd + '_' + str(specMin) + "_to_" + str(specMax) + output_workspace = getWSprefix(inputWS) + 'conv_' + ftype + bgd + '_s' + str(specMin) + "_to_" + str(specMax) #convert input workspace to get Q axis temp_fit_workspace = "__convfit_fit_ws" @@ -105,7 +105,7 @@ def confitSeq(inputWS, func, startX, endX, ftype, bgd, temperature=None, specMin OutputWorkspace=output_workspace, Function=func, StartX=startX, EndX=endX, FitType='Sequential', CreateOutput=True, OutputCompositeMembers=True, - ConvolveMembers=True) + ConvolveMembers=convolve) DeleteWorkspace(output_workspace + '_NormalisedCovarianceMatrices') DeleteWorkspace(output_workspace + '_Parameters') @@ -122,6 +122,7 @@ def confitSeq(inputWS, func, startX, endX, ftype, bgd, temperature=None, specMin axis.setUnit("MomentumTransfer") 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)) @@ -295,13 +296,6 @@ def elwin(inputFiles, eRange, log_type='sample', Normalise = False, else: ename = first+'to_'+last - #check if temp was increasing or decreasing - if(datTx[0] > datTx[-1]): - # if so reverse data to follow natural ordering - datTx = datTx[::-1] - datTy = datTy[::-1] - datTe = datTe[::-1] - elfWS = ename+'_elf' e1WS = ename+'_eq1' e2WS = ename+'_eq2' @@ -337,6 +331,8 @@ def elwin(inputFiles, eRange, log_type='sample', Normalise = False, CreateWorkspace(OutputWorkspace=wsname, DataX=x, DataY=y, DataE=e, Nspec=nspec, UnitX=xunit, VerticalAxisUnit=vunit, VerticalAxisValues=vvalue) + SortXAxis(InputWorkspace=wsname, OutputWorkspace=wsname) + #add sample logs to new workspace CopyLogs(InputWorkspace=tempWS, OutputWorkspace=wsname) addElwinLogs(wsname, label, eRange, Range2) @@ -537,27 +533,30 @@ def fury(samWorkspaces, res_workspace, rebinParam, RES=True, Save=False, Verbose # FuryFit ############################################################################## - -def furyfitSeq(inputWS, func, ftype, startx, endx, intensities_constrained=False, Save=False, Plot='None', Verbose=False): - +def furyfitSeq(inputWS, func, ftype, startx, endx, spec_min=0, spec_max=None, intensities_constrained=False, Save=False, Plot='None', Verbose=False): + StartTime('FuryFit') - nHist = mtd[inputWS].getNumberHistograms() - - #name stem for generated workspace - output_workspace = getWSprefix(inputWS) + 'fury_' + ftype + "0_to_" + str(nHist-1) - fitType = ftype[:-2] + fit_type = ftype[:-2] if Verbose: - logger.notice('Option: '+fitType) + logger.notice('Option: ' + fit_type) logger.notice(func) tmp_fit_workspace = "__furyfit_fit_ws" CropWorkspace(InputWorkspace=inputWS, OutputWorkspace=tmp_fit_workspace, XMin=startx, XMax=endx) + + num_hist = mtd[inputWS].getNumberHistograms() + if spec_max is None: + spec_max = num_hist - 1 + + # name stem for generated workspace + output_workspace = getWSprefix(inputWS) + 'fury_' + ftype + str(spec_min) + "_to_" + str(spec_max) + ConvertToHistogram(tmp_fit_workspace, OutputWorkspace=tmp_fit_workspace) convertToElasticQ(tmp_fit_workspace) #build input string for PlotPeakByLogValue - input_str = [tmp_fit_workspace + ',i%d' % i for i in range(0,nHist)] + input_str = [tmp_fit_workspace + ',i%d' % i for i in range(spec_min, spec_max + 1)] input_str = ';'.join(input_str) PlotPeakByLogValue(Input=input_str, OutputWorkspace=output_workspace, Function=func, @@ -582,12 +581,12 @@ def furyfitSeq(inputWS, func, ftype, startx, endx, intensities_constrained=False #process generated workspaces wsnames = mtd[fit_group].getNames() - params = [startx, endx, fitType] + params = [startx, endx, fit_type] for i, ws in enumerate(wsnames): output_ws = output_workspace + '_%d_Workspace' % i RenameWorkspace(ws, OutputWorkspace=output_ws) - - sample_logs = {'start_x': startx, 'end_x': endx, 'fit_type': ftype, + + sample_logs = {'start_x': startx, 'end_x': endx, 'fit_type': fit_type, 'intensities_constrained': intensities_constrained, 'beta_constrained': False} CopyLogs(InputWorkspace=inputWS, OutputWorkspace=fit_group) @@ -607,7 +606,7 @@ def furyfitSeq(inputWS, func, ftype, startx, endx, intensities_constrained=False return result_workspace -def furyfitMult(inputWS, function, ftype, startx, endx, intensities_constrained=False, Save=False, Plot='None', Verbose=False): +def furyfitMult(inputWS, function, ftype, startx, endx, spec_min=0, spec_max=None, intensities_constrained=False, Save=False, Plot='None', Verbose=False): StartTime('FuryFit Multi') nHist = mtd[inputWS].getNumberHistograms() @@ -620,7 +619,13 @@ def furyfitMult(inputWS, function, ftype, startx, endx, intensities_constrained= #prepare input workspace for fitting tmp_fit_workspace = "__furyfit_fit_ws" - CropWorkspace(InputWorkspace=inputWS, OutputWorkspace=tmp_fit_workspace, XMin=startx, XMax=endx) + if spec_max is None: + CropWorkspace(InputWorkspace=inputWS, OutputWorkspace=tmp_fit_workspace, XMin=startx, XMax=endx, + StartWorkspaceIndex=spec_min) + else: + CropWorkspace(InputWorkspace=inputWS, OutputWorkspace=tmp_fit_workspace, XMin=startx, XMax=endx, + StartWorkspaceIndex=spec_min, EndWorkspaceIndex=spec_max) + ConvertToHistogram(tmp_fit_workspace, OutputWorkspace=tmp_fit_workspace) convertToElasticQ(tmp_fit_workspace) @@ -868,18 +873,18 @@ def applyCorrections(inputWS, canWS, corr, rebin_can=False, Verbose=False): # Corrections are applied in Lambda (Wavelength) efixed = getEfixed(inputWS) # Get efixed + sam_name = getWSprefix(inputWS) ConvertUnits(InputWorkspace=inputWS, OutputWorkspace=inputWS, Target='Wavelength', EMode='Indirect', EFixed=efixed) nameStem = corr[:-4] - if canWS != '': + corrections = mtd[corr].getNames() + if mtd.doesExist(canWS): (instr, can_run) = getInstrRun(canWS) - corrections = [nameStem+'_ass', nameStem+'_assc', nameStem+'_acsc', nameStem+'_acc'] CorrectedWS = sam_name +'Correct_'+ can_run ConvertUnits(InputWorkspace=canWS, OutputWorkspace=canWS, Target='Wavelength', EMode='Indirect', EFixed=efixed) else: - corrections = [nameStem+'_ass'] CorrectedWS = sam_name +'Corrected' nHist = mtd[inputWS].getNumberHistograms() # Check that number of histograms in each corrections workspace matches @@ -893,6 +898,7 @@ def applyCorrections(inputWS, canWS, corr, rebin_can=False, Verbose=False): for i in range(0, nHist): # Loop through each spectra in the inputWS ExtractSingleSpectrum(InputWorkspace=inputWS, OutputWorkspace=CorrectedSampleWS, WorkspaceIndex=i) + logger.notice(str(i) + str(mtd[CorrectedSampleWS].readX(0))) if ( len(corrections) == 1 ): Ass = CubicFit(corrections[0], i, Verbose) PolynomialCorrection(InputWorkspace=CorrectedSampleWS, OutputWorkspace=CorrectedSampleWS, @@ -902,16 +908,17 @@ def applyCorrections(inputWS, canWS, corr, rebin_can=False, Verbose=False): else: ConjoinWorkspaces(InputWorkspace1=CorrectedWS, InputWorkspace2=CorrectedSampleWS) else: - ExtractSingleSpectrum(InputWorkspace=canWS, OutputWorkspace=CorrectedCanWS, - WorkspaceIndex=i) - Acc = CubicFit(corrections[3], i, Verbose) - PolynomialCorrection(InputWorkspace=CorrectedCanWS, OutputWorkspace=CorrectedCanWS, - Coefficients=Acc, Operation='Divide') - Acsc = CubicFit(corrections[2], i, Verbose) - PolynomialCorrection(InputWorkspace=CorrectedCanWS, OutputWorkspace=CorrectedCanWS, - Coefficients=Acsc, Operation='Multiply') - - subractCanWorkspace(CorrectedSampleWS, CorrectedCanWS, CorrectedSampleWS, rebin_can=rebin_can) + if mtd.doesExist(canWS): + ExtractSingleSpectrum(InputWorkspace=canWS, OutputWorkspace=CorrectedCanWS, + WorkspaceIndex=i) + Acc = CubicFit(corrections[3], i, Verbose) + PolynomialCorrection(InputWorkspace=CorrectedCanWS, OutputWorkspace=CorrectedCanWS, + Coefficients=Acc, Operation='Divide') + Acsc = CubicFit(corrections[2], i, Verbose) + PolynomialCorrection(InputWorkspace=CorrectedCanWS, OutputWorkspace=CorrectedCanWS, + Coefficients=Acsc, Operation='Multiply') + + subractCanWorkspace(CorrectedSampleWS, CorrectedCanWS, CorrectedSampleWS, rebin_can=rebin_can) Assc = CubicFit(corrections[1], i, Verbose) PolynomialCorrection(InputWorkspace=CorrectedSampleWS, OutputWorkspace=CorrectedSampleWS, @@ -931,7 +938,7 @@ def applyCorrections(inputWS, canWS, corr, rebin_can=False, Verbose=False): RenameWorkspace(InputWorkspace=CorrectedWS, OutputWorkspace=CorrectedWS+'_red') - if canWS != '': + if mtd.doesExist(canWS): ConvertUnits(InputWorkspace=canWS, OutputWorkspace=canWS, Target='DeltaE', EMode='Indirect', EFixed=efixed) @@ -948,6 +955,10 @@ def abscorFeeder(sample, container, geom, useCor, corrections, Verbose=False, Re workdir = config['defaultsave.directory'] s_hist,sxlen = CheckHistZero(sample) + CloneWorkspace(sample, OutputWorkspace='__apply_corr_cloned_sample') + sample = '__apply_corr_cloned_sample' + scaled_container = "__apply_corr_scaled_container" + diffraction_run = checkUnitIs(sample, 'dSpacing') sam_name = getWSprefix(sample) ext = '_red' @@ -966,7 +977,6 @@ def abscorFeeder(sample, container, geom, useCor, corrections, Verbose=False, Re (instr, can_run) = getInstrRun(container) - scaled_container = "__apply_corr_scaled_container" if ScaleOrNotToScale: #use temp workspace so we don't modify original data Scale(InputWorkspace=container, OutputWorkspace=scaled_container, Factor=factor, Operation='Multiply') @@ -982,11 +992,11 @@ def abscorFeeder(sample, container, geom, useCor, corrections, Verbose=False, Re if Verbose: text = 'Correcting sample ' + sample - if scaled_container != '': - text += ' with ' + scaled_container + if container != '': + text += ' with ' + container logger.notice(text) - cor_result = applyCorrections(sample, container, corrections, RebinCan, Verbose) + cor_result = applyCorrections(sample, scaled_container, corrections, RebinCan, Verbose) rws = mtd[cor_result + ext] outNm = cor_result + '_Result_' @@ -1029,7 +1039,7 @@ def abscorFeeder(sample, container, geom, useCor, corrections, Verbose=False, Re if (PlotResult != 'None'): plotCorrResult(res_plot, PlotResult) - if ( scaled_container != '' ): + if ( mtd.doesExist(scaled_container) ): sws = mtd[sample] cws = mtd[scaled_container] names = 'Sample,Can,Calc' diff --git a/Code/Mantid/scripts/Inelastic/IndirectDiffractionReduction.py b/Code/Mantid/scripts/Inelastic/IndirectDiffractionReduction.py index fafc71c22180..f41533106ec1 100644 --- a/Code/Mantid/scripts/Inelastic/IndirectDiffractionReduction.py +++ b/Code/Mantid/scripts/Inelastic/IndirectDiffractionReduction.py @@ -2,12 +2,14 @@ from msg_reducer import MSGReducer import inelastic_indirect_reduction_steps as steps + class MSGDiffractionReducer(MSGReducer): """Reducer for Diffraction on IRIS and TOSCA. """ def __init__(self): super(MSGDiffractionReducer, self).__init__() + self._grouping_policy = 'All' def _setup_steps(self): self.append_step(steps.IdentifyBadDetectors( @@ -36,11 +38,11 @@ def _setup_steps(self): self.append_step(steps.RebinToFirstSpectrum()) step = steps.Grouping() - step.set_grouping_policy("All") + step.set_grouping_policy(self._grouping_policy) self.append_step(step) # The "SaveItem" step saves the files in the requested formats. - if (len(self._save_formats) > 0): + if len(self._save_formats) > 0: step = steps.SaveItem() step.set_formats(self._save_formats) self.append_step(step) @@ -48,6 +50,17 @@ def _setup_steps(self): step = steps.Naming() self.append_step(step) + def set_grouping_policy(self, policy): + """ + Sets the grouping policy for the result data. + + @parm policy New grouping policy + """ + if not isinstance(policy, str): + raise ValueError('Grouping policy must be a string') + + self._grouping_policy = policy + def getStringProperty(workspace, property): """This function is used in the interface. diff --git a/Code/Mantid/scripts/Inelastic/IndirectEnergyConversion.py b/Code/Mantid/scripts/Inelastic/IndirectEnergyConversion.py index 71958d442408..c295b1c277de 100644 --- a/Code/Mantid/scripts/Inelastic/IndirectEnergyConversion.py +++ b/Code/Mantid/scripts/Inelastic/IndirectEnergyConversion.py @@ -50,202 +50,6 @@ def createMappingFile(groupFile, ngroup, nspec, first): handle.close() return filename -def resolution(files, iconOpt, rebinParam, bground, - instrument, analyser, reflection, - Res=True, factor=None, Plot=False, Verbose=False, Save=False): - reducer = inelastic_indirect_reducer.IndirectReducer() - reducer.set_instrument_name(instrument) - reducer.set_detector_range(iconOpt['first']-1,iconOpt['last']-1) - for file in files: - reducer.append_data_file(file) - parfile = instrument +"_"+ analyser +"_"+ reflection +"_Parameters.xml" - reducer.set_parameter_file(parfile) - reducer.set_grouping_policy('All') - reducer.set_sum_files(True) - - try: - reducer.reduce() - except Exception, e: - logger.error(str(e)) - return - - iconWS = reducer.get_result_workspaces()[0] - - if factor != None: - Scale(InputWorkspace=iconWS, OutputWorkspace=iconWS, Factor = factor) - - if Res: - name = getWSprefix(iconWS) + 'res' - CalculateFlatBackground(InputWorkspace=iconWS, OutputWorkspace=name, StartX=bground[0], EndX=bground[1], - Mode='Mean', OutputMode='Subtract Background') - Rebin(InputWorkspace=name, OutputWorkspace=name, Params=rebinParam) - - if Save: - if Verbose: - logger.notice("Resolution file saved to default save directory.") - SaveNexusProcessed(InputWorkspace=name, Filename=name+'.nxs') - - if Plot: - graph = mp.plotSpectrum(name, 0) - return name - else: - if Plot: - graph = mp.plotSpectrum(iconWS, 0) - return iconWS - -############################################################################## -# Slice Functions -############################################################################## - -def sliceReadRawFile(fname, Verbose): - - if Verbose: - logger.notice('Reading file :'+fname) - - #Load the raw file - (dir, filename) = os.path.split(fname) - (root, ext) = os.path.splitext(filename) - - Load(Filename=fname, OutputWorkspace=root, LoadLogFiles=False) - - return root - -# returns the number of monitors -# and if they're at the start or end of the file -def countMonitors(rawFile): - rawFile = mtd[rawFile] - nhist = rawFile.getNumberHistograms() - detector = rawFile.getDetector(0) - monCount = 1 - - if detector.isMonitor(): - #monitors are at the start - for i in range(1,nhist): - detector = rawFile.getDetector(i) - - if detector.isMonitor(): - monCount += 1 - else: - break - - return monCount, True - else: - #monitors are at the end - detector = rawFile.getDetector(nhist) - - if not detector.isMonitor(): - #if it's not, we don't have any monitors! - return 0, True - - for i in range(nhist,0,-1): - detector = rawFile.getDetector(i) - - if detector.isMonitor(): - monCount += 1 - else: - break - - return monCount, False - -# Run the calibration file with the raw file workspace -def sliceProcessCalib(rawFile, calibWsName, spec): - calibSpecMin, calibSpecMax = spec - - if calibSpecMax-calibSpecMin > mtd[calibWsName].getNumberHistograms(): - raise IndexError("Number of spectra used is greater than the number of spectra in the calibration file.") - - #offset cropping range to account for monitors - (monCount, atStart) = countMonitors(rawFile) - - if atStart: - calibSpecMin -= monCount+1 - calibSpecMax -= monCount+1 - - #Crop the calibration workspace, excluding the monitors - CropWorkspace(InputWorkspace=calibWsName, OutputWorkspace=calibWsName, - StartWorkspaceIndex=calibSpecMin, EndWorkspaceIndex=calibSpecMax) - -def sliceProcessRawFile(rawFile, calibWsName, useCalib, xRange, useTwoRanges, spec, suffix, Verbose): - - #Crop the raw file to use the desired number of spectra - #less one because CropWorkspace is zero based - CropWorkspace(InputWorkspace=rawFile, OutputWorkspace=rawFile, - StartWorkspaceIndex=spec[0]-1, EndWorkspaceIndex=spec[1]-1) - - nhist,ntc = CheckHistZero(rawFile) - - #use calibration file if desired - if useCalib: - Divide(LHSWorkspace=rawFile, RHSWorkspace=calibWsName, OutputWorkspace=rawFile) - - #construct output workspace name - run = mtd[rawFile].getRun().getLogData("run_number").value - sfile = rawFile[:3].lower() + run + '_' + suffix + '_slice' - - if not useTwoRanges: - Integration(InputWorkspace=rawFile, OutputWorkspace=sfile, RangeLower=xRange[0], RangeUpper=xRange[1], - StartWorkspaceIndex=0, EndWorkspaceIndex=nhist-1) - else: - CalculateFlatBackground(InputWorkspace=rawFile, OutputWorkspace=sfile, StartX=xRange[2], EndX=xRange[3], - Mode='Mean') - Integration(InputWorkspace=sfile, OutputWorkspace=sfile, RangeLower=xRange[0], RangeUpper=xRange[1], - StartWorkspaceIndex=0, EndWorkspaceIndex=nhist-1) - - return sfile - -def slice(inputfiles, calib, xRange, spec, suffix, Save=False, Verbose=False, Plot=False): - - StartTime('Slice') - - CheckXrange(xRange,'Time') - - workdir = config['defaultsave.directory'] - - outWSlist = [] - useTwoRanges = (len(xRange) != 2) - useCalib = (calib != '') - calibWsName = '__calibration' - - #load the calibration file - if useCalib: - Load(Filename=calib, OutputWorkspace=calibWsName) - if Verbose: - logger.notice('Using Calibration file: %s' % calib) - - for index, file in enumerate(inputfiles): - rawFile = sliceReadRawFile(file, Verbose) - - #only need to process the calib file once - if(index == 0 and useCalib): - sliceProcessCalib(rawFile, calibWsName, spec) - - sfile = sliceProcessRawFile(rawFile, calibWsName, useCalib, xRange, useTwoRanges, spec, suffix, Verbose) - Transpose(InputWorkspace=sfile, OutputWorkspace=sfile) - unit = mtd[sfile].getAxis(0).setUnit("Label") - unit.setLabel("Spectrum Number", "") - - outWSlist.append(sfile) - DeleteWorkspace(rawFile) - - if Save: - # path name for nxs file - o_path = os.path.join(workdir, sfile+'.nxs') - SaveNexusProcessed(InputWorkspace=sfile, Filename=o_path) - - if Verbose: - logger.notice('Output file :'+o_path) - - if useCalib: - DeleteWorkspace(Workspace=calibWsName) - - if Plot: - try: - graph = mp.plotSpectrum(sfile, 0) - except RuntimeError, e: - #User clicked cancel on plot so don't do anything - pass - - EndTime('Slice') def getInstrumentDetails(instrument): instr_name = '__empty_' + instrument @@ -310,81 +114,3 @@ def getReflectionDetails(inst, analyser, refl): except IndexError: pass return result - -############################################################################## -# Transmission -############################################################################## - -def UnwrapMon(inWS): -# Unwrap monitor - inWS contains M1,M2,S1 - outWS contains unwrapped Mon -#Unwrap s1>2 to L of S2 (M2) ie 38.76 Ouput is in wavelength - out, join = UnwrapMonitor(InputWorkspace=inWS,LRef='37.86') - outWS = 'out' -#Fill bad (dip) in spectrum - RemoveBins(InputWorkspace=outWS, OutputWorkspace=outWS, Xmin=join-0.001, Xmax=join+0.001, - Interpolation="Linear") - FFTSmooth(InputWorkspace=outWS, OutputWorkspace=outWS, WorkspaceIndex=0, IgnoreXBins=True) # Smooth - FFT - DeleteWorkspace(inWS) # delete monWS - return outWS - -def TransMon(inst, type,file,verbose): - if verbose: - logger.notice('Raw file : '+file) - LoadRaw(Filename=file,OutputWorkspace='__m1',SpectrumMin=1,SpectrumMax=1) - LoadRaw(Filename=file,OutputWorkspace='__m2',SpectrumMin=2,SpectrumMax=2) - LoadRaw(Filename=file,OutputWorkspace='__det',SpectrumMin=3,SpectrumMax=3) -# Check for single or multiple time regimes - MonTCBstart = mtd['__m1'].readX(0)[0] - SpecTCBstart = mtd['__det'].readX(0)[0] - DeleteWorkspace('__det') # delete monWS - monWS = '__Mon' - if (SpecTCBstart == MonTCBstart): - monWS = UnwrapMon('__m1') # unwrap the monitor spectrum and convert to wavelength - RenameWorkspace(InputWorkspace=monWS, OutputWorkspace='__Mon1') - else: - ConvertUnits(InputWorkspace='__m1', OutputWorkspace='__Mon1', Target="Wavelength") - ConvertUnits(InputWorkspace='__m2', OutputWorkspace='__Mon2', Target="Wavelength") - DeleteWorkspace('__m2') # delete monWS - Xin = mtd['__Mon1'].readX(0) - xmin1 = mtd['__Mon1'].readX(0)[0] - xmax1 = mtd['__Mon1'].readX(0)[len(Xin)-1] - Xin = mtd['__Mon2'].readX(0) - xmin2 = mtd['__Mon2'].readX(0)[0] - xmax2 = mtd['__Mon2'].readX(0)[len(Xin)-1] - wmin = max(xmin1,xmin2) - wmax = min(xmax1,xmax2) - CropWorkspace(InputWorkspace='__Mon1', OutputWorkspace='__Mon1', XMin=wmin, XMax=wmax) - RebinToWorkspace(WorkspaceToRebin='__Mon2', WorkspaceToMatch='__Mon1', OutputWorkspace='__Mon2') - monWS = inst +'_'+ type - Divide(LHSWorkspace='__Mon2', RHSWorkspace='__Mon1', OutputWorkspace=monWS) - DeleteWorkspace('__Mon1') # delete monWS - DeleteWorkspace('__Mon2') # delete monWS - -def TransPlot(inputWS): - tr_plot=mp.plotSpectrum(inputWS,0) - -def IndirectTrans(inst, sfile,cfile,Verbose=False,Plot=False,Save=False): - StartTime('Transmission') - TransMon(inst,'Sam',sfile,Verbose) - TransMon(inst,'Can',cfile,Verbose) - samWS = inst + '_Sam' - canWS = inst + '_Can' - trWS = inst + '_Trans' - Divide(LHSWorkspace=samWS, RHSWorkspace=canWS, OutputWorkspace=trWS) - trans = np.average(mtd[trWS].readY(0)) - transWS = inst + '_Transmission' - workdir = config['defaultsave.directory'] - group = samWS +','+ canWS +','+ trWS - GroupWorkspaces(InputWorkspaces=group,OutputWorkspace=transWS) - if Verbose: - logger.notice('Transmission : '+str(trans)) - path = os.path.join(workdir,transWS+'.nxs') - - if Save: - SaveNexusProcessed(InputWorkspace=transWS, Filename=path) - if Verbose: - logger.notice('Output file created : '+path) - - if Plot: - TransPlot(transWS) - EndTime('Transmission') diff --git a/Code/Mantid/scripts/Inelastic/IndirectJumpFit.py b/Code/Mantid/scripts/Inelastic/IndirectJumpFit.py deleted file mode 100644 index 3f8eb185f2bf..000000000000 --- a/Code/Mantid/scripts/Inelastic/IndirectJumpFit.py +++ /dev/null @@ -1,102 +0,0 @@ -from mantid.simpleapi import * -from mantid import config, logger, mtd -from IndirectCommon import * -from IndirectImport import import_mantidplot -import sys, os.path -mp = import_mantidplot() - -# Jump programs -def JumpRun(samWS,jumpFunc,width,qmin,qmax,Verbose=False,Plot=False,Save=False): - StartTime('Jump fit : '+jumpFunc+' ; ') - - workdir = getDefaultWorkingDirectory() - - #select the width we wish to fit - spectrumWs = "__" + samWS - ExtractSingleSpectrum(InputWorkspace=samWS, OutputWorkspace=spectrumWs, WorkspaceIndex=width) - - #convert to HWHM - Scale(InputWorkspace=spectrumWs, Factor=0.5, OutputWorkspace=spectrumWs) - - #crop the workspace between the given ranges - if Verbose: - logger.notice('Cropping from Q= ' + str(qmin) +' to '+ str(qmax)) - - #give the user some extra infromation if required - if Verbose: - inGR = mtd[samWS].getRun() - try: - log = inGR.getLogData('fit_program') - if log: - val = log.value - logger.notice('Fit program was : '+val) - except RuntimeError: - #if we couldn't find the fit program, just pass - pass - - logger.notice('Parameters in ' + samWS) - - x = mtd[samWS].readX(0) - xmax = x[-1] - - #select fit function to use - if jumpFunc == 'CE': - # Chudley-Elliott: HWHM=(1-sin*(Q*L)/(Q*L))/Tau - # for Q->0 W=Q^2*L^2/(6*Tau) - - tval = 1.0/xmax - lval = 1.5 - func = 'name=ChudleyElliot, Tau='+str(tval)+', L='+str(lval) - - elif jumpFunc == 'HallRoss': - # Hall-Ross: HWHM=(1-exp(-L*Q^2))/Tau - # for Q->0 W=A*Q^2*r - - tval = 1.0/xmax - lval = 1.5 - func = 'name=HallRoss, Tau='+str(tval)+', L='+str(lval) - - elif jumpFunc == 'Fick': - # Fick: HWHM=D*Q^2 - - y = mtd[samWS].readY(0) - diff = (y[2]-y[0])/((x[2]-x[0])*(x[2]-x[0])) - func = 'name=FickDiffusion, D='+str(diff) - - elif jumpFunc == 'Teixeira': - # Teixeira: HWHM=Q^2*L/((1+Q^2*L)*tau) - # for Q->0 W= - - tval = 1.0/xmax - lval = 1.5 - func = 'name=TeixeiraWater, Tau='+str(tval)+', L='+str(lval) - - else: - sys.exit("Error in Jump Fit: Invalid fit function supplied.") - return - - #run fit function - fit_workspace_base = samWS[:-10] +'_'+ jumpFunc +'fit' - Fit(Function=func, InputWorkspace=spectrumWs, CreateOutput=True, Output=fit_workspace_base, StartX=qmin, EndX=qmax) - fit_workspace = fit_workspace_base + '_Workspace' - - CopyLogs(InputWorkspace=samWS, OutputWorkspace=fit_workspace) - AddSampleLog(Workspace=fit_workspace, LogName="jump_function", LogType="String", LogText=jumpFunc) - AddSampleLog(Workspace=fit_workspace, LogName="q_min", LogType="Number", LogText=str(qmin)) - AddSampleLog(Workspace=fit_workspace, LogName="q_max", LogType="Number", LogText=str(qmax)) - - #process output options - if Save: - fit_path = os.path.join(workdir,fit_workspace+'.nxs') - SaveNexusProcessed(InputWorkspace=fit_workspace, Filename=fit_path) - - if Verbose: - logger.notice('Fit file is ' + fit_path) - - if Plot: - JumpPlot(fit_workspace) - - EndTime('Jump fit : '+jumpFunc+' ; ') - -def JumpPlot(inputWS): - mp.plotSpectrum(inputWS,[0,1,2],True) \ No newline at end of file diff --git a/Code/Mantid/scripts/Inelastic/IndirectMolDyn.py b/Code/Mantid/scripts/Inelastic/IndirectMolDyn.py deleted file mode 100644 index 3b9485f8dea2..000000000000 --- a/Code/Mantid/scripts/Inelastic/IndirectMolDyn.py +++ /dev/null @@ -1,328 +0,0 @@ -#Force for ILL backscattering raw -# -from IndirectImport import * -from mantid.simpleapi import * -from mantid import config, logger, mtd -from mantid.kernel import V3D -import sys, math, os.path, numpy as np -from IndirectCommon import StartTime, EndTime, ExtractFloat, ExtractInt -from IndirectNeutron import ChangeAngles, InstrParas, RunParas -mp = import_mantidplot() - -# Routines for Ascii file of MolDyn data - -def SplitLine(a): - elements = a.split() #split line on character - extracted = [] - for n in elements: - extracted.append(float(n)) - return extracted #values as list - -def FindDimensions(a,Verbose): - ldim = FindStarts(a,'dimensions',0) - lQ = FindTabStarts(a,'NQVALUES',0) - lT = FindTabStarts(a,'NTIMES',0) - lF = FindTabStarts(a,'NFREQUENCIES',0) - Qel = a[lQ].split() - nQ = int(Qel[2]) - Tel = a[lT].split() - nT = int(Tel[2]) - Fel = a[lF].split() - nF = int(Tel[2]) - if Verbose: - logger.notice(a[2][1:-1]) - logger.notice(a[3][1:-1]) - logger.notice(a[6][1:-1]) - return nQ,nT,nF - -def FindStarts(asc,c,l1): - for l in range(l1,len(asc)): - char = asc[l] - if char.startswith(c): - line = l - break - return line - -def FindTabStarts(asc,c,l1): - for l in range(l1,len(asc)): - char = asc[l][1:] - if char.startswith(c): - line = l - break - return line - -def FindEnds(asc,c,l1): - for l in range(l1,len(asc)): - char = asc[l] - if char.endswith(c): - line = l - break - return line - -def FindChar(asc,c,l1): - for l in range(l1,len(asc)): - char = asc[l] - if char.find(c): - line = l - break - return line - -def MakeList(a,l1,l2): - asc = '' - for m in range(l1,l2+1): - asc += a[m] - alist = asc.split(',') - return alist - -# Load an dat/cdl file -def loadFile(path): - try: - handle = open(path, 'r') - asc = [] - for line in handle: - line = line.rstrip() - asc.append(line) - handle.close() - - return asc - except: - error = 'ERROR *** Could not load ' + path - sys.exit(error) - -def MolDynImport(fname,functions,Verbose,Plot,Save): #Ascii start routine - StartTime('MolDynImport') - workdir = config['defaultsave.directory'] - - #seperate functions string and strip whitespace - functions = [x.strip() for x in functions.split(',')] - - path = fname - base = os.path.basename(path) - fname = os.path.splitext(base)[0] - - if(not os.path.isfile(path)): - path = FileFinder.getFullPath(path) - - if Verbose: - logger.notice('Functions : '+str(functions)) - logger.notice('Reading file : ' + path) - - asc = loadFile(path) - lasc = len(asc) - -# raw head - nQ,nT,nF = FindDimensions(asc,Verbose) - ldata = FindStarts(asc,'data:',0) - lq1 = FindStarts(asc,' q =',ldata) #start Q values - lq2 = FindStarts(asc,' q =',lq1-1) - Qlist = MakeList(asc,lq1,lq2) - if nQ != len(Qlist): - error = 'ERROR *** reading Q values' - logger.notice(error) - sys.exit(error) - Qf = Qlist[0].split() - Q = [float(Qf[2])/10.0] - for m in range(1,nQ-1): - Q.append(float(Qlist[m])/10.0) - Q.append(float(Qlist[nQ-1][:-1])/10.0) - if Verbose: - logger.notice('Q values = '+str(Q)) - lt1 = FindStarts(asc,' time =',lq2) #start T values - lt2 = FindEnds(asc,';',lt1) - Tlist = MakeList(asc,lt1,lt2) - if nT != len(Tlist): - error = 'ERROR *** reading Time values' - logger.notice(error) - sys.exit(error) - Tf = Tlist[0].split() - T = [float(Tf[2])] - for m in range(1,nT-1): - T.append(float(Tlist[m])) - T.append(float(Tlist[nT-1][:-1])) - T.append(2*T[nT-1]-T[nT-2]) - if Verbose: - logger.notice('T values = '+str(T[:2])+' to '+str(T[-3:])) - lf1 = FindStarts(asc,' frequency =',lq2) #start F values - lf2 = FindEnds(asc,';',lf1) - Flist = MakeList(asc,lf1,lf2) - if nF != len(Flist): - error = 'ERROR *** reading Freq values' - logger.notice(error) - sys.exit(error) - Ff = Flist[0].split() - F = [float(Ff[2])] - for m in range(1,nF-1): - F.append(float(Flist[m])) - F.append(float(Flist[nF-1][:-1])) - F.append(2*F[nF-1]-T[nF-2]) - if Verbose: - logger.notice('F values = '+str(F[:2])+' to '+str(F[-3:])) -# Function - for func in functions: - start = [] - lstart = lt2 - if func[:3] == 'Fqt': - nP = nT - xEn = np.array(T) - eZero = np.zeros(nT) - xUnit = 'TOF' - elif func[:3] == 'Sqw': - nP = nF - xEn = np.array(F) - eZero = np.zeros(nF) - xUnit = 'Energy' - else: - error = "ERROR *** Failed to parse function string " + func - sys.exit(error) - - for n in range(0,nQ): - for m in range(lstart,lasc): - char = asc[m] - if char.startswith(' // '+func): - start.append(m) - lstart = m+1 - lend = FindEnds(asc,';',lstart) - start.append(lend+1) - - #Throw error if we couldn't find the function - if(len(start) < 2): - error = "ERROR *** Failed to parse function string " + func - sys.exit(error) - -# logger.notice('Start lines : '+str(start)) - Qaxis = '' - for n in range(0,nQ): - if Verbose: - print start - logger.notice('Reading : '+asc[start[n]]) - Slist = MakeList(asc,start[n]+1,start[n+1]-1) - if n == nQ-1: - Slist[nP-1] = Slist[nP-1][:-1] - S = [] - for m in range(0,nP): - S.append(float(Slist[m])) - if nP != len(S): - error = 'ERROR *** reading S values' - logger.notice(error) - sys.exit(error) - else: - if Verbose: - logger.notice('S values = '+str(S[:2])+' to '+str(S[-2:])) - if n == 0: - Qaxis += str(Q[n]) - xDat = xEn - yDat = np.array(S) - eDat = eZero - else: - Qaxis += ','+str(Q[n]) - xDat = np.append(xDat,xEn) - yDat = np.append(yDat,np.array(S)) - eDat = np.append(eDat,eZero) - outWS = fname+'_'+func - CreateWorkspace(OutputWorkspace=outWS, DataX=xDat, DataY=yDat, DataE=eDat, - Nspec=nQ, UnitX=xUnit, VerticalAxisUnit='MomentumTransfer', VerticalAxisValues=Qaxis) - if Save: - opath = os.path.join(workdir,outWS+'.nxs') - SaveNexusProcessed(InputWorkspace=outWS, Filename=opath) - if Verbose: - logger.notice('Output file : ' + opath) - if (Plot != 'None'): - plotMolDyn(outWS,Plot) - EndTime('MolDynImport') - -def plotMolDyn(inWS,Plot): - if (Plot == 'Spectrum' or Plot == 'Both'): - nHist = mtd[inWS].getNumberHistograms() - if nHist > 10 : - nHist = 10 - plot_list = [] - for i in range(0, nHist): - plot_list.append(i) - res_plot=mp.plotSpectrum(inWS,plot_list) - if (Plot == 'Contour' or Plot == 'Both'): - cont_plot=mp.importMatrixWorkspace(inWS).plotGraph2D() - -def MolDynText(fname,Verbose,Plot,Save): #Ascii start routine - StartTime('MolDynAscii') - workdir = config['defaultsave.directory'] - - path = fname - base = os.path.basename(path) - fname = os.path.splitext(base)[0] - - if(not os.path.isfile(path)): - path = FileFinder.getFullPath(path) - - if Verbose: - logger.notice('Reading file : ' + path) - - asc = loadFile(path) - lasc = len(asc) - - val = SplitLine(asc[3]) - Q = [] - for n in range(1,len(val)): - Q.append(val[n]) - nQ = len(Q) - x = [] - y = [] - for n in range(4,lasc): - val = SplitLine(asc[n]) - x.append(val[0]) - yval = val[1:] - y.append(yval) - nX = len(x) - if Verbose: - logger.notice('nQ = '+str(nQ)) - logger.notice('nT = '+str(nX)) - xT = np.array(x) - eZero = np.zeros(nX) - Qaxis = '' - for m in range(0,nQ): - if Verbose: - logger.notice('Q['+str(m+1)+'] : '+str(Q[m])) - S = [] - for n in range(0,nX): - S.append(y[n][m]) - if m == 0: - Qaxis += str(Q[m]) - xDat = xT - yDat = np.array(S) - eDat = eZero - else: - Qaxis += ','+str(Q[m]) - xDat = np.append(xDat,xT) - yDat = np.append(yDat,np.array(S)) - eDat = np.append(eDat,eZero) - outWS = fname + '_iqt' - CreateWorkspace(OutputWorkspace=outWS, DataX=xDat, DataY=yDat, DataE=eDat, - Nspec=nQ, UnitX='TOF') -# Nspec=nQ, UnitX='TOF', VerticalAxisUnit='MomentumTransfer', VerticalAxisValues=Qaxis) - Qmax = Q[nQ-1] - instr = 'MolDyn' - ana = 'qmax' - if Qmax <= 2.0: - refl = '2' - else: - refl = '4' - InstrParas(outWS,instr,ana,refl) - efixed = RunParas(outWS,instr,fname,fname,Verbose) - if Verbose: - logger.notice('Qmax = '+str(Qmax)+' ; efixed = '+str(efixed)) - pi4 = 4.0*math.pi - wave=1.8*math.sqrt(25.2429/efixed) - theta = [] - for n in range(0,nQ): - qw = wave*Q[n]/pi4 - ang = 2.0*math.degrees(math.asin(qw)) - theta.append(ang) - ChangeAngles(outWS,instr,theta,Verbose) - if Save: - opath = os.path.join(workdir,outWS+'.nxs') - SaveNexusProcessed(InputWorkspace=outWS, Filename=opath) - if Verbose: - logger.notice('Output file : ' + opath) - if (Plot != 'None'): - plotMolDyn(outWS,Plot) - EndTime('MolDynAscii') - diff --git a/Code/Mantid/scripts/Inelastic/IndirectSymm.py b/Code/Mantid/scripts/Inelastic/IndirectSymm.py deleted file mode 100644 index 5405b44a42bf..000000000000 --- a/Code/Mantid/scripts/Inelastic/IndirectSymm.py +++ /dev/null @@ -1,98 +0,0 @@ -# SYMMetrise -# -from mantid.simpleapi import * -from mantid import config, logger, mtd -from IndirectCommon import * -from IndirectImport import import_mantidplot -import sys, platform, math, os.path, numpy as np -mp = import_mantidplot() - -def SymmRun(sample,cut,Verbose,Plot,Save): - workdir = config['defaultsave.directory'] - symWS = sample[:-3] + 'sym' - hist,npt = CheckHistZero(sample) - Xin = mtd[sample].readX(0) - delx = Xin[1]-Xin[0] - if math.fabs(cut) < 1e-5: - error = 'Cut point is Zero' - logger.notice('ERROR *** ' + error) - sys.exit(error) - for n in range(0,npt): - x = Xin[n]-cut - if math.fabs(x) < delx: - ineg = n - if ineg <= 0: - error = 'Negative point('+str(ineg)+') < 0' - logger.notice('ERROR *** ' + error) - sys.exit(error) - if ineg >= npt: - error = type + 'Negative point('+str(ineg)+') > '+str(npt) - logger.notice('ERROR *** ' + error) - sys.exit(error) - for n in range(0,npt): - x = Xin[n]+Xin[ineg] - if math.fabs(x) < delx: - ipos = n - if ipos <= 0: - error = 'Positive point('+str(ipos)+') < 0' - logger.notice('ERROR *** ' + error) - sys.exit(error) - if ipos >= npt: - error = type + 'Positive point('+str(ipos)+') > '+str(npt) - logger.notice('ERROR *** ' + error) - sys.exit(error) - ncut = npt-ipos+1 - if Verbose: - logger.notice('No. points = '+str(npt)) - logger.notice('Negative : at i ='+str(ineg)+' ; x = '+str(Xin[ineg])) - logger.notice('Positive : at i ='+str(ipos)+' ; x = '+str(Xin[ipos])) - logger.notice('Copy points = '+str(ncut)) - for m in range(0,hist): - Xin = mtd[sample].readX(m) - Yin = mtd[sample].readY(m) - Ein = mtd[sample].readE(m) - Xout = [] - Yout = [] - Eout = [] - for n in range(0,ncut): - icut = npt-n-1 - Xout.append(-Xin[icut]) - Yout.append(Yin[icut]) - Eout.append(Ein[icut]) - for n in range(ncut,npt): - Xout.append(Xin[n]) - Yout.append(Yin[n]) - Eout.append(Ein[n]) - if m == 0: - CreateWorkspace(OutputWorkspace=symWS, DataX=Xout, DataY=Yout, DataE=Eout, - Nspec=1, UnitX='DeltaE') - else: - CreateWorkspace(OutputWorkspace='__tmp', DataX=Xout, DataY=Yout, DataE=Eout, - Nspec=1, UnitX='DeltaE') - ConjoinWorkspaces(InputWorkspace1=symWS, InputWorkspace2='__tmp',CheckOverlapping=False) -# Nspec=nt, UnitX='MomentumTransfer', VerticalAxisUnit='Text', VerticalAxisValues='Taxis') -# start output - if Save: - path = os.path.join(workdir,symWS+'.nxs') - SaveNexusProcessed(InputWorkspace=symWS, Filename=path) - if Verbose: - logger.notice('Output file : ' + path) - if Plot: - plotSymm(symWS,sample) - -def SymmStart(inType,sname,cut,Verbose,Plot,Save): - StartTime('Symmetrise') - workdir = config['defaultsave.directory'] - if inType == 'File': - spath = os.path.join(workdir, sname+'.nxs') # path name for sample nxs file - LoadNexusProcessed(FileName=spath, OutputWorkspace=sname) - message = 'Input from File : '+spath - else: - message = 'Input from Workspace : '+sname - if Verbose: - logger.notice(message) - SymmRun(sname,cut,Verbose,Plot,Save) - EndTime('Symmetrise') - -def plotSymm(sym,sample): - tot_plot=mp.plotSpectrum([sym,sample],0) diff --git a/Code/Mantid/scripts/Inelastic/dgreduce.py b/Code/Mantid/scripts/Inelastic/dgreduce.py index fed605942091..df35acd037bc 100644 --- a/Code/Mantid/scripts/Inelastic/dgreduce.py +++ b/Code/Mantid/scripts/Inelastic/dgreduce.py @@ -45,7 +45,7 @@ def setup(instname=None,reload=False): def help(keyword=None) : """function returns help on reduction parameters. - Returns the list of the parameters availible if provided without arguments + Returns the list of the parameters available if provided without arguments or the description and the default value for the key requested """ if Reducer == None: @@ -54,7 +54,7 @@ def help(keyword=None) : Reducer.help(keyword) -def arb_units(wb_run,sample_run,ei_guess,rebin,map_file='default',monovan_run=None,**kwargs): +def arb_units(wb_run,sample_run,ei_guess,rebin,map_file='default',monovan_run=None,second_wb=None,**kwargs): """ One step conversion of run into workspace containing information about energy transfer Usage: >>arb_units(wb_run,sample_run,ei_guess,rebin) @@ -190,7 +190,10 @@ def arb_units(wb_run,sample_run,ei_guess,rebin,map_file='default',monovan_run=No wb_for_monovanadium = kwargs['wb_for_monovanadium'] del kwargs['wb_for_monovanadium'] else: - wb_for_monovanadium = wb_run; + if second_wb is None: + wb_for_monovanadium = wb_run; + else: + wb_for_monovanadium = second_wb; @@ -256,7 +259,7 @@ def arb_units(wb_run,sample_run,ei_guess,rebin,map_file='default',monovan_run=No #this sums the runs together before passing the summed file to the rest of the reduction #this circumvents the inbuilt method of summing which fails to sum the files for diag - #the D.E.C. tries to be too clever so we have to fool it into thinking the raw file is already exists as a workpsace + #the D.E.C. tries to be too clever so we have to fool it into thinking the raw file is already exists as a workspace sumfilename=Reducer.instr_name+str(sample_run[0])+'.raw' sample_run =sum_files(Reducer.instr_name,sumfilename, sample_run) common.apply_calibration(Reducer.instr_name,sample_run,Reducer.det_cal_file) @@ -291,7 +294,7 @@ def arb_units(wb_run,sample_run,ei_guess,rebin,map_file='default',monovan_run=No if not masks_done: print '########### Run diagnose for sample run ##############################' masking = Reducer.diagnose(wb_run,sample = mask_run, - second_white = None,print_results=True) + second_white=None,print_results=True) header = "Diag Processed workspace with {0:d} spectra and masked {1:d} bad spectra" @@ -329,7 +332,7 @@ def arb_units(wb_run,sample_run,ei_guess,rebin,map_file='default',monovan_run=No # calculate absolute units integral and apply it to the workspace if monovan_run != None or Reducer.mono_correction_factor != None : - deltaE_wkspace_sample = apply_absolute_normalization(Reducer,deltaE_wkspace_sample,monovan_run,ei_guess,wb_run) + deltaE_wkspace_sample = apply_absolute_normalization(Reducer,deltaE_wkspace_sample,monovan_run,ei_guess,wb_for_monovanadium) # Hack for multirep #if isinstance(monovan_run,int): # filename = common.find_file(monovan_run) @@ -412,7 +415,7 @@ def abs_units(wb_for_run,sample_run,monovan_run,wb_for_monovanadium,samp_rmm,sam variation -The number of medians the ratio of the first/second white beam can deviate from the average by (default=1.1) bleed_test - If true then the CreatePSDBleedMask algorithm is run - bleed_maxrate - If the bleed test is on then this is the maximum framerate allowed in a tube + bleed_maxrate - If the bleed test is on then this is the maximum frame rate allowed in a tube bleed_pixels - If the bleed test is on then this is the number of pixels ignored within the bleed test diagnostic print_results - If True then the results are printed to the screen @@ -438,11 +441,10 @@ def abs_units(wb_for_run,sample_run,monovan_run,wb_for_monovanadium,samp_rmm,sam abs_units_van_range=[-40,40] integral range for absolute vanadium data - mono_correction_factor=float User specified correction factor for absolute units normalisation + mono_correction_factor=float User specified correction factor for absolute units normalization """ kwargs['monovan_mapfile'] = monovan_mapfile - kwargs['wb_for_monovanadium']= wb_for_monovanadium kwargs['sample_mass'] = samp_mass kwargs['sample_rmm'] = samp_rmm @@ -462,7 +464,7 @@ def abs_units(wb_for_run,sample_run,monovan_run,wb_for_monovanadium,samp_rmm,sam results_name = wksp_out - wksp_out = arb_units(wb_for_run,sample_run,ei_guess,rebin,map_file,monovan_run,**kwargs) + wksp_out = arb_units(wb_for_run,sample_run,ei_guess,rebin,map_file,monovan_run,wb_for_monovanadium,**kwargs) if results_name != wksp_out.getName(): @@ -522,7 +524,7 @@ def apply_absolute_normalization(Reducer,deltaE_wkspace_sample,monovan_run,ei_gu def process_legacy_parameters(**kwargs) : """ The method to deal with old parameters which have logi c different from default and easy to process using - subprogram. All other parameters just copiet to output + subprogram. All other parameters just copied to output """ params = dict(); for key,value in kwargs.iteritems(): @@ -568,7 +570,7 @@ def get_abs_normalization_factor(Reducer,deltaE_wkspaceName,ei_monovan) : are different and accounted for by dividing each MV value by corresponding WBV value, the signal on a detector has poison distribution and the error for a detector is the square root of correspondent signal on a detector. - Error for WBV considered negligebly small wrt the error on MV + Error for WBV considered negligibly small wrt. the error on MV """ van_mass=Reducer.van_mass; @@ -627,7 +629,7 @@ def get_abs_normalization_factor(Reducer,deltaE_wkspaceName,ei_monovan) : weight = err_sq/signal signal3_sum += err_sq weight3_sum += weight - # Guess which estimatnes value sum(n_i^2/Sigma_i^2)/sum(n_i/Sigma_i^2) TGP suggestion from 12-2012 + # Guess which estimates value sum(n_i^2/Sigma_i^2)/sum(n_i/Sigma_i^2) TGP suggestion from 12-2012 signal4_sum += signal*signal/err_sq weight4_sum += signal/err_sq @@ -638,7 +640,7 @@ def get_abs_normalization_factor(Reducer,deltaE_wkspaceName,ei_monovan) : #---------------- Loop finished if( weight1_sum==0.0 or weight2_sum == 0.0 or weight3_sum == 0.0 or weight4_sum == 0.0) : - print "WB integral has been calculated incorrectrly, look at van_int workspace in the input workspace: ",deltaE_wkspaceName + print "WB integral has been calculated incorrectly, look at van_int workspace in the input workspace: ",deltaE_wkspaceName raise IOError(" divided by 0 weight") integral_monovanLibISIS=signal1_sum / weight1_sum @@ -693,7 +695,7 @@ def get_abs_normalization_factor(Reducer,deltaE_wkspaceName,ei_monovan) : def sum_files(inst_name, accumulator, files): """ Custom sum for multiple runs - Left for compartibility as internal summation had some unspecified problems. + Left for compatibility as internal summation had some unspecified problems. Will go in a future """ accum_name = accumulator diff --git a/Code/Mantid/scripts/Inelastic/inelastic_indirect_reduction_steps.py b/Code/Mantid/scripts/Inelastic/inelastic_indirect_reduction_steps.py index 1e96a4d86def..6a663d354eec 100644 --- a/Code/Mantid/scripts/Inelastic/inelastic_indirect_reduction_steps.py +++ b/Code/Mantid/scripts/Inelastic/inelastic_indirect_reduction_steps.py @@ -1,10 +1,14 @@ from reduction.reducer import ReductionStep + import mantid from mantid import config from mantid.simpleapi import * +from mantid.api import IEventWorkspace + import string import os + class LoadData(ReductionStep): """Handles the loading of the data for Indirect instruments. The summing of input workspaces is handled in this routine, as well as the identifying @@ -29,6 +33,7 @@ class LoadData(ReductionStep): _parameter_file = None _data_files = {} _extra_load_opts = {} + _contains_event_data = False def __init__(self): """Initialise the ReductionStep. Constructor should set the initial @@ -92,10 +97,16 @@ def set_ws_list(self, value): def get_ws_list(self): return self._data_files + def contains_event_data(self): + return self._contains_event_data + def _load_single_file(self, filename, output_ws): logger.notice("Loading file %s" % filename) - loader_name = self._load_data(filename, output_ws) + self._load_data(filename, output_ws) + + if type(mtd[output_ws]) is IEventWorkspace: + self._contains_event_data = True inst_name = mtd[output_ws].getInstrument().getName() if inst_name == 'BASIS': @@ -153,50 +164,58 @@ def _load_single_file(self, filename, output_ws): def _load_data(self, filename, output_ws): if self._parameter_file is not None and "VESUVIO" in self._parameter_file: loaded_ws = LoadVesuvio(Filename=filename, OutputWorkspace=output_ws, SpectrumList="1-198", **self._extra_load_opts) - loader_name = "LoadVesuvio" else: - loaded_ws = Load(Filename=filename, OutputWorkspace=output_ws, LoadLogFiles=False, **self._extra_load_opts) + # loaded_ws = Load(Filename=filename, OutputWorkspace=output_ws, LoadLogFiles=False, **self._extra_load_opts) if self._load_logs == True: loaded_ws = Load(Filename=filename, OutputWorkspace=output_ws, LoadLogFiles=True, **self._extra_load_opts) logger.notice("Loaded sample logs") else: loaded_ws = Load(Filename=filename, OutputWorkspace=output_ws, LoadLogFiles=False, **self._extra_load_opts) - loader_handle = loaded_ws.getHistory().lastAlgorithm() - loader_name = loader_handle.getPropertyValue("LoaderName") - return loader_name def _sum_regular(self, wsname): merges = [[], []] + run_numbers = [] for ws in self._data_files: merges[0].append(ws) - merges[1].append(ws+'_mon') - MergeRuns(InputWorkspaces=','.join(merges[0]),OutputWorkspace= wsname) - MergeRuns(InputWorkspaces=','.join(merges[1]),OutputWorkspace= wsname+'_mon') + merges[1].append(ws + '_mon') + run_numbers.append(str(mtd[ws].getRunNumber())) + + MergeRuns(InputWorkspaces=','.join(merges[0]), OutputWorkspace=wsname) + MergeRuns(InputWorkspaces=','.join(merges[1]), OutputWorkspace=wsname + '_mon') + + AddSampleLog(Workspace=wsname, LogName='multi_run_numbers', LogType='String', + LogText=','.join(run_numbers)) + for n in range(1, len(merges[0])): DeleteWorkspace(Workspace=merges[0][n]) DeleteWorkspace(Workspace=merges[1][n]) + factor = 1.0 / len(self._data_files) - Scale(InputWorkspace=wsname,OutputWorkspace= wsname,Factor= factor) - Scale(InputWorkspace=wsname+'_mon',OutputWorkspace= wsname+'_mon',Factor= factor) + Scale(InputWorkspace=wsname, OutputWorkspace=wsname, Factor=factor) + Scale(InputWorkspace=wsname + '_mon', OutputWorkspace=wsname + '_mon', Factor=factor) def _sum_chopped(self, wsname): merges = [] nmerges = len(mtd[wsname].getNames()) + for n in range(0, nmerges): merges.append([]) merges.append([]) + for file in self._data_files: try: - merges[2*n].append(mtd[file].getNames()[n]) - merges[2*n+1].append(mtd[file].getNames()[n]+'_mon') + merges[2 * n].append(mtd[file].getNames()[n]) + merges[2 * n + 1].append(mtd[file].getNames()[n] + '_mon') except AttributeError: if n == 0: merges[0].append(file) - merges[1].append(file+'_mon') + merges[1].append(file + '_mon') + for merge in merges: - MergeRuns(InputWorkspaces=','.join(merge),OutputWorkspace= merge[0]) + MergeRuns(InputWorkspaces=','.join(merge), OutputWorkspace=merge[0]) factor = 1.0 / len(merge) - Scale(InputWorkspace=merge[0],OutputWorkspace= merge[0],Factor= factor) + Scale(InputWorkspace=merge[0], OutputWorkspace=merge[0], Factor=factor) + for n in range(1, len(merge)): DeleteWorkspace(Workspace=merge[n]) @@ -305,146 +324,6 @@ def set_range(self, start, end): self._background_start = start self._background_end = end -class CreateCalibrationWorkspace(ReductionStep): - """Creates a calibration workspace from a White-Beam Vanadium run. - """ - - _back_min = None - _back_max = None - _peak_min = None - _peak_max = None - _detector_range_start = None - _detector_range_end = None - _calib_raw_files = [] - _calib_workspace = None - _analyser = None - _reflection = None - - def __init__(self): - super(CreateCalibrationWorkspace, self).__init__() - self._back_min = None - self._back_max = None - self._peak_min = None - self._peak_max = None - self._detector_range_start = None - self._detector_range_end = None - self._calib_raw_files = [] - self._calib_workspace = None - self._analyser = None - self._reflection = None - self._intensity_scale = None - - def execute(self, reducer, file_ws): - """The information we use here is not from the main reducer object - (ie, we are not looking at one of the data files.) - - The ApplyCalibration step is related to this. - """ - rawfiles = self._calib_raw_files - if ( len(rawfiles) == 0 ): - print "Indirect: No calibration run specified." - return - - backMin, backMax, peakMin, peakMax = self._get_calib_details() - specMin = self._detector_range_start + 1 - specMax = self._detector_range_end + 1 - - runs = [] - for file in rawfiles: - (direct, filename) = os.path.split(file) - (root, ext) = os.path.splitext(filename) - try: - Load(Filename=file,OutputWorkspace= root, SpectrumMin=specMin, SpectrumMax=specMax, - LoadLogFiles=False) - runs.append(root) - except: - sys.exit('Indirect: Could not load raw file: ' + file) - cwsn = 'calibration' - if ( len(runs) > 1 ): - MergeRuns(InputWorkspaces=",".join(runs),OutputWorkspace= cwsn) - factor = 1.0 / len(runs) - Scale(InputWorkspace=cwsn,OutputWorkspace= cwsn,Factor= factor) - else: - cwsn = runs[0] - CalculateFlatBackground(InputWorkspace=cwsn,OutputWorkspace= cwsn,StartX= backMin,EndX= backMax, Mode='Mean') - - cal_ws = mtd[cwsn] - runNo = cal_ws.getRun().getLogData("run_number").value - outWS_n = runs[0][:3] + runNo + '_' + self._analyser + self._reflection + '_calib' - - ntu = NormaliseToUnityStep() - ntu.set_factor(self._intensity_scale) - ntu.set_peak_range(peakMin, peakMax) - ntu.execute(reducer, cwsn) - - RenameWorkspace(InputWorkspace=cwsn,OutputWorkspace= outWS_n) - - # Add data about the files creation to the logs - if self._intensity_scale: - AddSampleLog(Workspace=outWS_n, LogName='Scale Factor', LogType='Number', LogText=str(self._intensity_scale)) - - AddSampleLog(Workspace=outWS_n, LogName='Peak Min', LogType='Number', LogText=str(peakMin)) - AddSampleLog(Workspace=outWS_n, LogName='Peak Max', LogType='Number', LogText=str(peakMax)) - AddSampleLog(Workspace=outWS_n, LogName='Back Min', LogType='Number', LogText=str(backMin)) - AddSampleLog(Workspace=outWS_n, LogName='Back Max', LogType='Number', LogText=str(backMax)) - - self._calib_workspace = outWS_n # Set result workspace value - if ( len(runs) > 1 ): - for run in runs: - DeleteWorkspace(Workspace=run) - - def set_parameters(self, back_min, back_max, peak_min, peak_max): - self._back_min = back_min - self._back_max = back_max - self._peak_min = peak_min - self._peak_max = peak_max - - def set_intensity_scale(self, factor): - self._intensity_scale = float(factor) - - def set_detector_range(self, start, end): - self._detector_range_start = start - self._detector_range_end = end - - def set_instrument_workspace(self, workspace): - self._instrument_workspace = workspace - - def set_files(self, files): - if len(files) > 0: - self._calib_raw_files = files - else: - raise ValueError("Indirect: Can't set calib files if you don't " - "specify a calib file.") - - def set_analyser(self, analyser): - self._analyser = str(analyser) - - def set_reflection(self, reflection): - self._reflection = str(reflection) - - def result_workspace(self): - return self._calib_workspace - - def _get_calib_details(self): - if ( self._back_min is None and - self._back_max is None and - self._peak_min is None and - self._peak_max is None ): - instrument = mtd[self._instrument_workspace].getInstrument() - try: - backMin = instrument.getNumberParameter('back-start')[0] - backMax = instrument.getNumberParameter('back-end')[0] - peakMin = instrument.getNumberParameter('peak-start')[0] - peakMax = instrument.getNumberParameter('peak-end')[0] - except IndexError: - sys.exit("Indirect: Unable to retrieve calibration details " - "from instrument of workspace.") - else: - return backMin, backMax, peakMin, peakMax - else: - return ( self._back_min, self._back_max, self._peak_min, - self._peak_max ) - class ApplyCalibration(ReductionStep): """Applies a calibration workspace to the data. """ @@ -946,25 +825,40 @@ def _group_data(self, workspace): for i in range(0, nhist): if i not in self._masking_detectors: wslist.append(i) - GroupDetectors(InputWorkspace=workspace,OutputWorkspace= workspace, - WorkspaceIndexList=wslist, Behaviour='Average') + GroupDetectors(InputWorkspace=workspace, OutputWorkspace=workspace, + WorkspaceIndexList=wslist, Behaviour='Average') else: - # Assume we have a grouping file. - # First lets, find the file... - if (os.path.isfile(grouping)): - grouping_filename = grouping - else: - grouping_filename = os.path.join(config.getString('groupingFiles.directory'), - grouping) + # We may have either a workspace name or a mapping file name here + grouping_workspace = None + grouping_filename = None - #mask detectors before grouping if we need to + # See if it a workspace in ADS + # If not assume it is a mapping file + try: + grouping_workspace = mtd[grouping] + except KeyError: + logger.notice("Cannot find group workspace " + grouping + ", attempting to find as file") + + # See if it is an absolute path + # Otherwise check in the default group files directory + if (os.path.isfile(grouping)): + grouping_filename = grouping + else: + grouping_filename = os.path.join(config.getString('groupingFiles.directory'), grouping) + + # Mask detectors before grouping if we need to if len(self._masking_detectors) > 0: MaskDetectors(workspace, WorkspaceIndexList=self._masking_detectors) - # Final check that the Mapfile exists, if not don't run the alg. - if os.path.isfile(grouping_filename): - GroupDetectors(InputWorkspace=workspace,OutputWorkspace=workspace, MapFile=grouping_filename, + # Run GroupDetectors with a workspace if we have one + # Otherwise try to run it with a mapping file + if grouping_workspace is not None: + GroupDetectors(InputWorkspace=workspace, OutputWorkspace=workspace, CopyGroupingFromWorkspace=grouping_workspace, + Behaviour='Average') + elif os.path.isfile(grouping_filename): + GroupDetectors(InputWorkspace=workspace, OutputWorkspace=workspace, MapFile=grouping_filename, Behaviour='Average') + return workspace class SaveItem(ReductionStep): @@ -976,6 +870,7 @@ class SaveItem(ReductionStep): * 'ascii' - Comma Seperated Values (file extension '.dat') * 'gss' - GSAS file format (N.B.: units will be converted to Time of Flight if not already in that unit for saving in this format). + * 'davegrp' - DAVE grouped ASCII format """ _formats = [] _save_to_cm_1 = False @@ -986,32 +881,37 @@ def __init__(self): def execute(self, reducer, file_ws): naming = Naming() - filename = naming._get_ws_name(file_ws) + filename = naming.get_ws_name(file_ws, reducer) for format in self._formats: if format == 'spe': - SaveSPE(InputWorkspace=file_ws,Filename= filename+'.spe') + SaveSPE(InputWorkspace=file_ws, Filename=filename + '.spe') elif format == 'nxs': - SaveNexusProcessed(InputWorkspace=file_ws,Filename= filename+'.nxs') + SaveNexusProcessed(InputWorkspace=file_ws, Filename=filename + '.nxs') elif format == 'nxspe': - SaveNXSPE(InputWorkspace=file_ws,Filename= filename+'.nxspe') + SaveNXSPE(InputWorkspace=file_ws, Filename=filename + '.nxspe') elif format == 'ascii': #version 1 of SaveASCII produces output that works better with excel/origin - SaveAscii(InputWorkspace=file_ws,Filename= filename+'.dat', Version=1) + SaveAscii(InputWorkspace=file_ws, Filename=filename + '.dat', Version=1) elif format == 'gss': - ConvertUnits(InputWorkspace=file_ws,OutputWorkspace= "__save_item_temp",Target= "TOF") - SaveGSS(InputWorkspace="__save_item_temp",Filename= filename+".gss") + ConvertUnits(InputWorkspace=file_ws, OutputWorkspace="__save_item_temp", Target="TOF") + SaveGSS(InputWorkspace="__save_item_temp", Filename=filename + ".gss") DeleteWorkspace(Workspace="__save_item_temp") elif format == 'aclimax': - if (self._save_to_cm_1 == False): + if self._save_to_cm_1 == False: bins = '3, -0.005, 500' #meV else: bins = '24, -0.005, 4000' #cm-1 - Rebin(InputWorkspace=file_ws,OutputWorkspace= file_ws + '_aclimax_save_temp',Params= bins) - SaveAscii(InputWorkspace=file_ws + '_aclimax_save_temp',Filename= filename+ '_aclimax.dat', Separator='Tab') + Rebin(InputWorkspace=file_ws,OutputWorkspace= file_ws + '_aclimax_save_temp', Params=bins) + SaveAscii(InputWorkspace=file_ws + '_aclimax_save_temp', Filename=filename + '_aclimax.dat', Separator='Tab') DeleteWorkspace(Workspace=file_ws + '_aclimax_save_temp') + elif format == 'davegrp': + ConvertSpectrumAxis(InputWorkspace=file_ws, OutputWorkspace=file_ws + '_davegrp_save_temp', Target='ElasticQ', EMode='Indirect') + SaveDaveGrp(InputWorkspace=file_ws + '_davegrp_save_temp', Filename=filename + '.grp') + DeleteWorkspace(Workspace=file_ws + '_davegrp_save_temp') def set_formats(self, formats): self._formats = formats + def set_save_to_cm_1(self, save_to_cm_1): self._save_to_cm_1 = save_to_cm_1 @@ -1027,15 +927,21 @@ class Naming(ReductionStep): def __init__(self): super(Naming, self).__init__() self._result_workspaces = [] + self._multi_run = False def execute(self, reducer, file_ws): + self._multi_run = reducer._sum wsname = self._get_ws_name(file_ws) - RenameWorkspace(InputWorkspace=file_ws,OutputWorkspace= wsname) + RenameWorkspace(InputWorkspace=file_ws, OutputWorkspace=wsname) self._result_workspaces.append(wsname) def get_result_workspaces(self): return self._result_workspaces + def get_ws_name(self, workspace, reducer): + self._multi_run = reducer._sum + return self._get_ws_name(workspace) + def _get_ws_name(self, workspace): try: type = mtd[workspace].getInstrument().getStringParameter( @@ -1043,9 +949,9 @@ def _get_ws_name(self, workspace): except IndexError: type = 'RunTitle' - if ( type == 'AnalyserReflection' ): + if type == 'AnalyserReflection': return self._analyser_reflection(workspace) - elif ( type == 'RunTitle' ): + elif type == 'RunTitle': return self._run_title(workspace) else: raise NotImplementedError('Unknown \'Workflow.NamingConvention\'' @@ -1055,6 +961,8 @@ def _run_title(self, workspace): ws = mtd[workspace] title = ws.getRun()['run_title'].value.strip() runNo = ws.getRun()['run_number'].value + if self._multi_run: + runNo += '_multi' inst = ws.getInstrument().getName() isn = config.getFacility().instrument(inst).shortName().upper() valid = "-_.() %s%s" % (string.ascii_letters, string.digits) @@ -1066,14 +974,32 @@ def _analyser_reflection(self, workspace): if workspace == '': return '' ws = mtd[workspace] - ins = ws.getInstrument().getName() - ins = config.getFacility().instrument(ins).shortName().lower() + inst = ws.getInstrument().getName() + + short_name = '' + try: + short_name = config.getFacility().instrument(inst).shortName().lower() + except RuntimeError: + original_facility = config['default.facility'] + for facility in config.getFacilities(): + config['default.facility'] = facility.name() + try: + short_name = config.getFacility().instrument(inst).shortName().lower() + except RuntimeError: + pass + config['default.facility'] = original_facility + + if short_name == '': + raise RuntimeError('Cannot find instrument "%s" in any facility' % str(inst)) + run = ws.getRun().getLogData('run_number').value + if self._multi_run: + run += '_multi' try: analyser = ws.getInstrument().getStringParameter('analyser')[0] reflection = ws.getInstrument().getStringParameter('reflection')[0] except IndexError: analyser = '' reflection = '' - prefix = ins + run + '_' + analyser + reflection + '_red' + prefix = short_name + run + '_' + analyser + reflection + '_red' return prefix diff --git a/Code/Mantid/scripts/Inelastic/msg_reducer.py b/Code/Mantid/scripts/Inelastic/msg_reducer.py index e6eefd45d9bc..2f06d44cee44 100644 --- a/Code/Mantid/scripts/Inelastic/msg_reducer.py +++ b/Code/Mantid/scripts/Inelastic/msg_reducer.py @@ -3,7 +3,7 @@ import os.path from mantid.simpleapi import * -from mantid.kernel import config +from mantid.kernel import config, logger import reduction.reducer as reducer import inelastic_indirect_reduction_steps as steps @@ -42,6 +42,9 @@ def pre_process(self): loadData.set_parameter_file(self._parameter_file) loadData.set_extra_load_opts(self._extra_load_opts) loadData.execute(self, None) + + if loadData.contains_event_data and (self._rebin_string is None or self._rebin_string is ''): + logger.warning('Reductins of event data without rebinning may give bad data!') self._multiple_frames = loadData.is_multiple_frames() @@ -104,8 +107,11 @@ def set_parameter_file(self, file_name): Note: This is *not* the base parameter file, ie "IRIS_Parameters.xml" but, rather, the additional parameter file. """ - self._parameter_file = \ - os.path.join(config["parameterDefinition.directory"], file_name) + self._parameter_file = file_name + for directory in config.getInstrumentDirectories(): + if os.path.isfile(os.path.join(directory, file_name)): + self._parameter_file = os.path.join(directory, file_name) + return def set_rebin_string(self, rebin): """Sets the rebin string to be used with the Rebin algorithm. diff --git a/Code/Mantid/scripts/Interface/reduction_gui/instruments/interface.py b/Code/Mantid/scripts/Interface/reduction_gui/instruments/interface.py index b74e941e2bd8..5d4c44518e9e 100644 --- a/Code/Mantid/scripts/Interface/reduction_gui/instruments/interface.py +++ b/Code/Mantid/scripts/Interface/reduction_gui/instruments/interface.py @@ -88,7 +88,7 @@ def load_file(self, file_name): populate the UI with them @param file_name: XML file to be loaded """ - if self.scripter.check_xml_compatibility(file_name, 'Instrument'): + if self.scripter.check_xml_compatibility(file_name, 'mantid_version'): self.scripter.from_xml(file_name) self.scripter.push_state() elif self.scripter.check_xml_compatibility(file_name, 'SetupInfo'): diff --git a/Code/Mantid/scripts/Interface/reduction_gui/reduction/sans/hfir_options_script.py b/Code/Mantid/scripts/Interface/reduction_gui/reduction/sans/hfir_options_script.py index 2e417b07acb1..32ad19dd2778 100644 --- a/Code/Mantid/scripts/Interface/reduction_gui/reduction/sans/hfir_options_script.py +++ b/Code/Mantid/scripts/Interface/reduction_gui/reduction/sans/hfir_options_script.py @@ -38,6 +38,9 @@ class ReductionOptions(BaseScriptElement): n_q_bins = 100 n_sub_pix = 1 log_binning = False + + # Mask side + masked_side = None # Masking class RectangleMask(object): @@ -116,6 +119,9 @@ def to_script(self): script += "IQxQy(nbins=%g)\n" % self.n_q_bins # Mask + # Detector plane + if self.masked_side is not None: + script += "MaskDetectorSide('%s')\n" % str(self.masked_side) # Edges if (self.top != 0 or self.bottom != 0 or self.left != 0 or self.right != 0): script += "Mask(nx_low=%d, nx_high=%d, ny_low=%d, ny_high=%d)\n" % (self.left, self.right, self.bottom, self.top) @@ -182,6 +188,8 @@ def to_xml(self): xml += " %g\n" % self.bottom xml += " %g\n" % self.left xml += " %g\n" % self.right + + xml += " %s\n" % str(self.masked_side) xml += " \n" for item in self.shapes: @@ -265,6 +273,8 @@ def from_xml(self, xml_str): self.right = BaseScriptElement.getIntElement(mask_dom, "mask_right", default=ReductionOptions.right) self.left = BaseScriptElement.getIntElement(mask_dom, "mask_left", default=ReductionOptions.left) + self.masked_side = BaseScriptElement.getStringElement(mask_dom, "mask_side", default=ReductionOptions.masked_side) + self.shapes = [] shapes_dom_list = mask_dom.getElementsByTagName("Shapes") if len(shapes_dom_list)>0: @@ -409,6 +419,7 @@ def reset(self): self.detector_ids = [] self.mask_file = '' self.use_mask_file = ReductionOptions.use_mask_file + self.masked_side = None self.use_data_directory = ReductionOptions.use_data_directory self.output_directory = ReductionOptions.output_directory diff --git a/Code/Mantid/scripts/Interface/reduction_gui/widgets/reflectometer/base_ref_reduction.py b/Code/Mantid/scripts/Interface/reduction_gui/widgets/reflectometer/base_ref_reduction.py index 2fbdd9a26918..f8105395e8d8 100644 --- a/Code/Mantid/scripts/Interface/reduction_gui/widgets/reflectometer/base_ref_reduction.py +++ b/Code/Mantid/scripts/Interface/reduction_gui/widgets/reflectometer/base_ref_reduction.py @@ -973,7 +973,7 @@ def _plot_count_vs_y(self, is_peak=True): For REFM, this is X For REFL, this is Y """ - + # run_number = self._summary.data_run_number_edit.text() # f = FileFinder.findRuns("%s%s" % (self.instrument_name, str(run_number)))[0] # @@ -1246,7 +1246,8 @@ def call_back(xmin, xmax): max_ctrl.setText("%-d" % int(xmax)) # For REFL, Y is high-res - is_pixel_y = is_high_res + + is_pixel_y = is_high_res # For REFM it's the other way around if self.short_name == "REFM": is_pixel_y = not is_pixel_y diff --git a/Code/Mantid/scripts/Interface/reduction_gui/widgets/reflectometer/refm_reduction.py b/Code/Mantid/scripts/Interface/reduction_gui/widgets/reflectometer/refm_reduction.py index ecc838d6552e..062c0497128a 100644 --- a/Code/Mantid/scripts/Interface/reduction_gui/widgets/reflectometer/refm_reduction.py +++ b/Code/Mantid/scripts/Interface/reduction_gui/widgets/reflectometer/refm_reduction.py @@ -973,7 +973,7 @@ def _plot_data_count_vs_tof_2d(self): import mantidqtpython self.ref_det_view = mantidqtpython.MantidQt.RefDetectorViewer.RefMatrixWSImageView(ws_output_base_ff+'_2D', peak_min, peak_max, back_min, back_max, tof_min, tof_max) - QtCore.QObject.connect(self.ref_det_view.getConnections(), QtCore.SIGNAL("peak_back_tof_range_update(double,double, double,double,double,double)"), self.call_back) + QtCore.QObject.connect(self.ref_det_view.getConnections(), QtCore.SIGNAL("peakBackTofRangeUpdate(double,double,double,double,double,double)"), self.call_back) def call_back(self, peakmin, peakmax, backmin, backmax, tofmin, tofmax): self._summary.data_peak_from_pixel.setText("%-d" % int(peakmin)) diff --git a/Code/Mantid/scripts/Interface/reduction_gui/widgets/sans/hfir_instrument.py b/Code/Mantid/scripts/Interface/reduction_gui/widgets/sans/hfir_instrument.py index 32b5983d9cae..4f44d963b0f7 100644 --- a/Code/Mantid/scripts/Interface/reduction_gui/widgets/sans/hfir_instrument.py +++ b/Code/Mantid/scripts/Interface/reduction_gui/widgets/sans/hfir_instrument.py @@ -138,6 +138,14 @@ def initialize_content(self): self.connect(self._summary.scale_chk, QtCore.SIGNAL("clicked(bool)"), self._scale_clicked) self._scale_clicked(self._summary.scale_chk.isChecked()) + # If we are not in debug/expert mode, hide some advanced options + if not self._settings.debug: + self._summary.mask_side_layout.deleteLater() + self._summary.mask_side_label.hide() + self._summary.mask_side_none_radio.hide() + self._summary.mask_side_front_radio.hide() + self._summary.mask_side_back_radio.hide() + if not self._in_mantidplot: self._summary.dark_plot_button.hide() self._summary.scale_data_plot_button.hide() @@ -340,6 +348,13 @@ def set_state(self, state): self._mask_checked(state.use_mask_file) self._masked_detectors = state.detector_ids self.mask_reload = True + + if state.masked_side == 'Front': + self._summary.mask_side_front_radio.setChecked(True) + elif state.masked_side == 'Back': + self._summary.mask_side_back_radio.setChecked(True) + else: + self._summary.mask_side_none_radio.setChecked(True) def _prepare_field(self, is_enabled, stored_value, chk_widget, edit_widget, suppl_value=None, suppl_edit=None): #to_display = str(stored_value) if is_enabled else '' @@ -400,6 +415,14 @@ def get_state(self): m.n_sub_pix = util._check_and_get_int_line_edit(self._summary.n_sub_pix_edit) m.log_binning = self._summary.log_binning_radio.isChecked() + # Detector side masking + if self._summary.mask_side_front_radio.isChecked(): + m.masked_side = 'Front' + elif self._summary.mask_side_back_radio.isChecked(): + m.masked_side = 'Back' + else: + m.masked_side = None + # Mask detector IDs m.use_mask_file = self._summary.mask_check.isChecked() m.mask_file = unicode(self._summary.mask_edit.text()) diff --git a/Code/Mantid/scripts/Interface/ui/reflectometer/refl_gui.py b/Code/Mantid/scripts/Interface/ui/reflectometer/refl_gui.py index 6367428a0459..ac2edbe01814 100644 --- a/Code/Mantid/scripts/Interface/ui/reflectometer/refl_gui.py +++ b/Code/Mantid/scripts/Interface/ui/reflectometer/refl_gui.py @@ -65,6 +65,7 @@ def __init__(self): self.__column_settings = "Mantid/ISISReflGui/Columns" self.__icat_download_key = "icat_download" self.__ads_use_key = "AlgUse" + self.__alg_migration_key="AlgUseReset" self.__live_data_frequency_key = "frequency" self.__live_data_method_key = "method" self.__group_tof_workspaces_key = "group_tof_workspaces" @@ -92,13 +93,20 @@ def __init__(self): settings.beginGroup(self.__generic_settings) - self.alg_use = settings.value(self.__ads_use_key, False, type=bool) + self.__alg_migrate = settings.value(self.__alg_migration_key, True, type=bool) + if self.__alg_migrate: + self.__alg_use = True # We will use the algorithms by default rather than the quick scripts + self.__alg_migrate = False # Never do this again. We only want to reset once. + else: + self.__alg_use = settings.value(self.__ads_use_key, True, type=bool) + self.__icat_download = settings.value(self.__icat_download_key, False, type=bool) self.__group_tof_workspaces = settings.value(self.__group_tof_workspaces_key, True, type=bool) - settings.setValue(self.__ads_use_key, self.alg_use) + settings.setValue(self.__ads_use_key, self.__alg_use) settings.setValue(self.__icat_download_key, self.__icat_download) settings.setValue(self.__group_tof_workspaces_key, self.__group_tof_workspaces) + settings.setValue(self.__alg_migration_key, self.__alg_migrate) settings.endGroup() @@ -953,7 +961,7 @@ def _do_run(self, runno, row, which): else: raise RuntimeError("Up to 2 transmission runs can be specified. No more than that.") - if self.alg_use: + if self.__alg_use: #Load the runs required ConvertToWavelength will deal with the transmission runs, while .to_workspace will deal with the run itself ws = ConvertToWavelength.to_workspace(loadedRun, ws_prefix="") @@ -977,6 +985,8 @@ def _do_run(self, runno, row, which): if ',' in runno: runno = runno.split(',')[0] inst = wq.getInstrument() + #NOTE: In the new Refl UI, these adjustments to lmin/lmax are NOT made. This has been + #noted in the parameter files for INTER/CRIST/POLREF/SURF. lmin = inst.getNumberParameter('LambdaMin')[0] + 1 lmax = inst.getNumberParameter('LambdaMax')[0] - 2 qmin = 4 * math.pi / lmax * math.sin(th * math.pi / 180) @@ -1150,14 +1160,14 @@ def _options_dialog(self): try: dialog_controller = refl_options.ReflOptions(def_method = self.live_method, def_freq = self.live_freq, - def_alg_use = self.alg_use, def_icat_download=self.__icat_download, + def_alg_use = self.__alg_use, def_icat_download=self.__icat_download, def_group_tof_workspaces = self.__group_tof_workspaces) if dialog_controller.exec_(): # Fetch the settings back off the controller self.live_freq = dialog_controller.frequency() self.live_method = dialog_controller.method() - self.alg_use = dialog_controller.useAlg() + self.__alg_use = dialog_controller.useAlg() self.__icat_download = dialog_controller.icatDownload() self.__group_tof_workspaces = dialog_controller.groupTOFWorkspaces() @@ -1168,7 +1178,7 @@ def _options_dialog(self): settings.setValue(self.__live_data_method_key, self.live_method) settings.endGroup() settings.beginGroup(self.__generic_settings) - settings.setValue(self.__ads_use_key, self.alg_use) + settings.setValue(self.__ads_use_key, self.__alg_use) settings.setValue(self.__icat_download_key, self.__icat_download) settings.setValue(self.__group_tof_workspaces_key, self.__group_tof_workspaces) settings.endGroup() diff --git a/Code/Mantid/scripts/Interface/ui/sans/hfir_instrument.ui b/Code/Mantid/scripts/Interface/ui/sans/hfir_instrument.ui index 68d7d79351d6..3ec86accdd4a 100644 --- a/Code/Mantid/scripts/Interface/ui/sans/hfir_instrument.ui +++ b/Code/Mantid/scripts/Interface/ui/sans/hfir_instrument.ui @@ -1052,6 +1052,72 @@ Values can be selected by hand by checking the boxes below. + + + + + + + 0 + 0 + + + + + 150 + 0 + + + + Mask detector side + + + + + + + Select to keep both sides of the detector active [default]. + + + None + + + + + + + Select to mask the front panel of the detector. + + + Front + + + + + + + Select to mask the back panel of the detector. + + + Back + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + diff --git a/Code/Mantid/scripts/Interface/ui/sans/ui_hfir_instrument.py b/Code/Mantid/scripts/Interface/ui/sans/ui_hfir_instrument.py index d9193459baae..93b22de1ce87 100644 --- a/Code/Mantid/scripts/Interface/ui/sans/ui_hfir_instrument.py +++ b/Code/Mantid/scripts/Interface/ui/sans/ui_hfir_instrument.py @@ -2,7 +2,7 @@ # Form implementation generated from reading ui file 'ui/sans/hfir_instrument.ui' # -# Created: Thu Jun 27 16:46:08 2013 +# Created: Fri Oct 10 11:46:57 2014 # by: PyQt4 UI code generator 4.7.4 # # WARNING! All changes made in this file will be lost! @@ -398,6 +398,29 @@ def setupUi(self, Frame): self.verticalLayout_2.setObjectName("verticalLayout_2") self.verticalLayout_3 = QtGui.QVBoxLayout() self.verticalLayout_3.setObjectName("verticalLayout_3") + self.mask_side_layout = QtGui.QHBoxLayout() + self.mask_side_layout.setObjectName("mask_side_layout") + self.mask_side_label = QtGui.QLabel(self.groupBox) + sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Preferred, QtGui.QSizePolicy.Preferred) + sizePolicy.setHorizontalStretch(0) + sizePolicy.setVerticalStretch(0) + sizePolicy.setHeightForWidth(self.mask_side_label.sizePolicy().hasHeightForWidth()) + self.mask_side_label.setSizePolicy(sizePolicy) + self.mask_side_label.setMinimumSize(QtCore.QSize(150, 0)) + self.mask_side_label.setObjectName("mask_side_label") + self.mask_side_layout.addWidget(self.mask_side_label) + self.mask_side_none_radio = QtGui.QRadioButton(self.groupBox) + self.mask_side_none_radio.setObjectName("mask_side_none_radio") + self.mask_side_layout.addWidget(self.mask_side_none_radio) + self.mask_side_front_radio = QtGui.QRadioButton(self.groupBox) + self.mask_side_front_radio.setObjectName("mask_side_front_radio") + self.mask_side_layout.addWidget(self.mask_side_front_radio) + self.mask_side_back_radio = QtGui.QRadioButton(self.groupBox) + self.mask_side_back_radio.setObjectName("mask_side_back_radio") + self.mask_side_layout.addWidget(self.mask_side_back_radio) + spacerItem9 = QtGui.QSpacerItem(40, 20, QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Minimum) + self.mask_side_layout.addItem(spacerItem9) + self.verticalLayout_3.addLayout(self.mask_side_layout) self.label_5 = QtGui.QLabel(self.groupBox) font = QtGui.QFont() font.setFamily("Bitstream Charter") @@ -428,13 +451,13 @@ def setupUi(self, Frame): self.mask_plot_button = QtGui.QPushButton(self.groupBox) self.mask_plot_button.setObjectName("mask_plot_button") self.horizontalLayout.addWidget(self.mask_plot_button) - spacerItem9 = QtGui.QSpacerItem(40, 20, QtGui.QSizePolicy.Fixed, QtGui.QSizePolicy.Minimum) - self.horizontalLayout.addItem(spacerItem9) + spacerItem10 = QtGui.QSpacerItem(40, 20, QtGui.QSizePolicy.Fixed, QtGui.QSizePolicy.Minimum) + self.horizontalLayout.addItem(spacerItem10) self.verticalLayout_3.addLayout(self.horizontalLayout) self.verticalLayout_2.addLayout(self.verticalLayout_3) self.verticalLayout_4.addWidget(self.groupBox) - spacerItem10 = QtGui.QSpacerItem(20, 40, QtGui.QSizePolicy.Minimum, QtGui.QSizePolicy.Expanding) - self.verticalLayout_4.addItem(spacerItem10) + spacerItem11 = QtGui.QSpacerItem(20, 40, QtGui.QSizePolicy.Minimum, QtGui.QSizePolicy.Expanding) + self.verticalLayout_4.addItem(spacerItem11) self.scrollArea.setWidget(self.scrollAreaWidgetContents) self.verticalLayout.addWidget(self.scrollArea) @@ -501,6 +524,13 @@ def retranslateUi(self, Frame): self.label_10.setText(QtGui.QApplication.translate("Frame", "Wavelength spread [ratio]", None, QtGui.QApplication.UnicodeUTF8)) self.wavelength_spread_edit.setToolTip(QtGui.QApplication.translate("Frame", "Enter the value of the neutron wavelength spread.", None, QtGui.QApplication.UnicodeUTF8)) self.groupBox.setTitle(QtGui.QApplication.translate("Frame", "Mask", None, QtGui.QApplication.UnicodeUTF8)) + self.mask_side_label.setText(QtGui.QApplication.translate("Frame", "Mask detector side", None, QtGui.QApplication.UnicodeUTF8)) + self.mask_side_none_radio.setToolTip(QtGui.QApplication.translate("Frame", "Select to keep both sides of the detector active [default].", None, QtGui.QApplication.UnicodeUTF8)) + self.mask_side_none_radio.setText(QtGui.QApplication.translate("Frame", "None", None, QtGui.QApplication.UnicodeUTF8)) + self.mask_side_front_radio.setToolTip(QtGui.QApplication.translate("Frame", "Select to mask the front panel of the detector.", None, QtGui.QApplication.UnicodeUTF8)) + self.mask_side_front_radio.setText(QtGui.QApplication.translate("Frame", "Front", None, QtGui.QApplication.UnicodeUTF8)) + self.mask_side_back_radio.setToolTip(QtGui.QApplication.translate("Frame", "Select to mask the back panel of the detector.", None, QtGui.QApplication.UnicodeUTF8)) + self.mask_side_back_radio.setText(QtGui.QApplication.translate("Frame", "Back", None, QtGui.QApplication.UnicodeUTF8)) self.label_5.setText(QtGui.QApplication.translate("Frame", "Choose a file to set your mask. Note that only the mask information, not the data, will be used in the reduction.\n" "The data is only used to help you setting the mask.\n" "The mask information is saved separately so that your data file will NOT be modified.", None, QtGui.QApplication.UnicodeUTF8)) diff --git a/Code/Mantid/scripts/LargeScaleStructures/REFL_Detector_Grouping_Sum_X_rot.xml b/Code/Mantid/scripts/LargeScaleStructures/REFL_Detector_Grouping_Sum_X_rot.xml new file mode 100644 index 000000000000..3a884fe2a035 --- /dev/null +++ b/Code/Mantid/scripts/LargeScaleStructures/REFL_Detector_Grouping_Sum_X_rot.xml @@ -0,0 +1,914 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Code/Mantid/scripts/LargeScaleStructures/REFL_Detector_Grouping_Sum_Y_rot.xml b/Code/Mantid/scripts/LargeScaleStructures/REFL_Detector_Grouping_Sum_Y_rot.xml new file mode 100644 index 000000000000..d159bb2edfd9 --- /dev/null +++ b/Code/Mantid/scripts/LargeScaleStructures/REFL_Detector_Grouping_Sum_Y_rot.xml @@ -0,0 +1,770 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Code/Mantid/scripts/LargeScaleStructures/REF_L_geometry.py b/Code/Mantid/scripts/LargeScaleStructures/REF_L_geometry.py index 6d3d4025dd4f..f0beaa1ca094 100644 --- a/Code/Mantid/scripts/LargeScaleStructures/REF_L_geometry.py +++ b/Code/Mantid/scripts/LargeScaleStructures/REF_L_geometry.py @@ -1,27 +1,29 @@ from geometry_writer import MantidGeom import math -NUM_PIXELS_PER_TUBE = 256 -NUM_TUBES = 304 +NUM_PIXELS_PER_TUBE = 304 +NUM_TUBES = 256 PIXEL_WIDTH = 0.0007 PIXEL_HEIGHT = 0.0007 def create_grouping(workspace=None): # This should be read from the - npix_x = 304 - npix_y = 256 + npix_x = 256 + npix_y = 304 + + ## Integrated over X if workspace is not None: if mtd[workspace].getInstrument().hasParameter("number-of-x-pixels"): npix_x = int(mtd[workspace].getInstrument().getNumberParameter("number-of-x-pixels")[0]) if mtd[workspace].getInstrument().hasParameter("number-of-y-pixels"): npix_y = int(mtd[workspace].getInstrument().getNumberParameter("number-of-y-pixels")[0]) - f = open("REFL_Detector_Grouping_Sum_X.xml",'w') + f = open("REFL_Detector_Grouping_Sum_X_rot.xml",'w') f.write("\n") for y in range(npix_y): # index = max_y * x + y - indices = range(y, npix_x*(npix_y-1), npix_y) + indices = range(y, npix_x*(npix_y), npix_y) # Detector IDs start at zero, but spectrum numbers start at 1 # Grouping works on spectrum numbers @@ -34,6 +36,26 @@ def create_grouping(workspace=None): f.write("\n") f.close() + ## Integrated over Y + f = open("REFL_Detector_Grouping_Sum_Y_rot.xml",'w') + f.write("\n") + + for x in range(npix_x): + # index = max_y * x + y + indices = range(x*npix_y,(x+1)*npix_y) + + # Detector IDs start at zero, but spectrum numbers start at 1 + # Grouping works on spectrum numbers + indices_lst = [str(i+1) for i in indices] + indices_str = ','.join(indices_lst) + f.write(" \n" % 303) + f.write(" \n" % indices_str) + f.write(" \n") + + f.write("\n") + f.close() + + def create_geometry(file_name=None, pixel_width=None, pixel_height=None): inst_name = "REF_L" short_name = "REF_L" @@ -77,4 +99,5 @@ def create_geometry(file_name=None, pixel_width=None, pixel_height=None): det.writeGeom(xml_outfile) if __name__ == "__main__": - create_geometry() \ No newline at end of file + #create_geometry() + create_grouping() \ No newline at end of file diff --git a/Code/Mantid/scripts/LargeScaleStructures/ScalingFactorCalculation/sfCalculator.py b/Code/Mantid/scripts/LargeScaleStructures/ScalingFactorCalculation/sfCalculator.py index 288c12a68457..8fc284bffaec 100644 --- a/Code/Mantid/scripts/LargeScaleStructures/ScalingFactorCalculation/sfCalculator.py +++ b/Code/Mantid/scripts/LargeScaleStructures/ScalingFactorCalculation/sfCalculator.py @@ -146,9 +146,17 @@ def _calculateFinalYAxis(self, bNumerator=True): self.back_pixel_max = self.d_back_pixel_max nexus_file_numerator = file - LoadEventNexus(Filename=nexus_file_numerator, - OutputWorkspace='EventDataWks') + ws_event_data = LoadEventNexus(Filename=nexus_file_numerator, + OutputWorkspace='EventDataWks') mt1 = mtd['EventDataWks'] + + is_nexus_detector_rotated_flag = wks_utility.isNexusTakeAfterRefDate(ws_event_data.getRun().getProperty('run_start').value) + if is_nexus_detector_rotated_flag: + self.alpha_pixel_nbr = 304 + self.beta_pixel_nbr = 256 + else: + self.alpha_pixel_nbr = 256 + self.beta_pixel_nbr = 304 proton_charge = self._getProtonCharge(mt1) rebin(InputWorkspace='EventDataWks', diff --git a/Code/Mantid/scripts/SANS/ISISCommandInterface.py b/Code/Mantid/scripts/SANS/ISISCommandInterface.py index c94dcc85e0bb..f3cd45cac67a 100644 --- a/Code/Mantid/scripts/SANS/ISISCommandInterface.py +++ b/Code/Mantid/scripts/SANS/ISISCommandInterface.py @@ -560,56 +560,56 @@ def _fitRescaleAndShift(rAnds, frontData, rearData): Fit rear data to FRONTnew(Q) = ( FRONT(Q) + SHIFT )xRESCALE, FRONT(Q) is the frontData argument. Returns scale and shift + Note SHIFT is shift of a constant back, not the Shift parameter in + TabulatedFunction. + @param rAnds: A DetectorBank -> _RescaleAndShift structure @param frontData: Reduced front data @param rearData: Reduced rear data """ if rAnds.fitScale==False and rAnds.fitShift==False: return rAnds.scale, rAnds.shift - #TODO: we should allow the user to add constraints? + if rAnds.fitScale==False: if rAnds.qRangeUserSelected: Fit(InputWorkspace=rearData, Function='name=TabulatedFunction, Workspace="'+str(frontData)+'"' - +";name=FlatBackground", Ties='f0.Scaling='+str(rAnds.scale), + +";name=FlatBackground", + Ties='f0.Scaling='+str(rAnds.scale)+',f0.Shift=0.0', Output="__fitRescaleAndShift", StartX=rAnds.qMin, EndX=rAnds.qMax) else: Fit(InputWorkspace=rearData, Function='name=TabulatedFunction, Workspace="'+str(frontData)+'"' - +";name=FlatBackground", Ties='f0.Scaling='+str(rAnds.scale), + +";name=FlatBackground", + Ties='f0.Scaling='+str(rAnds.scale)+',f0.Shift=0.0', Output="__fitRescaleAndShift") elif rAnds.fitShift==False: if rAnds.qRangeUserSelected: - function_input = 'name=TabulatedFunction, Workspace="'+str(frontData)+'"' +";name=FlatBackground" - ties = 'f1.A0='+str(rAnds.shift*rAnds.scale) - logger.warning('function input ' + str(function_input)) - Fit(InputWorkspace=rearData, Function='name=TabulatedFunction, Workspace="'+str(frontData)+'"' - +";name=FlatBackground", Ties='f1.A0='+str(rAnds.shift*rAnds.scale), + +";name=FlatBackground", + Ties='f1.A0='+str(rAnds.shift*rAnds.scale)+',f0.Shift=0.0', Output="__fitRescaleAndShift", StartX=rAnds.qMin, EndX=rAnds.qMax) else: Fit(InputWorkspace=rearData, Function='name=TabulatedFunction, Workspace="'+str(frontData)+'"' - +";name=FlatBackground", Ties='f1.A0='+str(rAnds.shift*rAnds.scale), + +";name=FlatBackground", + Ties='f1.A0='+str(rAnds.shift*rAnds.scale)+',f0.Shift=0.0', Output="__fitRescaleAndShift") else: if rAnds.qRangeUserSelected: Fit(InputWorkspace=rearData, Function='name=TabulatedFunction, Workspace="'+str(frontData)+'"' - +";name=FlatBackground", + +";name=FlatBackground", Ties=',f0.Shift=0.0', Output="__fitRescaleAndShift", StartX=rAnds.qMin, EndX=rAnds.qMax) else: Fit(InputWorkspace=rearData, Function='name=TabulatedFunction, Workspace="'+str(frontData)+'"' - +";name=FlatBackground",Output="__fitRescaleAndShift") + +";name=FlatBackground", Ties=',f0.Shift=0.0', Output="__fitRescaleAndShift") param = mtd['__fitRescaleAndShift_Parameters'] - row1 = param.row(0).items() - row2 = param.row(1).items() - row3 = param.row(2).items() - scale = row1[1][1] - chiSquared = row3[1][1] + scale = param.row(0).items()[1][1] + chiSquared = param.row(3).items()[1][1] fitSuccess = True if not chiSquared > 0: @@ -622,7 +622,7 @@ def _fitRescaleAndShift(rAnds, frontData, rearData): if fitSuccess == False: return rAnds.scale, rAnds.shift - shift = row2[1][1] / scale + shift = param.row(2).items()[1][1] / scale delete_workspaces('__fitRescaleAndShift_Parameters') delete_workspaces('__fitRescaleAndShift_NormalisedCovarianceMatrix') diff --git a/Code/Mantid/scripts/reduction/instruments/reflectometer/data_manipulation.py b/Code/Mantid/scripts/reduction/instruments/reflectometer/data_manipulation.py index 26e8f99eee9b..636b843bc708 100644 --- a/Code/Mantid/scripts/reduction/instruments/reflectometer/data_manipulation.py +++ b/Code/Mantid/scripts/reduction/instruments/reflectometer/data_manipulation.py @@ -95,14 +95,24 @@ def _load_entry(entry, ws, title=""): instr_dir = config.getInstrumentDirectory() + # check date of input file + date = mtd['ws'].getRun().getProperty('run_start').value + nexus_acquisition = date.split('T')[0] + if nexus_acquisition > '2014-10-01': + geo_base_file_x = "REFL_Detector_Grouping_Sum_X_rot.xml" + geo_base_file_y = "REFL_Detector_Grouping_Sum_Y_rot.xml" + else: + geo_base_file_x = "REFL_Detector_Grouping_Sum_X.xml" + geo_base_file_y = "REFL_Detector_Grouping_Sum_Y.xml" + if is_pixel_y: grouping_file = os.path.join(instr_dir, "Grouping", - "REFL_Detector_Grouping_Sum_X.xml") + geo_base_file_x) GroupDetectors(InputWorkspace=ws, OutputWorkspace=ws_output, MapFile=grouping_file) else: grouping_file = os.path.join(instr_dir, "Grouping", - "REFL_Detector_Grouping_Sum_Y.xml") + geo_base_file_y) GroupDetectors(InputWorkspace=ws, OutputWorkspace=ws_output, MapFile=grouping_file) diff --git a/Code/Mantid/scripts/reduction/instruments/reflectometer/wks_utility.py b/Code/Mantid/scripts/reduction/instruments/reflectometer/wks_utility.py index aac80c05959a..ece19eda8bad 100644 --- a/Code/Mantid/scripts/reduction/instruments/reflectometer/wks_utility.py +++ b/Code/Mantid/scripts/reduction/instruments/reflectometer/wks_utility.py @@ -7,6 +7,7 @@ h = 6.626e-34 #m^2 kg s^-1 m = 1.675e-27 #kg +ref_date = '2014-10-01' #when the detector has been rotated def getSequenceRuns(run_numbers): """ @@ -1003,7 +1004,8 @@ def normalizeNeXus(inputWorkspace, type): def integrateOverLowResRange(mt1, dataLowResRange, - type): + type, + is_nexus_detector_rotated_flag): """ This creates the integrated workspace over the low resolution range leaving us with a [256,nbr TOF] workspace @@ -1021,19 +1023,25 @@ def integrateOverLowResRange(mt1, fromXpixel = min(dataLowResRange) - 1 toXpixel = max(dataLowResRange) - 1 - _y_axis = zeros((256, len(_tof_axis) - 1)) - _y_error_axis = zeros((256, len(_tof_axis) - 1)) + if is_nexus_detector_rotated_flag: + sz_y_axis = 304 + sz_x_axis = 256 + else: + sz_y_axis = 256 + sz_x_axis = 304 + + _y_axis = zeros((sz_y_axis, len(_tof_axis) - 1)) + _y_error_axis = zeros((sz_y_axis, len(_tof_axis) - 1)) x_size = toXpixel - fromXpixel + 1 x_range = arange(x_size) + fromXpixel - y_range = range(256) + y_range = range(sz_y_axis) for x in x_range: for y in y_range: - _index = int((256) * x + y) + _index = int((sz_y_axis) * x + y) _y_axis[y, :] += mt1.readY(_index)[:].copy() - _tmp_error_axis = mt1.readE(_index)[:].copy() # 0 -> 1 # index_where_0 = where(_tmp_error_axis == 0) @@ -1050,7 +1058,7 @@ def substractBackground(tof_axis, y_axis, y_error_axis, peakRange, backFlag, backRange, error_0, type): """ - shape of y_axis : [256, nbr_tof] + shape of y_axis : [sz_y_axis, nbr_tof] This routine will calculate the background, remove it from the peak and will return only the range of peak -> [peak_size, nbr_tof] @@ -1561,12 +1569,19 @@ def divideArrays(num_array, num_error_array, den_array, den_error_array): return [ratio_array, ratio_error_array] -def getCentralPixel(ws_event_data, dataPeakRange): +def getCentralPixel(ws_event_data, dataPeakRange, is_new_geometry): """ This function will calculate the central pixel position """ - pixelXtof_data = getPixelXTOF(ws_event_data, maxX=304, maxY=256) + if is_new_geometry: + _maxX = 256 + _maxY = 304 + else: + _maxX = 304 + _maxY = 256 + + pixelXtof_data = getPixelXTOF(ws_event_data, maxX=_maxX, maxY=_maxY) pixelXtof_1d = pixelXtof_data.sum(axis=1) # Keep only range of pixels pixelXtof_roi = pixelXtof_1d[dataPeakRange[0]:dataPeakRange[1]] @@ -1744,7 +1759,6 @@ def convertToQWithoutCorrection(tof_axis, y_axis, y_error_axis, peak_range = None, - central_pixel = None, source_to_detector_distance = None, sample_to_detector_distance = None, theta = None, @@ -2029,7 +2043,16 @@ def cleanupData1D(final_data_y_axis, final_data_y_error_axis): return [final_data_y_axis, final_data_y_error_axis] - +def isNexusTakeAfterRefDate(nexus_date): + ''' + This function parses the output.date and returns true if this date is after the ref date + ''' + nexus_date_acquistion = nexus_date.split('T')[0] + + if nexus_date_acquistion > ref_date: + return True + else: + return False diff --git a/Code/Mantid/scripts/test/IndirectApplyCorrectionsTest.py b/Code/Mantid/scripts/test/IndirectApplyCorrectionsTest.py new file mode 100644 index 000000000000..2d4499a49d12 --- /dev/null +++ b/Code/Mantid/scripts/test/IndirectApplyCorrectionsTest.py @@ -0,0 +1,295 @@ +import os +import unittest + +from mantid.simpleapi import * +from mantid.api import MatrixWorkspace, WorkspaceGroup +from IndirectDataAnalysis import abscorFeeder + +def setup_corrections_test(using_can=False): + """ Decorator to setup a test to use a corrections workspace """ + def _decorator(test_case): + def _inner_decorator(self, *args, **kwargs): + self._corrections_workspace = self.make_corrections_workspace(using_can) + self._reference_corrections = CloneWorkspace(self._corrections_workspace, + OutputWorkspace='ref_corrections') + self._using_corrections = True + return test_case(self, *args, **kwargs) + return _inner_decorator + return _decorator + +def setup_can_test(test_case): + """ Decorator to setup a test to use a can workspace """ + def _decorator(self, *args, **kwargs): + self._can_workspace = self.make_can_workspace() + self._reference_can = CloneWorkspace(self._can_workspace, + OutputWorkspace='ref_can') + return test_case(self, *args, **kwargs) + return _decorator + + +class ApplyCorrectionsTests(unittest.TestCase): + + def setUp(self): + self._sample_workspace = self.make_sample_workspace() + self._can_workspace = '' + self._corrections_workspace = '' + self._can_geometry = 'cyl' + self._using_corrections = False + + self._kwargs = {'Verbose':True, 'RebinCan':False, 'ScaleOrNotToScale':False, + 'factor':1, 'Save':False, 'PlotResult':'None', 'PlotContrib':False} + + self._saved_workspaces = [] + + self._reference_sample = CloneWorkspace(self._sample_workspace, OutputWorkspace='ref_sample') + self._reference_can = None + self._reference_corrections = None + + def tearDown(self): + mtd.clear() + self.clean_up_saved_workspaces() + + @setup_can_test + def test_with_can_workspace(self): + output_workspaces = self.run_apply_corrections() + + self.assert_workspaces_exist(output_workspaces) + self.assert_workspaces_have_correct_types(output_workspaces) + self.assert_workspaces_have_correct_units(output_workspaces) + self.assert_input_workspaces_not_modified() + + @setup_can_test + def test_scale_can_workspace(self): + self._kwargs['ScaleOrNotToScale'] = True + self._kwargs['factor'] = 2 + + output_workspaces = self.run_apply_corrections() + + self.assert_workspaces_exist(output_workspaces) + self.assert_workspaces_have_correct_types(output_workspaces) + self.assert_workspaces_have_correct_units(output_workspaces) + self.assert_input_workspaces_not_modified() + + @setup_can_test + def test_rebin_can_workspace(self): + self._can_workspace = self.make_can_workspace(bin_width=0.001) + ScaleX(self._can_workspace, Factor=0.1, OutputWorkspace=self._can_workspace) + self._reference_can = CloneWorkspace(self._can_workspace, OutputWorkspace='ref_can') + + #should fail because the binning of the sample and can don't match + self.assertRaises(ValueError, self.run_apply_corrections) + + #try again, but rebin the can before the subraction + self._kwargs['RebinCan'] = True + try: + output_workspaces = self.run_apply_corrections() + except ValueError, ex: + self.fail("Apply Corrections raised a ValueError when it shouldn't! \ + \nException was: %s" % ex) + + self.assert_workspaces_exist(output_workspaces) + self.assert_workspaces_have_correct_types(output_workspaces) + self.assert_workspaces_have_correct_units(output_workspaces) + self.assert_input_workspaces_not_modified() + + @setup_can_test + def test_save_apply_corrections_output(self): + self._kwargs['Save'] = True + + output_workspaces = self.run_apply_corrections() + + self.assert_workspaces_exist(output_workspaces) + self.assert_workspaces_have_correct_types(output_workspaces) + self.assert_workspaces_have_correct_units(output_workspaces) + self.assert_input_workspaces_not_modified() + self.assert_workspace_was_saved(output_workspaces['result_workspace']) + self.assert_workspace_was_saved(output_workspaces['reduced_workspace']) + + #append saved workspaces to list for cleanup + self._saved_workspaces.append(output_workspaces['result_workspace']) + self._saved_workspaces.append(output_workspaces['reduced_workspace']) + + @setup_can_test + @setup_corrections_test(using_can=True) + def test_with_corrections_workspace(self): + output_workspaces = self.run_apply_corrections() + + self.assert_workspaces_exist(output_workspaces) + self.assert_workspaces_have_correct_types(output_workspaces) + self.assert_workspaces_have_correct_units(output_workspaces) + self.assert_input_workspaces_not_modified() + + @setup_corrections_test + def test_with_corrections_no_can(self): + output_workspaces = self.run_apply_corrections() + + self.assert_workspaces_exist(output_workspaces) + self.assert_workspaces_have_correct_types(output_workspaces) + self.assert_workspaces_have_correct_units(output_workspaces) + self.assert_input_workspaces_not_modified() + + #---------------------------------------------------------------- + # Custom assertion function defintions + #---------------------------------------------------------------- + + def assert_workspaces_exist(self, output_workspaces): + for ws in output_workspaces.itervalues(): + self.assertTrue(mtd.doesExist(ws), "%s does not exist in the ADS" % ws) + + def assert_workspaces_have_correct_units(self, output_workspaces): + self.assert_units_match(output_workspaces['reduced_workspace'], 'DeltaE') + self.assert_units_match(output_workspaces['rqw_workspace'], 'DeltaE') + + self.assert_units_match(output_workspaces['reduced_workspace'], 'Label', axis=1) + self.assert_units_match(output_workspaces['rqw_workspace'], 'MomentumTransfer', axis=1) + + def assert_workspaces_have_correct_types(self, output_workspaces): + self.assertTrue(isinstance(mtd[output_workspaces['reduced_workspace']], MatrixWorkspace), + "Reduced workspace should be a matrix workspace") + + self.assertTrue(isinstance(mtd[output_workspaces['rqw_workspace']], MatrixWorkspace), + "R(Q,w) workspace should be a matrix workspace") + + if 'result_workspace' in output_workspaces: + self.assertTrue(isinstance(mtd[output_workspaces['result_workspace']], WorkspaceGroup), + "Result workspace should be a group workspace") + result_workspace = mtd[output_workspaces['result_workspace']] + self.assertEquals(1, result_workspace.size()) + + for workspace in result_workspace.getNames(): + self.assertTrue(isinstance(mtd[workspace], MatrixWorkspace), + "%s should be a matrix workspace" % workspace) + + def assert_units_match(self, workspace, unit_id, axis=0): + unit = mtd[workspace].getAxis(axis).getUnit() + self.assertEquals(unit_id, unit.unitID(), + "The units of axis %d in workspace %s do not match. (%s != %s)" + % (axis, workspace, unit_id, unit.unitID())) + + def assert_workspace_was_saved(self, workspace): + working_directory = config['defaultsave.directory'] + file_name = workspace + '.nxs' + file_path = os.path.join(working_directory, file_name) + + self.assertTrue(os.path.exists(file_path), + "%s does not exist in the default save directory." % file_name) + self.assertTrue(os.path.isfile(file_path), + "%s should be a file but it is not" % file_name) + + def assert_input_workspaces_not_modified(self): + + result = CheckWorkspacesMatch(self._reference_sample, self._sample_workspace) + self.assertEquals("Success!", result) + + if self._can_workspace != '': + result = CheckWorkspacesMatch(self._reference_can, self._can_workspace) + self.assertEquals("Success!", result) + + if self._corrections_workspace != '': + result = CheckWorkspacesMatch(self._reference_corrections, self._corrections_workspace) + self.assertEquals("Success!", result) + + #---------------------------------------------------------------- + # Functions for creating a dummy workspaces that look like + # apply corrections input data + #---------------------------------------------------------------- + + def make_dummy_workspace(self, function, output_name, x_unit='DeltaE', num_spectra=1, bin_width=0.001): + """ Create a dummy workspace that looks like IRIS QENS data""" + dummy_workspace = CreateSampleWorkspace(Random=True, XMin=0, XMax=1, BinWidth=bin_width, XUnit=x_unit, + Function="User Defined", UserDefinedFunction=function, + OutputWorkspace=output_name) + ScaleX(dummy_workspace, -0.5, Operation="Add", OutputWorkspace=output_name) + dummy_workspace = CropWorkspace(dummy_workspace, StartWorkspaceIndex=0, EndWorkspaceIndex=num_spectra-1, + OutputWorkspace=output_name) + + idf = os.path.join(config['instrumentDefinition.directory'], "IRIS_Definition.xml") + ipf = os.path.join(config['instrumentDefinition.directory'], "IRIS_graphite_002_Parameters.xml") + LoadInstrument(Workspace=dummy_workspace, Filename=idf) + LoadParameterFile(Workspace=dummy_workspace, Filename=ipf) + + AddSampleLog(dummy_workspace, LogName='run_number', LogType='Number', LogText='00001') + + return dummy_workspace.name() + + def make_sample_workspace(self, **kwargs): + """ Create a dummy workspace that looks like a QENS sample run""" + function = "name=LinearBackground, A0=0.1;name=Lorentzian, PeakCentre=0.5, Amplitude=2, FWHM=0.1" + sample = self.make_dummy_workspace(function, output_name='sample', **kwargs) + return sample + + def make_can_workspace(self, **kwargs): + """ Create a dummy workspace that looks like a QENS can run""" + function = "name=LinearBackground, A0=0.1;name=Lorentzian, PeakCentre=0.5, Amplitude=0.5, FWHM=0.02" + can = self.make_dummy_workspace(function, output_name='can', **kwargs) + return can + + def make_corrections_workspace(self, using_can=False): + """ + Creates a dummy workspace that looks like a workspace of corrections output from the + indirect calculate corrections routine. The naming convention must match and uses the formalism + for absoprtion corrections outlined in Paalman and Pings (1962). + """ + workspace_names = [] + ass_workspace = self.make_dummy_workspace("name=LinearBackground, A0=0.922948, A1=0;", + x_unit='Wavelength', output_name='corr_ass') + if using_can: + workspace_names.append(ass_workspace) + assc_workspace = self.make_dummy_workspace("name=LinearBackground, A0=0.921233, A1=-0.007078;", + x_unit='Wavelength', output_name='corr_assc') + workspace_names.append(assc_workspace) + acsc_workspace = self.make_dummy_workspace("name=LinearBackground, A0=0.933229, A1=-0.010020;", + x_unit='Wavelength', output_name='corr_acsc') + workspace_names.append(acsc_workspace) + acc_workspace = self.make_dummy_workspace("name=LinearBackground, A0=0.995029, A1=-0.010694;", + x_unit='Wavelength', output_name='corr_acc') + workspace_names.append(acc_workspace) + + workspace_names = ','.join(workspace_names) + corrections_workspace = GroupWorkspaces(workspace_names, OutputWorkspace='corrections_workspace') + + return corrections_workspace.name() + + #---------------------------------------------------------------- + # Misc helper functions + #---------------------------------------------------------------- + + def run_apply_corrections(self): + abscorFeeder(self._sample_workspace, self._can_workspace, self._can_geometry, + self._using_corrections, self._corrections_workspace, **self._kwargs) + return self.get_output_workspace_names() + + def get_output_workspace_names(self): + """ + abscorFeeder doesn't return anything, these names should exist in the ADS + apply corrections uses the following naming convention: + ___ + """ + mode = '' + if self._corrections_workspace != '' and self._can_workspace != '': + mode = 'Correct_1' + elif self._corrections_workspace != '': + mode = 'Corrected' + else: + mode = 'Subtract_1' + + workspace_name_stem = 'irs1_graphite002_%s' % mode + + output_workspaces = { + 'reduced_workspace': workspace_name_stem + '_red', + 'rqw_workspace': workspace_name_stem + '_rqw', + } + + if self._can_workspace != '': + output_workspaces['result_workspace'] = workspace_name_stem + '_Result' + + return output_workspaces + + def clean_up_saved_workspaces(self): + for name in self._saved_workspaces: + file_path = os.path.join(config['defaultsave.directory'], name + '.nxs') + if os.path.isfile(file_path): + os.remove(file_path) + +if __name__ == '__main__': + unittest.main() diff --git a/Code/Mantid/scripts/test/IndirectCommonTests.py b/Code/Mantid/scripts/test/IndirectCommonTests.py index 08b6124dd17b..6b047e3916bb 100644 --- a/Code/Mantid/scripts/test/IndirectCommonTests.py +++ b/Code/Mantid/scripts/test/IndirectCommonTests.py @@ -97,27 +97,27 @@ def test_createQaxis(self): ws = self.make_dummy_QENS_workspace() expected_result = [0.48372274526965614, 0.5253047207470043, 0.5667692111215948, 0.6079351677527526, 0.6487809073399486] actual_result = indirect_common.createQaxis(ws) - self.assert_lists_match(expected_result, actual_result) + self.assert_lists_almost_match(expected_result, actual_result) def test_GetWSangles(self): ws = self.make_dummy_QENS_workspace() expected_result = [29.700000000000006, 32.32, 34.949999999999996, 37.58, 40.209999999999994] actual_result = indirect_common.GetWSangles(ws) - self.assert_lists_match(expected_result, actual_result) + self.assert_lists_almost_match(expected_result, actual_result) def test_GetThetaQ(self): ws = self.make_dummy_QENS_workspace() expected_theta_result = [29.700000000000006, 32.32, 34.949999999999996, 37.58, 40.209999999999994] expected_Q_result = [0.48372274526965625, 0.5253047207470042, 0.5667692111215948, 0.6079351677527525, 0.6487809073399485] actual_theta_result, actual_Q_result = indirect_common.GetThetaQ(ws) - self.assert_lists_match(expected_theta_result, actual_theta_result) - self.assert_lists_match(expected_Q_result, actual_Q_result) + self.assert_lists_almost_match(expected_theta_result, actual_theta_result) + self.assert_lists_almost_match(expected_Q_result, actual_Q_result) def test_ExtractFloat(self): data = "0.0 1 .2 3e-3 4.3 -5.5 6.0" expected_result = [0, 1, 0.2, 3e-3, 4.3, -5.5, 6.0] actual_result = indirect_common.ExtractFloat(data) - self.assert_lists_match(expected_result, actual_result) + self.assert_lists_almost_match(expected_result, actual_result) def test_ExtractInt(self): data = "-2 -1 0 1 2 3 4 5" @@ -318,6 +318,10 @@ def test_addSampleLogs_empty_dict(self): # Custom assertion functions #----------------------------------------------------------- + def assert_lists_almost_match(self, expected, actual,decimal=6): + self.assertTrue(isinstance(expected, list)) + np.testing.assert_array_almost_equal(expected, actual, decimal, "The results do not match") + def assert_lists_match(self, expected, actual): self.assertTrue(isinstance(expected, list)) np.testing.assert_array_equal(expected, actual, "The results do not match") diff --git a/Code/Tools/Workflow/git/install_git_macros.bat b/Code/Tools/Workflow/git/install_git_macros.bat index 952a446dff35..48c9db79aea2 100755 --- a/Code/Tools/Workflow/git/install_git_macros.bat +++ b/Code/Tools/Workflow/git/install_git_macros.bat @@ -1,28 +1,31 @@ @echo off :: Batch script to install the git macros in to the appropriate location. -:: This assumes you have installed git in the standard location: -:: 32-bit: C:\Program Files\Git -:: 64-bit: C:\Program Files(x86)\Git -:: Check whether we're 64 or 32 bit and set the install directory appropriately -set RegQry=HKLM\Hardware\Description\System\CentralProcessor\0 -REG.exe Query %RegQry% > checkOS.txt -Find /i "x86" < CheckOS.txt > StringCheck.txt +setlocal -If %ERRORLEVEL% == 0 ( - set GIT_BIN_DIR="C:\Program Files\Git\bin\" -) ELSE ( - set GIT_BIN_DIR="C:\Program Files (x86)\Git\bin\" +:: Get the install location of Git from the registry +:REG_QUERY +for /f "skip=2 delims=: tokens=1*" %%a in ('reg query "HKLM\SOFTWARE%WOW%\Microsoft\Windows\CurrentVersion\Uninstall\Git_is1" /v InstallLocation 2^> nul') do ( + for /f "tokens=3" %%z in ("%%a") do ( + set GIT_BIN_DIR=%%z:%%b + ) ) -:: Remove temporary files created above -del CheckOS.txt -del StringCheck.txt + +if "%GIT_BIN_DIR%"=="" ( + if "%WOW%"=="" ( + :: Assume we are on 64-bit Windows, so explicitly read the 32-bit Registry. + set WOW=\Wow6432Node + goto REG_QUERY + ) +) + +echo Found Git at %GIT_BIN_DIR% :: Define files to be copied set FILES=git-new git-checkbuild gitworkflow-helpers git-finish git-test git-publish :: Do copy -FOR %%f IN (%FILES%) DO echo Copying %%f to %GIT_BIN_DIR% && xcopy /Y %~dp0%%f %GIT_BIN_DIR% +FOR %%f IN (%FILES%) DO echo Copying %%f to "%GIT_BIN_DIR%bin\" && xcopy /Y %~dp0%%f "%GIT_BIN_DIR%bin\" :: Leave the window open just in case any error messages pause diff --git a/README.md b/README.md index 478b33acbfc1..71a05dea8d76 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@ Mantid ====== -The Mantid project provides a framework that supports high-performance computing and visualisation of scientific data. Mantid has been created to manipulate and analyse Neutron and Muon scattering data, but could be applied to many other techniques. The framework is open source and supported on multiple target platforms (Windows, Linux, Mac). +The Mantid project provides a framework that supports high-performance computing and visualisation of scientific data. Mantid has been created to manipulate and analyse Neutron and Muon scattering data, but could be applied to many other techniques. The framework is open source and supported on multiple target platforms (Windows, Linux, Mac OS X). Useful links ------------ diff --git a/Test/AutoTestData/FITS_small_01.fits b/Test/AutoTestData/FITS_small_01.fits new file mode 100644 index 000000000000..c3fc7f2ac7de Binary files /dev/null and b/Test/AutoTestData/FITS_small_01.fits differ diff --git a/Test/AutoTestData/FITS_small_02.fits b/Test/AutoTestData/FITS_small_02.fits new file mode 100644 index 000000000000..34c6325ec178 Binary files /dev/null and b/Test/AutoTestData/FITS_small_02.fits differ diff --git a/Test/AutoTestData/ILLD17-161876-Ni.nxs b/Test/AutoTestData/ILLD17-161876-Ni.nxs new file mode 100644 index 000000000000..680b6e001b52 Binary files /dev/null and b/Test/AutoTestData/ILLD17-161876-Ni.nxs differ diff --git a/Test/AutoTestData/ILLD17_111686.nxs b/Test/AutoTestData/ILLD17_111686.nxs deleted file mode 100644 index 5ff9a291b658..000000000000 Binary files a/Test/AutoTestData/ILLD17_111686.nxs and /dev/null differ diff --git a/Test/AutoTestData/IRS26173.RAW b/Test/AutoTestData/IRS26173.RAW new file mode 100644 index 000000000000..e9d7fa89babd Binary files /dev/null and b/Test/AutoTestData/IRS26173.RAW differ diff --git a/Test/AutoTestData/IRS26176.RAW b/Test/AutoTestData/IRS26176.RAW new file mode 100644 index 000000000000..3e64dce7b128 Binary files /dev/null and b/Test/AutoTestData/IRS26176.RAW differ diff --git a/Test/AutoTestData/NXSPEData.nxspe b/Test/AutoTestData/NXSPEData.nxspe new file mode 100644 index 000000000000..b5c0fed5d77c Binary files /dev/null and b/Test/AutoTestData/NXSPEData.nxspe differ diff --git a/Test/AutoTestData/UsageData/CORELLI_2100.nxs.h5 b/Test/AutoTestData/UsageData/CORELLI_2100.nxs.h5 new file mode 100644 index 000000000000..1f88e92abb90 Binary files /dev/null and b/Test/AutoTestData/UsageData/CORELLI_2100.nxs.h5 differ diff --git a/Test/AutoTestData/UsageData/GEM_Definition.vtp b/Test/AutoTestData/UsageData/GEM_Definition.vtp new file mode 100644 index 000000000000..d6415ab3b951 --- /dev/null +++ b/Test/AutoTestData/UsageData/GEM_Definition.vtp @@ -0,0 +1,2047 @@ + + + + + -0.0101667 -0.0582343 0 -0.00533706 -0.0595284 0 -0.00533706 -0.0595284 0.001 -0.0101667 -0.0582343 0.001 -0.0101667 -0.0582343 0 -0.00533706 -0.0595284 0 -0.0025 -5.51091e-17 0 -0.00591826 -0.0390708 0 -0.00335619 -0.01961 0 -0.0101667 0.0582343 0 -0.00335619 0.01961 0 -0.00591826 0.0390708 0 -0.00533706 0.0595284 0 0.0025 -5.63338e-17 0 0.00162478 0.0200458 0 -0.000994217 0.0399391 0 -0.000994217 -0.0399391 0 0.00162478 -0.0200458 0 -0.00533706 -0.0595284 0 -0.00533706 -0.0595284 0.001 0.0025 -5.63338e-17 0.001 -0.000994217 -0.0399391 0.001 0.00162478 -0.0200458 0.001 0.0025 -5.63338e-17 0 -0.000994217 -0.0399391 0 0.00162478 -0.0200458 0 -0.0101667 -0.0582343 0.001 -0.00533706 -0.0595284 0.001 -0.0025 -5.51091e-17 0.001 -0.00591826 -0.0390708 0.001 -0.00335619 -0.01961 0.001 -0.0101667 0.0582343 0.001 -0.00335619 0.01961 0.001 -0.00591826 0.0390708 0.001 -0.00533706 0.0595284 0.001 0.0025 -5.63338e-17 0.001 0.00162478 0.0200458 0.001 -0.000994217 0.0399391 0.001 -0.000994217 -0.0399391 0.001 0.00162478 -0.0200458 0.001 -0.0101667 -0.0582343 0 -0.0101667 -0.0582343 0.001 -0.0025 -5.51091e-17 0.001 -0.00591826 -0.0390708 0.001 -0.00335619 -0.01961 0.001 -0.0025 -5.51091e-17 0 -0.00591826 -0.0390708 0 -0.00335619 -0.01961 0 -0.0025 -5.51091e-17 0 -0.0025 -5.51091e-17 0.001 -0.0101667 0.0582343 0.001 -0.00335619 0.01961 0.001 -0.00591826 0.0390708 0.001 -0.0101667 0.0582343 0 -0.00335619 0.01961 0 -0.00591826 0.0390708 0 -0.0101667 0.0582343 0 -0.00533706 0.0595284 0 -0.00533706 0.0595284 0.001 -0.0101667 0.0582343 0.001 0.0025 -5.63338e-17 0 0.0025 -5.63338e-17 0.001 -0.00533706 0.0595284 0.001 0.00162478 0.0200458 0.001 -0.000994217 0.0399391 0.001 -0.00533706 0.0595284 0 0.00162478 0.0200458 0 -0.000994217 0.0399391 0 + + + 2 0 3 1 0 2 16 4 5 16 7 4 17 8 7 17 7 16 6 8 17 13 6 17 14 10 6 14 6 13 15 11 10 15 10 14 12 9 11 12 11 15 21 19 18 21 18 24 22 24 25 22 21 24 20 25 23 20 22 25 38 26 27 38 29 26 39 30 29 39 29 38 28 30 39 35 28 39 36 32 28 36 28 35 37 33 32 37 32 36 34 31 33 34 33 37 43 41 40 43 40 46 44 46 47 44 43 46 42 47 45 42 44 47 51 49 48 51 48 54 52 54 55 52 51 54 50 55 53 50 52 55 58 56 59 57 56 58 63 61 60 63 60 66 64 66 67 64 63 66 62 67 65 62 64 67 + 3 6 9 12 15 18 21 24 27 30 33 36 39 42 45 48 51 54 57 60 63 66 69 72 75 78 81 84 87 90 93 96 99 102 105 108 111 114 117 120 123 126 129 132 135 138 141 144 147 150 153 156 + + + + + -0.0103371 -0.0595284 0 -0.00550743 -0.0608225 0 -0.00550743 -0.0608225 0.001 -0.0103371 -0.0595284 0.001 -0.0103371 -0.0595284 0 -0.00550743 -0.0608225 0 -0.0025 -5.63338e-17 0 -0.00599422 -0.0399391 0 -0.00337522 -0.0200458 0 -0.0103371 0.0595284 0 -0.00337522 0.0200458 0 -0.00599422 0.0399391 0 -0.00550743 0.0608225 0 0.0025 -5.75584e-17 0 0.00160575 0.0204816 0 -0.00107018 0.0408073 0 -0.00107018 -0.0408073 0 0.00160575 -0.0204816 0 -0.00550743 -0.0608225 0 -0.00550743 -0.0608225 0.001 0.0025 -5.75584e-17 0.001 -0.00107018 -0.0408073 0.001 0.00160575 -0.0204816 0.001 0.0025 -5.75584e-17 0 -0.00107018 -0.0408073 0 0.00160575 -0.0204816 0 -0.0103371 -0.0595284 0.001 -0.00550743 -0.0608225 0.001 -0.0025 -5.63338e-17 0.001 -0.00599422 -0.0399391 0.001 -0.00337522 -0.0200458 0.001 -0.0103371 0.0595284 0.001 -0.00337522 0.0200458 0.001 -0.00599422 0.0399391 0.001 -0.00550743 0.0608225 0.001 0.0025 -5.75584e-17 0.001 0.00160575 0.0204816 0.001 -0.00107018 0.0408073 0.001 -0.00107018 -0.0408073 0.001 0.00160575 -0.0204816 0.001 -0.0103371 -0.0595284 0 -0.0103371 -0.0595284 0.001 -0.0025 -5.63338e-17 0.001 -0.00599422 -0.0399391 0.001 -0.00337522 -0.0200458 0.001 -0.0025 -5.63338e-17 0 -0.00599422 -0.0399391 0 -0.00337522 -0.0200458 0 -0.0025 -5.63338e-17 0 -0.0025 -5.63338e-17 0.001 -0.0103371 0.0595284 0.001 -0.00337522 0.0200458 0.001 -0.00599422 0.0399391 0.001 -0.0103371 0.0595284 0 -0.00337522 0.0200458 0 -0.00599422 0.0399391 0 -0.0103371 0.0595284 0 -0.00550743 0.0608225 0 -0.00550743 0.0608225 0.001 -0.0103371 0.0595284 0.001 0.0025 -5.75584e-17 0 0.0025 -5.75584e-17 0.001 -0.00550743 0.0608225 0.001 0.00160575 0.0204816 0.001 -0.00107018 0.0408073 0.001 -0.00550743 0.0608225 0 0.00160575 0.0204816 0 -0.00107018 0.0408073 0 + + + 2 0 3 1 0 2 16 4 5 16 7 4 17 8 7 17 7 16 13 6 8 13 8 17 10 6 13 14 10 13 15 11 10 15 10 14 12 9 11 12 11 15 21 19 18 21 18 24 22 24 25 22 21 24 20 25 23 20 22 25 38 26 27 38 29 26 39 30 29 39 29 38 35 28 30 35 30 39 32 28 35 36 32 35 37 33 32 37 32 36 34 31 33 34 33 37 43 41 40 43 40 46 44 46 47 44 43 46 42 47 45 42 44 47 51 49 48 51 48 54 52 54 55 52 51 54 50 55 53 50 52 55 58 56 59 57 56 58 63 61 60 63 60 66 64 66 67 64 63 66 62 67 65 62 64 67 + 3 6 9 12 15 18 21 24 27 30 33 36 39 42 45 48 51 54 57 60 63 66 69 72 75 78 81 84 87 90 93 96 99 102 105 108 111 114 117 120 123 126 129 132 135 138 141 144 147 150 153 156 + + + + + -0.0118602 -0.0710976 0 -0.00703055 -0.0723917 0 -0.00703055 -0.0723917 0.001 -0.0118602 -0.0710976 0.001 -0.0118602 -0.0710976 0 -0.00703055 -0.0723917 0 -0.0025 -6.72821e-17 0 -0.00667331 -0.0477012 0 -0.00354532 -0.0239417 0 -0.0118602 0.0710976 0 -0.00354532 0.0239417 0 -0.00667331 0.0477012 0 -0.00703055 0.0723917 0 0.0025 -6.85067e-17 0 0.00143566 0.0243775 0 -0.00174927 0.0485694 0 -0.00174927 -0.0485694 0 0.00143566 -0.0243775 0 -0.00703055 -0.0723917 0 -0.00703055 -0.0723917 0.001 0.0025 -6.85067e-17 0.001 -0.00174927 -0.0485694 0.001 0.00143566 -0.0243775 0.001 0.0025 -6.85067e-17 0 -0.00174927 -0.0485694 0 0.00143566 -0.0243775 0 -0.0118602 -0.0710976 0.001 -0.00703055 -0.0723917 0.001 -0.0025 -6.72821e-17 0.001 -0.00667331 -0.0477012 0.001 -0.00354532 -0.0239417 0.001 -0.0118602 0.0710976 0.001 -0.00354532 0.0239417 0.001 -0.00667331 0.0477012 0.001 -0.00703055 0.0723917 0.001 0.0025 -6.85067e-17 0.001 0.00143566 0.0243775 0.001 -0.00174927 0.0485694 0.001 -0.00174927 -0.0485694 0.001 0.00143566 -0.0243775 0.001 -0.0118602 -0.0710976 0 -0.0118602 -0.0710976 0.001 -0.0025 -6.72821e-17 0.001 -0.00667331 -0.0477012 0.001 -0.00354532 -0.0239417 0.001 -0.0025 -6.72821e-17 0 -0.00667331 -0.0477012 0 -0.00354532 -0.0239417 0 -0.0025 -6.72821e-17 0 -0.0025 -6.72821e-17 0.001 -0.0118602 0.0710976 0.001 -0.00354532 0.0239417 0.001 -0.00667331 0.0477012 0.001 -0.0118602 0.0710976 0 -0.00354532 0.0239417 0 -0.00667331 0.0477012 0 -0.0118602 0.0710976 0 -0.00703055 0.0723917 0 -0.00703055 0.0723917 0.001 -0.0118602 0.0710976 0.001 0.0025 -6.85067e-17 0 0.0025 -6.85067e-17 0.001 -0.00703055 0.0723917 0.001 0.00143566 0.0243775 0.001 -0.00174927 0.0485694 0.001 -0.00703055 0.0723917 0 0.00143566 0.0243775 0 -0.00174927 0.0485694 0 + + + 2 0 3 1 0 2 16 4 5 16 7 4 17 8 7 17 7 16 6 8 17 13 6 17 10 6 13 14 10 13 15 11 10 15 10 14 12 9 11 12 11 15 21 19 18 21 18 24 22 24 25 22 21 24 20 25 23 20 22 25 38 26 27 38 29 26 39 30 29 39 29 38 28 30 39 35 28 39 32 28 35 36 32 35 37 33 32 37 32 36 34 31 33 34 33 37 43 41 40 43 40 46 44 46 47 44 43 46 42 47 45 42 44 47 51 49 48 51 48 54 52 54 55 52 51 54 50 55 53 50 52 55 58 56 59 57 56 58 63 61 60 63 60 66 64 66 67 64 63 66 62 67 65 62 64 67 + 3 6 9 12 15 18 21 24 27 30 33 36 39 42 45 48 51 54 57 60 63 66 69 72 75 78 81 84 87 90 93 96 99 102 105 108 111 114 117 120 123 126 129 132 135 138 141 144 147 150 153 156 + + + + + -0.0120305 -0.0723917 0 -0.00720092 -0.0736858 0 -0.00720092 -0.0736858 0.001 -0.0120305 -0.0723917 0.001 -0.0120305 -0.0723917 0 -0.00720092 -0.0736858 0 -0.0025 -6.85067e-17 0 -0.00674927 -0.0485694 0 -0.00356434 -0.0243775 0 -0.0120305 0.0723917 0 -0.00356434 0.0243775 0 -0.00674927 0.0485694 0 -0.00720092 0.0736858 0 0.0025 -6.97314e-17 0 0.00141663 0.0248132 0 -0.00182523 0.0494376 0 -0.00182523 -0.0494376 0 0.00141663 -0.0248132 0 -0.00720092 -0.0736858 0 -0.00720092 -0.0736858 0.001 0.0025 -6.97314e-17 0.001 -0.00182523 -0.0494376 0.001 0.00141663 -0.0248132 0.001 0.0025 -6.97314e-17 0 -0.00182523 -0.0494376 0 0.00141663 -0.0248132 0 -0.0120305 -0.0723917 0.001 -0.00720092 -0.0736858 0.001 -0.0025 -6.85067e-17 0.001 -0.00674927 -0.0485694 0.001 -0.00356434 -0.0243775 0.001 -0.0120305 0.0723917 0.001 -0.00356434 0.0243775 0.001 -0.00674927 0.0485694 0.001 -0.00720092 0.0736858 0.001 0.0025 -6.97314e-17 0.001 0.00141663 0.0248132 0.001 -0.00182523 0.0494376 0.001 -0.00182523 -0.0494376 0.001 0.00141663 -0.0248132 0.001 -0.0120305 -0.0723917 0 -0.0120305 -0.0723917 0.001 -0.0025 -6.85067e-17 0.001 -0.00674927 -0.0485694 0.001 -0.00356434 -0.0243775 0.001 -0.0025 -6.85067e-17 0 -0.00674927 -0.0485694 0 -0.00356434 -0.0243775 0 -0.0025 -6.85067e-17 0 -0.0025 -6.85067e-17 0.001 -0.0120305 0.0723917 0.001 -0.00356434 0.0243775 0.001 -0.00674927 0.0485694 0.001 -0.0120305 0.0723917 0 -0.00356434 0.0243775 0 -0.00674927 0.0485694 0 -0.0120305 0.0723917 0 -0.00720092 0.0736858 0 -0.00720092 0.0736858 0.001 -0.0120305 0.0723917 0.001 0.0025 -6.97314e-17 0 0.0025 -6.97314e-17 0.001 -0.00720092 0.0736858 0.001 0.00141663 0.0248132 0.001 -0.00182523 0.0494376 0.001 -0.00720092 0.0736858 0 0.00141663 0.0248132 0 -0.00182523 0.0494376 0 + + + 2 0 3 1 0 2 16 4 5 16 7 4 17 8 7 17 7 16 6 8 17 13 6 17 10 6 13 14 10 13 15 11 10 15 10 14 12 9 11 12 11 15 21 19 18 21 18 24 22 24 25 22 21 24 20 25 23 20 22 25 38 26 27 38 29 26 39 30 29 39 29 38 28 30 39 35 28 39 32 28 35 36 32 35 37 33 32 37 32 36 34 31 33 34 33 37 43 41 40 43 40 46 44 46 47 44 43 46 42 47 45 42 44 47 51 49 48 51 48 54 52 54 55 52 51 54 50 55 53 50 52 55 58 56 59 57 56 58 63 61 60 63 60 66 64 66 67 64 63 66 62 67 65 62 64 67 + 3 6 9 12 15 18 21 24 27 30 33 36 39 42 45 48 51 54 57 60 63 66 69 72 75 78 81 84 87 90 93 96 99 102 105 108 111 114 117 120 123 126 129 132 135 138 141 144 147 150 153 156 + + + + + -0.0121975 -0.0736599 0 -0.00736788 -0.074954 0 -0.00736788 -0.074954 0.001 -0.0121975 -0.0736599 0.001 -0.0121975 -0.0736599 0 -0.00736788 -0.074954 0 -0.0025 -6.97069e-17 0 -0.00682371 -0.0494203 0 -0.00358299 -0.0248045 0 -0.0121975 0.0736599 0 -0.00358299 0.0248045 0 -0.00682371 0.0494203 0 -0.00736788 0.074954 0 0.0025 -7.09315e-17 0 0.00139798 0.0252403 0 -0.00189967 0.0502885 0 -0.00189967 -0.0502885 0 0.00139798 -0.0252403 0 -0.00736788 -0.074954 0 -0.00736788 -0.074954 0.001 0.0025 -7.09315e-17 0.001 -0.00189967 -0.0502885 0.001 0.00139798 -0.0252403 0.001 0.0025 -7.09315e-17 0 -0.00189967 -0.0502885 0 0.00139798 -0.0252403 0 -0.0121975 -0.0736599 0.001 -0.00736788 -0.074954 0.001 -0.0025 -6.97069e-17 0.001 -0.00682371 -0.0494203 0.001 -0.00358299 -0.0248045 0.001 -0.0121975 0.0736599 0.001 -0.00358299 0.0248045 0.001 -0.00682371 0.0494203 0.001 -0.00736788 0.074954 0.001 0.0025 -7.09315e-17 0.001 0.00139798 0.0252403 0.001 -0.00189967 0.0502885 0.001 -0.00189967 -0.0502885 0.001 0.00139798 -0.0252403 0.001 -0.0121975 -0.0736599 0 -0.0121975 -0.0736599 0.001 -0.0025 -6.97069e-17 0.001 -0.00682371 -0.0494203 0.001 -0.00358299 -0.0248045 0.001 -0.0025 -6.97069e-17 0 -0.00682371 -0.0494203 0 -0.00358299 -0.0248045 0 -0.0025 -6.97069e-17 0 -0.0025 -6.97069e-17 0.001 -0.0121975 0.0736599 0.001 -0.00358299 0.0248045 0.001 -0.00682371 0.0494203 0.001 -0.0121975 0.0736599 0 -0.00358299 0.0248045 0 -0.00682371 0.0494203 0 -0.0121975 0.0736599 0 -0.00736788 0.074954 0 -0.00736788 0.074954 0.001 -0.0121975 0.0736599 0.001 0.0025 -7.09315e-17 0 0.0025 -7.09315e-17 0.001 -0.00736788 0.074954 0.001 0.00139798 0.0252403 0.001 -0.00189967 0.0502885 0.001 -0.00736788 0.074954 0 0.00139798 0.0252403 0 -0.00189967 0.0502885 0 + + + 1 3 2 1 0 3 16 4 5 16 7 4 17 8 7 17 7 16 6 8 17 13 6 17 10 6 13 14 10 13 15 11 10 15 10 14 12 9 11 12 11 15 21 19 18 21 18 24 22 24 25 22 21 24 20 25 23 20 22 25 38 26 27 38 29 26 39 30 29 39 29 38 28 30 39 35 28 39 32 28 35 36 32 35 37 33 32 37 32 36 34 31 33 34 33 37 43 41 40 43 40 46 44 46 47 44 43 46 42 47 45 42 44 47 51 49 48 51 48 54 52 54 55 52 51 54 50 55 53 50 52 55 58 56 59 57 56 58 63 61 60 63 60 66 64 66 67 64 63 66 62 67 65 62 64 67 + 3 6 9 12 15 18 21 24 27 30 33 36 39 42 45 48 51 54 57 60 63 66 69 72 75 78 81 84 87 90 93 96 99 102 105 108 111 114 117 120 123 126 129 132 135 138 141 144 147 150 153 156 + + + + + -0.0123679 -0.074954 0 -0.00753825 -0.0762481 0 -0.00753825 -0.0762481 0.001 -0.0123679 -0.074954 0.001 -0.0123679 -0.074954 0 -0.00753825 -0.0762481 0 -0.0025 -7.09315e-17 0 -0.00689967 -0.0502885 0 -0.00360202 -0.0252403 0 -0.0123679 0.074954 0 -0.00360202 0.0252403 0 -0.00689967 0.0502885 0 -0.00753825 0.0762481 0 0.0025 -7.21562e-17 0 0.00137896 0.0256761 0 -0.00197564 0.0511568 0 -0.00197564 -0.0511568 0 0.00137896 -0.0256761 0 -0.00753825 -0.0762481 0 -0.00753825 -0.0762481 0.001 0.0025 -7.21562e-17 0.001 -0.00197564 -0.0511568 0.001 0.00137896 -0.0256761 0.001 0.0025 -7.21562e-17 0 -0.00197564 -0.0511568 0 0.00137896 -0.0256761 0 -0.0123679 -0.074954 0.001 -0.00753825 -0.0762481 0.001 -0.0025 -7.09315e-17 0.001 -0.00689967 -0.0502885 0.001 -0.00360202 -0.0252403 0.001 -0.0123679 0.074954 0.001 -0.00360202 0.0252403 0.001 -0.00689967 0.0502885 0.001 -0.00753825 0.0762481 0.001 0.0025 -7.21562e-17 0.001 0.00137896 0.0256761 0.001 -0.00197564 0.0511568 0.001 -0.00197564 -0.0511568 0.001 0.00137896 -0.0256761 0.001 -0.0123679 -0.074954 0 -0.0123679 -0.074954 0.001 -0.0025 -7.09315e-17 0.001 -0.00689967 -0.0502885 0.001 -0.00360202 -0.0252403 0.001 -0.0025 -7.09315e-17 0 -0.00689967 -0.0502885 0 -0.00360202 -0.0252403 0 -0.0025 -7.09315e-17 0 -0.0025 -7.09315e-17 0.001 -0.0123679 0.074954 0.001 -0.00360202 0.0252403 0.001 -0.00689967 0.0502885 0.001 -0.0123679 0.074954 0 -0.00360202 0.0252403 0 -0.00689967 0.0502885 0 -0.0123679 0.074954 0 -0.00753825 0.0762481 0 -0.00753825 0.0762481 0.001 -0.0123679 0.074954 0.001 0.0025 -7.21562e-17 0 0.0025 -7.21562e-17 0.001 -0.00753825 0.0762481 0.001 0.00137896 0.0256761 0.001 -0.00197564 0.0511568 0.001 -0.00753825 0.0762481 0 0.00137896 0.0256761 0 -0.00197564 0.0511568 0 + + + 1 3 2 1 0 3 16 4 5 16 7 4 17 8 7 17 7 16 6 8 17 13 6 17 10 6 13 14 10 13 15 11 10 15 10 14 9 11 15 12 9 15 21 19 18 21 18 24 22 24 25 22 21 24 20 25 23 20 22 25 38 26 27 38 29 26 39 30 29 39 29 38 28 30 39 35 28 39 32 28 35 36 32 35 37 33 32 37 32 36 31 33 37 34 31 37 43 41 40 43 40 46 44 46 47 44 43 46 42 47 45 42 44 47 51 49 48 51 48 54 52 54 55 52 51 54 50 55 53 50 52 55 58 56 59 57 56 58 63 61 60 63 60 66 64 66 67 64 63 66 62 67 65 62 64 67 + 3 6 9 12 15 18 21 24 27 30 33 36 39 42 45 48 51 54 57 60 63 66 69 72 75 78 81 84 87 90 93 96 99 102 105 108 111 114 117 120 123 126 129 132 135 138 141 144 147 150 153 156 + + + + + -0.0125383 -0.0762481 0 -0.00770862 -0.0775422 0 -0.00770862 -0.0775422 0.001 -0.0125383 -0.0762481 0.001 -0.0125383 -0.0762481 0 -0.00770862 -0.0775422 0 -0.0025 -7.21562e-17 0 -0.00697564 -0.0511568 0 -0.00362104 -0.0256761 0 -0.0125383 0.0762481 0 -0.00362104 0.0256761 0 -0.00697564 0.0511568 0 -0.00770862 0.0775422 0 0.0025 -7.33808e-17 0 0.00135993 0.0261119 0 -0.0020516 0.052025 0 -0.0020516 -0.052025 0 0.00135993 -0.0261119 0 -0.00770862 -0.0775422 0 -0.00770862 -0.0775422 0.001 0.0025 -7.33808e-17 0.001 -0.0020516 -0.052025 0.001 0.00135993 -0.0261119 0.001 0.0025 -7.33808e-17 0 -0.0020516 -0.052025 0 0.00135993 -0.0261119 0 -0.0125383 -0.0762481 0.001 -0.00770862 -0.0775422 0.001 -0.0025 -7.21562e-17 0.001 -0.00697564 -0.0511568 0.001 -0.00362104 -0.0256761 0.001 -0.0125383 0.0762481 0.001 -0.00362104 0.0256761 0.001 -0.00697564 0.0511568 0.001 -0.00770862 0.0775422 0.001 0.0025 -7.33808e-17 0.001 0.00135993 0.0261119 0.001 -0.0020516 0.052025 0.001 -0.0020516 -0.052025 0.001 0.00135993 -0.0261119 0.001 -0.0125383 -0.0762481 0 -0.0125383 -0.0762481 0.001 -0.0025 -7.21562e-17 0.001 -0.00697564 -0.0511568 0.001 -0.00362104 -0.0256761 0.001 -0.0025 -7.21562e-17 0 -0.00697564 -0.0511568 0 -0.00362104 -0.0256761 0 -0.0025 -7.21562e-17 0 -0.0025 -7.21562e-17 0.001 -0.0125383 0.0762481 0.001 -0.00362104 0.0256761 0.001 -0.00697564 0.0511568 0.001 -0.0125383 0.0762481 0 -0.00362104 0.0256761 0 -0.00697564 0.0511568 0 -0.0125383 0.0762481 0 -0.00770862 0.0775422 0 -0.00770862 0.0775422 0.001 -0.0125383 0.0762481 0.001 0.0025 -7.33808e-17 0 0.0025 -7.33808e-17 0.001 -0.00770862 0.0775422 0.001 0.00135993 0.0261119 0.001 -0.0020516 0.052025 0.001 -0.00770862 0.0775422 0 0.00135993 0.0261119 0 -0.0020516 0.052025 0 + + + 2 0 3 1 0 2 16 4 5 16 7 4 17 8 7 17 7 16 6 8 17 13 6 17 10 6 13 14 10 13 15 11 10 15 10 14 12 9 11 12 11 15 21 19 18 21 18 24 22 24 25 22 21 24 20 25 23 20 22 25 38 26 27 38 29 26 39 30 29 39 29 38 28 30 39 35 28 39 32 28 35 36 32 35 37 33 32 37 32 36 34 31 33 34 33 37 43 41 40 43 40 46 44 46 47 44 43 46 42 47 45 42 44 47 51 49 48 51 48 54 52 54 55 52 51 54 50 55 53 50 52 55 58 56 59 57 56 58 63 61 60 63 60 66 64 66 67 64 63 66 62 67 65 62 64 67 + 3 6 9 12 15 18 21 24 27 30 33 36 39 42 45 48 51 54 57 60 63 66 69 72 75 78 81 84 87 90 93 96 99 102 105 108 111 114 117 120 123 126 129 132 135 138 141 144 147 150 153 156 + + + + + -0.0127052 -0.0775163 0 -0.00787559 -0.0788104 0 -0.00787559 -0.0788104 0.001 -0.0127052 -0.0775163 0.001 -0.0127052 -0.0775163 0 -0.00787559 -0.0788104 0 -0.0025 -7.33563e-17 0 -0.00705008 -0.0520076 0 -0.00363969 -0.0261031 0 -0.0127052 0.0775163 0 -0.00363969 0.0261031 0 -0.00705008 0.0520076 0 -0.00787559 0.0788104 0 0.0025 -7.4581e-17 0 0.00134129 0.0265389 0 -0.00212604 0.0528759 0 -0.00212604 -0.0528759 0 0.00134129 -0.0265389 0 -0.00787559 -0.0788104 0 -0.00787559 -0.0788104 0.001 0.0025 -7.4581e-17 0.001 -0.00212604 -0.0528759 0.001 0.00134129 -0.0265389 0.001 0.0025 -7.4581e-17 0 -0.00212604 -0.0528759 0 0.00134129 -0.0265389 0 -0.0127052 -0.0775163 0.001 -0.00787559 -0.0788104 0.001 -0.0025 -7.33563e-17 0.001 -0.00705008 -0.0520076 0.001 -0.00363969 -0.0261031 0.001 -0.0127052 0.0775163 0.001 -0.00363969 0.0261031 0.001 -0.00705008 0.0520076 0.001 -0.00787559 0.0788104 0.001 0.0025 -7.4581e-17 0.001 0.00134129 0.0265389 0.001 -0.00212604 0.0528759 0.001 -0.00212604 -0.0528759 0.001 0.00134129 -0.0265389 0.001 -0.0127052 -0.0775163 0 -0.0127052 -0.0775163 0.001 -0.0025 -7.33563e-17 0.001 -0.00705008 -0.0520076 0.001 -0.00363969 -0.0261031 0.001 -0.0025 -7.33563e-17 0 -0.00705008 -0.0520076 0 -0.00363969 -0.0261031 0 -0.0025 -7.33563e-17 0 -0.0025 -7.33563e-17 0.001 -0.0127052 0.0775163 0.001 -0.00363969 0.0261031 0.001 -0.00705008 0.0520076 0.001 -0.0127052 0.0775163 0 -0.00363969 0.0261031 0 -0.00705008 0.0520076 0 -0.0127052 0.0775163 0 -0.00787559 0.0788104 0 -0.00787559 0.0788104 0.001 -0.0127052 0.0775163 0.001 0.0025 -7.4581e-17 0 0.0025 -7.4581e-17 0.001 -0.00787559 0.0788104 0.001 0.00134129 0.0265389 0.001 -0.00212604 0.0528759 0.001 -0.00787559 0.0788104 0 0.00134129 0.0265389 0 -0.00212604 0.0528759 0 + + + 1 3 2 1 0 3 16 4 5 16 7 4 17 8 7 17 7 16 6 8 17 13 6 17 10 6 13 14 10 13 15 11 10 15 10 14 9 11 15 12 9 15 21 19 18 21 18 24 22 24 25 22 21 24 20 25 23 20 22 25 38 26 27 38 29 26 39 30 29 39 29 38 28 30 39 35 28 39 32 28 35 36 32 35 37 33 32 37 32 36 31 33 37 34 31 37 43 41 40 43 40 46 44 46 47 44 43 46 42 47 45 42 44 47 51 49 48 51 48 54 52 54 55 52 51 54 50 55 53 50 52 55 58 56 59 57 56 58 63 61 60 63 60 66 64 66 67 64 63 66 62 67 65 62 64 67 + 3 6 9 12 15 18 21 24 27 30 33 36 39 42 45 48 51 54 57 60 63 66 69 72 75 78 81 84 87 90 93 96 99 102 105 108 111 114 117 120 123 126 129 132 135 138 141 144 147 150 153 156 + + + + + -0.0128756 -0.0788104 0 -0.00804596 -0.0801045 0 -0.00804596 -0.0801045 0.001 -0.0128756 -0.0788104 0.001 -0.0128756 -0.0788104 0 -0.00804596 -0.0801045 0 -0.0025 -7.4581e-17 0 -0.00712604 -0.0528759 0 -0.00365871 -0.0265389 0 -0.0128756 0.0788104 0 -0.00365871 0.0265389 0 -0.00712604 0.0528759 0 -0.00804596 0.0801045 0 0.0025 -7.58056e-17 0 0.00132226 0.0269747 0 -0.002202 0.0537441 0 -0.002202 -0.0537441 0 0.00132226 -0.0269747 0 -0.00804596 -0.0801045 0 -0.00804596 -0.0801045 0.001 0.0025 -7.58056e-17 0.001 -0.002202 -0.0537441 0.001 0.00132226 -0.0269747 0.001 0.0025 -7.58056e-17 0 -0.002202 -0.0537441 0 0.00132226 -0.0269747 0 -0.0128756 -0.0788104 0.001 -0.00804596 -0.0801045 0.001 -0.0025 -7.4581e-17 0.001 -0.00712604 -0.0528759 0.001 -0.00365871 -0.0265389 0.001 -0.0128756 0.0788104 0.001 -0.00365871 0.0265389 0.001 -0.00712604 0.0528759 0.001 -0.00804596 0.0801045 0.001 0.0025 -7.58056e-17 0.001 0.00132226 0.0269747 0.001 -0.002202 0.0537441 0.001 -0.002202 -0.0537441 0.001 0.00132226 -0.0269747 0.001 -0.0128756 -0.0788104 0 -0.0128756 -0.0788104 0.001 -0.0025 -7.4581e-17 0.001 -0.00712604 -0.0528759 0.001 -0.00365871 -0.0265389 0.001 -0.0025 -7.4581e-17 0 -0.00712604 -0.0528759 0 -0.00365871 -0.0265389 0 -0.0025 -7.4581e-17 0 -0.0025 -7.4581e-17 0.001 -0.0128756 0.0788104 0.001 -0.00365871 0.0265389 0.001 -0.00712604 0.0528759 0.001 -0.0128756 0.0788104 0 -0.00365871 0.0265389 0 -0.00712604 0.0528759 0 -0.0128756 0.0788104 0 -0.00804596 0.0801045 0 -0.00804596 0.0801045 0.001 -0.0128756 0.0788104 0.001 0.0025 -7.58056e-17 0 0.0025 -7.58056e-17 0.001 -0.00804596 0.0801045 0.001 0.00132226 0.0269747 0.001 -0.002202 0.0537441 0.001 -0.00804596 0.0801045 0 0.00132226 0.0269747 0 -0.002202 0.0537441 0 + + + 1 3 2 1 0 3 16 4 5 16 7 4 17 8 7 17 7 16 6 8 17 13 6 17 10 6 13 14 10 13 15 11 10 15 10 14 12 9 11 12 11 15 21 19 18 21 18 24 22 24 25 22 21 24 20 25 23 20 22 25 38 26 27 38 29 26 39 30 29 39 29 38 28 30 39 35 28 39 32 28 35 36 32 35 37 33 32 37 32 36 34 31 33 34 33 37 43 41 40 43 40 46 44 46 47 44 43 46 42 47 45 42 44 47 51 49 48 51 48 54 52 54 55 52 51 54 50 55 53 50 52 55 58 56 59 57 56 58 63 61 60 63 60 66 64 66 67 64 63 66 62 67 65 62 64 67 + 3 6 9 12 15 18 21 24 27 30 33 36 39 42 45 48 51 54 57 60 63 66 69 72 75 78 81 84 87 90 93 96 99 102 105 108 111 114 117 120 123 126 129 132 135 138 141 144 147 150 153 156 + + + + + -0.0130425 -0.0800786 0 -0.00821292 -0.0813727 0 -0.00821292 -0.0813727 0.001 -0.0130425 -0.0800786 0.001 -0.0130425 -0.0800786 0 -0.00821292 -0.0813727 0 -0.0025 -7.57811e-17 0 -0.00720048 -0.0537267 0 -0.00367736 -0.026966 0 -0.0130425 0.0800786 0 -0.00367736 0.026966 0 -0.00720048 0.0537267 0 -0.00821292 0.0813727 0 0.0025 -7.70058e-17 0 0.00130361 0.0274018 0 -0.00227644 0.054595 0 -0.00227644 -0.054595 0 0.00130361 -0.0274018 0 -0.00821292 -0.0813727 0 -0.00821292 -0.0813727 0.001 0.0025 -7.70058e-17 0.001 -0.00227644 -0.054595 0.001 0.00130361 -0.0274018 0.001 0.0025 -7.70058e-17 0 -0.00227644 -0.054595 0 0.00130361 -0.0274018 0 -0.0130425 -0.0800786 0.001 -0.00821292 -0.0813727 0.001 -0.0025 -7.57811e-17 0.001 -0.00720048 -0.0537267 0.001 -0.00367736 -0.026966 0.001 -0.0130425 0.0800786 0.001 -0.00367736 0.026966 0.001 -0.00720048 0.0537267 0.001 -0.00821292 0.0813727 0.001 0.0025 -7.70058e-17 0.001 0.00130361 0.0274018 0.001 -0.00227644 0.054595 0.001 -0.00227644 -0.054595 0.001 0.00130361 -0.0274018 0.001 -0.0130425 -0.0800786 0 -0.0130425 -0.0800786 0.001 -0.0025 -7.57811e-17 0.001 -0.00720048 -0.0537267 0.001 -0.00367736 -0.026966 0.001 -0.0025 -7.57811e-17 0 -0.00720048 -0.0537267 0 -0.00367736 -0.026966 0 -0.0025 -7.57811e-17 0 -0.0025 -7.57811e-17 0.001 -0.0130425 0.0800786 0.001 -0.00367736 0.026966 0.001 -0.00720048 0.0537267 0.001 -0.0130425 0.0800786 0 -0.00367736 0.026966 0 -0.00720048 0.0537267 0 -0.0130425 0.0800786 0 -0.00821292 0.0813727 0 -0.00821292 0.0813727 0.001 -0.0130425 0.0800786 0.001 0.0025 -7.70058e-17 0 0.0025 -7.70058e-17 0.001 -0.00821292 0.0813727 0.001 0.00130361 0.0274018 0.001 -0.00227644 0.054595 0.001 -0.00821292 0.0813727 0 0.00130361 0.0274018 0 -0.00227644 0.054595 0 + + + 1 3 2 1 0 3 16 4 5 16 7 4 17 8 7 17 7 16 6 8 17 13 6 17 10 6 13 14 10 13 15 11 10 15 10 14 12 9 11 12 11 15 21 19 18 21 18 24 22 24 25 22 21 24 20 25 23 20 22 25 38 26 27 38 29 26 39 30 29 39 29 38 28 30 39 35 28 39 32 28 35 36 32 35 37 33 32 37 32 36 34 31 33 34 33 37 43 41 40 43 40 46 44 46 47 44 43 46 42 47 45 42 44 47 51 49 48 51 48 54 52 54 55 52 51 54 50 55 53 50 52 55 58 56 59 57 56 58 63 61 60 63 60 66 64 66 67 64 63 66 62 67 65 62 64 67 + 3 6 9 12 15 18 21 24 27 30 33 36 39 42 45 48 51 54 57 60 63 66 69 72 75 78 81 84 87 90 93 96 99 102 105 108 111 114 117 120 123 126 129 132 135 138 141 144 147 150 153 156 + + + + + -0.0132129 -0.0813727 0 -0.00838329 -0.0826668 0 -0.00838329 -0.0826668 0.001 -0.0132129 -0.0813727 0.001 -0.0132129 -0.0813727 0 -0.00838329 -0.0826668 0 -0.0025 -7.70058e-17 0 -0.00727644 -0.054595 0 -0.00369639 -0.0274018 0 -0.0132129 0.0813727 0 -0.00369639 0.0274018 0 -0.00727644 0.054595 0 -0.00838329 0.0826668 0 0.0025 -7.82304e-17 0 0.00128459 0.0278375 0 -0.0023524 0.0554632 0 -0.0023524 -0.0554632 0 0.00128459 -0.0278375 0 -0.00838329 -0.0826668 0 -0.00838329 -0.0826668 0.001 0.0025 -7.82304e-17 0.001 -0.0023524 -0.0554632 0.001 0.00128459 -0.0278375 0.001 0.0025 -7.82304e-17 0 -0.0023524 -0.0554632 0 0.00128459 -0.0278375 0 -0.0132129 -0.0813727 0.001 -0.00838329 -0.0826668 0.001 -0.0025 -7.70058e-17 0.001 -0.00727644 -0.054595 0.001 -0.00369639 -0.0274018 0.001 -0.0132129 0.0813727 0.001 -0.00369639 0.0274018 0.001 -0.00727644 0.054595 0.001 -0.00838329 0.0826668 0.001 0.0025 -7.82304e-17 0.001 0.00128459 0.0278375 0.001 -0.0023524 0.0554632 0.001 -0.0023524 -0.0554632 0.001 0.00128459 -0.0278375 0.001 -0.0132129 -0.0813727 0 -0.0132129 -0.0813727 0.001 -0.0025 -7.70058e-17 0.001 -0.00727644 -0.054595 0.001 -0.00369639 -0.0274018 0.001 -0.0025 -7.70058e-17 0 -0.00727644 -0.054595 0 -0.00369639 -0.0274018 0 -0.0025 -7.70058e-17 0 -0.0025 -7.70058e-17 0.001 -0.0132129 0.0813727 0.001 -0.00369639 0.0274018 0.001 -0.00727644 0.054595 0.001 -0.0132129 0.0813727 0 -0.00369639 0.0274018 0 -0.00727644 0.054595 0 -0.0132129 0.0813727 0 -0.00838329 0.0826668 0 -0.00838329 0.0826668 0.001 -0.0132129 0.0813727 0.001 0.0025 -7.82304e-17 0 0.0025 -7.82304e-17 0.001 -0.00838329 0.0826668 0.001 0.00128459 0.0278375 0.001 -0.0023524 0.0554632 0.001 -0.00838329 0.0826668 0 0.00128459 0.0278375 0 -0.0023524 0.0554632 0 + + + 1 3 2 1 0 3 16 4 5 16 7 4 17 8 7 17 7 16 6 8 17 13 6 17 10 6 13 14 10 13 15 11 10 15 10 14 12 9 11 12 11 15 21 19 18 21 18 24 22 24 25 22 21 24 20 25 23 20 22 25 38 26 27 38 29 26 39 30 29 39 29 38 28 30 39 35 28 39 32 28 35 36 32 35 37 33 32 37 32 36 34 31 33 34 33 37 43 41 40 43 40 46 44 46 47 44 43 46 42 47 45 42 44 47 51 49 48 51 48 54 52 54 55 52 51 54 50 55 53 50 52 55 58 56 59 57 56 58 63 61 60 63 60 66 64 66 67 64 63 66 62 67 65 62 64 67 + 3 6 9 12 15 18 21 24 27 30 33 36 39 42 45 48 51 54 57 60 63 66 69 72 75 78 81 84 87 90 93 96 99 102 105 108 111 114 117 120 123 126 129 132 135 138 141 144 147 150 153 156 + + + + + -0.0133833 -0.0826668 0 -0.00855366 -0.0839609 0 -0.00855366 -0.0839609 0.001 -0.0133833 -0.0826668 0.001 -0.0133833 -0.0826668 0 -0.00855366 -0.0839609 0 -0.0025 -7.82304e-17 0 -0.0073524 -0.0554632 0 -0.00371541 -0.0278375 0 -0.0133833 0.0826668 0 -0.00371541 0.0278375 0 -0.0073524 0.0554632 0 -0.00855366 0.0839609 0 0.0025 -7.94551e-17 0 0.00126556 0.0282733 0 -0.00242836 0.0563315 0 -0.00242836 -0.0563315 0 0.00126556 -0.0282733 0 -0.00855366 -0.0839609 0 -0.00855366 -0.0839609 0.001 0.0025 -7.94551e-17 0.001 -0.00242836 -0.0563315 0.001 0.00126556 -0.0282733 0.001 0.0025 -7.94551e-17 0 -0.00242836 -0.0563315 0 0.00126556 -0.0282733 0 -0.0133833 -0.0826668 0.001 -0.00855366 -0.0839609 0.001 -0.0025 -7.82304e-17 0.001 -0.0073524 -0.0554632 0.001 -0.00371541 -0.0278375 0.001 -0.0133833 0.0826668 0.001 -0.00371541 0.0278375 0.001 -0.0073524 0.0554632 0.001 -0.00855366 0.0839609 0.001 0.0025 -7.94551e-17 0.001 0.00126556 0.0282733 0.001 -0.00242836 0.0563315 0.001 -0.00242836 -0.0563315 0.001 0.00126556 -0.0282733 0.001 -0.0133833 -0.0826668 0 -0.0133833 -0.0826668 0.001 -0.0025 -7.82304e-17 0.001 -0.0073524 -0.0554632 0.001 -0.00371541 -0.0278375 0.001 -0.0025 -7.82304e-17 0 -0.0073524 -0.0554632 0 -0.00371541 -0.0278375 0 -0.0025 -7.82304e-17 0 -0.0025 -7.82304e-17 0.001 -0.0133833 0.0826668 0.001 -0.00371541 0.0278375 0.001 -0.0073524 0.0554632 0.001 -0.0133833 0.0826668 0 -0.00371541 0.0278375 0 -0.0073524 0.0554632 0 -0.0133833 0.0826668 0 -0.00855366 0.0839609 0 -0.00855366 0.0839609 0.001 -0.0133833 0.0826668 0.001 0.0025 -7.94551e-17 0 0.0025 -7.94551e-17 0.001 -0.00855366 0.0839609 0.001 0.00126556 0.0282733 0.001 -0.00242836 0.0563315 0.001 -0.00855366 0.0839609 0 0.00126556 0.0282733 0 -0.00242836 0.0563315 0 + + + 2 0 3 1 0 2 16 4 5 16 7 4 17 8 7 17 7 16 6 8 17 13 6 17 10 6 13 14 10 13 15 11 10 15 10 14 12 9 11 12 11 15 21 19 18 21 18 24 22 24 25 22 21 24 20 25 23 20 22 25 38 26 27 38 29 26 39 30 29 39 29 38 28 30 39 35 28 39 32 28 35 36 32 35 37 33 32 37 32 36 34 31 33 34 33 37 43 41 40 43 40 46 44 46 47 44 43 46 42 47 45 42 44 47 51 49 48 51 48 54 52 54 55 52 51 54 50 55 53 50 52 55 58 56 59 57 56 58 63 61 60 63 60 66 64 66 67 64 63 66 62 67 65 62 64 67 + 3 6 9 12 15 18 21 24 27 30 33 36 39 42 45 48 51 54 57 60 63 66 69 72 75 78 81 84 87 90 93 96 99 102 105 108 111 114 117 120 123 126 129 132 135 138 141 144 147 150 153 156 + + + + + -0.010504 -0.0607966 0 -0.00567439 -0.0620907 0 -0.00567439 -0.0620907 0.001 -0.010504 -0.0607966 0.001 -0.010504 -0.0607966 0 -0.00567439 -0.0620907 0 -0.0025 -5.75339e-17 0 -0.00606866 -0.04079 0 -0.00339387 -0.0204729 0 -0.010504 0.0607966 0 -0.00339387 0.0204729 0 -0.00606866 0.04079 0 -0.00567439 0.0620907 0 0.0025 -5.87586e-17 0 0.00158711 0.0209087 0 -0.00114462 0.0416582 0 -0.00114462 -0.0416582 0 0.00158711 -0.0209087 0 -0.00567439 -0.0620907 0 -0.00567439 -0.0620907 0.001 0.0025 -5.87586e-17 0.001 -0.00114462 -0.0416582 0.001 0.00158711 -0.0209087 0.001 0.0025 -5.87586e-17 0 -0.00114462 -0.0416582 0 0.00158711 -0.0209087 0 -0.010504 -0.0607966 0.001 -0.00567439 -0.0620907 0.001 -0.0025 -5.75339e-17 0.001 -0.00606866 -0.04079 0.001 -0.00339387 -0.0204729 0.001 -0.010504 0.0607966 0.001 -0.00339387 0.0204729 0.001 -0.00606866 0.04079 0.001 -0.00567439 0.0620907 0.001 0.0025 -5.87586e-17 0.001 0.00158711 0.0209087 0.001 -0.00114462 0.0416582 0.001 -0.00114462 -0.0416582 0.001 0.00158711 -0.0209087 0.001 -0.010504 -0.0607966 0 -0.010504 -0.0607966 0.001 -0.0025 -5.75339e-17 0.001 -0.00606866 -0.04079 0.001 -0.00339387 -0.0204729 0.001 -0.0025 -5.75339e-17 0 -0.00606866 -0.04079 0 -0.00339387 -0.0204729 0 -0.0025 -5.75339e-17 0 -0.0025 -5.75339e-17 0.001 -0.010504 0.0607966 0.001 -0.00339387 0.0204729 0.001 -0.00606866 0.04079 0.001 -0.010504 0.0607966 0 -0.00339387 0.0204729 0 -0.00606866 0.04079 0 -0.010504 0.0607966 0 -0.00567439 0.0620907 0 -0.00567439 0.0620907 0.001 -0.010504 0.0607966 0.001 0.0025 -5.87586e-17 0 0.0025 -5.87586e-17 0.001 -0.00567439 0.0620907 0.001 0.00158711 0.0209087 0.001 -0.00114462 0.0416582 0.001 -0.00567439 0.0620907 0 0.00158711 0.0209087 0 -0.00114462 0.0416582 0 + + + 2 0 3 1 0 2 16 4 5 16 7 4 17 8 7 17 7 16 6 8 17 13 6 17 10 6 13 14 10 13 15 11 10 15 10 14 12 9 11 12 11 15 21 19 18 21 18 24 22 24 25 22 21 24 20 25 23 20 22 25 38 26 27 38 29 26 39 30 29 39 29 38 28 30 39 35 28 39 32 28 35 36 32 35 37 33 32 37 32 36 34 31 33 34 33 37 43 41 40 43 40 46 44 46 47 44 43 46 42 47 45 42 44 47 51 49 48 51 48 54 52 54 55 52 51 54 50 55 53 50 52 55 58 56 59 57 56 58 63 61 60 63 60 66 64 66 67 64 63 66 62 67 65 62 64 67 + 3 6 9 12 15 18 21 24 27 30 33 36 39 42 45 48 51 54 57 60 63 66 69 72 75 78 81 84 87 90 93 96 99 102 105 108 111 114 117 120 123 126 129 132 135 138 141 144 147 150 153 156 + + + + + -0.0135503 -0.083935 0 -0.00872063 -0.0852291 0 -0.00872063 -0.0852291 0.001 -0.0135503 -0.083935 0.001 -0.0135503 -0.083935 0 -0.00872063 -0.0852291 0 -0.0025 -7.94306e-17 0 -0.00742685 -0.0563141 0 -0.00373406 -0.0282646 0 -0.0135503 0.083935 0 -0.00373406 0.0282646 0 -0.00742685 0.0563141 0 -0.00872063 0.0852291 0 0.0025 -8.06552e-17 0 0.00124691 0.0287004 0 -0.00250281 0.0571823 0 -0.00250281 -0.0571823 0 0.00124691 -0.0287004 0 -0.00872063 -0.0852291 0 -0.00872063 -0.0852291 0.001 0.0025 -8.06552e-17 0.001 -0.00250281 -0.0571823 0.001 0.00124691 -0.0287004 0.001 0.0025 -8.06552e-17 0 -0.00250281 -0.0571823 0 0.00124691 -0.0287004 0 -0.0135503 -0.083935 0.001 -0.00872063 -0.0852291 0.001 -0.0025 -7.94306e-17 0.001 -0.00742685 -0.0563141 0.001 -0.00373406 -0.0282646 0.001 -0.0135503 0.083935 0.001 -0.00373406 0.0282646 0.001 -0.00742685 0.0563141 0.001 -0.00872063 0.0852291 0.001 0.0025 -8.06552e-17 0.001 0.00124691 0.0287004 0.001 -0.00250281 0.0571823 0.001 -0.00250281 -0.0571823 0.001 0.00124691 -0.0287004 0.001 -0.0135503 -0.083935 0 -0.0135503 -0.083935 0.001 -0.0025 -7.94306e-17 0.001 -0.00742685 -0.0563141 0.001 -0.00373406 -0.0282646 0.001 -0.0025 -7.94306e-17 0 -0.00742685 -0.0563141 0 -0.00373406 -0.0282646 0 -0.0025 -7.94306e-17 0 -0.0025 -7.94306e-17 0.001 -0.0135503 0.083935 0.001 -0.00373406 0.0282646 0.001 -0.00742685 0.0563141 0.001 -0.0135503 0.083935 0 -0.00373406 0.0282646 0 -0.00742685 0.0563141 0 -0.0135503 0.083935 0 -0.00872063 0.0852291 0 -0.00872063 0.0852291 0.001 -0.0135503 0.083935 0.001 0.0025 -8.06552e-17 0 0.0025 -8.06552e-17 0.001 -0.00872063 0.0852291 0.001 0.00124691 0.0287004 0.001 -0.00250281 0.0571823 0.001 -0.00872063 0.0852291 0 0.00124691 0.0287004 0 -0.00250281 0.0571823 0 + + + 1 3 2 1 0 3 16 4 5 16 7 4 17 8 7 17 7 16 6 8 17 13 6 17 10 6 13 14 10 13 15 11 10 15 10 14 12 9 11 12 11 15 21 19 18 21 18 24 22 24 25 22 21 24 20 25 23 20 22 25 38 26 27 38 29 26 39 30 29 39 29 38 28 30 39 35 28 39 32 28 35 36 32 35 37 33 32 37 32 36 34 31 33 34 33 37 43 41 40 43 40 46 44 46 47 44 43 46 42 47 45 42 44 47 51 49 48 51 48 54 52 54 55 52 51 54 50 55 53 50 52 55 58 56 59 57 56 58 63 61 60 63 60 66 64 66 67 64 63 66 62 67 65 62 64 67 + 3 6 9 12 15 18 21 24 27 30 33 36 39 42 45 48 51 54 57 60 63 66 69 72 75 78 81 84 87 90 93 96 99 102 105 108 111 114 117 120 123 126 129 132 135 138 141 144 147 150 153 156 + + + + + -0.0137206 -0.0852291 0 -0.008891 -0.0865232 0 -0.008891 -0.0865232 0.001 -0.0137206 -0.0852291 0.001 -0.0137206 -0.0852291 0 -0.008891 -0.0865232 0 -0.0025 -8.06552e-17 0 -0.00750281 -0.0571823 0 -0.00375309 -0.0287004 0 -0.0137206 0.0852291 0 -0.00375309 0.0287004 0 -0.00750281 0.0571823 0 -0.008891 0.0865232 0 0.0025 -8.18799e-17 0 0.00122789 0.0291362 0 -0.00257877 0.0580506 0 -0.00257877 -0.0580506 0 0.00122789 -0.0291362 0 -0.008891 -0.0865232 0 -0.008891 -0.0865232 0.001 0.0025 -8.18799e-17 0.001 -0.00257877 -0.0580506 0.001 0.00122789 -0.0291362 0.001 0.0025 -8.18799e-17 0 -0.00257877 -0.0580506 0 0.00122789 -0.0291362 0 -0.0137206 -0.0852291 0.001 -0.008891 -0.0865232 0.001 -0.0025 -8.06552e-17 0.001 -0.00750281 -0.0571823 0.001 -0.00375309 -0.0287004 0.001 -0.0137206 0.0852291 0.001 -0.00375309 0.0287004 0.001 -0.00750281 0.0571823 0.001 -0.008891 0.0865232 0.001 0.0025 -8.18799e-17 0.001 0.00122789 0.0291362 0.001 -0.00257877 0.0580506 0.001 -0.00257877 -0.0580506 0.001 0.00122789 -0.0291362 0.001 -0.0137206 -0.0852291 0 -0.0137206 -0.0852291 0.001 -0.0025 -8.06552e-17 0.001 -0.00750281 -0.0571823 0.001 -0.00375309 -0.0287004 0.001 -0.0025 -8.06552e-17 0 -0.00750281 -0.0571823 0 -0.00375309 -0.0287004 0 -0.0025 -8.06552e-17 0 -0.0025 -8.06552e-17 0.001 -0.0137206 0.0852291 0.001 -0.00375309 0.0287004 0.001 -0.00750281 0.0571823 0.001 -0.0137206 0.0852291 0 -0.00375309 0.0287004 0 -0.00750281 0.0571823 0 -0.0137206 0.0852291 0 -0.008891 0.0865232 0 -0.008891 0.0865232 0.001 -0.0137206 0.0852291 0.001 0.0025 -8.18799e-17 0 0.0025 -8.18799e-17 0.001 -0.008891 0.0865232 0.001 0.00122789 0.0291362 0.001 -0.00257877 0.0580506 0.001 -0.008891 0.0865232 0 0.00122789 0.0291362 0 -0.00257877 0.0580506 0 + + + 1 3 2 1 0 3 16 4 5 16 7 4 17 8 7 17 7 16 6 8 17 13 6 17 10 6 13 14 10 13 15 11 10 15 10 14 12 9 11 12 11 15 21 19 18 21 18 24 22 24 25 22 21 24 20 25 23 20 22 25 38 26 27 38 29 26 39 30 29 39 29 38 28 30 39 35 28 39 32 28 35 36 32 35 37 33 32 37 32 36 34 31 33 34 33 37 43 41 40 43 40 46 44 46 47 44 43 46 42 47 45 42 44 47 51 49 48 51 48 54 52 54 55 52 51 54 50 55 53 50 52 55 58 56 59 57 56 58 63 61 60 63 60 66 64 66 67 64 63 66 62 67 65 62 64 67 + 3 6 9 12 15 18 21 24 27 30 33 36 39 42 45 48 51 54 57 60 63 66 69 72 75 78 81 84 87 90 93 96 99 102 105 108 111 114 117 120 123 126 129 132 135 138 141 144 147 150 153 156 + + + + + -0.0138876 -0.0864973 0 -0.00905796 -0.0877914 0 -0.00905796 -0.0877914 0.001 -0.0138876 -0.0864973 0.001 -0.0138876 -0.0864973 0 -0.00905796 -0.0877914 0 -0.0025 -8.18554e-17 0 -0.00757725 -0.0580332 0 -0.00377173 -0.0291274 0 -0.0138876 0.0864973 0 -0.00377173 0.0291274 0 -0.00757725 0.0580332 0 -0.00905796 0.0877914 0 0.0025 -8.308e-17 0 0.00120924 0.0295632 0 -0.00265321 0.0589015 0 -0.00265321 -0.0589015 0 0.00120924 -0.0295632 0 -0.00905796 -0.0877914 0 -0.00905796 -0.0877914 0.001 0.0025 -8.308e-17 0.001 -0.00265321 -0.0589015 0.001 0.00120924 -0.0295632 0.001 0.0025 -8.308e-17 0 -0.00265321 -0.0589015 0 0.00120924 -0.0295632 0 -0.0138876 -0.0864973 0.001 -0.00905796 -0.0877914 0.001 -0.0025 -8.18554e-17 0.001 -0.00757725 -0.0580332 0.001 -0.00377173 -0.0291274 0.001 -0.0138876 0.0864973 0.001 -0.00377173 0.0291274 0.001 -0.00757725 0.0580332 0.001 -0.00905796 0.0877914 0.001 0.0025 -8.308e-17 0.001 0.00120924 0.0295632 0.001 -0.00265321 0.0589015 0.001 -0.00265321 -0.0589015 0.001 0.00120924 -0.0295632 0.001 -0.0138876 -0.0864973 0 -0.0138876 -0.0864973 0.001 -0.0025 -8.18554e-17 0.001 -0.00757725 -0.0580332 0.001 -0.00377173 -0.0291274 0.001 -0.0025 -8.18554e-17 0 -0.00757725 -0.0580332 0 -0.00377173 -0.0291274 0 -0.0025 -8.18554e-17 0 -0.0025 -8.18554e-17 0.001 -0.0138876 0.0864973 0.001 -0.00377173 0.0291274 0.001 -0.00757725 0.0580332 0.001 -0.0138876 0.0864973 0 -0.00377173 0.0291274 0 -0.00757725 0.0580332 0 -0.0138876 0.0864973 0 -0.00905796 0.0877914 0 -0.00905796 0.0877914 0.001 -0.0138876 0.0864973 0.001 0.0025 -8.308e-17 0 0.0025 -8.308e-17 0.001 -0.00905796 0.0877914 0.001 0.00120924 0.0295632 0.001 -0.00265321 0.0589015 0.001 -0.00905796 0.0877914 0 0.00120924 0.0295632 0 -0.00265321 0.0589015 0 + + + 1 3 2 1 0 3 16 4 5 16 7 4 17 8 7 17 7 16 6 8 17 13 6 17 10 6 13 14 10 13 15 11 10 15 10 14 12 9 11 12 11 15 21 19 18 21 18 24 22 24 25 22 21 24 20 25 23 20 22 25 38 26 27 38 29 26 39 30 29 39 29 38 28 30 39 35 28 39 32 28 35 36 32 35 37 33 32 37 32 36 34 31 33 34 33 37 43 41 40 43 40 46 44 46 47 44 43 46 42 47 45 42 44 47 51 49 48 51 48 54 52 54 55 52 51 54 50 55 53 50 52 55 58 56 59 57 56 58 63 61 60 63 60 66 64 66 67 64 63 66 62 67 65 62 64 67 + 3 6 9 12 15 18 21 24 27 30 33 36 39 42 45 48 51 54 57 60 63 66 69 72 75 78 81 84 87 90 93 96 99 102 105 108 111 114 117 120 123 126 129 132 135 138 141 144 147 150 153 156 + + + + + -0.014058 -0.0877914 0 -0.00922833 -0.0890855 0 -0.00922833 -0.0890855 0.001 -0.014058 -0.0877914 0.001 -0.014058 -0.0877914 0 -0.00922833 -0.0890855 0 -0.0025 -8.308e-17 0 -0.00765321 -0.0589015 0 -0.00379076 -0.0295632 0 -0.014058 0.0877914 0 -0.00379076 0.0295632 0 -0.00765321 0.0589015 0 -0.00922833 0.0890855 0 0.0025 -8.43047e-17 0 0.00119022 0.029999 0 -0.00272917 0.0597697 0 -0.00272917 -0.0597697 0 0.00119022 -0.029999 0 -0.00922833 -0.0890855 0 -0.00922833 -0.0890855 0.001 0.0025 -8.43047e-17 0.001 -0.00272917 -0.0597697 0.001 0.00119022 -0.029999 0.001 0.0025 -8.43047e-17 0 -0.00272917 -0.0597697 0 0.00119022 -0.029999 0 -0.014058 -0.0877914 0.001 -0.00922833 -0.0890855 0.001 -0.0025 -8.308e-17 0.001 -0.00765321 -0.0589015 0.001 -0.00379076 -0.0295632 0.001 -0.014058 0.0877914 0.001 -0.00379076 0.0295632 0.001 -0.00765321 0.0589015 0.001 -0.00922833 0.0890855 0.001 0.0025 -8.43047e-17 0.001 0.00119022 0.029999 0.001 -0.00272917 0.0597697 0.001 -0.00272917 -0.0597697 0.001 0.00119022 -0.029999 0.001 -0.014058 -0.0877914 0 -0.014058 -0.0877914 0.001 -0.0025 -8.308e-17 0.001 -0.00765321 -0.0589015 0.001 -0.00379076 -0.0295632 0.001 -0.0025 -8.308e-17 0 -0.00765321 -0.0589015 0 -0.00379076 -0.0295632 0 -0.0025 -8.308e-17 0 -0.0025 -8.308e-17 0.001 -0.014058 0.0877914 0.001 -0.00379076 0.0295632 0.001 -0.00765321 0.0589015 0.001 -0.014058 0.0877914 0 -0.00379076 0.0295632 0 -0.00765321 0.0589015 0 -0.014058 0.0877914 0 -0.00922833 0.0890855 0 -0.00922833 0.0890855 0.001 -0.014058 0.0877914 0.001 0.0025 -8.43047e-17 0 0.0025 -8.43047e-17 0.001 -0.00922833 0.0890855 0.001 0.00119022 0.029999 0.001 -0.00272917 0.0597697 0.001 -0.00922833 0.0890855 0 0.00119022 0.029999 0 -0.00272917 0.0597697 0 + + + 2 0 3 1 0 2 16 4 5 16 7 4 17 8 7 17 7 16 6 8 17 13 6 17 10 6 13 14 10 13 15 11 10 15 10 14 12 9 11 12 11 15 21 19 18 21 18 24 22 24 25 22 21 24 20 25 23 20 22 25 38 26 27 38 29 26 39 30 29 39 29 38 28 30 39 35 28 39 32 28 35 36 32 35 37 33 32 37 32 36 34 31 33 34 33 37 43 41 40 43 40 46 44 46 47 44 43 46 42 47 45 42 44 47 51 49 48 51 48 54 52 54 55 52 51 54 50 55 53 50 52 55 58 56 59 57 56 58 63 61 60 63 60 66 64 66 67 64 63 66 62 67 65 62 64 67 + 3 6 9 12 15 18 21 24 27 30 33 36 39 42 45 48 51 54 57 60 63 66 69 72 75 78 81 84 87 90 93 96 99 102 105 108 111 114 117 120 123 126 129 132 135 138 141 144 147 150 153 156 + + + + + -0.0142249 -0.0890596 0 -0.00939529 -0.0903537 0 -0.00939529 -0.0903537 0.001 -0.0142249 -0.0890596 0.001 -0.0142249 -0.0890596 0 -0.00939529 -0.0903537 0 -0.0025 -8.42802e-17 0 -0.00772765 -0.0597523 0 -0.0038094 -0.0299903 0 -0.0142249 0.0890596 0 -0.0038094 0.0299903 0 -0.00772765 0.0597523 0 -0.00939529 0.0903537 0 0.0025 -8.55048e-17 0 0.00117157 0.0304261 0 -0.00280361 0.0606206 0 -0.00280361 -0.0606206 0 0.00117157 -0.0304261 0 -0.00939529 -0.0903537 0 -0.00939529 -0.0903537 0.001 0.0025 -8.55048e-17 0.001 -0.00280361 -0.0606206 0.001 0.00117157 -0.0304261 0.001 0.0025 -8.55048e-17 0 -0.00280361 -0.0606206 0 0.00117157 -0.0304261 0 -0.0142249 -0.0890596 0.001 -0.00939529 -0.0903537 0.001 -0.0025 -8.42802e-17 0.001 -0.00772765 -0.0597523 0.001 -0.0038094 -0.0299903 0.001 -0.0142249 0.0890596 0.001 -0.0038094 0.0299903 0.001 -0.00772765 0.0597523 0.001 -0.00939529 0.0903537 0.001 0.0025 -8.55048e-17 0.001 0.00117157 0.0304261 0.001 -0.00280361 0.0606206 0.001 -0.00280361 -0.0606206 0.001 0.00117157 -0.0304261 0.001 -0.0142249 -0.0890596 0 -0.0142249 -0.0890596 0.001 -0.0025 -8.42802e-17 0.001 -0.00772765 -0.0597523 0.001 -0.0038094 -0.0299903 0.001 -0.0025 -8.42802e-17 0 -0.00772765 -0.0597523 0 -0.0038094 -0.0299903 0 -0.0025 -8.42802e-17 0 -0.0025 -8.42802e-17 0.001 -0.0142249 0.0890596 0.001 -0.0038094 0.0299903 0.001 -0.00772765 0.0597523 0.001 -0.0142249 0.0890596 0 -0.0038094 0.0299903 0 -0.00772765 0.0597523 0 -0.0142249 0.0890596 0 -0.00939529 0.0903537 0 -0.00939529 0.0903537 0.001 -0.0142249 0.0890596 0.001 0.0025 -8.55048e-17 0 0.0025 -8.55048e-17 0.001 -0.00939529 0.0903537 0.001 0.00117157 0.0304261 0.001 -0.00280361 0.0606206 0.001 -0.00939529 0.0903537 0 0.00117157 0.0304261 0 -0.00280361 0.0606206 0 + + + 1 3 2 1 0 3 16 4 5 16 7 4 17 8 7 17 7 16 6 8 17 13 6 17 10 6 13 14 10 13 15 11 10 15 10 14 12 9 11 12 11 15 21 19 18 21 18 24 22 24 25 22 21 24 20 25 23 20 22 25 38 26 27 38 29 26 39 30 29 39 29 38 28 30 39 35 28 39 32 28 35 36 32 35 37 33 32 37 32 36 34 31 33 34 33 37 43 41 40 43 40 46 44 46 47 44 43 46 42 47 45 42 44 47 51 49 48 51 48 54 52 54 55 52 51 54 50 55 53 50 52 55 58 56 59 57 56 58 63 61 60 63 60 66 64 66 67 64 63 66 62 67 65 62 64 67 + 3 6 9 12 15 18 21 24 27 30 33 36 39 42 45 48 51 54 57 60 63 66 69 72 75 78 81 84 87 90 93 96 99 102 105 108 111 114 117 120 123 126 129 132 135 138 141 144 147 150 153 156 + + + + + -0.0143953 -0.0903537 0 -0.00956566 -0.0916478 0 -0.00956566 -0.0916478 0.001 -0.0143953 -0.0903537 0.001 -0.0143953 -0.0903537 0 -0.00956566 -0.0916478 0 -0.0025 -8.55048e-17 0 -0.00780361 -0.0606206 0 -0.00382843 -0.0304261 0 -0.0143953 0.0903537 0 -0.00382843 0.0304261 0 -0.00780361 0.0606206 0 -0.00956566 0.0916478 0 0.0025 -8.67295e-17 0 0.00115254 0.0308618 0 -0.00287957 0.0614888 0 -0.00287957 -0.0614888 0 0.00115254 -0.0308618 0 -0.00956566 -0.0916478 0 -0.00956566 -0.0916478 0.001 0.0025 -8.67295e-17 0.001 -0.00287957 -0.0614888 0.001 0.00115254 -0.0308618 0.001 0.0025 -8.67295e-17 0 -0.00287957 -0.0614888 0 0.00115254 -0.0308618 0 -0.0143953 -0.0903537 0.001 -0.00956566 -0.0916478 0.001 -0.0025 -8.55048e-17 0.001 -0.00780361 -0.0606206 0.001 -0.00382843 -0.0304261 0.001 -0.0143953 0.0903537 0.001 -0.00382843 0.0304261 0.001 -0.00780361 0.0606206 0.001 -0.00956566 0.0916478 0.001 0.0025 -8.67295e-17 0.001 0.00115254 0.0308618 0.001 -0.00287957 0.0614888 0.001 -0.00287957 -0.0614888 0.001 0.00115254 -0.0308618 0.001 -0.0143953 -0.0903537 0 -0.0143953 -0.0903537 0.001 -0.0025 -8.55048e-17 0.001 -0.00780361 -0.0606206 0.001 -0.00382843 -0.0304261 0.001 -0.0025 -8.55048e-17 0 -0.00780361 -0.0606206 0 -0.00382843 -0.0304261 0 -0.0025 -8.55048e-17 0 -0.0025 -8.55048e-17 0.001 -0.0143953 0.0903537 0.001 -0.00382843 0.0304261 0.001 -0.00780361 0.0606206 0.001 -0.0143953 0.0903537 0 -0.00382843 0.0304261 0 -0.00780361 0.0606206 0 -0.0143953 0.0903537 0 -0.00956566 0.0916478 0 -0.00956566 0.0916478 0.001 -0.0143953 0.0903537 0.001 0.0025 -8.67295e-17 0 0.0025 -8.67295e-17 0.001 -0.00956566 0.0916478 0.001 0.00115254 0.0308618 0.001 -0.00287957 0.0614888 0.001 -0.00956566 0.0916478 0 0.00115254 0.0308618 0 -0.00287957 0.0614888 0 + + + 1 3 2 1 0 3 16 4 5 16 7 4 17 8 7 17 7 16 6 8 17 13 6 17 10 6 13 14 10 13 15 11 10 15 10 14 12 9 11 12 11 15 21 19 18 21 18 24 22 24 25 22 21 24 20 25 23 20 22 25 38 26 27 38 29 26 39 30 29 39 29 38 28 30 39 35 28 39 32 28 35 36 32 35 37 33 32 37 32 36 31 33 37 34 31 37 43 41 40 43 40 46 44 46 47 44 43 46 42 47 45 42 44 47 51 49 48 51 48 54 52 54 55 52 51 54 50 55 53 50 52 55 58 56 59 57 56 58 63 61 60 63 60 66 64 66 67 64 63 66 62 67 65 62 64 67 + 3 6 9 12 15 18 21 24 27 30 33 36 39 42 45 48 51 54 57 60 63 66 69 72 75 78 81 84 87 90 93 96 99 102 105 108 111 114 117 120 123 126 129 132 135 138 141 144 147 150 153 156 + + + + + -0.0145623 -0.0916219 0 -0.00973263 -0.092916 0 -0.00973263 -0.092916 0.001 -0.0145623 -0.0916219 0.001 -0.0145623 -0.0916219 0 -0.00973263 -0.092916 0 -0.0025 -8.6705e-17 0 -0.00787806 -0.0614715 0 -0.00384708 -0.0308531 0 -0.0145623 0.0916219 0 -0.00384708 0.0308531 0 -0.00787806 0.0614715 0 -0.00973263 0.092916 0 0.0025 -8.79296e-17 0 0.0011339 0.0312889 0 -0.00295402 0.0623397 0 -0.00295402 -0.0623397 0 0.0011339 -0.0312889 0 -0.00973263 -0.092916 0 -0.00973263 -0.092916 0.001 0.0025 -8.79296e-17 0.001 -0.00295402 -0.0623397 0.001 0.0011339 -0.0312889 0.001 0.0025 -8.79296e-17 0 -0.00295402 -0.0623397 0 0.0011339 -0.0312889 0 -0.0145623 -0.0916219 0.001 -0.00973263 -0.092916 0.001 -0.0025 -8.6705e-17 0.001 -0.00787806 -0.0614715 0.001 -0.00384708 -0.0308531 0.001 -0.0145623 0.0916219 0.001 -0.00384708 0.0308531 0.001 -0.00787806 0.0614715 0.001 -0.00973263 0.092916 0.001 0.0025 -8.79296e-17 0.001 0.0011339 0.0312889 0.001 -0.00295402 0.0623397 0.001 -0.00295402 -0.0623397 0.001 0.0011339 -0.0312889 0.001 -0.0145623 -0.0916219 0 -0.0145623 -0.0916219 0.001 -0.0025 -8.6705e-17 0.001 -0.00787806 -0.0614715 0.001 -0.00384708 -0.0308531 0.001 -0.0025 -8.6705e-17 0 -0.00787806 -0.0614715 0 -0.00384708 -0.0308531 0 -0.0025 -8.6705e-17 0 -0.0025 -8.6705e-17 0.001 -0.0145623 0.0916219 0.001 -0.00384708 0.0308531 0.001 -0.00787806 0.0614715 0.001 -0.0145623 0.0916219 0 -0.00384708 0.0308531 0 -0.00787806 0.0614715 0 -0.0145623 0.0916219 0 -0.00973263 0.092916 0 -0.00973263 0.092916 0.001 -0.0145623 0.0916219 0.001 0.0025 -8.79296e-17 0 0.0025 -8.79296e-17 0.001 -0.00973263 0.092916 0.001 0.0011339 0.0312889 0.001 -0.00295402 0.0623397 0.001 -0.00973263 0.092916 0 0.0011339 0.0312889 0 -0.00295402 0.0623397 0 + + + 1 3 2 1 0 3 16 4 5 16 7 4 17 8 7 17 7 16 6 8 17 13 6 17 10 6 13 14 10 13 15 11 10 15 10 14 12 9 11 12 11 15 21 19 18 21 18 24 22 24 25 22 21 24 20 25 23 20 22 25 38 26 27 38 29 26 39 30 29 39 29 38 28 30 39 35 28 39 32 28 35 36 32 35 37 33 32 37 32 36 34 31 33 34 33 37 43 41 40 43 40 46 44 46 47 44 43 46 42 47 45 42 44 47 51 49 48 51 48 54 52 54 55 52 51 54 50 55 53 50 52 55 58 56 59 57 56 58 63 61 60 63 60 66 64 66 67 64 63 66 62 67 65 62 64 67 + 3 6 9 12 15 18 21 24 27 30 33 36 39 42 45 48 51 54 57 60 63 66 69 72 75 78 81 84 87 90 93 96 99 102 105 108 111 114 117 120 123 126 129 132 135 138 141 144 147 150 153 156 + + + + + -0.0147326 -0.092916 0 -0.009903 -0.0942101 0 -0.009903 -0.0942101 0.001 -0.0147326 -0.092916 0.001 -0.0147326 -0.092916 0 -0.009903 -0.0942101 0 -0.0025 -8.79296e-17 0 -0.00795402 -0.0623397 0 -0.0038661 -0.0312889 0 -0.0147326 0.092916 0 -0.0038661 0.0312889 0 -0.00795402 0.0623397 0 -0.009903 0.0942101 0 0.0025 -8.91543e-17 0 0.00111487 0.0317247 0 -0.00302998 0.0632079 0 -0.00302998 -0.0632079 0 0.00111487 -0.0317247 0 -0.009903 -0.0942101 0 -0.009903 -0.0942101 0.001 0.0025 -8.91543e-17 0.001 -0.00302998 -0.0632079 0.001 0.00111487 -0.0317247 0.001 0.0025 -8.91543e-17 0 -0.00302998 -0.0632079 0 0.00111487 -0.0317247 0 -0.0147326 -0.092916 0.001 -0.009903 -0.0942101 0.001 -0.0025 -8.79296e-17 0.001 -0.00795402 -0.0623397 0.001 -0.0038661 -0.0312889 0.001 -0.0147326 0.092916 0.001 -0.0038661 0.0312889 0.001 -0.00795402 0.0623397 0.001 -0.009903 0.0942101 0.001 0.0025 -8.91543e-17 0.001 0.00111487 0.0317247 0.001 -0.00302998 0.0632079 0.001 -0.00302998 -0.0632079 0.001 0.00111487 -0.0317247 0.001 -0.0147326 -0.092916 0 -0.0147326 -0.092916 0.001 -0.0025 -8.79296e-17 0.001 -0.00795402 -0.0623397 0.001 -0.0038661 -0.0312889 0.001 -0.0025 -8.79296e-17 0 -0.00795402 -0.0623397 0 -0.0038661 -0.0312889 0 -0.0025 -8.79296e-17 0 -0.0025 -8.79296e-17 0.001 -0.0147326 0.092916 0.001 -0.0038661 0.0312889 0.001 -0.00795402 0.0623397 0.001 -0.0147326 0.092916 0 -0.0038661 0.0312889 0 -0.00795402 0.0623397 0 -0.0147326 0.092916 0 -0.009903 0.0942101 0 -0.009903 0.0942101 0.001 -0.0147326 0.092916 0.001 0.0025 -8.91543e-17 0 0.0025 -8.91543e-17 0.001 -0.009903 0.0942101 0.001 0.00111487 0.0317247 0.001 -0.00302998 0.0632079 0.001 -0.009903 0.0942101 0 0.00111487 0.0317247 0 -0.00302998 0.0632079 0 + + + 1 3 2 1 0 3 16 4 5 16 7 4 17 8 7 17 7 16 6 8 17 13 6 17 10 6 13 14 10 13 15 11 10 15 10 14 12 9 11 12 11 15 21 19 18 21 18 24 22 24 25 22 21 24 20 25 23 20 22 25 38 26 27 38 29 26 39 30 29 39 29 38 28 30 39 35 28 39 32 28 35 36 32 35 37 33 32 37 32 36 34 31 33 34 33 37 43 41 40 43 40 46 44 46 47 44 43 46 42 47 45 42 44 47 51 49 48 51 48 54 52 54 55 52 51 54 50 55 53 50 52 55 58 56 59 57 56 58 63 61 60 63 60 66 64 66 67 64 63 66 62 67 65 62 64 67 + 3 6 9 12 15 18 21 24 27 30 33 36 39 42 45 48 51 54 57 60 63 66 69 72 75 78 81 84 87 90 93 96 99 102 105 108 111 114 117 120 123 126 129 132 135 138 141 144 147 150 153 156 + + + + + -0.0148996 -0.0941843 0 -0.01007 -0.0954783 0 -0.01007 -0.0954783 0.001 -0.0148996 -0.0941843 0.001 -0.0148996 -0.0941843 0 -0.01007 -0.0954783 0 -0.0025 -8.91298e-17 0 -0.00802846 -0.0631906 0 -0.00388475 -0.031716 0 -0.0148996 0.0941843 0 -0.00388475 0.031716 0 -0.00802846 0.0631906 0 -0.01007 0.0954783 0 0.0025 -9.03544e-17 0 0.00109622 0.0321518 0 -0.00310442 0.0640588 0 -0.00310442 -0.0640588 0 0.00109622 -0.0321518 0 -0.01007 -0.0954783 0 -0.01007 -0.0954783 0.001 0.0025 -9.03544e-17 0.001 -0.00310442 -0.0640588 0.001 0.00109622 -0.0321518 0.001 0.0025 -9.03544e-17 0 -0.00310442 -0.0640588 0 0.00109622 -0.0321518 0 -0.0148996 -0.0941843 0.001 -0.01007 -0.0954783 0.001 -0.0025 -8.91298e-17 0.001 -0.00802846 -0.0631906 0.001 -0.00388475 -0.031716 0.001 -0.0148996 0.0941843 0.001 -0.00388475 0.031716 0.001 -0.00802846 0.0631906 0.001 -0.01007 0.0954783 0.001 0.0025 -9.03544e-17 0.001 0.00109622 0.0321518 0.001 -0.00310442 0.0640588 0.001 -0.00310442 -0.0640588 0.001 0.00109622 -0.0321518 0.001 -0.0148996 -0.0941843 0 -0.0148996 -0.0941843 0.001 -0.0025 -8.91298e-17 0.001 -0.00802846 -0.0631906 0.001 -0.00388475 -0.031716 0.001 -0.0025 -8.91298e-17 0 -0.00802846 -0.0631906 0 -0.00388475 -0.031716 0 -0.0025 -8.91298e-17 0 -0.0025 -8.91298e-17 0.001 -0.0148996 0.0941843 0.001 -0.00388475 0.031716 0.001 -0.00802846 0.0631906 0.001 -0.0148996 0.0941843 0 -0.00388475 0.031716 0 -0.00802846 0.0631906 0 -0.0148996 0.0941843 0 -0.01007 0.0954783 0 -0.01007 0.0954783 0.001 -0.0148996 0.0941843 0.001 0.0025 -9.03544e-17 0 0.0025 -9.03544e-17 0.001 -0.01007 0.0954783 0.001 0.00109622 0.0321518 0.001 -0.00310442 0.0640588 0.001 -0.01007 0.0954783 0 0.00109622 0.0321518 0 -0.00310442 0.0640588 0 + + + 2 0 3 1 0 2 16 4 5 16 7 4 17 8 7 17 7 16 6 8 17 13 6 17 10 6 13 14 10 13 15 11 10 15 10 14 9 11 15 12 9 15 21 19 18 21 18 24 22 24 25 22 21 24 20 25 23 20 22 25 38 26 27 38 29 26 39 30 29 39 29 38 28 30 39 35 28 39 32 28 35 36 32 35 37 33 32 37 32 36 31 33 37 34 31 37 43 41 40 43 40 46 44 46 47 44 43 46 42 47 45 42 44 47 51 49 48 51 48 54 52 54 55 52 51 54 50 55 53 50 52 55 58 56 59 57 56 58 63 61 60 63 60 66 64 66 67 64 63 66 62 67 65 62 64 67 + 3 6 9 12 15 18 21 24 27 30 33 36 39 42 45 48 51 54 57 60 63 66 69 72 75 78 81 84 87 90 93 96 99 102 105 108 111 114 117 120 123 126 129 132 135 138 141 144 147 150 153 156 + + + + + -0.0150666 -0.0954525 0 -0.0102369 -0.0967466 0 -0.0102369 -0.0967466 0.001 -0.0150666 -0.0954525 0.001 -0.0150666 -0.0954525 0 -0.0102369 -0.0967466 0 -0.0025 -9.03299e-17 0 -0.0081029 -0.0640414 0 -0.0039034 -0.032143 0 -0.0150666 0.0954525 0 -0.0039034 0.032143 0 -0.0081029 0.0640414 0 -0.0102369 0.0967466 0 0.0025 -9.15546e-17 0 0.00107758 0.0325788 0 -0.00317886 0.0649097 0 -0.00317886 -0.0649097 0 0.00107758 -0.0325788 0 -0.0102369 -0.0967466 0 -0.0102369 -0.0967466 0.001 0.0025 -9.15546e-17 0.001 -0.00317886 -0.0649097 0.001 0.00107758 -0.0325788 0.001 0.0025 -9.15546e-17 0 -0.00317886 -0.0649097 0 0.00107758 -0.0325788 0 -0.0150666 -0.0954525 0.001 -0.0102369 -0.0967466 0.001 -0.0025 -9.03299e-17 0.001 -0.0081029 -0.0640414 0.001 -0.0039034 -0.032143 0.001 -0.0150666 0.0954525 0.001 -0.0039034 0.032143 0.001 -0.0081029 0.0640414 0.001 -0.0102369 0.0967466 0.001 0.0025 -9.15546e-17 0.001 0.00107758 0.0325788 0.001 -0.00317886 0.0649097 0.001 -0.00317886 -0.0649097 0.001 0.00107758 -0.0325788 0.001 -0.0150666 -0.0954525 0 -0.0150666 -0.0954525 0.001 -0.0025 -9.03299e-17 0.001 -0.0081029 -0.0640414 0.001 -0.0039034 -0.032143 0.001 -0.0025 -9.03299e-17 0 -0.0081029 -0.0640414 0 -0.0039034 -0.032143 0 -0.0025 -9.03299e-17 0 -0.0025 -9.03299e-17 0.001 -0.0150666 0.0954525 0.001 -0.0039034 0.032143 0.001 -0.0081029 0.0640414 0.001 -0.0150666 0.0954525 0 -0.0039034 0.032143 0 -0.0081029 0.0640414 0 -0.0150666 0.0954525 0 -0.0102369 0.0967466 0 -0.0102369 0.0967466 0.001 -0.0150666 0.0954525 0.001 0.0025 -9.15546e-17 0 0.0025 -9.15546e-17 0.001 -0.0102369 0.0967466 0.001 0.00107758 0.0325788 0.001 -0.00317886 0.0649097 0.001 -0.0102369 0.0967466 0 0.00107758 0.0325788 0 -0.00317886 0.0649097 0 + + + 2 0 3 1 0 2 16 4 5 16 7 4 8 7 16 17 8 16 6 8 17 13 6 17 10 6 13 14 10 13 15 11 10 15 10 14 12 9 11 12 11 15 21 19 18 21 18 24 22 24 25 22 21 24 20 25 23 20 22 25 38 26 27 38 29 26 30 29 38 39 30 38 28 30 39 35 28 39 32 28 35 36 32 35 37 33 32 37 32 36 34 31 33 34 33 37 43 41 40 43 40 46 44 46 47 44 43 46 42 47 45 42 44 47 51 49 48 51 48 54 52 54 55 52 51 54 50 55 53 50 52 55 58 56 59 57 56 58 63 61 60 63 60 66 64 66 67 64 63 66 62 67 65 62 64 67 + 3 6 9 12 15 18 21 24 27 30 33 36 39 42 45 48 51 54 57 60 63 66 69 72 75 78 81 84 87 90 93 96 99 102 105 108 111 114 117 120 123 126 129 132 135 138 141 144 147 150 153 156 + + + + + -0.0106744 -0.0620907 0 -0.00584477 -0.0633848 0 -0.00584477 -0.0633848 0.001 -0.0106744 -0.0620907 0.001 -0.0106744 -0.0620907 0 -0.00584477 -0.0633848 0 -0.0025 -5.87586e-17 0 -0.00614462 -0.0416582 0 -0.00341289 -0.0209087 0 -0.0106744 0.0620907 0 -0.00341289 0.0209087 0 -0.00614462 0.0416582 0 -0.00584477 0.0633848 0 0.0025 -5.99832e-17 0 0.00156808 0.0213444 0 -0.00122058 0.0425264 0 -0.00122058 -0.0425264 0 0.00156808 -0.0213444 0 -0.00584477 -0.0633848 0 -0.00584477 -0.0633848 0.001 0.0025 -5.99832e-17 0.001 -0.00122058 -0.0425264 0.001 0.00156808 -0.0213444 0.001 0.0025 -5.99832e-17 0 -0.00122058 -0.0425264 0 0.00156808 -0.0213444 0 -0.0106744 -0.0620907 0.001 -0.00584477 -0.0633848 0.001 -0.0025 -5.87586e-17 0.001 -0.00614462 -0.0416582 0.001 -0.00341289 -0.0209087 0.001 -0.0106744 0.0620907 0.001 -0.00341289 0.0209087 0.001 -0.00614462 0.0416582 0.001 -0.00584477 0.0633848 0.001 0.0025 -5.99832e-17 0.001 0.00156808 0.0213444 0.001 -0.00122058 0.0425264 0.001 -0.00122058 -0.0425264 0.001 0.00156808 -0.0213444 0.001 -0.0106744 -0.0620907 0 -0.0106744 -0.0620907 0.001 -0.0025 -5.87586e-17 0.001 -0.00614462 -0.0416582 0.001 -0.00341289 -0.0209087 0.001 -0.0025 -5.87586e-17 0 -0.00614462 -0.0416582 0 -0.00341289 -0.0209087 0 -0.0025 -5.87586e-17 0 -0.0025 -5.87586e-17 0.001 -0.0106744 0.0620907 0.001 -0.00341289 0.0209087 0.001 -0.00614462 0.0416582 0.001 -0.0106744 0.0620907 0 -0.00341289 0.0209087 0 -0.00614462 0.0416582 0 -0.0106744 0.0620907 0 -0.00584477 0.0633848 0 -0.00584477 0.0633848 0.001 -0.0106744 0.0620907 0.001 0.0025 -5.99832e-17 0 0.0025 -5.99832e-17 0.001 -0.00584477 0.0633848 0.001 0.00156808 0.0213444 0.001 -0.00122058 0.0425264 0.001 -0.00584477 0.0633848 0 0.00156808 0.0213444 0 -0.00122058 0.0425264 0 + + + 2 0 3 1 0 2 16 4 5 16 7 4 17 8 7 17 7 16 13 6 8 13 8 17 10 6 13 14 10 13 15 11 10 15 10 14 12 9 11 12 11 15 21 19 18 21 18 24 22 24 25 22 21 24 20 25 23 20 22 25 38 26 27 38 29 26 39 30 29 39 29 38 35 28 30 35 30 39 32 28 35 36 32 35 37 33 32 37 32 36 34 31 33 34 33 37 43 41 40 43 40 46 44 46 47 44 43 46 42 47 45 42 44 47 51 49 48 51 48 54 52 54 55 52 51 54 50 55 53 50 52 55 58 56 59 57 56 58 63 61 60 63 60 66 64 66 67 64 63 66 62 67 65 62 64 67 + 3 6 9 12 15 18 21 24 27 30 33 36 39 42 45 48 51 54 57 60 63 66 69 72 75 78 81 84 87 90 93 96 99 102 105 108 111 114 117 120 123 126 129 132 135 138 141 144 147 150 153 156 + + + + + -0.0152369 -0.0967466 0 -0.0104073 -0.0980407 0 -0.0104073 -0.0980407 0.001 -0.0152369 -0.0967466 0.001 -0.0152369 -0.0967466 0 -0.0104073 -0.0980407 0 -0.0025 -9.15546e-17 0 -0.00817886 -0.0649097 0 -0.00392242 -0.0325788 0 -0.0152369 0.0967466 0 -0.00392242 0.0325788 0 -0.00817886 0.0649097 0 -0.0104073 0.0980407 0 0.0025 -9.27792e-17 0 0.00105855 0.0330146 0 -0.00325482 0.0657779 0 -0.00325482 -0.0657779 0 0.00105855 -0.0330146 0 -0.0104073 -0.0980407 0 -0.0104073 -0.0980407 0.001 0.0025 -9.27792e-17 0.001 -0.00325482 -0.0657779 0.001 0.00105855 -0.0330146 0.001 0.0025 -9.27792e-17 0 -0.00325482 -0.0657779 0 0.00105855 -0.0330146 0 -0.0152369 -0.0967466 0.001 -0.0104073 -0.0980407 0.001 -0.0025 -9.15546e-17 0.001 -0.00817886 -0.0649097 0.001 -0.00392242 -0.0325788 0.001 -0.0152369 0.0967466 0.001 -0.00392242 0.0325788 0.001 -0.00817886 0.0649097 0.001 -0.0104073 0.0980407 0.001 0.0025 -9.27792e-17 0.001 0.00105855 0.0330146 0.001 -0.00325482 0.0657779 0.001 -0.00325482 -0.0657779 0.001 0.00105855 -0.0330146 0.001 -0.0152369 -0.0967466 0 -0.0152369 -0.0967466 0.001 -0.0025 -9.15546e-17 0.001 -0.00817886 -0.0649097 0.001 -0.00392242 -0.0325788 0.001 -0.0025 -9.15546e-17 0 -0.00817886 -0.0649097 0 -0.00392242 -0.0325788 0 -0.0025 -9.15546e-17 0 -0.0025 -9.15546e-17 0.001 -0.0152369 0.0967466 0.001 -0.00392242 0.0325788 0.001 -0.00817886 0.0649097 0.001 -0.0152369 0.0967466 0 -0.00392242 0.0325788 0 -0.00817886 0.0649097 0 -0.0152369 0.0967466 0 -0.0104073 0.0980407 0 -0.0104073 0.0980407 0.001 -0.0152369 0.0967466 0.001 0.0025 -9.27792e-17 0 0.0025 -9.27792e-17 0.001 -0.0104073 0.0980407 0.001 0.00105855 0.0330146 0.001 -0.00325482 0.0657779 0.001 -0.0104073 0.0980407 0 0.00105855 0.0330146 0 -0.00325482 0.0657779 0 + + + 1 3 2 1 0 3 16 4 5 16 7 4 17 8 7 17 7 16 6 8 17 13 6 17 10 6 13 14 10 13 15 11 10 15 10 14 12 9 11 12 11 15 21 19 18 21 18 24 22 24 25 22 21 24 20 25 23 20 22 25 38 26 27 38 29 26 39 30 29 39 29 38 28 30 39 35 28 39 32 28 35 36 32 35 37 33 32 37 32 36 34 31 33 34 33 37 43 41 40 43 40 46 44 46 47 44 43 46 42 47 45 42 44 47 51 49 48 51 48 54 52 54 55 52 51 54 50 55 53 50 52 55 58 56 59 57 56 58 63 61 60 63 60 66 64 66 67 64 63 66 62 67 65 62 64 67 + 3 6 9 12 15 18 21 24 27 30 33 36 39 42 45 48 51 54 57 60 63 66 69 72 75 78 81 84 87 90 93 96 99 102 105 108 111 114 117 120 123 126 129 132 135 138 141 144 147 150 153 156 + + + + + -0.0154039 -0.0980148 0 -0.0105743 -0.0993089 0 -0.0105743 -0.0993089 0.001 -0.0154039 -0.0980148 0.001 -0.0154039 -0.0980148 0 -0.0105743 -0.0993089 0 -0.0025 -9.27547e-17 0 -0.0082533 -0.0657606 0 -0.00394107 -0.0330059 0 -0.0154039 0.0980148 0 -0.00394107 0.0330059 0 -0.0082533 0.0657606 0 -0.0105743 0.0993089 0 0.0025 -9.39794e-17 0 0.00103991 0.0334417 0 -0.00332927 0.0666288 0 -0.00332927 -0.0666288 0 0.00103991 -0.0334417 0 -0.0105743 -0.0993089 0 -0.0105743 -0.0993089 0.001 0.0025 -9.39794e-17 0.001 -0.00332927 -0.0666288 0.001 0.00103991 -0.0334417 0.001 0.0025 -9.39794e-17 0 -0.00332927 -0.0666288 0 0.00103991 -0.0334417 0 -0.0154039 -0.0980148 0.001 -0.0105743 -0.0993089 0.001 -0.0025 -9.27547e-17 0.001 -0.0082533 -0.0657606 0.001 -0.00394107 -0.0330059 0.001 -0.0154039 0.0980148 0.001 -0.00394107 0.0330059 0.001 -0.0082533 0.0657606 0.001 -0.0105743 0.0993089 0.001 0.0025 -9.39794e-17 0.001 0.00103991 0.0334417 0.001 -0.00332927 0.0666288 0.001 -0.00332927 -0.0666288 0.001 0.00103991 -0.0334417 0.001 -0.0154039 -0.0980148 0 -0.0154039 -0.0980148 0.001 -0.0025 -9.27547e-17 0.001 -0.0082533 -0.0657606 0.001 -0.00394107 -0.0330059 0.001 -0.0025 -9.27547e-17 0 -0.0082533 -0.0657606 0 -0.00394107 -0.0330059 0 -0.0025 -9.27547e-17 0 -0.0025 -9.27547e-17 0.001 -0.0154039 0.0980148 0.001 -0.00394107 0.0330059 0.001 -0.0082533 0.0657606 0.001 -0.0154039 0.0980148 0 -0.00394107 0.0330059 0 -0.0082533 0.0657606 0 -0.0154039 0.0980148 0 -0.0105743 0.0993089 0 -0.0105743 0.0993089 0.001 -0.0154039 0.0980148 0.001 0.0025 -9.39794e-17 0 0.0025 -9.39794e-17 0.001 -0.0105743 0.0993089 0.001 0.00103991 0.0334417 0.001 -0.00332927 0.0666288 0.001 -0.0105743 0.0993089 0 0.00103991 0.0334417 0 -0.00332927 0.0666288 0 + + + 1 3 2 1 0 3 16 4 5 16 7 4 17 8 7 17 7 16 6 8 17 13 6 17 10 6 13 14 10 13 15 11 10 15 10 14 12 9 11 12 11 15 21 19 18 21 18 24 22 24 25 22 21 24 20 25 23 20 22 25 38 26 27 38 29 26 39 30 29 39 29 38 28 30 39 35 28 39 32 28 35 36 32 35 37 33 32 37 32 36 34 31 33 34 33 37 43 41 40 43 40 46 44 46 47 44 43 46 42 47 45 42 44 47 51 49 48 51 48 54 52 54 55 52 51 54 50 55 53 50 52 55 58 56 59 57 56 58 63 61 60 63 60 66 64 66 67 64 63 66 62 67 65 62 64 67 + 3 6 9 12 15 18 21 24 27 30 33 36 39 42 45 48 51 54 57 60 63 66 69 72 75 78 81 84 87 90 93 96 99 102 105 108 111 114 117 120 123 126 129 132 135 138 141 144 147 150 153 156 + + + + + -0.0155709 -0.099283 0 -0.0107412 -0.100577 0 -0.0107412 -0.100577 0.001 -0.0155709 -0.099283 0.001 -0.0155709 -0.099283 0 -0.0107412 -0.100577 0 -0.0025 -9.39549e-17 0 -0.00832775 -0.0666114 0 -0.00395971 -0.0334329 0 -0.0155709 0.099283 0 -0.00395971 0.0334329 0 -0.00832775 0.0666114 0 -0.0107412 0.100577 0 0.0025 -9.51795e-17 0 0.00102126 0.0338687 0 -0.00340371 0.0674797 0 -0.00340371 -0.0674797 0 0.00102126 -0.0338687 0 -0.0107412 -0.100577 0 -0.0107412 -0.100577 0.001 0.0025 -9.51795e-17 0.001 -0.00340371 -0.0674797 0.001 0.00102126 -0.0338687 0.001 0.0025 -9.51795e-17 0 -0.00340371 -0.0674797 0 0.00102126 -0.0338687 0 -0.0155709 -0.099283 0.001 -0.0107412 -0.100577 0.001 -0.0025 -9.39549e-17 0.001 -0.00832775 -0.0666114 0.001 -0.00395971 -0.0334329 0.001 -0.0155709 0.099283 0.001 -0.00395971 0.0334329 0.001 -0.00832775 0.0666114 0.001 -0.0107412 0.100577 0.001 0.0025 -9.51795e-17 0.001 0.00102126 0.0338687 0.001 -0.00340371 0.0674797 0.001 -0.00340371 -0.0674797 0.001 0.00102126 -0.0338687 0.001 -0.0155709 -0.099283 0 -0.0155709 -0.099283 0.001 -0.0025 -9.39549e-17 0.001 -0.00832775 -0.0666114 0.001 -0.00395971 -0.0334329 0.001 -0.0025 -9.39549e-17 0 -0.00832775 -0.0666114 0 -0.00395971 -0.0334329 0 -0.0025 -9.39549e-17 0 -0.0025 -9.39549e-17 0.001 -0.0155709 0.099283 0.001 -0.00395971 0.0334329 0.001 -0.00832775 0.0666114 0.001 -0.0155709 0.099283 0 -0.00395971 0.0334329 0 -0.00832775 0.0666114 0 -0.0155709 0.099283 0 -0.0107412 0.100577 0 -0.0107412 0.100577 0.001 -0.0155709 0.099283 0.001 0.0025 -9.51795e-17 0 0.0025 -9.51795e-17 0.001 -0.0107412 0.100577 0.001 0.00102126 0.0338687 0.001 -0.00340371 0.0674797 0.001 -0.0107412 0.100577 0 0.00102126 0.0338687 0 -0.00340371 0.0674797 0 + + + 1 3 2 1 0 3 16 4 5 16 7 4 17 8 7 17 7 16 6 8 17 13 6 17 10 6 13 14 10 13 15 11 10 15 10 14 12 9 11 12 11 15 21 19 18 21 18 24 22 24 25 22 21 24 20 25 23 20 22 25 38 26 27 38 29 26 39 30 29 39 29 38 28 30 39 35 28 39 32 28 35 36 32 35 37 33 32 37 32 36 34 31 33 34 33 37 43 41 40 43 40 46 44 46 47 44 43 46 42 47 45 42 44 47 51 49 48 51 48 54 52 54 55 52 51 54 50 55 53 50 52 55 58 56 59 57 56 58 63 61 60 63 60 66 64 66 67 64 63 66 62 67 65 62 64 67 + 3 6 9 12 15 18 21 24 27 30 33 36 39 42 45 48 51 54 57 60 63 66 69 72 75 78 81 84 87 90 93 96 99 102 105 108 111 114 117 120 123 126 129 132 135 138 141 144 147 150 153 156 + + + + + -0.0157412 -0.100577 0 -0.0109116 -0.101871 0 -0.0109116 -0.101871 0.001 -0.0157412 -0.100577 0.001 -0.0157412 -0.100577 0 -0.0109116 -0.101871 0 -0.0025 -9.51795e-17 0 -0.00840371 -0.0674797 0 -0.00397874 -0.0338687 0 -0.0157412 0.100577 0 -0.00397874 0.0338687 0 -0.00840371 0.0674797 0 -0.0109116 0.101871 0 0.0025 -9.64042e-17 0 0.00100223 0.0343045 0 -0.00347967 0.0683479 0 -0.00347967 -0.0683479 0 0.00100223 -0.0343045 0 -0.0109116 -0.101871 0 -0.0109116 -0.101871 0.001 0.0025 -9.64042e-17 0.001 -0.00347967 -0.0683479 0.001 0.00100223 -0.0343045 0.001 0.0025 -9.64042e-17 0 -0.00347967 -0.0683479 0 0.00100223 -0.0343045 0 -0.0157412 -0.100577 0.001 -0.0109116 -0.101871 0.001 -0.0025 -9.51795e-17 0.001 -0.00840371 -0.0674797 0.001 -0.00397874 -0.0338687 0.001 -0.0157412 0.100577 0.001 -0.00397874 0.0338687 0.001 -0.00840371 0.0674797 0.001 -0.0109116 0.101871 0.001 0.0025 -9.64042e-17 0.001 0.00100223 0.0343045 0.001 -0.00347967 0.0683479 0.001 -0.00347967 -0.0683479 0.001 0.00100223 -0.0343045 0.001 -0.0157412 -0.100577 0 -0.0157412 -0.100577 0.001 -0.0025 -9.51795e-17 0.001 -0.00840371 -0.0674797 0.001 -0.00397874 -0.0338687 0.001 -0.0025 -9.51795e-17 0 -0.00840371 -0.0674797 0 -0.00397874 -0.0338687 0 -0.0025 -9.51795e-17 0 -0.0025 -9.51795e-17 0.001 -0.0157412 0.100577 0.001 -0.00397874 0.0338687 0.001 -0.00840371 0.0674797 0.001 -0.0157412 0.100577 0 -0.00397874 0.0338687 0 -0.00840371 0.0674797 0 -0.0157412 0.100577 0 -0.0109116 0.101871 0 -0.0109116 0.101871 0.001 -0.0157412 0.100577 0.001 0.0025 -9.64042e-17 0 0.0025 -9.64042e-17 0.001 -0.0109116 0.101871 0.001 0.00100223 0.0343045 0.001 -0.00347967 0.0683479 0.001 -0.0109116 0.101871 0 0.00100223 0.0343045 0 -0.00347967 0.0683479 0 + + + 1 3 2 1 0 3 16 4 5 16 7 4 8 7 16 17 8 16 6 8 17 13 6 17 10 6 13 14 10 13 15 11 10 15 10 14 9 11 15 12 9 15 21 19 18 21 18 24 22 24 25 22 21 24 20 25 23 20 22 25 38 26 27 38 29 26 30 29 38 39 30 38 28 30 39 35 28 39 32 28 35 36 32 35 37 33 32 37 32 36 31 33 37 34 31 37 43 41 40 43 40 46 44 46 47 44 43 46 42 47 45 42 44 47 51 49 48 51 48 54 52 54 55 52 51 54 50 55 53 50 52 55 58 56 59 57 56 58 63 61 60 63 60 66 64 66 67 64 63 66 62 67 65 62 64 67 + 3 6 9 12 15 18 21 24 27 30 33 36 39 42 45 48 51 54 57 60 63 66 69 72 75 78 81 84 87 90 93 96 99 102 105 108 111 114 117 120 123 126 129 132 135 138 141 144 147 150 153 156 + + + + + -0.0159082 -0.101845 0 -0.0110786 -0.103139 0 -0.0110786 -0.103139 0.001 -0.0159082 -0.101845 0.001 -0.0159082 -0.101845 0 -0.0110786 -0.103139 0 -0.0025 -9.63797e-17 0 -0.00847815 -0.0683306 0 -0.00399739 -0.0342958 0 -0.0159082 0.101845 0 -0.00399739 0.0342958 0 -0.00847815 0.0683306 0 -0.0110786 0.103139 0 0.0025 -9.76043e-17 0 0.000983587 0.0347316 0 -0.00355411 0.0691988 0 -0.00355411 -0.0691988 0 0.000983587 -0.0347316 0 -0.0110786 -0.103139 0 -0.0110786 -0.103139 0.001 0.0025 -9.76043e-17 0.001 -0.00355411 -0.0691988 0.001 0.000983587 -0.0347316 0.001 0.0025 -9.76043e-17 0 -0.00355411 -0.0691988 0 0.000983587 -0.0347316 0 -0.0159082 -0.101845 0.001 -0.0110786 -0.103139 0.001 -0.0025 -9.63797e-17 0.001 -0.00847815 -0.0683306 0.001 -0.00399739 -0.0342958 0.001 -0.0159082 0.101845 0.001 -0.00399739 0.0342958 0.001 -0.00847815 0.0683306 0.001 -0.0110786 0.103139 0.001 0.0025 -9.76043e-17 0.001 0.000983587 0.0347316 0.001 -0.00355411 0.0691988 0.001 -0.00355411 -0.0691988 0.001 0.000983587 -0.0347316 0.001 -0.0159082 -0.101845 0 -0.0159082 -0.101845 0.001 -0.0025 -9.63797e-17 0.001 -0.00847815 -0.0683306 0.001 -0.00399739 -0.0342958 0.001 -0.0025 -9.63797e-17 0 -0.00847815 -0.0683306 0 -0.00399739 -0.0342958 0 -0.0025 -9.63797e-17 0 -0.0025 -9.63797e-17 0.001 -0.0159082 0.101845 0.001 -0.00399739 0.0342958 0.001 -0.00847815 0.0683306 0.001 -0.0159082 0.101845 0 -0.00399739 0.0342958 0 -0.00847815 0.0683306 0 -0.0159082 0.101845 0 -0.0110786 0.103139 0 -0.0110786 0.103139 0.001 -0.0159082 0.101845 0.001 0.0025 -9.76043e-17 0 0.0025 -9.76043e-17 0.001 -0.0110786 0.103139 0.001 0.000983587 0.0347316 0.001 -0.00355411 0.0691988 0.001 -0.0110786 0.103139 0 0.000983587 0.0347316 0 -0.00355411 0.0691988 0 + + + 2 0 3 1 0 2 16 4 5 16 7 4 17 8 7 17 7 16 6 8 17 13 6 17 10 6 13 14 10 13 15 11 10 15 10 14 12 9 11 12 11 15 21 19 18 21 18 24 22 24 25 22 21 24 20 25 23 20 22 25 38 26 27 38 29 26 39 30 29 39 29 38 28 30 39 35 28 39 32 28 35 36 32 35 37 33 32 37 32 36 34 31 33 34 33 37 43 41 40 43 40 46 44 46 47 44 43 46 42 47 45 42 44 47 51 49 48 51 48 54 52 54 55 52 51 54 50 55 53 50 52 55 58 56 59 57 56 58 63 61 60 63 60 66 64 66 67 64 63 66 62 67 65 62 64 67 + 3 6 9 12 15 18 21 24 27 30 33 36 39 42 45 48 51 54 57 60 63 66 69 72 75 78 81 84 87 90 93 96 99 102 105 108 111 114 117 120 123 126 129 132 135 138 141 144 147 150 153 156 + + + + + -0.0160752 -0.103114 0 -0.0112455 -0.104408 0 -0.0112455 -0.104408 0.001 -0.0160752 -0.103114 0.001 -0.0160752 -0.103114 0 -0.0112455 -0.104408 0 -0.0025 -9.75799e-17 0 -0.00855259 -0.0691814 0 -0.00401603 -0.0347228 0 -0.0160752 0.103114 0 -0.00401603 0.0347228 0 -0.00855259 0.0691814 0 -0.0112455 0.104408 0 0.0025 -9.88045e-17 0 0.000964941 0.0351586 0 -0.00362855 0.0700497 0 -0.00362855 -0.0700497 0 0.000964941 -0.0351586 0 -0.0112455 -0.104408 0 -0.0112455 -0.104408 0.001 0.0025 -9.88045e-17 0.001 -0.00362855 -0.0700497 0.001 0.000964941 -0.0351586 0.001 0.0025 -9.88045e-17 0 -0.00362855 -0.0700497 0 0.000964941 -0.0351586 0 -0.0160752 -0.103114 0.001 -0.0112455 -0.104408 0.001 -0.0025 -9.75799e-17 0.001 -0.00855259 -0.0691814 0.001 -0.00401603 -0.0347228 0.001 -0.0160752 0.103114 0.001 -0.00401603 0.0347228 0.001 -0.00855259 0.0691814 0.001 -0.0112455 0.104408 0.001 0.0025 -9.88045e-17 0.001 0.000964941 0.0351586 0.001 -0.00362855 0.0700497 0.001 -0.00362855 -0.0700497 0.001 0.000964941 -0.0351586 0.001 -0.0160752 -0.103114 0 -0.0160752 -0.103114 0.001 -0.0025 -9.75799e-17 0.001 -0.00855259 -0.0691814 0.001 -0.00401603 -0.0347228 0.001 -0.0025 -9.75799e-17 0 -0.00855259 -0.0691814 0 -0.00401603 -0.0347228 0 -0.0025 -9.75799e-17 0 -0.0025 -9.75799e-17 0.001 -0.0160752 0.103114 0.001 -0.00401603 0.0347228 0.001 -0.00855259 0.0691814 0.001 -0.0160752 0.103114 0 -0.00401603 0.0347228 0 -0.00855259 0.0691814 0 -0.0160752 0.103114 0 -0.0112455 0.104408 0 -0.0112455 0.104408 0.001 -0.0160752 0.103114 0.001 0.0025 -9.88045e-17 0 0.0025 -9.88045e-17 0.001 -0.0112455 0.104408 0.001 0.000964941 0.0351586 0.001 -0.00362855 0.0700497 0.001 -0.0112455 0.104408 0 0.000964941 0.0351586 0 -0.00362855 0.0700497 0 + + + 2 0 3 1 0 2 16 4 5 16 7 4 17 8 7 17 7 16 6 8 17 13 6 17 10 6 13 14 10 13 15 11 10 15 10 14 12 9 11 12 11 15 21 19 18 21 18 24 22 24 25 22 21 24 20 25 23 20 22 25 38 26 27 38 29 26 39 30 29 39 29 38 28 30 39 35 28 39 32 28 35 36 32 35 37 33 32 37 32 36 34 31 33 34 33 37 43 41 40 43 40 46 44 46 47 44 43 46 42 47 45 42 44 47 51 49 48 51 48 54 52 54 55 52 51 54 50 55 53 50 52 55 58 56 59 57 56 58 63 61 60 63 60 66 64 66 67 64 63 66 62 67 65 62 64 67 + 3 6 9 12 15 18 21 24 27 30 33 36 39 42 45 48 51 54 57 60 63 66 69 72 75 78 81 84 87 90 93 96 99 102 105 108 111 114 117 120 123 126 129 132 135 138 141 144 147 150 153 156 + + + + + -0.0162455 -0.104408 0 -0.0114159 -0.105702 0 -0.0114159 -0.105702 0.001 -0.0162455 -0.104408 0.001 -0.0162455 -0.104408 0 -0.0114159 -0.105702 0 -0.0025 -9.88045e-17 0 -0.00862855 -0.0700497 0 -0.00403506 -0.0351586 0 -0.0162455 0.104408 0 -0.00403506 0.0351586 0 -0.00862855 0.0700497 0 -0.0114159 0.105702 0 0.0025 -1.00029e-16 0 0.000945915 0.0355944 0 -0.00370451 0.0709179 0 -0.00370451 -0.0709179 0 0.000945915 -0.0355944 0 -0.0114159 -0.105702 0 -0.0114159 -0.105702 0.001 0.0025 -1.00029e-16 0.001 -0.00370451 -0.0709179 0.001 0.000945915 -0.0355944 0.001 0.0025 -1.00029e-16 0 -0.00370451 -0.0709179 0 0.000945915 -0.0355944 0 -0.0162455 -0.104408 0.001 -0.0114159 -0.105702 0.001 -0.0025 -9.88045e-17 0.001 -0.00862855 -0.0700497 0.001 -0.00403506 -0.0351586 0.001 -0.0162455 0.104408 0.001 -0.00403506 0.0351586 0.001 -0.00862855 0.0700497 0.001 -0.0114159 0.105702 0.001 0.0025 -1.00029e-16 0.001 0.000945915 0.0355944 0.001 -0.00370451 0.0709179 0.001 -0.00370451 -0.0709179 0.001 0.000945915 -0.0355944 0.001 -0.0162455 -0.104408 0 -0.0162455 -0.104408 0.001 -0.0025 -9.88045e-17 0.001 -0.00862855 -0.0700497 0.001 -0.00403506 -0.0351586 0.001 -0.0025 -9.88045e-17 0 -0.00862855 -0.0700497 0 -0.00403506 -0.0351586 0 -0.0025 -9.88045e-17 0 -0.0025 -9.88045e-17 0.001 -0.0162455 0.104408 0.001 -0.00403506 0.0351586 0.001 -0.00862855 0.0700497 0.001 -0.0162455 0.104408 0 -0.00403506 0.0351586 0 -0.00862855 0.0700497 0 -0.0162455 0.104408 0 -0.0114159 0.105702 0 -0.0114159 0.105702 0.001 -0.0162455 0.104408 0.001 0.0025 -1.00029e-16 0 0.0025 -1.00029e-16 0.001 -0.0114159 0.105702 0.001 0.000945915 0.0355944 0.001 -0.00370451 0.0709179 0.001 -0.0114159 0.105702 0 0.000945915 0.0355944 0 -0.00370451 0.0709179 0 + + + 2 0 3 1 0 2 16 4 5 16 7 4 17 8 7 17 7 16 6 8 17 13 6 17 10 6 13 14 10 13 15 11 10 15 10 14 12 9 11 12 11 15 21 19 18 21 18 24 22 24 25 22 21 24 20 25 23 20 22 25 38 26 27 38 29 26 39 30 29 39 29 38 28 30 39 35 28 39 32 28 35 36 32 35 37 33 32 37 32 36 34 31 33 34 33 37 43 41 40 43 40 46 44 46 47 44 43 46 42 47 45 42 44 47 51 49 48 51 48 54 52 54 55 52 51 54 50 55 53 50 52 55 58 56 59 57 56 58 63 61 60 63 60 66 64 66 67 64 63 66 62 67 65 62 64 67 + 3 6 9 12 15 18 21 24 27 30 33 36 39 42 45 48 51 54 57 60 63 66 69 72 75 78 81 84 87 90 93 96 99 102 105 108 111 114 117 120 123 126 129 132 135 138 141 144 147 150 153 156 + + + + + -0.0164125 -0.105676 0 -0.0115829 -0.10697 0 -0.0115829 -0.10697 0.001 -0.0164125 -0.105676 0.001 -0.0164125 -0.105676 0 -0.0115829 -0.10697 0 -0.0025 -1.00005e-16 0 -0.00870299 -0.0709006 0 -0.0040537 -0.0355857 0 -0.0164125 0.105676 0 -0.0040537 0.0355857 0 -0.00870299 0.0709006 0 -0.0115829 0.10697 0 0.0025 -1.01229e-16 0 0.000927269 0.0360215 0 -0.00377896 0.0717688 0 -0.00377896 -0.0717688 0 0.000927269 -0.0360215 0 -0.0115829 -0.10697 0 -0.0115829 -0.10697 0.001 0.0025 -1.01229e-16 0.001 -0.00377896 -0.0717688 0.001 0.000927269 -0.0360215 0.001 0.0025 -1.01229e-16 0 -0.00377896 -0.0717688 0 0.000927269 -0.0360215 0 -0.0164125 -0.105676 0.001 -0.0115829 -0.10697 0.001 -0.0025 -1.00005e-16 0.001 -0.00870299 -0.0709006 0.001 -0.0040537 -0.0355857 0.001 -0.0164125 0.105676 0.001 -0.0040537 0.0355857 0.001 -0.00870299 0.0709006 0.001 -0.0115829 0.10697 0.001 0.0025 -1.01229e-16 0.001 0.000927269 0.0360215 0.001 -0.00377896 0.0717688 0.001 -0.00377896 -0.0717688 0.001 0.000927269 -0.0360215 0.001 -0.0164125 -0.105676 0 -0.0164125 -0.105676 0.001 -0.0025 -1.00005e-16 0.001 -0.00870299 -0.0709006 0.001 -0.0040537 -0.0355857 0.001 -0.0025 -1.00005e-16 0 -0.00870299 -0.0709006 0 -0.0040537 -0.0355857 0 -0.0025 -1.00005e-16 0 -0.0025 -1.00005e-16 0.001 -0.0164125 0.105676 0.001 -0.0040537 0.0355857 0.001 -0.00870299 0.0709006 0.001 -0.0164125 0.105676 0 -0.0040537 0.0355857 0 -0.00870299 0.0709006 0 -0.0164125 0.105676 0 -0.0115829 0.10697 0 -0.0115829 0.10697 0.001 -0.0164125 0.105676 0.001 0.0025 -1.01229e-16 0 0.0025 -1.01229e-16 0.001 -0.0115829 0.10697 0.001 0.000927269 0.0360215 0.001 -0.00377896 0.0717688 0.001 -0.0115829 0.10697 0 0.000927269 0.0360215 0 -0.00377896 0.0717688 0 + + + 2 0 3 1 0 2 16 4 5 16 7 4 17 8 7 17 7 16 6 8 17 13 6 17 10 6 13 14 10 13 15 11 10 15 10 14 12 9 11 12 11 15 21 19 18 21 18 24 22 24 25 22 21 24 20 25 23 20 22 25 38 26 27 38 29 26 39 30 29 39 29 38 28 30 39 35 28 39 32 28 35 36 32 35 37 33 32 37 32 36 34 31 33 34 33 37 43 41 40 43 40 46 44 46 47 44 43 46 42 47 45 42 44 47 51 49 48 51 48 54 52 54 55 52 51 54 50 55 53 50 52 55 58 56 59 57 56 58 63 61 60 63 60 66 64 66 67 64 63 66 62 67 65 62 64 67 + 3 6 9 12 15 18 21 24 27 30 33 36 39 42 45 48 51 54 57 60 63 66 69 72 75 78 81 84 87 90 93 96 99 102 105 108 111 114 117 120 123 126 129 132 135 138 141 144 147 150 153 156 + + + + + -0.0165794 -0.106944 0 -0.0117498 -0.108238 0 -0.0117498 -0.108238 0.001 -0.0165794 -0.106944 0.001 -0.0165794 -0.106944 0 -0.0117498 -0.108238 0 -0.0025 -1.01205e-16 0 -0.00877744 -0.0717514 0 -0.00407235 -0.0360128 0 -0.0165794 0.106944 0 -0.00407235 0.0360128 0 -0.00877744 0.0717514 0 -0.0117498 0.108238 0 0.0025 -1.02429e-16 0 0.000908623 0.0364485 0 -0.0038534 0.0726197 0 -0.0038534 -0.0726197 0 0.000908623 -0.0364485 0 -0.0117498 -0.108238 0 -0.0117498 -0.108238 0.001 0.0025 -1.02429e-16 0.001 -0.0038534 -0.0726197 0.001 0.000908623 -0.0364485 0.001 0.0025 -1.02429e-16 0 -0.0038534 -0.0726197 0 0.000908623 -0.0364485 0 -0.0165794 -0.106944 0.001 -0.0117498 -0.108238 0.001 -0.0025 -1.01205e-16 0.001 -0.00877744 -0.0717514 0.001 -0.00407235 -0.0360128 0.001 -0.0165794 0.106944 0.001 -0.00407235 0.0360128 0.001 -0.00877744 0.0717514 0.001 -0.0117498 0.108238 0.001 0.0025 -1.02429e-16 0.001 0.000908623 0.0364485 0.001 -0.0038534 0.0726197 0.001 -0.0038534 -0.0726197 0.001 0.000908623 -0.0364485 0.001 -0.0165794 -0.106944 0 -0.0165794 -0.106944 0.001 -0.0025 -1.01205e-16 0.001 -0.00877744 -0.0717514 0.001 -0.00407235 -0.0360128 0.001 -0.0025 -1.01205e-16 0 -0.00877744 -0.0717514 0 -0.00407235 -0.0360128 0 -0.0025 -1.01205e-16 0 -0.0025 -1.01205e-16 0.001 -0.0165794 0.106944 0.001 -0.00407235 0.0360128 0.001 -0.00877744 0.0717514 0.001 -0.0165794 0.106944 0 -0.00407235 0.0360128 0 -0.00877744 0.0717514 0 -0.0165794 0.106944 0 -0.0117498 0.108238 0 -0.0117498 0.108238 0.001 -0.0165794 0.106944 0.001 0.0025 -1.02429e-16 0 0.0025 -1.02429e-16 0.001 -0.0117498 0.108238 0.001 0.000908623 0.0364485 0.001 -0.0038534 0.0726197 0.001 -0.0117498 0.108238 0 0.000908623 0.0364485 0 -0.0038534 0.0726197 0 + + + 2 0 3 1 0 2 16 4 5 16 7 4 17 8 7 17 7 16 6 8 17 13 6 17 10 6 13 14 10 13 15 11 10 15 10 14 12 9 11 12 11 15 21 19 18 21 18 24 22 24 25 22 21 24 20 25 23 20 22 25 38 26 27 38 29 26 39 30 29 39 29 38 28 30 39 35 28 39 32 28 35 36 32 35 37 33 32 37 32 36 34 31 33 34 33 37 43 41 40 43 40 46 44 46 47 44 43 46 42 47 45 42 44 47 51 49 48 51 48 54 52 54 55 52 51 54 50 55 53 50 52 55 58 56 59 57 56 58 63 61 60 63 60 66 64 66 67 64 63 66 62 67 65 62 64 67 + 3 6 9 12 15 18 21 24 27 30 33 36 39 42 45 48 51 54 57 60 63 66 69 72 75 78 81 84 87 90 93 96 99 102 105 108 111 114 117 120 123 126 129 132 135 138 141 144 147 150 153 156 + + + + + -0.0167464 -0.108212 0 -0.0119168 -0.109506 0 -0.0119168 -0.109506 0.001 -0.0167464 -0.108212 0.001 -0.0167464 -0.108212 0 -0.0119168 -0.109506 0 -0.0025 -1.02405e-16 0 -0.00885188 -0.0726023 0 -0.004091 -0.0364398 0 -0.0167464 0.108212 0 -0.004091 0.0364398 0 -0.00885188 0.0726023 0 -0.0119168 0.109506 0 0.0025 -1.0363e-16 0 0.000889977 0.0368756 0 -0.00392784 0.0734705 0 -0.00392784 -0.0734705 0 0.000889977 -0.0368756 0 -0.0119168 -0.109506 0 -0.0119168 -0.109506 0.001 0.0025 -1.0363e-16 0.001 -0.00392784 -0.0734705 0.001 0.000889977 -0.0368756 0.001 0.0025 -1.0363e-16 0 -0.00392784 -0.0734705 0 0.000889977 -0.0368756 0 -0.0167464 -0.108212 0.001 -0.0119168 -0.109506 0.001 -0.0025 -1.02405e-16 0.001 -0.00885188 -0.0726023 0.001 -0.004091 -0.0364398 0.001 -0.0167464 0.108212 0.001 -0.004091 0.0364398 0.001 -0.00885188 0.0726023 0.001 -0.0119168 0.109506 0.001 0.0025 -1.0363e-16 0.001 0.000889977 0.0368756 0.001 -0.00392784 0.0734705 0.001 -0.00392784 -0.0734705 0.001 0.000889977 -0.0368756 0.001 -0.0167464 -0.108212 0 -0.0167464 -0.108212 0.001 -0.0025 -1.02405e-16 0.001 -0.00885188 -0.0726023 0.001 -0.004091 -0.0364398 0.001 -0.0025 -1.02405e-16 0 -0.00885188 -0.0726023 0 -0.004091 -0.0364398 0 -0.0025 -1.02405e-16 0 -0.0025 -1.02405e-16 0.001 -0.0167464 0.108212 0.001 -0.004091 0.0364398 0.001 -0.00885188 0.0726023 0.001 -0.0167464 0.108212 0 -0.004091 0.0364398 0 -0.00885188 0.0726023 0 -0.0167464 0.108212 0 -0.0119168 0.109506 0 -0.0119168 0.109506 0.001 -0.0167464 0.108212 0.001 0.0025 -1.0363e-16 0 0.0025 -1.0363e-16 0.001 -0.0119168 0.109506 0.001 0.000889977 0.0368756 0.001 -0.00392784 0.0734705 0.001 -0.0119168 0.109506 0 0.000889977 0.0368756 0 -0.00392784 0.0734705 0 + + + 2 0 3 1 0 2 16 4 5 16 7 4 17 8 7 17 7 16 6 8 17 13 6 17 10 6 13 14 10 13 15 11 10 15 10 14 12 9 11 12 11 15 21 19 18 21 18 24 22 24 25 22 21 24 20 25 23 20 22 25 38 26 27 38 29 26 39 30 29 39 29 38 28 30 39 35 28 39 32 28 35 36 32 35 37 33 32 37 32 36 34 31 33 34 33 37 43 41 40 43 40 46 44 46 47 44 43 46 42 47 45 42 44 47 51 49 48 51 48 54 52 54 55 52 51 54 50 55 53 50 52 55 58 56 59 57 56 58 63 61 60 63 60 66 64 66 67 64 63 66 62 67 65 62 64 67 + 3 6 9 12 15 18 21 24 27 30 33 36 39 42 45 48 51 54 57 60 63 66 69 72 75 78 81 84 87 90 93 96 99 102 105 108 111 114 117 120 123 126 129 132 135 138 141 144 147 150 153 156 + + + + + -0.0108448 -0.0633848 0 -0.00601514 -0.0646789 0 -0.00601514 -0.0646789 0.001 -0.0108448 -0.0633848 0.001 -0.0108448 -0.0633848 0 -0.00601514 -0.0646789 0 -0.0025 -5.99832e-17 0 -0.00622058 -0.0425264 0 -0.00343192 -0.0213444 0 -0.0108448 0.0633848 0 -0.00343192 0.0213444 0 -0.00622058 0.0425264 0 -0.00601514 0.0646789 0 0.0025 -6.12078e-17 0 0.00154906 0.0217802 0 -0.00129654 0.0433947 0 -0.00129654 -0.0433947 0 0.00154906 -0.0217802 0 -0.00601514 -0.0646789 0 -0.00601514 -0.0646789 0.001 0.0025 -6.12078e-17 0.001 -0.00129654 -0.0433947 0.001 0.00154906 -0.0217802 0.001 0.0025 -6.12078e-17 0 -0.00129654 -0.0433947 0 0.00154906 -0.0217802 0 -0.0108448 -0.0633848 0.001 -0.00601514 -0.0646789 0.001 -0.0025 -5.99832e-17 0.001 -0.00622058 -0.0425264 0.001 -0.00343192 -0.0213444 0.001 -0.0108448 0.0633848 0.001 -0.00343192 0.0213444 0.001 -0.00622058 0.0425264 0.001 -0.00601514 0.0646789 0.001 0.0025 -6.12078e-17 0.001 0.00154906 0.0217802 0.001 -0.00129654 0.0433947 0.001 -0.00129654 -0.0433947 0.001 0.00154906 -0.0217802 0.001 -0.0108448 -0.0633848 0 -0.0108448 -0.0633848 0.001 -0.0025 -5.99832e-17 0.001 -0.00622058 -0.0425264 0.001 -0.00343192 -0.0213444 0.001 -0.0025 -5.99832e-17 0 -0.00622058 -0.0425264 0 -0.00343192 -0.0213444 0 -0.0025 -5.99832e-17 0 -0.0025 -5.99832e-17 0.001 -0.0108448 0.0633848 0.001 -0.00343192 0.0213444 0.001 -0.00622058 0.0425264 0.001 -0.0108448 0.0633848 0 -0.00343192 0.0213444 0 -0.00622058 0.0425264 0 -0.0108448 0.0633848 0 -0.00601514 0.0646789 0 -0.00601514 0.0646789 0.001 -0.0108448 0.0633848 0.001 0.0025 -6.12078e-17 0 0.0025 -6.12078e-17 0.001 -0.00601514 0.0646789 0.001 0.00154906 0.0217802 0.001 -0.00129654 0.0433947 0.001 -0.00601514 0.0646789 0 0.00154906 0.0217802 0 -0.00129654 0.0433947 0 + + + 2 0 3 1 0 2 16 4 5 16 7 4 17 8 7 17 7 16 6 8 17 13 6 17 14 10 6 14 6 13 15 11 10 15 10 14 12 9 11 12 11 15 21 19 18 21 18 24 22 24 25 22 21 24 20 25 23 20 22 25 38 26 27 38 29 26 39 30 29 39 29 38 28 30 39 35 28 39 36 32 28 36 28 35 37 33 32 37 32 36 34 31 33 34 33 37 43 41 40 43 40 46 44 46 47 44 43 46 42 47 45 42 44 47 51 49 48 51 48 54 52 54 55 52 51 54 50 55 53 50 52 55 58 56 59 57 56 58 63 61 60 63 60 66 64 66 67 64 63 66 62 67 65 62 64 67 + 3 6 9 12 15 18 21 24 27 30 33 36 39 42 45 48 51 54 57 60 63 66 69 72 75 78 81 84 87 90 93 96 99 102 105 108 111 114 117 120 123 126 129 132 135 138 141 144 147 150 153 156 + + + + + -0.0169168 -0.109506 0 -0.0120872 -0.1108 0 -0.0120872 -0.1108 0.001 -0.0169168 -0.109506 0.001 -0.0169168 -0.109506 0 -0.0120872 -0.1108 0 -0.0025 -1.0363e-16 0 -0.00892784 -0.0734705 0 -0.00411002 -0.0368756 0 -0.0169168 0.109506 0 -0.00411002 0.0368756 0 -0.00892784 0.0734705 0 -0.0120872 0.1108 0 0.0025 -1.04854e-16 0 0.00087095 0.0373114 0 -0.0040038 0.0743388 0 -0.0040038 -0.0743388 0 0.00087095 -0.0373114 0 -0.0120872 -0.1108 0 -0.0120872 -0.1108 0.001 0.0025 -1.04854e-16 0.001 -0.0040038 -0.0743388 0.001 0.00087095 -0.0373114 0.001 0.0025 -1.04854e-16 0 -0.0040038 -0.0743388 0 0.00087095 -0.0373114 0 -0.0169168 -0.109506 0.001 -0.0120872 -0.1108 0.001 -0.0025 -1.0363e-16 0.001 -0.00892784 -0.0734705 0.001 -0.00411002 -0.0368756 0.001 -0.0169168 0.109506 0.001 -0.00411002 0.0368756 0.001 -0.00892784 0.0734705 0.001 -0.0120872 0.1108 0.001 0.0025 -1.04854e-16 0.001 0.00087095 0.0373114 0.001 -0.0040038 0.0743388 0.001 -0.0040038 -0.0743388 0.001 0.00087095 -0.0373114 0.001 -0.0169168 -0.109506 0 -0.0169168 -0.109506 0.001 -0.0025 -1.0363e-16 0.001 -0.00892784 -0.0734705 0.001 -0.00411002 -0.0368756 0.001 -0.0025 -1.0363e-16 0 -0.00892784 -0.0734705 0 -0.00411002 -0.0368756 0 -0.0025 -1.0363e-16 0 -0.0025 -1.0363e-16 0.001 -0.0169168 0.109506 0.001 -0.00411002 0.0368756 0.001 -0.00892784 0.0734705 0.001 -0.0169168 0.109506 0 -0.00411002 0.0368756 0 -0.00892784 0.0734705 0 -0.0169168 0.109506 0 -0.0120872 0.1108 0 -0.0120872 0.1108 0.001 -0.0169168 0.109506 0.001 0.0025 -1.04854e-16 0 0.0025 -1.04854e-16 0.001 -0.0120872 0.1108 0.001 0.00087095 0.0373114 0.001 -0.0040038 0.0743388 0.001 -0.0120872 0.1108 0 0.00087095 0.0373114 0 -0.0040038 0.0743388 0 + + + 2 0 3 1 0 2 16 4 5 16 7 4 17 8 7 17 7 16 6 8 17 13 6 17 10 6 13 14 10 13 15 11 10 15 10 14 12 9 11 12 11 15 21 19 18 21 18 24 22 24 25 22 21 24 20 25 23 20 22 25 38 26 27 38 29 26 39 30 29 39 29 38 28 30 39 35 28 39 32 28 35 36 32 35 37 33 32 37 32 36 34 31 33 34 33 37 43 41 40 43 40 46 44 46 47 44 43 46 42 47 45 42 44 47 51 49 48 51 48 54 52 54 55 52 51 54 50 55 53 50 52 55 58 56 59 57 56 58 63 61 60 63 60 66 64 66 67 64 63 66 62 67 65 62 64 67 + 3 6 9 12 15 18 21 24 27 30 33 36 39 42 45 48 51 54 57 60 63 66 69 72 75 78 81 84 87 90 93 96 99 102 105 108 111 114 117 120 123 126 129 132 135 138 141 144 147 150 153 156 + + + + + -0.0170837 -0.110775 0 -0.0122541 -0.112069 0 -0.0122541 -0.112069 0.001 -0.0170837 -0.110775 0.001 -0.0170837 -0.110775 0 -0.0122541 -0.112069 0 -0.0025 -1.0483e-16 0 -0.00900228 -0.0743214 0 -0.00412867 -0.0373027 0 -0.0170837 0.110775 0 -0.00412867 0.0373027 0 -0.00900228 0.0743214 0 -0.0122541 0.112069 0 0.0025 -1.06054e-16 0 0.000852304 0.0377384 0 -0.00407824 0.0751897 0 -0.00407824 -0.0751897 0 0.000852304 -0.0377384 0 -0.0122541 -0.112069 0 -0.0122541 -0.112069 0.001 0.0025 -1.06054e-16 0.001 -0.00407824 -0.0751897 0.001 0.000852304 -0.0377384 0.001 0.0025 -1.06054e-16 0 -0.00407824 -0.0751897 0 0.000852304 -0.0377384 0 -0.0170837 -0.110775 0.001 -0.0122541 -0.112069 0.001 -0.0025 -1.0483e-16 0.001 -0.00900228 -0.0743214 0.001 -0.00412867 -0.0373027 0.001 -0.0170837 0.110775 0.001 -0.00412867 0.0373027 0.001 -0.00900228 0.0743214 0.001 -0.0122541 0.112069 0.001 0.0025 -1.06054e-16 0.001 0.000852304 0.0377384 0.001 -0.00407824 0.0751897 0.001 -0.00407824 -0.0751897 0.001 0.000852304 -0.0377384 0.001 -0.0170837 -0.110775 0 -0.0170837 -0.110775 0.001 -0.0025 -1.0483e-16 0.001 -0.00900228 -0.0743214 0.001 -0.00412867 -0.0373027 0.001 -0.0025 -1.0483e-16 0 -0.00900228 -0.0743214 0 -0.00412867 -0.0373027 0 -0.0025 -1.0483e-16 0 -0.0025 -1.0483e-16 0.001 -0.0170837 0.110775 0.001 -0.00412867 0.0373027 0.001 -0.00900228 0.0743214 0.001 -0.0170837 0.110775 0 -0.00412867 0.0373027 0 -0.00900228 0.0743214 0 -0.0170837 0.110775 0 -0.0122541 0.112069 0 -0.0122541 0.112069 0.001 -0.0170837 0.110775 0.001 0.0025 -1.06054e-16 0 0.0025 -1.06054e-16 0.001 -0.0122541 0.112069 0.001 0.000852304 0.0377384 0.001 -0.00407824 0.0751897 0.001 -0.0122541 0.112069 0 0.000852304 0.0377384 0 -0.00407824 0.0751897 0 + + + 2 0 3 1 0 2 16 4 5 16 7 4 17 8 7 17 7 16 6 8 17 13 6 17 10 6 13 14 10 13 15 11 10 15 10 14 12 9 11 12 11 15 21 19 18 21 18 24 22 24 25 22 21 24 20 25 23 20 22 25 38 26 27 38 29 26 39 30 29 39 29 38 28 30 39 35 28 39 32 28 35 36 32 35 37 33 32 37 32 36 34 31 33 34 33 37 43 41 40 43 40 46 44 46 47 44 43 46 42 47 45 42 44 47 51 49 48 51 48 54 52 54 55 52 51 54 50 55 53 50 52 55 58 56 59 57 56 58 63 61 60 63 60 66 64 66 67 64 63 66 62 67 65 62 64 67 + 3 6 9 12 15 18 21 24 27 30 33 36 39 42 45 48 51 54 57 60 63 66 69 72 75 78 81 84 87 90 93 96 99 102 105 108 111 114 117 120 123 126 129 132 135 138 141 144 147 150 153 156 + + + + + -0.0172507 -0.112043 0 -0.0124211 -0.113337 0 -0.0124211 -0.113337 0.001 -0.0172507 -0.112043 0.001 -0.0172507 -0.112043 0 -0.0124211 -0.113337 0 -0.0025 -1.0603e-16 0 -0.00907672 -0.0751723 0 -0.00414732 -0.0377297 0 -0.0172507 0.112043 0 -0.00414732 0.0377297 0 -0.00907672 0.0751723 0 -0.0124211 0.113337 0 0.0025 -1.07255e-16 0 0.000833658 0.0381655 0 -0.00415268 0.0760405 0 -0.00415268 -0.0760405 0 0.000833658 -0.0381655 0 -0.0124211 -0.113337 0 -0.0124211 -0.113337 0.001 0.0025 -1.07255e-16 0.001 -0.00415268 -0.0760405 0.001 0.000833658 -0.0381655 0.001 0.0025 -1.07255e-16 0 -0.00415268 -0.0760405 0 0.000833658 -0.0381655 0 -0.0172507 -0.112043 0.001 -0.0124211 -0.113337 0.001 -0.0025 -1.0603e-16 0.001 -0.00907672 -0.0751723 0.001 -0.00414732 -0.0377297 0.001 -0.0172507 0.112043 0.001 -0.00414732 0.0377297 0.001 -0.00907672 0.0751723 0.001 -0.0124211 0.113337 0.001 0.0025 -1.07255e-16 0.001 0.000833658 0.0381655 0.001 -0.00415268 0.0760405 0.001 -0.00415268 -0.0760405 0.001 0.000833658 -0.0381655 0.001 -0.0172507 -0.112043 0 -0.0172507 -0.112043 0.001 -0.0025 -1.0603e-16 0.001 -0.00907672 -0.0751723 0.001 -0.00414732 -0.0377297 0.001 -0.0025 -1.0603e-16 0 -0.00907672 -0.0751723 0 -0.00414732 -0.0377297 0 -0.0025 -1.0603e-16 0 -0.0025 -1.0603e-16 0.001 -0.0172507 0.112043 0.001 -0.00414732 0.0377297 0.001 -0.00907672 0.0751723 0.001 -0.0172507 0.112043 0 -0.00414732 0.0377297 0 -0.00907672 0.0751723 0 -0.0172507 0.112043 0 -0.0124211 0.113337 0 -0.0124211 0.113337 0.001 -0.0172507 0.112043 0.001 0.0025 -1.07255e-16 0 0.0025 -1.07255e-16 0.001 -0.0124211 0.113337 0.001 0.000833658 0.0381655 0.001 -0.00415268 0.0760405 0.001 -0.0124211 0.113337 0 0.000833658 0.0381655 0 -0.00415268 0.0760405 0 + + + 2 0 3 1 0 2 16 4 5 16 7 4 17 8 7 17 7 16 6 8 17 13 6 17 10 6 13 14 10 13 15 11 10 15 10 14 12 9 11 12 11 15 21 19 18 21 18 24 22 24 25 22 21 24 20 25 23 20 22 25 38 26 27 38 29 26 39 30 29 39 29 38 28 30 39 35 28 39 32 28 35 36 32 35 37 33 32 37 32 36 34 31 33 34 33 37 43 41 40 43 40 46 44 46 47 44 43 46 42 47 45 42 44 47 51 49 48 51 48 54 52 54 55 52 51 54 50 55 53 50 52 55 58 56 59 57 56 58 63 61 60 63 60 66 64 66 67 64 63 66 62 67 65 62 64 67 + 3 6 9 12 15 18 21 24 27 30 33 36 39 42 45 48 51 54 57 60 63 66 69 72 75 78 81 84 87 90 93 96 99 102 105 108 111 114 117 120 123 126 129 132 135 138 141 144 147 150 153 156 + + + + + -0.0174177 -0.113311 0 -0.012588 -0.114605 0 -0.012588 -0.114605 0.001 -0.0174177 -0.113311 0.001 -0.0174177 -0.113311 0 -0.012588 -0.114605 0 -0.0025 -1.0723e-16 0 -0.00915117 -0.0760232 0 -0.00416596 -0.0381568 0 -0.0174177 0.113311 0 -0.00416596 0.0381568 0 -0.00915117 0.0760232 0 -0.012588 0.114605 0 0.0025 -1.08455e-16 0 0.000815012 0.0385926 0 -0.00422713 0.0768914 0 -0.00422713 -0.0768914 0 0.000815012 -0.0385926 0 -0.012588 -0.114605 0 -0.012588 -0.114605 0.001 0.0025 -1.08455e-16 0.001 -0.00422713 -0.0768914 0.001 0.000815012 -0.0385926 0.001 0.0025 -1.08455e-16 0 -0.00422713 -0.0768914 0 0.000815012 -0.0385926 0 -0.0174177 -0.113311 0.001 -0.012588 -0.114605 0.001 -0.0025 -1.0723e-16 0.001 -0.00915117 -0.0760232 0.001 -0.00416596 -0.0381568 0.001 -0.0174177 0.113311 0.001 -0.00416596 0.0381568 0.001 -0.00915117 0.0760232 0.001 -0.012588 0.114605 0.001 0.0025 -1.08455e-16 0.001 0.000815012 0.0385926 0.001 -0.00422713 0.0768914 0.001 -0.00422713 -0.0768914 0.001 0.000815012 -0.0385926 0.001 -0.0174177 -0.113311 0 -0.0174177 -0.113311 0.001 -0.0025 -1.0723e-16 0.001 -0.00915117 -0.0760232 0.001 -0.00416596 -0.0381568 0.001 -0.0025 -1.0723e-16 0 -0.00915117 -0.0760232 0 -0.00416596 -0.0381568 0 -0.0025 -1.0723e-16 0 -0.0025 -1.0723e-16 0.001 -0.0174177 0.113311 0.001 -0.00416596 0.0381568 0.001 -0.00915117 0.0760232 0.001 -0.0174177 0.113311 0 -0.00416596 0.0381568 0 -0.00915117 0.0760232 0 -0.0174177 0.113311 0 -0.012588 0.114605 0 -0.012588 0.114605 0.001 -0.0174177 0.113311 0.001 0.0025 -1.08455e-16 0 0.0025 -1.08455e-16 0.001 -0.012588 0.114605 0.001 0.000815012 0.0385926 0.001 -0.00422713 0.0768914 0.001 -0.012588 0.114605 0 0.000815012 0.0385926 0 -0.00422713 0.0768914 0 + + + 2 0 3 1 0 2 16 4 5 16 7 4 17 8 7 17 7 16 6 8 17 13 6 17 10 6 13 14 10 13 15 11 10 15 10 14 12 9 11 12 11 15 21 19 18 21 18 24 22 24 25 22 21 24 20 25 23 20 22 25 38 26 27 38 29 26 39 30 29 39 29 38 28 30 39 35 28 39 32 28 35 36 32 35 37 33 32 37 32 36 34 31 33 34 33 37 43 41 40 43 40 46 44 46 47 44 43 46 42 47 45 42 44 47 51 49 48 51 48 54 52 54 55 52 51 54 50 55 53 50 52 55 58 56 59 57 56 58 63 61 60 63 60 66 64 66 67 64 63 66 62 67 65 62 64 67 + 3 6 9 12 15 18 21 24 27 30 33 36 39 42 45 48 51 54 57 60 63 66 69 72 75 78 81 84 87 90 93 96 99 102 105 108 111 114 117 120 123 126 129 132 135 138 141 144 147 150 153 156 + + + + + -0.0175846 -0.114579 0 -0.012755 -0.115873 0 -0.012755 -0.115873 0.001 -0.0175846 -0.114579 0.001 -0.0175846 -0.114579 0 -0.012755 -0.115873 0 -0.0025 -1.0843e-16 0 -0.00922561 -0.076874 0 -0.00418461 -0.0385838 0 -0.0175846 0.114579 0 -0.00418461 0.0385838 0 -0.00922561 0.076874 0 -0.012755 0.115873 0 0.0025 -1.09655e-16 0 0.000796366 0.0390196 0 -0.00430157 0.0777423 0 -0.00430157 -0.0777423 0 0.000796366 -0.0390196 0 -0.012755 -0.115873 0 -0.012755 -0.115873 0.001 0.0025 -1.09655e-16 0.001 -0.00430157 -0.0777423 0.001 0.000796366 -0.0390196 0.001 0.0025 -1.09655e-16 0 -0.00430157 -0.0777423 0 0.000796366 -0.0390196 0 -0.0175846 -0.114579 0.001 -0.012755 -0.115873 0.001 -0.0025 -1.0843e-16 0.001 -0.00922561 -0.076874 0.001 -0.00418461 -0.0385838 0.001 -0.0175846 0.114579 0.001 -0.00418461 0.0385838 0.001 -0.00922561 0.076874 0.001 -0.012755 0.115873 0.001 0.0025 -1.09655e-16 0.001 0.000796366 0.0390196 0.001 -0.00430157 0.0777423 0.001 -0.00430157 -0.0777423 0.001 0.000796366 -0.0390196 0.001 -0.0175846 -0.114579 0 -0.0175846 -0.114579 0.001 -0.0025 -1.0843e-16 0.001 -0.00922561 -0.076874 0.001 -0.00418461 -0.0385838 0.001 -0.0025 -1.0843e-16 0 -0.00922561 -0.076874 0 -0.00418461 -0.0385838 0 -0.0025 -1.0843e-16 0 -0.0025 -1.0843e-16 0.001 -0.0175846 0.114579 0.001 -0.00418461 0.0385838 0.001 -0.00922561 0.076874 0.001 -0.0175846 0.114579 0 -0.00418461 0.0385838 0 -0.00922561 0.076874 0 -0.0175846 0.114579 0 -0.012755 0.115873 0 -0.012755 0.115873 0.001 -0.0175846 0.114579 0.001 0.0025 -1.09655e-16 0 0.0025 -1.09655e-16 0.001 -0.012755 0.115873 0.001 0.000796366 0.0390196 0.001 -0.00430157 0.0777423 0.001 -0.012755 0.115873 0 0.000796366 0.0390196 0 -0.00430157 0.0777423 0 + + + 2 0 3 1 0 2 16 4 5 16 7 4 17 8 7 17 7 16 6 8 17 13 6 17 10 6 13 14 10 13 11 10 14 15 11 14 12 9 11 12 11 15 21 19 18 21 18 24 22 24 25 22 21 24 20 25 23 20 22 25 38 26 27 38 29 26 39 30 29 39 29 38 28 30 39 35 28 39 32 28 35 36 32 35 33 32 36 37 33 36 34 31 33 34 33 37 43 41 40 43 40 46 44 46 47 44 43 46 42 47 45 42 44 47 51 49 48 51 48 54 52 54 55 52 51 54 50 55 53 50 52 55 58 56 59 57 56 58 63 61 60 63 60 66 64 66 67 64 63 66 62 67 65 62 64 67 + 3 6 9 12 15 18 21 24 27 30 33 36 39 42 45 48 51 54 57 60 63 66 69 72 75 78 81 84 87 90 93 96 99 102 105 108 111 114 117 120 123 126 129 132 135 138 141 144 147 150 153 156 + + + + + -0.0177516 -0.115847 0 -0.012922 -0.117141 0 -0.012922 -0.117141 0.001 -0.0177516 -0.115847 0.001 -0.0177516 -0.115847 0 -0.012922 -0.117141 0 -0.0025 -1.0963e-16 0 -0.00930005 -0.0777249 0 -0.00420325 -0.0390109 0 -0.0177516 0.115847 0 -0.00420325 0.0390109 0 -0.00930005 0.0777249 0 -0.012922 0.117141 0 0.0025 -1.10855e-16 0 0.00077772 0.0394467 0 -0.00437601 0.0785932 0 -0.00437601 -0.0785932 0 0.00077772 -0.0394467 0 -0.012922 -0.117141 0 -0.012922 -0.117141 0.001 0.0025 -1.10855e-16 0.001 -0.00437601 -0.0785932 0.001 0.00077772 -0.0394467 0.001 0.0025 -1.10855e-16 0 -0.00437601 -0.0785932 0 0.00077772 -0.0394467 0 -0.0177516 -0.115847 0.001 -0.012922 -0.117141 0.001 -0.0025 -1.0963e-16 0.001 -0.00930005 -0.0777249 0.001 -0.00420325 -0.0390109 0.001 -0.0177516 0.115847 0.001 -0.00420325 0.0390109 0.001 -0.00930005 0.0777249 0.001 -0.012922 0.117141 0.001 0.0025 -1.10855e-16 0.001 0.00077772 0.0394467 0.001 -0.00437601 0.0785932 0.001 -0.00437601 -0.0785932 0.001 0.00077772 -0.0394467 0.001 -0.0177516 -0.115847 0 -0.0177516 -0.115847 0.001 -0.0025 -1.0963e-16 0.001 -0.00930005 -0.0777249 0.001 -0.00420325 -0.0390109 0.001 -0.0025 -1.0963e-16 0 -0.00930005 -0.0777249 0 -0.00420325 -0.0390109 0 -0.0025 -1.0963e-16 0 -0.0025 -1.0963e-16 0.001 -0.0177516 0.115847 0.001 -0.00420325 0.0390109 0.001 -0.00930005 0.0777249 0.001 -0.0177516 0.115847 0 -0.00420325 0.0390109 0 -0.00930005 0.0777249 0 -0.0177516 0.115847 0 -0.012922 0.117141 0 -0.012922 0.117141 0.001 -0.0177516 0.115847 0.001 0.0025 -1.10855e-16 0 0.0025 -1.10855e-16 0.001 -0.012922 0.117141 0.001 0.00077772 0.0394467 0.001 -0.00437601 0.0785932 0.001 -0.012922 0.117141 0 0.00077772 0.0394467 0 -0.00437601 0.0785932 0 + + + 2 0 3 1 0 2 16 4 5 16 7 4 17 8 7 17 7 16 6 8 17 13 6 17 10 6 13 14 10 13 15 11 10 15 10 14 12 9 11 12 11 15 21 19 18 21 18 24 22 24 25 22 21 24 20 25 23 20 22 25 38 26 27 38 29 26 39 30 29 39 29 38 28 30 39 35 28 39 32 28 35 36 32 35 37 33 32 37 32 36 34 31 33 34 33 37 43 41 40 43 40 46 44 46 47 44 43 46 42 47 45 42 44 47 51 49 48 51 48 54 52 54 55 52 51 54 50 55 53 50 52 55 58 56 59 57 56 58 63 61 60 63 60 66 64 66 67 64 63 66 62 67 65 62 64 67 + 3 6 9 12 15 18 21 24 27 30 33 36 39 42 45 48 51 54 57 60 63 66 69 72 75 78 81 84 87 90 93 96 99 102 105 108 111 114 117 120 123 126 129 132 135 138 141 144 147 150 153 156 + + + + + -0.0179186 -0.117116 0 -0.0130889 -0.11841 0 -0.0130889 -0.11841 0.001 -0.0179186 -0.117116 0.001 -0.0179186 -0.117116 0 -0.0130889 -0.11841 0 -0.0025 -1.10831e-16 0 -0.00937449 -0.0785758 0 -0.0042219 -0.039438 0 -0.0179186 0.117116 0 -0.0042219 0.039438 0 -0.00937449 0.0785758 0 -0.0130889 0.11841 0 0.0025 -1.12055e-16 0 0.000759074 0.0398738 0 -0.00445045 0.079444 0 -0.00445045 -0.079444 0 0.000759074 -0.0398738 0 -0.0130889 -0.11841 0 -0.0130889 -0.11841 0.001 0.0025 -1.12055e-16 0.001 -0.00445045 -0.079444 0.001 0.000759074 -0.0398738 0.001 0.0025 -1.12055e-16 0 -0.00445045 -0.079444 0 0.000759074 -0.0398738 0 -0.0179186 -0.117116 0.001 -0.0130889 -0.11841 0.001 -0.0025 -1.10831e-16 0.001 -0.00937449 -0.0785758 0.001 -0.0042219 -0.039438 0.001 -0.0179186 0.117116 0.001 -0.0042219 0.039438 0.001 -0.00937449 0.0785758 0.001 -0.0130889 0.11841 0.001 0.0025 -1.12055e-16 0.001 0.000759074 0.0398738 0.001 -0.00445045 0.079444 0.001 -0.00445045 -0.079444 0.001 0.000759074 -0.0398738 0.001 -0.0179186 -0.117116 0 -0.0179186 -0.117116 0.001 -0.0025 -1.10831e-16 0.001 -0.00937449 -0.0785758 0.001 -0.0042219 -0.039438 0.001 -0.0025 -1.10831e-16 0 -0.00937449 -0.0785758 0 -0.0042219 -0.039438 0 -0.0025 -1.10831e-16 0 -0.0025 -1.10831e-16 0.001 -0.0179186 0.117116 0.001 -0.0042219 0.039438 0.001 -0.00937449 0.0785758 0.001 -0.0179186 0.117116 0 -0.0042219 0.039438 0 -0.00937449 0.0785758 0 -0.0179186 0.117116 0 -0.0130889 0.11841 0 -0.0130889 0.11841 0.001 -0.0179186 0.117116 0.001 0.0025 -1.12055e-16 0 0.0025 -1.12055e-16 0.001 -0.0130889 0.11841 0.001 0.000759074 0.0398738 0.001 -0.00445045 0.079444 0.001 -0.0130889 0.11841 0 0.000759074 0.0398738 0 -0.00445045 0.079444 0 + + + 2 0 3 1 0 2 16 4 5 16 7 4 17 8 7 17 7 16 6 8 17 13 6 17 10 6 13 14 10 13 15 11 10 15 10 14 12 9 11 12 11 15 21 19 18 21 18 24 22 24 25 22 21 24 20 25 23 20 22 25 38 26 27 38 29 26 39 30 29 39 29 38 28 30 39 35 28 39 32 28 35 36 32 35 37 33 32 37 32 36 34 31 33 34 33 37 43 41 40 43 40 46 44 46 47 44 43 46 42 47 45 42 44 47 51 49 48 51 48 54 52 54 55 52 51 54 50 55 53 50 52 55 58 56 59 57 56 58 63 61 60 63 60 66 64 66 67 64 63 66 62 67 65 62 64 67 + 3 6 9 12 15 18 21 24 27 30 33 36 39 42 45 48 51 54 57 60 63 66 69 72 75 78 81 84 87 90 93 96 99 102 105 108 111 114 117 120 123 126 129 132 135 138 141 144 147 150 153 156 + + + + + -0.0180889 -0.11841 0 -0.0132593 -0.119704 0 -0.0132593 -0.119704 0.001 -0.0180889 -0.11841 0.001 -0.0180889 -0.11841 0 -0.0132593 -0.119704 0 -0.0025 -1.12055e-16 0 -0.00945045 -0.079444 0 -0.00424093 -0.0398738 0 -0.0180889 0.11841 0 -0.00424093 0.0398738 0 -0.00945045 0.079444 0 -0.0132593 0.119704 0 0.0025 -1.1328e-16 0 0.000740048 0.0403095 0 -0.00452641 0.0803123 0 -0.00452641 -0.0803123 0 0.000740048 -0.0403095 0 -0.0132593 -0.119704 0 -0.0132593 -0.119704 0.001 0.0025 -1.1328e-16 0.001 -0.00452641 -0.0803123 0.001 0.000740048 -0.0403095 0.001 0.0025 -1.1328e-16 0 -0.00452641 -0.0803123 0 0.000740048 -0.0403095 0 -0.0180889 -0.11841 0.001 -0.0132593 -0.119704 0.001 -0.0025 -1.12055e-16 0.001 -0.00945045 -0.079444 0.001 -0.00424093 -0.0398738 0.001 -0.0180889 0.11841 0.001 -0.00424093 0.0398738 0.001 -0.00945045 0.079444 0.001 -0.0132593 0.119704 0.001 0.0025 -1.1328e-16 0.001 0.000740048 0.0403095 0.001 -0.00452641 0.0803123 0.001 -0.00452641 -0.0803123 0.001 0.000740048 -0.0403095 0.001 -0.0180889 -0.11841 0 -0.0180889 -0.11841 0.001 -0.0025 -1.12055e-16 0.001 -0.00945045 -0.079444 0.001 -0.00424093 -0.0398738 0.001 -0.0025 -1.12055e-16 0 -0.00945045 -0.079444 0 -0.00424093 -0.0398738 0 -0.0025 -1.12055e-16 0 -0.0025 -1.12055e-16 0.001 -0.0180889 0.11841 0.001 -0.00424093 0.0398738 0.001 -0.00945045 0.079444 0.001 -0.0180889 0.11841 0 -0.00424093 0.0398738 0 -0.00945045 0.079444 0 -0.0180889 0.11841 0 -0.0132593 0.119704 0 -0.0132593 0.119704 0.001 -0.0180889 0.11841 0.001 0.0025 -1.1328e-16 0 0.0025 -1.1328e-16 0.001 -0.0132593 0.119704 0.001 0.000740048 0.0403095 0.001 -0.00452641 0.0803123 0.001 -0.0132593 0.119704 0 0.000740048 0.0403095 0 -0.00452641 0.0803123 0 + + + 2 0 3 1 0 2 16 4 5 16 7 4 17 8 7 17 7 16 6 8 17 13 6 17 10 6 13 14 10 13 11 10 14 15 11 14 9 11 15 12 9 15 21 19 18 21 18 24 22 24 25 22 21 24 20 25 23 20 22 25 38 26 27 38 29 26 39 30 29 39 29 38 28 30 39 35 28 39 32 28 35 36 32 35 33 32 36 37 33 36 31 33 37 34 31 37 43 41 40 43 40 46 44 46 47 44 43 46 42 47 45 42 44 47 51 49 48 51 48 54 52 54 55 52 51 54 50 55 53 50 52 55 58 56 59 57 56 58 63 61 60 63 60 66 64 66 67 64 63 66 62 67 65 62 64 67 + 3 6 9 12 15 18 21 24 27 30 33 36 39 42 45 48 51 54 57 60 63 66 69 72 75 78 81 84 87 90 93 96 99 102 105 108 111 114 117 120 123 126 129 132 135 138 141 144 147 150 153 156 + + + + + -0.0182559 -0.119678 0 -0.0134263 -0.120972 0 -0.0134263 -0.120972 0.001 -0.0182559 -0.119678 0.001 -0.0182559 -0.119678 0 -0.0134263 -0.120972 0 -0.0025 -1.13255e-16 0 -0.0095249 -0.0802949 0 -0.00425957 -0.0403008 0 -0.0182559 0.119678 0 -0.00425957 0.0403008 0 -0.0095249 0.0802949 0 -0.0134263 0.120972 0 0.0025 -1.1448e-16 0 0.000721402 0.0407366 0 -0.00460086 0.0811632 0 -0.00460086 -0.0811632 0 0.000721402 -0.0407366 0 -0.0134263 -0.120972 0 -0.0134263 -0.120972 0.001 0.0025 -1.1448e-16 0.001 -0.00460086 -0.0811632 0.001 0.000721402 -0.0407366 0.001 0.0025 -1.1448e-16 0 -0.00460086 -0.0811632 0 0.000721402 -0.0407366 0 -0.0182559 -0.119678 0.001 -0.0134263 -0.120972 0.001 -0.0025 -1.13255e-16 0.001 -0.0095249 -0.0802949 0.001 -0.00425957 -0.0403008 0.001 -0.0182559 0.119678 0.001 -0.00425957 0.0403008 0.001 -0.0095249 0.0802949 0.001 -0.0134263 0.120972 0.001 0.0025 -1.1448e-16 0.001 0.000721402 0.0407366 0.001 -0.00460086 0.0811632 0.001 -0.00460086 -0.0811632 0.001 0.000721402 -0.0407366 0.001 -0.0182559 -0.119678 0 -0.0182559 -0.119678 0.001 -0.0025 -1.13255e-16 0.001 -0.0095249 -0.0802949 0.001 -0.00425957 -0.0403008 0.001 -0.0025 -1.13255e-16 0 -0.0095249 -0.0802949 0 -0.00425957 -0.0403008 0 -0.0025 -1.13255e-16 0 -0.0025 -1.13255e-16 0.001 -0.0182559 0.119678 0.001 -0.00425957 0.0403008 0.001 -0.0095249 0.0802949 0.001 -0.0182559 0.119678 0 -0.00425957 0.0403008 0 -0.0095249 0.0802949 0 -0.0182559 0.119678 0 -0.0134263 0.120972 0 -0.0134263 0.120972 0.001 -0.0182559 0.119678 0.001 0.0025 -1.1448e-16 0 0.0025 -1.1448e-16 0.001 -0.0134263 0.120972 0.001 0.000721402 0.0407366 0.001 -0.00460086 0.0811632 0.001 -0.0134263 0.120972 0 0.000721402 0.0407366 0 -0.00460086 0.0811632 0 + + + 2 0 3 1 0 2 16 4 5 16 7 4 17 8 7 17 7 16 6 8 17 13 6 17 10 6 13 14 10 13 15 11 10 15 10 14 9 11 15 12 9 15 21 19 18 21 18 24 22 24 25 22 21 24 20 25 23 20 22 25 38 26 27 38 29 26 39 30 29 39 29 38 28 30 39 35 28 39 32 28 35 36 32 35 37 33 32 37 32 36 31 33 37 34 31 37 43 41 40 43 40 46 44 46 47 44 43 46 42 47 45 42 44 47 51 49 48 51 48 54 52 54 55 52 51 54 50 55 53 50 52 55 58 56 59 57 56 58 63 61 60 63 60 66 64 66 67 64 63 66 62 67 65 62 64 67 + 3 6 9 12 15 18 21 24 27 30 33 36 39 42 45 48 51 54 57 60 63 66 69 72 75 78 81 84 87 90 93 96 99 102 105 108 111 114 117 120 123 126 129 132 135 138 141 144 147 150 153 156 + + + + + -0.0184229 -0.120946 0 -0.0135932 -0.12224 0 -0.0135932 -0.12224 0.001 -0.0184229 -0.120946 0.001 -0.0184229 -0.120946 0 -0.0135932 -0.12224 0 -0.0025 -1.14455e-16 0 -0.00959934 -0.0811458 0 -0.00427822 -0.0407279 0 -0.0184229 0.120946 0 -0.00427822 0.0407279 0 -0.00959934 0.0811458 0 -0.0135932 0.12224 0 0.0025 -1.1568e-16 0 0.000702756 0.0411637 0 -0.0046753 0.082014 0 -0.0046753 -0.082014 0 0.000702756 -0.0411637 0 -0.0135932 -0.12224 0 -0.0135932 -0.12224 0.001 0.0025 -1.1568e-16 0.001 -0.0046753 -0.082014 0.001 0.000702756 -0.0411637 0.001 0.0025 -1.1568e-16 0 -0.0046753 -0.082014 0 0.000702756 -0.0411637 0 -0.0184229 -0.120946 0.001 -0.0135932 -0.12224 0.001 -0.0025 -1.14455e-16 0.001 -0.00959934 -0.0811458 0.001 -0.00427822 -0.0407279 0.001 -0.0184229 0.120946 0.001 -0.00427822 0.0407279 0.001 -0.00959934 0.0811458 0.001 -0.0135932 0.12224 0.001 0.0025 -1.1568e-16 0.001 0.000702756 0.0411637 0.001 -0.0046753 0.082014 0.001 -0.0046753 -0.082014 0.001 0.000702756 -0.0411637 0.001 -0.0184229 -0.120946 0 -0.0184229 -0.120946 0.001 -0.0025 -1.14455e-16 0.001 -0.00959934 -0.0811458 0.001 -0.00427822 -0.0407279 0.001 -0.0025 -1.14455e-16 0 -0.00959934 -0.0811458 0 -0.00427822 -0.0407279 0 -0.0025 -1.14455e-16 0 -0.0025 -1.14455e-16 0.001 -0.0184229 0.120946 0.001 -0.00427822 0.0407279 0.001 -0.00959934 0.0811458 0.001 -0.0184229 0.120946 0 -0.00427822 0.0407279 0 -0.00959934 0.0811458 0 -0.0184229 0.120946 0 -0.0135932 0.12224 0 -0.0135932 0.12224 0.001 -0.0184229 0.120946 0.001 0.0025 -1.1568e-16 0 0.0025 -1.1568e-16 0.001 -0.0135932 0.12224 0.001 0.000702756 0.0411637 0.001 -0.0046753 0.082014 0.001 -0.0135932 0.12224 0 0.000702756 0.0411637 0 -0.0046753 0.082014 0 + + + 2 0 3 1 0 2 16 4 5 16 7 4 17 8 7 17 7 16 6 8 17 13 6 17 10 6 13 14 10 13 15 11 10 15 10 14 12 9 11 12 11 15 21 19 18 21 18 24 22 24 25 22 21 24 20 25 23 20 22 25 38 26 27 38 29 26 39 30 29 39 29 38 28 30 39 35 28 39 32 28 35 36 32 35 37 33 32 37 32 36 34 31 33 34 33 37 43 41 40 43 40 46 44 46 47 44 43 46 42 47 45 42 44 47 51 49 48 51 48 54 52 54 55 52 51 54 50 55 53 50 52 55 58 56 59 57 56 58 63 61 60 63 60 66 64 66 67 64 63 66 62 67 65 62 64 67 + 3 6 9 12 15 18 21 24 27 30 33 36 39 42 45 48 51 54 57 60 63 66 69 72 75 78 81 84 87 90 93 96 99 102 105 108 111 114 117 120 123 126 129 132 135 138 141 144 147 150 153 156 + + + + + -0.0110151 -0.0646789 0 -0.00618551 -0.065973 0 -0.00618551 -0.065973 0.001 -0.0110151 -0.0646789 0.001 -0.0110151 -0.0646789 0 -0.00618551 -0.065973 0 -0.0025 -6.12078e-17 0 -0.00629654 -0.0433947 0 -0.00345094 -0.0217802 0 -0.0110151 0.0646789 0 -0.00345094 0.0217802 0 -0.00629654 0.0433947 0 -0.00618551 0.065973 0 0.0025 -6.24325e-17 0 0.00153003 0.022216 0 -0.0013725 0.0442629 0 -0.0013725 -0.0442629 0 0.00153003 -0.022216 0 -0.00618551 -0.065973 0 -0.00618551 -0.065973 0.001 0.0025 -6.24325e-17 0.001 -0.0013725 -0.0442629 0.001 0.00153003 -0.022216 0.001 0.0025 -6.24325e-17 0 -0.0013725 -0.0442629 0 0.00153003 -0.022216 0 -0.0110151 -0.0646789 0.001 -0.00618551 -0.065973 0.001 -0.0025 -6.12078e-17 0.001 -0.00629654 -0.0433947 0.001 -0.00345094 -0.0217802 0.001 -0.0110151 0.0646789 0.001 -0.00345094 0.0217802 0.001 -0.00629654 0.0433947 0.001 -0.00618551 0.065973 0.001 0.0025 -6.24325e-17 0.001 0.00153003 0.022216 0.001 -0.0013725 0.0442629 0.001 -0.0013725 -0.0442629 0.001 0.00153003 -0.022216 0.001 -0.0110151 -0.0646789 0 -0.0110151 -0.0646789 0.001 -0.0025 -6.12078e-17 0.001 -0.00629654 -0.0433947 0.001 -0.00345094 -0.0217802 0.001 -0.0025 -6.12078e-17 0 -0.00629654 -0.0433947 0 -0.00345094 -0.0217802 0 -0.0025 -6.12078e-17 0 -0.0025 -6.12078e-17 0.001 -0.0110151 0.0646789 0.001 -0.00345094 0.0217802 0.001 -0.00629654 0.0433947 0.001 -0.0110151 0.0646789 0 -0.00345094 0.0217802 0 -0.00629654 0.0433947 0 -0.0110151 0.0646789 0 -0.00618551 0.065973 0 -0.00618551 0.065973 0.001 -0.0110151 0.0646789 0.001 0.0025 -6.24325e-17 0 0.0025 -6.24325e-17 0.001 -0.00618551 0.065973 0.001 0.00153003 0.022216 0.001 -0.0013725 0.0442629 0.001 -0.00618551 0.065973 0 0.00153003 0.022216 0 -0.0013725 0.0442629 0 + + + 2 0 3 1 0 2 16 4 5 16 7 4 17 8 7 17 7 16 6 8 17 13 6 17 10 6 13 14 10 13 15 11 10 15 10 14 12 9 11 12 11 15 21 19 18 21 18 24 22 24 25 22 21 24 20 25 23 20 22 25 38 26 27 38 29 26 39 30 29 39 29 38 28 30 39 35 28 39 32 28 35 36 32 35 37 33 32 37 32 36 34 31 33 34 33 37 43 41 40 43 40 46 44 46 47 44 43 46 42 47 45 42 44 47 51 49 48 51 48 54 52 54 55 52 51 54 50 55 53 50 52 55 58 56 59 57 56 58 63 61 60 63 60 66 64 66 67 64 63 66 62 67 65 62 64 67 + 3 6 9 12 15 18 21 24 27 30 33 36 39 42 45 48 51 54 57 60 63 66 69 72 75 78 81 84 87 90 93 96 99 102 105 108 111 114 117 120 123 126 129 132 135 138 141 144 147 150 153 156 + + + + + -0.0185898 -0.122214 0 -0.0137602 -0.123508 0 -0.0137602 -0.123508 0.001 -0.0185898 -0.122214 0.001 -0.0185898 -0.122214 0 -0.0137602 -0.123508 0 -0.0025 -1.15656e-16 0 -0.00967378 -0.0819967 0 -0.00429686 -0.0411549 0 -0.0185898 0.122214 0 -0.00429686 0.0411549 0 -0.00967378 0.0819967 0 -0.0137602 0.123508 0 0.0025 -1.1688e-16 0 0.00068411 0.0415907 0 -0.00474974 0.0828649 0 -0.00474974 -0.0828649 0 0.00068411 -0.0415907 0 -0.0137602 -0.123508 0 -0.0137602 -0.123508 0.001 0.0025 -1.1688e-16 0.001 -0.00474974 -0.0828649 0.001 0.00068411 -0.0415907 0.001 0.0025 -1.1688e-16 0 -0.00474974 -0.0828649 0 0.00068411 -0.0415907 0 -0.0185898 -0.122214 0.001 -0.0137602 -0.123508 0.001 -0.0025 -1.15656e-16 0.001 -0.00967378 -0.0819967 0.001 -0.00429686 -0.0411549 0.001 -0.0185898 0.122214 0.001 -0.00429686 0.0411549 0.001 -0.00967378 0.0819967 0.001 -0.0137602 0.123508 0.001 0.0025 -1.1688e-16 0.001 0.00068411 0.0415907 0.001 -0.00474974 0.0828649 0.001 -0.00474974 -0.0828649 0.001 0.00068411 -0.0415907 0.001 -0.0185898 -0.122214 0 -0.0185898 -0.122214 0.001 -0.0025 -1.15656e-16 0.001 -0.00967378 -0.0819967 0.001 -0.00429686 -0.0411549 0.001 -0.0025 -1.15656e-16 0 -0.00967378 -0.0819967 0 -0.00429686 -0.0411549 0 -0.0025 -1.15656e-16 0 -0.0025 -1.15656e-16 0.001 -0.0185898 0.122214 0.001 -0.00429686 0.0411549 0.001 -0.00967378 0.0819967 0.001 -0.0185898 0.122214 0 -0.00429686 0.0411549 0 -0.00967378 0.0819967 0 -0.0185898 0.122214 0 -0.0137602 0.123508 0 -0.0137602 0.123508 0.001 -0.0185898 0.122214 0.001 0.0025 -1.1688e-16 0 0.0025 -1.1688e-16 0.001 -0.0137602 0.123508 0.001 0.00068411 0.0415907 0.001 -0.00474974 0.0828649 0.001 -0.0137602 0.123508 0 0.00068411 0.0415907 0 -0.00474974 0.0828649 0 + + + 2 0 3 1 0 2 16 4 5 16 7 4 17 8 7 17 7 16 6 8 17 13 6 17 10 6 13 14 10 13 15 11 10 15 10 14 12 9 11 12 11 15 21 19 18 21 18 24 22 24 25 22 21 24 20 25 23 20 22 25 38 26 27 38 29 26 39 30 29 39 29 38 28 30 39 35 28 39 32 28 35 36 32 35 37 33 32 37 32 36 34 31 33 34 33 37 43 41 40 43 40 46 44 46 47 44 43 46 42 47 45 42 44 47 51 49 48 51 48 54 52 54 55 52 51 54 50 55 53 50 52 55 58 56 59 57 56 58 63 61 60 63 60 66 64 66 67 64 63 66 62 67 65 62 64 67 + 3 6 9 12 15 18 21 24 27 30 33 36 39 42 45 48 51 54 57 60 63 66 69 72 75 78 81 84 87 90 93 96 99 102 105 108 111 114 117 120 123 126 129 132 135 138 141 144 147 150 153 156 + + + + + -0.0187568 -0.123483 0 -0.0139272 -0.124777 0 -0.0139272 -0.124777 0.001 -0.0187568 -0.123483 0.001 -0.0187568 -0.123483 0 -0.0139272 -0.124777 0 -0.0025 -1.16856e-16 0 -0.00974822 -0.0828475 0 -0.00431551 -0.041582 0 -0.0187568 0.123483 0 -0.00431551 0.041582 0 -0.00974822 0.0828475 0 -0.0139272 0.124777 0 0.0025 -1.1808e-16 0 0.000665464 0.0420178 0 -0.00482418 0.0837158 0 -0.00482418 -0.0837158 0 0.000665464 -0.0420178 0 -0.0139272 -0.124777 0 -0.0139272 -0.124777 0.001 0.0025 -1.1808e-16 0.001 -0.00482418 -0.0837158 0.001 0.000665464 -0.0420178 0.001 0.0025 -1.1808e-16 0 -0.00482418 -0.0837158 0 0.000665464 -0.0420178 0 -0.0187568 -0.123483 0.001 -0.0139272 -0.124777 0.001 -0.0025 -1.16856e-16 0.001 -0.00974822 -0.0828475 0.001 -0.00431551 -0.041582 0.001 -0.0187568 0.123483 0.001 -0.00431551 0.041582 0.001 -0.00974822 0.0828475 0.001 -0.0139272 0.124777 0.001 0.0025 -1.1808e-16 0.001 0.000665464 0.0420178 0.001 -0.00482418 0.0837158 0.001 -0.00482418 -0.0837158 0.001 0.000665464 -0.0420178 0.001 -0.0187568 -0.123483 0 -0.0187568 -0.123483 0.001 -0.0025 -1.16856e-16 0.001 -0.00974822 -0.0828475 0.001 -0.00431551 -0.041582 0.001 -0.0025 -1.16856e-16 0 -0.00974822 -0.0828475 0 -0.00431551 -0.041582 0 -0.0025 -1.16856e-16 0 -0.0025 -1.16856e-16 0.001 -0.0187568 0.123483 0.001 -0.00431551 0.041582 0.001 -0.00974822 0.0828475 0.001 -0.0187568 0.123483 0 -0.00431551 0.041582 0 -0.00974822 0.0828475 0 -0.0187568 0.123483 0 -0.0139272 0.124777 0 -0.0139272 0.124777 0.001 -0.0187568 0.123483 0.001 0.0025 -1.1808e-16 0 0.0025 -1.1808e-16 0.001 -0.0139272 0.124777 0.001 0.000665464 0.0420178 0.001 -0.00482418 0.0837158 0.001 -0.0139272 0.124777 0 0.000665464 0.0420178 0 -0.00482418 0.0837158 0 + + + 2 0 3 1 0 2 16 4 5 16 7 4 17 8 7 17 7 16 6 8 17 13 6 17 10 6 13 14 10 13 11 10 14 15 11 14 12 9 11 12 11 15 21 19 18 21 18 24 22 24 25 22 21 24 20 25 23 20 22 25 38 26 27 38 29 26 39 30 29 39 29 38 28 30 39 35 28 39 32 28 35 36 32 35 33 32 36 37 33 36 34 31 33 34 33 37 43 41 40 43 40 46 44 46 47 44 43 46 42 47 45 42 44 47 51 49 48 51 48 54 52 54 55 52 51 54 50 55 53 50 52 55 58 56 59 57 56 58 63 61 60 63 60 66 64 66 67 64 63 66 62 67 65 62 64 67 + 3 6 9 12 15 18 21 24 27 30 33 36 39 42 45 48 51 54 57 60 63 66 69 72 75 78 81 84 87 90 93 96 99 102 105 108 111 114 117 120 123 126 129 132 135 138 141 144 147 150 153 156 + + + + + -0.0189238 -0.124751 0 -0.0140941 -0.126045 0 -0.0140941 -0.126045 0.001 -0.0189238 -0.124751 0.001 -0.0189238 -0.124751 0 -0.0140941 -0.126045 0 -0.0025 -1.18056e-16 0 -0.00982266 -0.0836984 0 -0.00433416 -0.0420091 0 -0.0189238 0.124751 0 -0.00433416 0.0420091 0 -0.00982266 0.0836984 0 -0.0140941 0.126045 0 0.0025 -1.19281e-16 0 0.000646818 0.0424448 0 -0.00489862 0.0845667 0 -0.00489862 -0.0845667 0 0.000646818 -0.0424448 0 -0.0140941 -0.126045 0 -0.0140941 -0.126045 0.001 0.0025 -1.19281e-16 0.001 -0.00489862 -0.0845667 0.001 0.000646818 -0.0424448 0.001 0.0025 -1.19281e-16 0 -0.00489862 -0.0845667 0 0.000646818 -0.0424448 0 -0.0189238 -0.124751 0.001 -0.0140941 -0.126045 0.001 -0.0025 -1.18056e-16 0.001 -0.00982266 -0.0836984 0.001 -0.00433416 -0.0420091 0.001 -0.0189238 0.124751 0.001 -0.00433416 0.0420091 0.001 -0.00982266 0.0836984 0.001 -0.0140941 0.126045 0.001 0.0025 -1.19281e-16 0.001 0.000646818 0.0424448 0.001 -0.00489862 0.0845667 0.001 -0.00489862 -0.0845667 0.001 0.000646818 -0.0424448 0.001 -0.0189238 -0.124751 0 -0.0189238 -0.124751 0.001 -0.0025 -1.18056e-16 0.001 -0.00982266 -0.0836984 0.001 -0.00433416 -0.0420091 0.001 -0.0025 -1.18056e-16 0 -0.00982266 -0.0836984 0 -0.00433416 -0.0420091 0 -0.0025 -1.18056e-16 0 -0.0025 -1.18056e-16 0.001 -0.0189238 0.124751 0.001 -0.00433416 0.0420091 0.001 -0.00982266 0.0836984 0.001 -0.0189238 0.124751 0 -0.00433416 0.0420091 0 -0.00982266 0.0836984 0 -0.0189238 0.124751 0 -0.0140941 0.126045 0 -0.0140941 0.126045 0.001 -0.0189238 0.124751 0.001 0.0025 -1.19281e-16 0 0.0025 -1.19281e-16 0.001 -0.0140941 0.126045 0.001 0.000646818 0.0424448 0.001 -0.00489862 0.0845667 0.001 -0.0140941 0.126045 0 0.000646818 0.0424448 0 -0.00489862 0.0845667 0 + + + 2 0 3 1 0 2 16 4 5 16 7 4 17 8 7 17 7 16 6 8 17 13 6 17 10 6 13 14 10 13 11 10 14 15 11 14 12 9 11 12 11 15 21 19 18 21 18 24 22 24 25 22 21 24 20 25 23 20 22 25 38 26 27 38 29 26 39 30 29 39 29 38 28 30 39 35 28 39 32 28 35 36 32 35 33 32 36 37 33 36 34 31 33 34 33 37 43 41 40 43 40 46 44 46 47 44 43 46 42 47 45 42 44 47 51 49 48 51 48 54 52 54 55 52 51 54 50 55 53 50 52 55 58 56 59 57 56 58 63 61 60 63 60 66 64 66 67 64 63 66 62 67 65 62 64 67 + 3 6 9 12 15 18 21 24 27 30 33 36 39 42 45 48 51 54 57 60 63 66 69 72 75 78 81 84 87 90 93 96 99 102 105 108 111 114 117 120 123 126 129 132 135 138 141 144 147 150 153 156 + + + + + -0.0190907 -0.126019 0 -0.0142611 -0.127313 0 -0.0142611 -0.127313 0.001 -0.0190907 -0.126019 0.001 -0.0190907 -0.126019 0 -0.0142611 -0.127313 0 -0.0025 -1.19256e-16 0 -0.00989711 -0.0845493 0 -0.0043528 -0.0424361 0 -0.0190907 0.126019 0 -0.0043528 0.0424361 0 -0.00989711 0.0845493 0 -0.0142611 0.127313 0 0.0025 -1.20481e-16 0 0.000628172 0.0428719 0 -0.00497307 0.0854175 0 -0.00497307 -0.0854175 0 0.000628172 -0.0428719 0 -0.0142611 -0.127313 0 -0.0142611 -0.127313 0.001 0.0025 -1.20481e-16 0.001 -0.00497307 -0.0854175 0.001 0.000628172 -0.0428719 0.001 0.0025 -1.20481e-16 0 -0.00497307 -0.0854175 0 0.000628172 -0.0428719 0 -0.0190907 -0.126019 0.001 -0.0142611 -0.127313 0.001 -0.0025 -1.19256e-16 0.001 -0.00989711 -0.0845493 0.001 -0.0043528 -0.0424361 0.001 -0.0190907 0.126019 0.001 -0.0043528 0.0424361 0.001 -0.00989711 0.0845493 0.001 -0.0142611 0.127313 0.001 0.0025 -1.20481e-16 0.001 0.000628172 0.0428719 0.001 -0.00497307 0.0854175 0.001 -0.00497307 -0.0854175 0.001 0.000628172 -0.0428719 0.001 -0.0190907 -0.126019 0 -0.0190907 -0.126019 0.001 -0.0025 -1.19256e-16 0.001 -0.00989711 -0.0845493 0.001 -0.0043528 -0.0424361 0.001 -0.0025 -1.19256e-16 0 -0.00989711 -0.0845493 0 -0.0043528 -0.0424361 0 -0.0025 -1.19256e-16 0 -0.0025 -1.19256e-16 0.001 -0.0190907 0.126019 0.001 -0.0043528 0.0424361 0.001 -0.00989711 0.0845493 0.001 -0.0190907 0.126019 0 -0.0043528 0.0424361 0 -0.00989711 0.0845493 0 -0.0190907 0.126019 0 -0.0142611 0.127313 0 -0.0142611 0.127313 0.001 -0.0190907 0.126019 0.001 0.0025 -1.20481e-16 0 0.0025 -1.20481e-16 0.001 -0.0142611 0.127313 0.001 0.000628172 0.0428719 0.001 -0.00497307 0.0854175 0.001 -0.0142611 0.127313 0 0.000628172 0.0428719 0 -0.00497307 0.0854175 0 + + + 2 0 3 1 0 2 16 4 5 16 7 4 17 8 7 17 7 16 6 8 17 13 6 17 10 6 13 14 10 13 15 11 10 15 10 14 12 9 11 12 11 15 21 19 18 21 18 24 22 24 25 22 21 24 20 25 23 20 22 25 38 26 27 38 29 26 39 30 29 39 29 38 28 30 39 35 28 39 32 28 35 36 32 35 37 33 32 37 32 36 34 31 33 34 33 37 43 41 40 43 40 46 44 46 47 44 43 46 42 47 45 42 44 47 51 49 48 51 48 54 52 54 55 52 51 54 50 55 53 50 52 55 58 56 59 57 56 58 63 61 60 63 60 66 64 66 67 64 63 66 62 67 65 62 64 67 + 3 6 9 12 15 18 21 24 27 30 33 36 39 42 45 48 51 54 57 60 63 66 69 72 75 78 81 84 87 90 93 96 99 102 105 108 111 114 117 120 123 126 129 132 135 138 141 144 147 150 153 156 + + + + + -0.0192543 -0.127261 0 -0.0144246 -0.128555 0 -0.0144246 -0.128555 0.001 -0.0192543 -0.127261 0.001 -0.0192543 -0.127261 0 -0.0144246 -0.128555 0 -0.0025 -1.20432e-16 0 -0.00997003 -0.0853828 0 -0.00437107 -0.0428545 0 -0.0192543 0.127261 0 -0.00437107 0.0428545 0 -0.00997003 0.0853828 0 -0.0144246 0.128555 0 0.0025 -1.21656e-16 0 0.000609907 0.0432903 0 -0.00504599 0.086251 0 -0.00504599 -0.086251 0 0.000609907 -0.0432903 0 -0.0144246 -0.128555 0 -0.0144246 -0.128555 0.001 0.0025 -1.21656e-16 0.001 -0.00504599 -0.086251 0.001 0.000609907 -0.0432903 0.001 0.0025 -1.21656e-16 0 -0.00504599 -0.086251 0 0.000609907 -0.0432903 0 -0.0192543 -0.127261 0.001 -0.0144246 -0.128555 0.001 -0.0025 -1.20432e-16 0.001 -0.00997003 -0.0853828 0.001 -0.00437107 -0.0428545 0.001 -0.0192543 0.127261 0.001 -0.00437107 0.0428545 0.001 -0.00997003 0.0853828 0.001 -0.0144246 0.128555 0.001 0.0025 -1.21656e-16 0.001 0.000609907 0.0432903 0.001 -0.00504599 0.086251 0.001 -0.00504599 -0.086251 0.001 0.000609907 -0.0432903 0.001 -0.0192543 -0.127261 0 -0.0192543 -0.127261 0.001 -0.0025 -1.20432e-16 0.001 -0.00997003 -0.0853828 0.001 -0.00437107 -0.0428545 0.001 -0.0025 -1.20432e-16 0 -0.00997003 -0.0853828 0 -0.00437107 -0.0428545 0 -0.0025 -1.20432e-16 0 -0.0025 -1.20432e-16 0.001 -0.0192543 0.127261 0.001 -0.00437107 0.0428545 0.001 -0.00997003 0.0853828 0.001 -0.0192543 0.127261 0 -0.00437107 0.0428545 0 -0.00997003 0.0853828 0 -0.0192543 0.127261 0 -0.0144246 0.128555 0 -0.0144246 0.128555 0.001 -0.0192543 0.127261 0.001 0.0025 -1.21656e-16 0 0.0025 -1.21656e-16 0.001 -0.0144246 0.128555 0.001 0.000609907 0.0432903 0.001 -0.00504599 0.086251 0.001 -0.0144246 0.128555 0 0.000609907 0.0432903 0 -0.00504599 0.086251 0 + + + 2 0 3 1 0 2 16 4 5 16 7 4 17 8 7 17 7 16 6 8 17 13 6 17 10 6 13 14 10 13 11 10 14 15 11 14 9 11 15 12 9 15 21 19 18 21 18 24 22 24 25 22 21 24 20 25 23 20 22 25 38 26 27 38 29 26 39 30 29 39 29 38 28 30 39 35 28 39 32 28 35 36 32 35 33 32 36 37 33 36 31 33 37 34 31 37 43 41 40 43 40 46 44 46 47 44 43 46 42 47 45 42 44 47 51 49 48 51 48 54 52 54 55 52 51 54 50 55 53 50 52 55 58 56 59 57 56 58 63 61 60 63 60 66 64 66 67 64 63 66 62 67 65 62 64 67 + 3 6 9 12 15 18 21 24 27 30 33 36 39 42 45 48 51 54 57 60 63 66 69 72 75 78 81 84 87 90 93 96 99 102 105 108 111 114 117 120 123 126 129 132 135 138 141 144 147 150 153 156 + + + + + -0.0194212 -0.12853 0 -0.0145916 -0.129824 0 -0.0145916 -0.129824 0.001 -0.0194212 -0.12853 0.001 -0.0194212 -0.12853 0 -0.0145916 -0.129824 0 -0.0025 -1.21632e-16 0 -0.0100445 -0.0862337 0 -0.00438971 -0.0432815 0 -0.0194212 0.12853 0 -0.00438971 0.0432815 0 -0.0100445 0.0862337 0 -0.0145916 0.129824 0 0.0025 -1.22857e-16 0 0.000591261 0.0437173 0 -0.00512043 0.0871019 0 -0.00512043 -0.0871019 0 0.000591261 -0.0437173 0 -0.0145916 -0.129824 0 -0.0145916 -0.129824 0.001 0.0025 -1.22857e-16 0.001 -0.00512043 -0.0871019 0.001 0.000591261 -0.0437173 0.001 0.0025 -1.22857e-16 0 -0.00512043 -0.0871019 0 0.000591261 -0.0437173 0 -0.0194212 -0.12853 0.001 -0.0145916 -0.129824 0.001 -0.0025 -1.21632e-16 0.001 -0.0100445 -0.0862337 0.001 -0.00438971 -0.0432815 0.001 -0.0194212 0.12853 0.001 -0.00438971 0.0432815 0.001 -0.0100445 0.0862337 0.001 -0.0145916 0.129824 0.001 0.0025 -1.22857e-16 0.001 0.000591261 0.0437173 0.001 -0.00512043 0.0871019 0.001 -0.00512043 -0.0871019 0.001 0.000591261 -0.0437173 0.001 -0.0194212 -0.12853 0 -0.0194212 -0.12853 0.001 -0.0025 -1.21632e-16 0.001 -0.0100445 -0.0862337 0.001 -0.00438971 -0.0432815 0.001 -0.0025 -1.21632e-16 0 -0.0100445 -0.0862337 0 -0.00438971 -0.0432815 0 -0.0025 -1.21632e-16 0 -0.0025 -1.21632e-16 0.001 -0.0194212 0.12853 0.001 -0.00438971 0.0432815 0.001 -0.0100445 0.0862337 0.001 -0.0194212 0.12853 0 -0.00438971 0.0432815 0 -0.0100445 0.0862337 0 -0.0194212 0.12853 0 -0.0145916 0.129824 0 -0.0145916 0.129824 0.001 -0.0194212 0.12853 0.001 0.0025 -1.22857e-16 0 0.0025 -1.22857e-16 0.001 -0.0145916 0.129824 0.001 0.000591261 0.0437173 0.001 -0.00512043 0.0871019 0.001 -0.0145916 0.129824 0 0.000591261 0.0437173 0 -0.00512043 0.0871019 0 + + + 2 0 3 1 0 2 16 4 5 16 7 4 17 8 7 17 7 16 6 8 17 13 6 17 10 6 13 14 10 13 15 11 10 15 10 14 9 11 15 12 9 15 21 19 18 21 18 24 22 24 25 22 21 24 20 25 23 20 22 25 38 26 27 38 29 26 39 30 29 39 29 38 28 30 39 35 28 39 32 28 35 36 32 35 37 33 32 37 32 36 31 33 37 34 31 37 43 41 40 43 40 46 44 46 47 44 43 46 42 47 45 42 44 47 51 49 48 51 48 54 52 54 55 52 51 54 50 55 53 50 52 55 58 56 59 57 56 58 63 61 60 63 60 66 64 66 67 64 63 66 62 67 65 62 64 67 + 3 6 9 12 15 18 21 24 27 30 33 36 39 42 45 48 51 54 57 60 63 66 69 72 75 78 81 84 87 90 93 96 99 102 105 108 111 114 117 120 123 126 129 132 135 138 141 144 147 150 153 156 + + + + + -0.0195882 -0.129798 0 -0.0147586 -0.131092 0 -0.0147586 -0.131092 0.001 -0.0195882 -0.129798 0.001 -0.0195882 -0.129798 0 -0.0147586 -0.131092 0 -0.0025 -1.22832e-16 0 -0.0101189 -0.0870846 0 -0.00440836 -0.0437086 0 -0.0195882 0.129798 0 -0.00440836 0.0437086 0 -0.0101189 0.0870846 0 -0.0147586 0.131092 0 0.0025 -1.24057e-16 0 0.000572615 0.0441444 0 -0.00519487 0.0879528 0 -0.00519487 -0.0879528 0 0.000572615 -0.0441444 0 -0.0147586 -0.131092 0 -0.0147586 -0.131092 0.001 0.0025 -1.24057e-16 0.001 -0.00519487 -0.0879528 0.001 0.000572615 -0.0441444 0.001 0.0025 -1.24057e-16 0 -0.00519487 -0.0879528 0 0.000572615 -0.0441444 0 -0.0195882 -0.129798 0.001 -0.0147586 -0.131092 0.001 -0.0025 -1.22832e-16 0.001 -0.0101189 -0.0870846 0.001 -0.00440836 -0.0437086 0.001 -0.0195882 0.129798 0.001 -0.00440836 0.0437086 0.001 -0.0101189 0.0870846 0.001 -0.0147586 0.131092 0.001 0.0025 -1.24057e-16 0.001 0.000572615 0.0441444 0.001 -0.00519487 0.0879528 0.001 -0.00519487 -0.0879528 0.001 0.000572615 -0.0441444 0.001 -0.0195882 -0.129798 0 -0.0195882 -0.129798 0.001 -0.0025 -1.22832e-16 0.001 -0.0101189 -0.0870846 0.001 -0.00440836 -0.0437086 0.001 -0.0025 -1.22832e-16 0 -0.0101189 -0.0870846 0 -0.00440836 -0.0437086 0 -0.0025 -1.22832e-16 0 -0.0025 -1.22832e-16 0.001 -0.0195882 0.129798 0.001 -0.00440836 0.0437086 0.001 -0.0101189 0.0870846 0.001 -0.0195882 0.129798 0 -0.00440836 0.0437086 0 -0.0101189 0.0870846 0 -0.0195882 0.129798 0 -0.0147586 0.131092 0 -0.0147586 0.131092 0.001 -0.0195882 0.129798 0.001 0.0025 -1.24057e-16 0 0.0025 -1.24057e-16 0.001 -0.0147586 0.131092 0.001 0.000572615 0.0441444 0.001 -0.00519487 0.0879528 0.001 -0.0147586 0.131092 0 0.000572615 0.0441444 0 -0.00519487 0.0879528 0 + + + 2 0 3 1 0 2 16 4 5 16 7 4 17 8 7 17 7 16 6 8 17 13 6 17 10 6 13 14 10 13 15 11 10 15 10 14 9 11 15 12 9 15 21 19 18 21 18 24 22 24 25 22 21 24 20 25 23 20 22 25 38 26 27 38 29 26 39 30 29 39 29 38 28 30 39 35 28 39 32 28 35 36 32 35 37 33 32 37 32 36 31 33 37 34 31 37 43 41 40 43 40 46 44 46 47 44 43 46 42 47 45 42 44 47 51 49 48 51 48 54 52 54 55 52 51 54 50 55 53 50 52 55 58 56 59 57 56 58 63 61 60 63 60 66 64 66 67 64 63 66 62 67 65 62 64 67 + 3 6 9 12 15 18 21 24 27 30 33 36 39 42 45 48 51 54 57 60 63 66 69 72 75 78 81 84 87 90 93 96 99 102 105 108 111 114 117 120 123 126 129 132 135 138 141 144 147 150 153 156 + + + + + -0.0197552 -0.131066 0 -0.0149255 -0.13236 0 -0.0149255 -0.13236 0.001 -0.0197552 -0.131066 0.001 -0.0197552 -0.131066 0 -0.0149255 -0.13236 0 -0.0025 -1.24032e-16 0 -0.0101934 -0.0879354 0 -0.004427 -0.0441357 0 -0.0197552 0.131066 0 -0.004427 0.0441357 0 -0.0101934 0.0879354 0 -0.0149255 0.13236 0 0.0025 -1.25257e-16 0 0.000553969 0.0445714 0 -0.00526932 0.0888037 0 -0.00526932 -0.0888037 0 0.000553969 -0.0445714 0 -0.0149255 -0.13236 0 -0.0149255 -0.13236 0.001 0.0025 -1.25257e-16 0.001 -0.00526932 -0.0888037 0.001 0.000553969 -0.0445714 0.001 0.0025 -1.25257e-16 0 -0.00526932 -0.0888037 0 0.000553969 -0.0445714 0 -0.0197552 -0.131066 0.001 -0.0149255 -0.13236 0.001 -0.0025 -1.24032e-16 0.001 -0.0101934 -0.0879354 0.001 -0.004427 -0.0441357 0.001 -0.0197552 0.131066 0.001 -0.004427 0.0441357 0.001 -0.0101934 0.0879354 0.001 -0.0149255 0.13236 0.001 0.0025 -1.25257e-16 0.001 0.000553969 0.0445714 0.001 -0.00526932 0.0888037 0.001 -0.00526932 -0.0888037 0.001 0.000553969 -0.0445714 0.001 -0.0197552 -0.131066 0 -0.0197552 -0.131066 0.001 -0.0025 -1.24032e-16 0.001 -0.0101934 -0.0879354 0.001 -0.004427 -0.0441357 0.001 -0.0025 -1.24032e-16 0 -0.0101934 -0.0879354 0 -0.004427 -0.0441357 0 -0.0025 -1.24032e-16 0 -0.0025 -1.24032e-16 0.001 -0.0197552 0.131066 0.001 -0.004427 0.0441357 0.001 -0.0101934 0.0879354 0.001 -0.0197552 0.131066 0 -0.004427 0.0441357 0 -0.0101934 0.0879354 0 -0.0197552 0.131066 0 -0.0149255 0.13236 0 -0.0149255 0.13236 0.001 -0.0197552 0.131066 0.001 0.0025 -1.25257e-16 0 0.0025 -1.25257e-16 0.001 -0.0149255 0.13236 0.001 0.000553969 0.0445714 0.001 -0.00526932 0.0888037 0.001 -0.0149255 0.13236 0 0.000553969 0.0445714 0 -0.00526932 0.0888037 0 + + + 2 0 3 1 0 2 16 4 5 16 7 4 17 8 7 17 7 16 6 8 17 13 6 17 10 6 13 14 10 13 11 10 14 15 11 14 12 9 11 12 11 15 21 19 18 21 18 24 22 24 25 22 21 24 20 25 23 20 22 25 38 26 27 38 29 26 39 30 29 39 29 38 28 30 39 35 28 39 32 28 35 36 32 35 33 32 36 37 33 36 34 31 33 34 33 37 43 41 40 43 40 46 44 46 47 44 43 46 42 47 45 42 44 47 51 49 48 51 48 54 52 54 55 52 51 54 50 55 53 50 52 55 58 56 59 57 56 58 63 61 60 63 60 66 64 66 67 64 63 66 62 67 65 62 64 67 + 3 6 9 12 15 18 21 24 27 30 33 36 39 42 45 48 51 54 57 60 63 66 69 72 75 78 81 84 87 90 93 96 99 102 105 108 111 114 117 120 123 126 129 132 135 138 141 144 147 150 153 156 + + + + + -0.0199221 -0.132334 0 -0.0150925 -0.133628 0 -0.0150925 -0.133628 0.001 -0.0199221 -0.132334 0.001 -0.0199221 -0.132334 0 -0.0150925 -0.133628 0 -0.0025 -1.25232e-16 0 -0.0102678 -0.0887863 0 -0.00444565 -0.0445627 0 -0.0199221 0.132334 0 -0.00444565 0.0445627 0 -0.0102678 0.0887863 0 -0.0150925 0.133628 0 0.0025 -1.26457e-16 0 0.000535323 0.0449985 0 -0.00534376 0.0896546 0 -0.00534376 -0.0896546 0 0.000535323 -0.0449985 0 -0.0150925 -0.133628 0 -0.0150925 -0.133628 0.001 0.0025 -1.26457e-16 0.001 -0.00534376 -0.0896546 0.001 0.000535323 -0.0449985 0.001 0.0025 -1.26457e-16 0 -0.00534376 -0.0896546 0 0.000535323 -0.0449985 0 -0.0199221 -0.132334 0.001 -0.0150925 -0.133628 0.001 -0.0025 -1.25232e-16 0.001 -0.0102678 -0.0887863 0.001 -0.00444565 -0.0445627 0.001 -0.0199221 0.132334 0.001 -0.00444565 0.0445627 0.001 -0.0102678 0.0887863 0.001 -0.0150925 0.133628 0.001 0.0025 -1.26457e-16 0.001 0.000535323 0.0449985 0.001 -0.00534376 0.0896546 0.001 -0.00534376 -0.0896546 0.001 0.000535323 -0.0449985 0.001 -0.0199221 -0.132334 0 -0.0199221 -0.132334 0.001 -0.0025 -1.25232e-16 0.001 -0.0102678 -0.0887863 0.001 -0.00444565 -0.0445627 0.001 -0.0025 -1.25232e-16 0 -0.0102678 -0.0887863 0 -0.00444565 -0.0445627 0 -0.0025 -1.25232e-16 0 -0.0025 -1.25232e-16 0.001 -0.0199221 0.132334 0.001 -0.00444565 0.0445627 0.001 -0.0102678 0.0887863 0.001 -0.0199221 0.132334 0 -0.00444565 0.0445627 0 -0.0102678 0.0887863 0 -0.0199221 0.132334 0 -0.0150925 0.133628 0 -0.0150925 0.133628 0.001 -0.0199221 0.132334 0.001 0.0025 -1.26457e-16 0 0.0025 -1.26457e-16 0.001 -0.0150925 0.133628 0.001 0.000535323 0.0449985 0.001 -0.00534376 0.0896546 0.001 -0.0150925 0.133628 0 0.000535323 0.0449985 0 -0.00534376 0.0896546 0 + + + 2 0 3 1 0 2 16 4 5 16 7 4 17 8 7 17 7 16 6 8 17 13 6 17 10 6 13 14 10 13 15 11 10 15 10 14 12 9 11 12 11 15 21 19 18 21 18 24 22 24 25 22 21 24 20 25 23 20 22 25 38 26 27 38 29 26 39 30 29 39 29 38 28 30 39 35 28 39 32 28 35 36 32 35 37 33 32 37 32 36 34 31 33 34 33 37 43 41 40 43 40 46 44 46 47 44 43 46 42 47 45 42 44 47 51 49 48 51 48 54 52 54 55 52 51 54 50 55 53 50 52 55 58 56 59 57 56 58 63 61 60 63 60 66 64 66 67 64 63 66 62 67 65 62 64 67 + 3 6 9 12 15 18 21 24 27 30 33 36 39 42 45 48 51 54 57 60 63 66 69 72 75 78 81 84 87 90 93 96 99 102 105 108 111 114 117 120 123 126 129 132 135 138 141 144 147 150 153 156 + + + + + -0.0200891 -0.133602 0 -0.0152595 -0.134896 0 -0.0152595 -0.134896 0.001 -0.0200891 -0.133602 0.001 -0.0200891 -0.133602 0 -0.0152595 -0.134896 0 -0.0025 -1.26433e-16 0 -0.0103422 -0.0896372 0 -0.0044643 -0.0449898 0 -0.0200891 0.133602 0 -0.0044643 0.0449898 0 -0.0103422 0.0896372 0 -0.0152595 0.134896 0 0.0025 -1.27657e-16 0 0.000516677 0.0454256 0 -0.0054182 0.0905054 0 -0.0054182 -0.0905054 0 0.000516677 -0.0454256 0 -0.0152595 -0.134896 0 -0.0152595 -0.134896 0.001 0.0025 -1.27657e-16 0.001 -0.0054182 -0.0905054 0.001 0.000516677 -0.0454256 0.001 0.0025 -1.27657e-16 0 -0.0054182 -0.0905054 0 0.000516677 -0.0454256 0 -0.0200891 -0.133602 0.001 -0.0152595 -0.134896 0.001 -0.0025 -1.26433e-16 0.001 -0.0103422 -0.0896372 0.001 -0.0044643 -0.0449898 0.001 -0.0200891 0.133602 0.001 -0.0044643 0.0449898 0.001 -0.0103422 0.0896372 0.001 -0.0152595 0.134896 0.001 0.0025 -1.27657e-16 0.001 0.000516677 0.0454256 0.001 -0.0054182 0.0905054 0.001 -0.0054182 -0.0905054 0.001 0.000516677 -0.0454256 0.001 -0.0200891 -0.133602 0 -0.0200891 -0.133602 0.001 -0.0025 -1.26433e-16 0.001 -0.0103422 -0.0896372 0.001 -0.0044643 -0.0449898 0.001 -0.0025 -1.26433e-16 0 -0.0103422 -0.0896372 0 -0.0044643 -0.0449898 0 -0.0025 -1.26433e-16 0 -0.0025 -1.26433e-16 0.001 -0.0200891 0.133602 0.001 -0.0044643 0.0449898 0.001 -0.0103422 0.0896372 0.001 -0.0200891 0.133602 0 -0.0044643 0.0449898 0 -0.0103422 0.0896372 0 -0.0200891 0.133602 0 -0.0152595 0.134896 0 -0.0152595 0.134896 0.001 -0.0200891 0.133602 0.001 0.0025 -1.27657e-16 0 0.0025 -1.27657e-16 0.001 -0.0152595 0.134896 0.001 0.000516677 0.0454256 0.001 -0.0054182 0.0905054 0.001 -0.0152595 0.134896 0 0.000516677 0.0454256 0 -0.0054182 0.0905054 0 + + + 2 0 3 1 0 2 16 4 5 16 7 4 17 8 7 17 7 16 6 8 17 13 6 17 10 6 13 14 10 13 11 10 14 15 11 14 12 9 11 12 11 15 21 19 18 21 18 24 22 24 25 22 21 24 20 25 23 20 22 25 38 26 27 38 29 26 39 30 29 39 29 38 28 30 39 35 28 39 32 28 35 36 32 35 33 32 36 37 33 36 34 31 33 34 33 37 43 41 40 43 40 46 44 46 47 44 43 46 42 47 45 42 44 47 51 49 48 51 48 54 52 54 55 52 51 54 50 55 53 50 52 55 58 56 59 57 56 58 63 61 60 63 60 66 64 66 67 64 63 66 62 67 65 62 64 67 + 3 6 9 12 15 18 21 24 27 30 33 36 39 42 45 48 51 54 57 60 63 66 69 72 75 78 81 84 87 90 93 96 99 102 105 108 111 114 117 120 123 126 129 132 135 138 141 144 147 150 153 156 + + + + + -0.0111821 -0.0659471 0 -0.00635247 -0.0672412 0 -0.00635247 -0.0672412 0.001 -0.0111821 -0.0659471 0.001 -0.0111821 -0.0659471 0 -0.00635247 -0.0672412 0 -0.0025 -6.2408e-17 0 -0.00637098 -0.0442456 0 -0.00346959 -0.0222073 0 -0.0111821 0.0659471 0 -0.00346959 0.0222073 0 -0.00637098 0.0442456 0 -0.00635247 0.0672412 0 0.0025 -6.36326e-17 0 0.00151138 0.0226431 0 -0.00144695 0.0451138 0 -0.00144695 -0.0451138 0 0.00151138 -0.0226431 0 -0.00635247 -0.0672412 0 -0.00635247 -0.0672412 0.001 0.0025 -6.36326e-17 0.001 -0.00144695 -0.0451138 0.001 0.00151138 -0.0226431 0.001 0.0025 -6.36326e-17 0 -0.00144695 -0.0451138 0 0.00151138 -0.0226431 0 -0.0111821 -0.0659471 0.001 -0.00635247 -0.0672412 0.001 -0.0025 -6.2408e-17 0.001 -0.00637098 -0.0442456 0.001 -0.00346959 -0.0222073 0.001 -0.0111821 0.0659471 0.001 -0.00346959 0.0222073 0.001 -0.00637098 0.0442456 0.001 -0.00635247 0.0672412 0.001 0.0025 -6.36326e-17 0.001 0.00151138 0.0226431 0.001 -0.00144695 0.0451138 0.001 -0.00144695 -0.0451138 0.001 0.00151138 -0.0226431 0.001 -0.0111821 -0.0659471 0 -0.0111821 -0.0659471 0.001 -0.0025 -6.2408e-17 0.001 -0.00637098 -0.0442456 0.001 -0.00346959 -0.0222073 0.001 -0.0025 -6.2408e-17 0 -0.00637098 -0.0442456 0 -0.00346959 -0.0222073 0 -0.0025 -6.2408e-17 0 -0.0025 -6.2408e-17 0.001 -0.0111821 0.0659471 0.001 -0.00346959 0.0222073 0.001 -0.00637098 0.0442456 0.001 -0.0111821 0.0659471 0 -0.00346959 0.0222073 0 -0.00637098 0.0442456 0 -0.0111821 0.0659471 0 -0.00635247 0.0672412 0 -0.00635247 0.0672412 0.001 -0.0111821 0.0659471 0.001 0.0025 -6.36326e-17 0 0.0025 -6.36326e-17 0.001 -0.00635247 0.0672412 0.001 0.00151138 0.0226431 0.001 -0.00144695 0.0451138 0.001 -0.00635247 0.0672412 0 0.00151138 0.0226431 0 -0.00144695 0.0451138 0 + + + 2 0 3 1 0 2 16 4 5 16 7 4 17 8 7 17 7 16 6 8 17 13 6 17 14 10 6 14 6 13 15 11 10 15 10 14 12 9 11 12 11 15 21 19 18 21 18 24 22 24 25 22 21 24 20 25 23 20 22 25 38 26 27 38 29 26 39 30 29 39 29 38 28 30 39 35 28 39 36 32 28 36 28 35 37 33 32 37 32 36 34 31 33 34 33 37 43 41 40 43 40 46 44 46 47 44 43 46 42 47 45 42 44 47 51 49 48 51 48 54 52 54 55 52 51 54 50 55 53 50 52 55 58 56 59 57 56 58 63 61 60 63 60 66 64 66 67 64 63 66 62 67 65 62 64 67 + 3 6 9 12 15 18 21 24 27 30 33 36 39 42 45 48 51 54 57 60 63 66 69 72 75 78 81 84 87 90 93 96 99 102 105 108 111 114 117 120 123 126 129 132 135 138 141 144 147 150 153 156 + + + + + -0.0113525 -0.0672412 0 -0.00652284 -0.0685353 0 -0.00652284 -0.0685353 0.001 -0.0113525 -0.0672412 0.001 -0.0113525 -0.0672412 0 -0.00652284 -0.0685353 0 -0.0025 -6.36326e-17 0 -0.00644695 -0.0451138 0 -0.00348862 -0.0226431 0 -0.0113525 0.0672412 0 -0.00348862 0.0226431 0 -0.00644695 0.0451138 0 -0.00652284 0.0685353 0 0.0025 -6.48573e-17 0 0.00149236 0.0230788 0 -0.00152291 0.045982 0 -0.00152291 -0.045982 0 0.00149236 -0.0230788 0 -0.00652284 -0.0685353 0 -0.00652284 -0.0685353 0.001 0.0025 -6.48573e-17 0.001 -0.00152291 -0.045982 0.001 0.00149236 -0.0230788 0.001 0.0025 -6.48573e-17 0 -0.00152291 -0.045982 0 0.00149236 -0.0230788 0 -0.0113525 -0.0672412 0.001 -0.00652284 -0.0685353 0.001 -0.0025 -6.36326e-17 0.001 -0.00644695 -0.0451138 0.001 -0.00348862 -0.0226431 0.001 -0.0113525 0.0672412 0.001 -0.00348862 0.0226431 0.001 -0.00644695 0.0451138 0.001 -0.00652284 0.0685353 0.001 0.0025 -6.48573e-17 0.001 0.00149236 0.0230788 0.001 -0.00152291 0.045982 0.001 -0.00152291 -0.045982 0.001 0.00149236 -0.0230788 0.001 -0.0113525 -0.0672412 0 -0.0113525 -0.0672412 0.001 -0.0025 -6.36326e-17 0.001 -0.00644695 -0.0451138 0.001 -0.00348862 -0.0226431 0.001 -0.0025 -6.36326e-17 0 -0.00644695 -0.0451138 0 -0.00348862 -0.0226431 0 -0.0025 -6.36326e-17 0 -0.0025 -6.36326e-17 0.001 -0.0113525 0.0672412 0.001 -0.00348862 0.0226431 0.001 -0.00644695 0.0451138 0.001 -0.0113525 0.0672412 0 -0.00348862 0.0226431 0 -0.00644695 0.0451138 0 -0.0113525 0.0672412 0 -0.00652284 0.0685353 0 -0.00652284 0.0685353 0.001 -0.0113525 0.0672412 0.001 0.0025 -6.48573e-17 0 0.0025 -6.48573e-17 0.001 -0.00652284 0.0685353 0.001 0.00149236 0.0230788 0.001 -0.00152291 0.045982 0.001 -0.00652284 0.0685353 0 0.00149236 0.0230788 0 -0.00152291 0.045982 0 + + + 2 0 3 1 0 2 16 4 5 16 7 4 17 8 7 17 7 16 6 8 17 13 6 17 10 6 13 14 10 13 15 11 10 15 10 14 12 9 11 12 11 15 21 19 18 21 18 24 22 24 25 22 21 24 20 25 23 20 22 25 38 26 27 38 29 26 39 30 29 39 29 38 28 30 39 35 28 39 32 28 35 36 32 35 37 33 32 37 32 36 34 31 33 34 33 37 43 41 40 43 40 46 44 46 47 44 43 46 42 47 45 42 44 47 51 49 48 51 48 54 52 54 55 52 51 54 50 55 53 50 52 55 58 56 59 57 56 58 63 61 60 63 60 66 64 66 67 64 63 66 62 67 65 62 64 67 + 3 6 9 12 15 18 21 24 27 30 33 36 39 42 45 48 51 54 57 60 63 66 69 72 75 78 81 84 87 90 93 96 99 102 105 108 111 114 117 120 123 126 129 132 135 138 141 144 147 150 153 156 + + + + + -0.0115228 -0.0685353 0 -0.00669321 -0.0698294 0 -0.00669321 -0.0698294 0.001 -0.0115228 -0.0685353 0.001 -0.0115228 -0.0685353 0 -0.00669321 -0.0698294 0 -0.0025 -6.48573e-17 0 -0.00652291 -0.045982 0 -0.00350764 -0.0230788 0 -0.0115228 0.0685353 0 -0.00350764 0.0230788 0 -0.00652291 0.045982 0 -0.00669321 0.0698294 0 0.0025 -6.60819e-17 0 0.00147333 0.0235146 0 -0.00159887 0.0468503 0 -0.00159887 -0.0468503 0 0.00147333 -0.0235146 0 -0.00669321 -0.0698294 0 -0.00669321 -0.0698294 0.001 0.0025 -6.60819e-17 0.001 -0.00159887 -0.0468503 0.001 0.00147333 -0.0235146 0.001 0.0025 -6.60819e-17 0 -0.00159887 -0.0468503 0 0.00147333 -0.0235146 0 -0.0115228 -0.0685353 0.001 -0.00669321 -0.0698294 0.001 -0.0025 -6.48573e-17 0.001 -0.00652291 -0.045982 0.001 -0.00350764 -0.0230788 0.001 -0.0115228 0.0685353 0.001 -0.00350764 0.0230788 0.001 -0.00652291 0.045982 0.001 -0.00669321 0.0698294 0.001 0.0025 -6.60819e-17 0.001 0.00147333 0.0235146 0.001 -0.00159887 0.0468503 0.001 -0.00159887 -0.0468503 0.001 0.00147333 -0.0235146 0.001 -0.0115228 -0.0685353 0 -0.0115228 -0.0685353 0.001 -0.0025 -6.48573e-17 0.001 -0.00652291 -0.045982 0.001 -0.00350764 -0.0230788 0.001 -0.0025 -6.48573e-17 0 -0.00652291 -0.045982 0 -0.00350764 -0.0230788 0 -0.0025 -6.48573e-17 0 -0.0025 -6.48573e-17 0.001 -0.0115228 0.0685353 0.001 -0.00350764 0.0230788 0.001 -0.00652291 0.045982 0.001 -0.0115228 0.0685353 0 -0.00350764 0.0230788 0 -0.00652291 0.045982 0 -0.0115228 0.0685353 0 -0.00669321 0.0698294 0 -0.00669321 0.0698294 0.001 -0.0115228 0.0685353 0.001 0.0025 -6.60819e-17 0 0.0025 -6.60819e-17 0.001 -0.00669321 0.0698294 0.001 0.00147333 0.0235146 0.001 -0.00159887 0.0468503 0.001 -0.00669321 0.0698294 0 0.00147333 0.0235146 0 -0.00159887 0.0468503 0 + + + 2 0 3 1 0 2 16 4 5 16 7 4 17 8 7 17 7 16 6 8 17 13 6 17 10 6 13 14 10 13 15 11 10 15 10 14 12 9 11 12 11 15 21 19 18 21 18 24 22 24 25 22 21 24 20 25 23 20 22 25 38 26 27 38 29 26 39 30 29 39 29 38 28 30 39 35 28 39 32 28 35 36 32 35 37 33 32 37 32 36 34 31 33 34 33 37 43 41 40 43 40 46 44 46 47 44 43 46 42 47 45 42 44 47 51 49 48 51 48 54 52 54 55 52 51 54 50 55 53 50 52 55 58 56 59 57 56 58 63 61 60 63 60 66 64 66 67 64 63 66 62 67 65 62 64 67 + 3 6 9 12 15 18 21 24 27 30 33 36 39 42 45 48 51 54 57 60 63 66 69 72 75 78 81 84 87 90 93 96 99 102 105 108 111 114 117 120 123 126 129 132 135 138 141 144 147 150 153 156 + + + + + -0.0116898 -0.0698035 0 -0.00686018 -0.0710976 0 -0.00686018 -0.0710976 0.001 -0.0116898 -0.0698035 0.001 -0.0116898 -0.0698035 0 -0.00686018 -0.0710976 0 -0.0025 -6.60574e-17 0 -0.00659735 -0.0468329 0 -0.00352629 -0.0235059 0 -0.0116898 0.0698035 0 -0.00352629 0.0235059 0 -0.00659735 0.0468329 0 -0.00686018 0.0710976 0 0.0025 -6.72821e-17 0 0.00145468 0.0239417 0 -0.00167331 0.0477012 0 -0.00167331 -0.0477012 0 0.00145468 -0.0239417 0 -0.00686018 -0.0710976 0 -0.00686018 -0.0710976 0.001 0.0025 -6.72821e-17 0.001 -0.00167331 -0.0477012 0.001 0.00145468 -0.0239417 0.001 0.0025 -6.72821e-17 0 -0.00167331 -0.0477012 0 0.00145468 -0.0239417 0 -0.0116898 -0.0698035 0.001 -0.00686018 -0.0710976 0.001 -0.0025 -6.60574e-17 0.001 -0.00659735 -0.0468329 0.001 -0.00352629 -0.0235059 0.001 -0.0116898 0.0698035 0.001 -0.00352629 0.0235059 0.001 -0.00659735 0.0468329 0.001 -0.00686018 0.0710976 0.001 0.0025 -6.72821e-17 0.001 0.00145468 0.0239417 0.001 -0.00167331 0.0477012 0.001 -0.00167331 -0.0477012 0.001 0.00145468 -0.0239417 0.001 -0.0116898 -0.0698035 0 -0.0116898 -0.0698035 0.001 -0.0025 -6.60574e-17 0.001 -0.00659735 -0.0468329 0.001 -0.00352629 -0.0235059 0.001 -0.0025 -6.60574e-17 0 -0.00659735 -0.0468329 0 -0.00352629 -0.0235059 0 -0.0025 -6.60574e-17 0 -0.0025 -6.60574e-17 0.001 -0.0116898 0.0698035 0.001 -0.00352629 0.0235059 0.001 -0.00659735 0.0468329 0.001 -0.0116898 0.0698035 0 -0.00352629 0.0235059 0 -0.00659735 0.0468329 0 -0.0116898 0.0698035 0 -0.00686018 0.0710976 0 -0.00686018 0.0710976 0.001 -0.0116898 0.0698035 0.001 0.0025 -6.72821e-17 0 0.0025 -6.72821e-17 0.001 -0.00686018 0.0710976 0.001 0.00145468 0.0239417 0.001 -0.00167331 0.0477012 0.001 -0.00686018 0.0710976 0 0.00145468 0.0239417 0 -0.00167331 0.0477012 0 + + + 2 0 3 1 0 2 16 4 5 16 7 4 17 8 7 17 7 16 6 8 17 13 6 17 10 6 13 14 10 13 15 11 10 15 10 14 12 9 11 12 11 15 21 19 18 21 18 24 22 24 25 22 21 24 20 25 23 20 22 25 38 26 27 38 29 26 39 30 29 39 29 38 28 30 39 35 28 39 32 28 35 36 32 35 37 33 32 37 32 36 34 31 33 34 33 37 43 41 40 43 40 46 44 46 47 44 43 46 42 47 45 42 44 47 51 49 48 51 48 54 52 54 55 52 51 54 50 55 53 50 52 55 58 56 59 57 56 58 63 61 60 63 60 66 64 66 67 64 63 66 62 67 65 62 64 67 + 3 6 9 12 15 18 21 24 27 30 33 36 39 42 45 48 51 54 57 60 63 66 69 72 75 78 81 84 87 90 93 96 99 102 105 108 111 114 117 120 123 126 129 132 135 138 141 144 147 150 153 156 + + + + + -0.0126711 -0.0772575 0 -0.00784151 -0.0785516 0 -0.00784151 -0.0785516 0.001 -0.0126711 -0.0772575 0.001 -0.0126711 -0.0772575 0 -0.00784151 -0.0785516 0 -0.0025 -7.31114e-17 0 -0.00703489 -0.051834 0 -0.00363588 -0.026016 0 -0.0126711 0.0772575 0 -0.00363588 0.026016 0 -0.00703489 0.051834 0 -0.00784151 0.0785516 0 0.0025 -7.43361e-17 0 0.00134509 0.0264518 0 -0.00211085 0.0527022 0 -0.00211085 -0.0527022 0 0.00134509 -0.0264518 0 -0.00784151 -0.0785516 0 -0.00784151 -0.0785516 0.001 0.0025 -7.43361e-17 0.001 -0.00211085 -0.0527022 0.001 0.00134509 -0.0264518 0.001 0.0025 -7.43361e-17 0 -0.00211085 -0.0527022 0 0.00134509 -0.0264518 0 -0.0126711 -0.0772575 0.001 -0.00784151 -0.0785516 0.001 -0.0025 -7.31114e-17 0.001 -0.00703489 -0.051834 0.001 -0.00363588 -0.026016 0.001 -0.0126711 0.0772575 0.001 -0.00363588 0.026016 0.001 -0.00703489 0.051834 0.001 -0.00784151 0.0785516 0.001 0.0025 -7.43361e-17 0.001 0.00134509 0.0264518 0.001 -0.00211085 0.0527022 0.001 -0.00211085 -0.0527022 0.001 0.00134509 -0.0264518 0.001 -0.0126711 -0.0772575 0 -0.0126711 -0.0772575 0.001 -0.0025 -7.31114e-17 0.001 -0.00703489 -0.051834 0.001 -0.00363588 -0.026016 0.001 -0.0025 -7.31114e-17 0 -0.00703489 -0.051834 0 -0.00363588 -0.026016 0 -0.0025 -7.31114e-17 0 -0.0025 -7.31114e-17 0.001 -0.0126711 0.0772575 0.001 -0.00363588 0.026016 0.001 -0.00703489 0.051834 0.001 -0.0126711 0.0772575 0 -0.00363588 0.026016 0 -0.00703489 0.051834 0 -0.0126711 0.0772575 0 -0.00784151 0.0785516 0 -0.00784151 0.0785516 0.001 -0.0126711 0.0772575 0.001 0.0025 -7.43361e-17 0 0.0025 -7.43361e-17 0.001 -0.00784151 0.0785516 0.001 0.00134509 0.0264518 0.001 -0.00211085 0.0527022 0.001 -0.00784151 0.0785516 0 0.00134509 0.0264518 0 -0.00211085 0.0527022 0 + + + 1 3 2 1 0 3 16 4 5 16 7 4 17 8 7 17 7 16 6 8 17 13 6 17 10 6 13 14 10 13 15 11 10 15 10 14 12 9 11 12 11 15 21 19 18 21 18 24 22 24 25 22 21 24 20 25 23 20 22 25 38 26 27 38 29 26 39 30 29 39 29 38 28 30 39 35 28 39 32 28 35 36 32 35 37 33 32 37 32 36 34 31 33 34 33 37 43 41 40 43 40 46 44 46 47 44 43 46 42 47 45 42 44 47 51 49 48 51 48 54 52 54 55 52 51 54 50 55 53 50 52 55 58 56 59 57 56 58 63 61 60 63 60 66 64 66 67 64 63 66 62 67 65 62 64 67 + 3 6 9 12 15 18 21 24 27 30 33 36 39 42 45 48 51 54 57 60 63 66 69 72 75 78 81 84 87 90 93 96 99 102 105 108 111 114 117 120 123 126 129 132 135 138 141 144 147 150 153 156 + + + + + -0.0128722 -0.0787845 0 -0.00804255 -0.0800786 0 -0.00804255 -0.0800786 0.001 -0.0128722 -0.0787845 0.001 -0.0128722 -0.0787845 0 -0.00804255 -0.0800786 0 -0.0025 -7.45565e-17 0 -0.00712452 -0.0528585 0 -0.00365833 -0.0265302 0 -0.0128722 0.0787845 0 -0.00365833 0.0265302 0 -0.00712452 0.0528585 0 -0.00804255 0.0800786 0 0.0025 -7.57811e-17 0 0.00132264 0.026966 0 -0.00220048 0.0537267 0 -0.00220048 -0.0537267 0 0.00132264 -0.026966 0 -0.00804255 -0.0800786 0 -0.00804255 -0.0800786 0.001 0.0025 -7.57811e-17 0.001 -0.00220048 -0.0537267 0.001 0.00132264 -0.026966 0.001 0.0025 -7.57811e-17 0 -0.00220048 -0.0537267 0 0.00132264 -0.026966 0 -0.0128722 -0.0787845 0.001 -0.00804255 -0.0800786 0.001 -0.0025 -7.45565e-17 0.001 -0.00712452 -0.0528585 0.001 -0.00365833 -0.0265302 0.001 -0.0128722 0.0787845 0.001 -0.00365833 0.0265302 0.001 -0.00712452 0.0528585 0.001 -0.00804255 0.0800786 0.001 0.0025 -7.57811e-17 0.001 0.00132264 0.026966 0.001 -0.00220048 0.0537267 0.001 -0.00220048 -0.0537267 0.001 0.00132264 -0.026966 0.001 -0.0128722 -0.0787845 0 -0.0128722 -0.0787845 0.001 -0.0025 -7.45565e-17 0.001 -0.00712452 -0.0528585 0.001 -0.00365833 -0.0265302 0.001 -0.0025 -7.45565e-17 0 -0.00712452 -0.0528585 0 -0.00365833 -0.0265302 0 -0.0025 -7.45565e-17 0 -0.0025 -7.45565e-17 0.001 -0.0128722 0.0787845 0.001 -0.00365833 0.0265302 0.001 -0.00712452 0.0528585 0.001 -0.0128722 0.0787845 0 -0.00365833 0.0265302 0 -0.00712452 0.0528585 0 -0.0128722 0.0787845 0 -0.00804255 0.0800786 0 -0.00804255 0.0800786 0.001 -0.0128722 0.0787845 0.001 0.0025 -7.57811e-17 0 0.0025 -7.57811e-17 0.001 -0.00804255 0.0800786 0.001 0.00132264 0.026966 0.001 -0.00220048 0.0537267 0.001 -0.00804255 0.0800786 0 0.00132264 0.026966 0 -0.00220048 0.0537267 0 + + + 2 0 3 1 0 2 16 4 5 16 7 4 17 8 7 17 7 16 6 8 17 13 6 17 10 6 13 14 10 13 15 11 10 15 10 14 12 9 11 12 11 15 21 19 18 21 18 24 22 24 25 22 21 24 20 25 23 20 22 25 38 26 27 38 29 26 39 30 29 39 29 38 28 30 39 35 28 39 32 28 35 36 32 35 37 33 32 37 32 36 34 31 33 34 33 37 43 41 40 43 40 46 44 46 47 44 43 46 42 47 45 42 44 47 51 49 48 51 48 54 52 54 55 52 51 54 50 55 53 50 52 55 58 56 59 57 56 58 63 61 60 63 60 66 64 66 67 64 63 66 62 67 65 62 64 67 + 3 6 9 12 15 18 21 24 27 30 33 36 39 42 45 48 51 54 57 60 63 66 69 72 75 78 81 84 87 90 93 96 99 102 105 108 111 114 117 120 123 126 129 132 135 138 141 144 147 150 153 156 + + + + + -0.0143544 -0.0900431 0 -0.00952478 -0.0913372 0 -0.00952478 -0.0913372 0.001 -0.0143544 -0.0900431 0.001 -0.0143544 -0.0900431 0 -0.00952478 -0.0913372 0 -0.0025 -8.52109e-17 0 -0.00778538 -0.0604122 0 -0.00382386 -0.0303215 0 -0.0143544 0.0900431 0 -0.00382386 0.0303215 0 -0.00778538 0.0604122 0 -0.00952478 0.0913372 0 0.0025 -8.64356e-17 0 0.00115711 0.0307573 0 -0.00286134 0.0612804 0 -0.00286134 -0.0612804 0 0.00115711 -0.0307573 0 -0.00952478 -0.0913372 0 -0.00952478 -0.0913372 0.001 0.0025 -8.64356e-17 0.001 -0.00286134 -0.0612804 0.001 0.00115711 -0.0307573 0.001 0.0025 -8.64356e-17 0 -0.00286134 -0.0612804 0 0.00115711 -0.0307573 0 -0.0143544 -0.0900431 0.001 -0.00952478 -0.0913372 0.001 -0.0025 -8.52109e-17 0.001 -0.00778538 -0.0604122 0.001 -0.00382386 -0.0303215 0.001 -0.0143544 0.0900431 0.001 -0.00382386 0.0303215 0.001 -0.00778538 0.0604122 0.001 -0.00952478 0.0913372 0.001 0.0025 -8.64356e-17 0.001 0.00115711 0.0307573 0.001 -0.00286134 0.0612804 0.001 -0.00286134 -0.0612804 0.001 0.00115711 -0.0307573 0.001 -0.0143544 -0.0900431 0 -0.0143544 -0.0900431 0.001 -0.0025 -8.52109e-17 0.001 -0.00778538 -0.0604122 0.001 -0.00382386 -0.0303215 0.001 -0.0025 -8.52109e-17 0 -0.00778538 -0.0604122 0 -0.00382386 -0.0303215 0 -0.0025 -8.52109e-17 0 -0.0025 -8.52109e-17 0.001 -0.0143544 0.0900431 0.001 -0.00382386 0.0303215 0.001 -0.00778538 0.0604122 0.001 -0.0143544 0.0900431 0 -0.00382386 0.0303215 0 -0.00778538 0.0604122 0 -0.0143544 0.0900431 0 -0.00952478 0.0913372 0 -0.00952478 0.0913372 0.001 -0.0143544 0.0900431 0.001 0.0025 -8.64356e-17 0 0.0025 -8.64356e-17 0.001 -0.00952478 0.0913372 0.001 0.00115711 0.0307573 0.001 -0.00286134 0.0612804 0.001 -0.00952478 0.0913372 0 0.00115711 0.0307573 0 -0.00286134 0.0612804 0 + + + 1 3 2 1 0 3 16 4 5 16 7 4 17 8 7 17 7 16 6 8 17 13 6 17 10 6 13 14 10 13 15 11 10 15 10 14 12 9 11 12 11 15 21 19 18 21 18 24 22 24 25 22 21 24 20 25 23 20 22 25 38 26 27 38 29 26 39 30 29 39 29 38 28 30 39 35 28 39 32 28 35 36 32 35 37 33 32 37 32 36 34 31 33 34 33 37 43 41 40 43 40 46 44 46 47 44 43 46 42 47 45 42 44 47 51 49 48 51 48 54 52 54 55 52 51 54 50 55 53 50 52 55 58 56 59 57 56 58 63 61 60 63 60 66 64 66 67 64 63 66 62 67 65 62 64 67 + 3 6 9 12 15 18 21 24 27 30 33 36 39 42 45 48 51 54 57 60 63 66 69 72 75 78 81 84 87 90 93 96 99 102 105 108 111 114 117 120 123 126 129 132 135 138 141 144 147 150 153 156 + + + + + -0.0145589 -0.0915961 0 -0.00972922 -0.0928902 0 -0.00972922 -0.0928902 0.001 -0.0145589 -0.0915961 0.001 -0.0145589 -0.0915961 0 -0.00972922 -0.0928902 0 -0.0025 -8.66805e-17 0 -0.00787654 -0.0614541 0 -0.0038467 -0.0308444 0 -0.0145589 0.0915961 0 -0.0038467 0.0308444 0 -0.00787654 0.0614541 0 -0.00972922 0.0928902 0 0.0025 -8.79051e-17 0 0.00113428 0.0312802 0 -0.0029525 0.0623223 0 -0.0029525 -0.0623223 0 0.00113428 -0.0312802 0 -0.00972922 -0.0928902 0 -0.00972922 -0.0928902 0.001 0.0025 -8.79051e-17 0.001 -0.0029525 -0.0623223 0.001 0.00113428 -0.0312802 0.001 0.0025 -8.79051e-17 0 -0.0029525 -0.0623223 0 0.00113428 -0.0312802 0 -0.0145589 -0.0915961 0.001 -0.00972922 -0.0928902 0.001 -0.0025 -8.66805e-17 0.001 -0.00787654 -0.0614541 0.001 -0.0038467 -0.0308444 0.001 -0.0145589 0.0915961 0.001 -0.0038467 0.0308444 0.001 -0.00787654 0.0614541 0.001 -0.00972922 0.0928902 0.001 0.0025 -8.79051e-17 0.001 0.00113428 0.0312802 0.001 -0.0029525 0.0623223 0.001 -0.0029525 -0.0623223 0.001 0.00113428 -0.0312802 0.001 -0.0145589 -0.0915961 0 -0.0145589 -0.0915961 0.001 -0.0025 -8.66805e-17 0.001 -0.00787654 -0.0614541 0.001 -0.0038467 -0.0308444 0.001 -0.0025 -8.66805e-17 0 -0.00787654 -0.0614541 0 -0.0038467 -0.0308444 0 -0.0025 -8.66805e-17 0 -0.0025 -8.66805e-17 0.001 -0.0145589 0.0915961 0.001 -0.0038467 0.0308444 0.001 -0.00787654 0.0614541 0.001 -0.0145589 0.0915961 0 -0.0038467 0.0308444 0 -0.00787654 0.0614541 0 -0.0145589 0.0915961 0 -0.00972922 0.0928902 0 -0.00972922 0.0928902 0.001 -0.0145589 0.0915961 0.001 0.0025 -8.79051e-17 0 0.0025 -8.79051e-17 0.001 -0.00972922 0.0928902 0.001 0.00113428 0.0312802 0.001 -0.0029525 0.0623223 0.001 -0.00972922 0.0928902 0 0.00113428 0.0312802 0 -0.0029525 0.0623223 0 + + + 1 3 2 1 0 3 16 4 5 16 7 4 17 8 7 17 7 16 6 8 17 13 6 17 10 6 13 14 10 13 15 11 10 15 10 14 9 11 15 12 9 15 21 19 18 21 18 24 22 24 25 22 21 24 20 25 23 20 22 25 38 26 27 38 29 26 39 30 29 39 29 38 28 30 39 35 28 39 32 28 35 36 32 35 37 33 32 37 32 36 31 33 37 34 31 37 43 41 40 43 40 46 44 46 47 44 43 46 42 47 45 42 44 47 51 49 48 51 48 54 52 54 55 52 51 54 50 55 53 50 52 55 58 56 59 57 56 58 63 61 60 63 60 66 64 66 67 64 63 66 62 67 65 62 64 67 + 3 6 9 12 15 18 21 24 27 30 33 36 39 42 45 48 51 54 57 60 63 66 69 72 75 78 81 84 87 90 93 96 99 102 105 108 111 114 117 120 123 126 129 132 135 138 141 144 147 150 153 156 + + + + + -0.0146883 -0.0925796 0 -0.0098587 -0.0938737 0 -0.0098587 -0.0938737 0.001 -0.0146883 -0.0925796 0.001 -0.0146883 -0.0925796 0 -0.0098587 -0.0938737 0 -0.0025 -8.76112e-17 0 -0.00793427 -0.062114 0 -0.00386116 -0.0311756 0 -0.0146883 0.0925796 0 -0.00386116 0.0311756 0 -0.00793427 0.062114 0 -0.0098587 0.0938737 0 0.0025 -8.88359e-17 0 0.00111982 0.0316114 0 -0.00301023 0.0629822 0 -0.00301023 -0.0629822 0 0.00111982 -0.0316114 0 -0.0098587 -0.0938737 0 -0.0098587 -0.0938737 0.001 0.0025 -8.88359e-17 0.001 -0.00301023 -0.0629822 0.001 0.00111982 -0.0316114 0.001 0.0025 -8.88359e-17 0 -0.00301023 -0.0629822 0 0.00111982 -0.0316114 0 -0.0146883 -0.0925796 0.001 -0.0098587 -0.0938737 0.001 -0.0025 -8.76112e-17 0.001 -0.00793427 -0.062114 0.001 -0.00386116 -0.0311756 0.001 -0.0146883 0.0925796 0.001 -0.00386116 0.0311756 0.001 -0.00793427 0.062114 0.001 -0.0098587 0.0938737 0.001 0.0025 -8.88359e-17 0.001 0.00111982 0.0316114 0.001 -0.00301023 0.0629822 0.001 -0.00301023 -0.0629822 0.001 0.00111982 -0.0316114 0.001 -0.0146883 -0.0925796 0 -0.0146883 -0.0925796 0.001 -0.0025 -8.76112e-17 0.001 -0.00793427 -0.062114 0.001 -0.00386116 -0.0311756 0.001 -0.0025 -8.76112e-17 0 -0.00793427 -0.062114 0 -0.00386116 -0.0311756 0 -0.0025 -8.76112e-17 0 -0.0025 -8.76112e-17 0.001 -0.0146883 0.0925796 0.001 -0.00386116 0.0311756 0.001 -0.00793427 0.062114 0.001 -0.0146883 0.0925796 0 -0.00386116 0.0311756 0 -0.00793427 0.062114 0 -0.0146883 0.0925796 0 -0.0098587 0.0938737 0 -0.0098587 0.0938737 0.001 -0.0146883 0.0925796 0.001 0.0025 -8.88359e-17 0 0.0025 -8.88359e-17 0.001 -0.0098587 0.0938737 0.001 0.00111982 0.0316114 0.001 -0.00301023 0.0629822 0.001 -0.0098587 0.0938737 0 0.00111982 0.0316114 0 -0.00301023 0.0629822 0 + + + 1 3 2 1 0 3 16 4 5 16 7 4 17 8 7 17 7 16 6 8 17 13 6 17 10 6 13 14 10 13 11 10 14 15 11 14 12 9 11 12 11 15 21 19 18 21 18 24 22 24 25 22 21 24 20 25 23 20 22 25 38 26 27 38 29 26 39 30 29 39 29 38 28 30 39 35 28 39 32 28 35 36 32 35 33 32 36 37 33 36 34 31 33 34 33 37 43 41 40 43 40 46 44 46 47 44 43 46 42 47 45 42 44 47 51 49 48 51 48 54 52 54 55 52 51 54 50 55 53 50 52 55 58 56 59 57 56 58 63 61 60 63 60 66 64 66 67 64 63 66 62 67 65 62 64 67 + 3 6 9 12 15 18 21 24 27 30 33 36 39 42 45 48 51 54 57 60 63 66 69 72 75 78 81 84 87 90 93 96 99 102 105 108 111 114 117 120 123 126 129 132 135 138 141 144 147 150 153 156 + + + + + -0.0148962 -0.0941584 0 -0.0100666 -0.0954525 0 -0.0100666 -0.0954525 0.001 -0.0148962 -0.0941584 0.001 -0.0148962 -0.0941584 0 -0.0100666 -0.0954525 0 -0.0025 -8.91053e-17 0 -0.00802694 -0.0631732 0 -0.00388437 -0.0317073 0 -0.0148962 0.0941584 0 -0.00388437 0.0317073 0 -0.00802694 0.0631732 0 -0.0100666 0.0954525 0 0.0025 -9.03299e-17 0 0.0010966 0.032143 0 -0.0031029 0.0640414 0 -0.0031029 -0.0640414 0 0.0010966 -0.032143 0 -0.0100666 -0.0954525 0 -0.0100666 -0.0954525 0.001 0.0025 -9.03299e-17 0.001 -0.0031029 -0.0640414 0.001 0.0010966 -0.032143 0.001 0.0025 -9.03299e-17 0 -0.0031029 -0.0640414 0 0.0010966 -0.032143 0 -0.0148962 -0.0941584 0.001 -0.0100666 -0.0954525 0.001 -0.0025 -8.91053e-17 0.001 -0.00802694 -0.0631732 0.001 -0.00388437 -0.0317073 0.001 -0.0148962 0.0941584 0.001 -0.00388437 0.0317073 0.001 -0.00802694 0.0631732 0.001 -0.0100666 0.0954525 0.001 0.0025 -9.03299e-17 0.001 0.0010966 0.032143 0.001 -0.0031029 0.0640414 0.001 -0.0031029 -0.0640414 0.001 0.0010966 -0.032143 0.001 -0.0148962 -0.0941584 0 -0.0148962 -0.0941584 0.001 -0.0025 -8.91053e-17 0.001 -0.00802694 -0.0631732 0.001 -0.00388437 -0.0317073 0.001 -0.0025 -8.91053e-17 0 -0.00802694 -0.0631732 0 -0.00388437 -0.0317073 0 -0.0025 -8.91053e-17 0 -0.0025 -8.91053e-17 0.001 -0.0148962 0.0941584 0.001 -0.00388437 0.0317073 0.001 -0.00802694 0.0631732 0.001 -0.0148962 0.0941584 0 -0.00388437 0.0317073 0 -0.00802694 0.0631732 0 -0.0148962 0.0941584 0 -0.0100666 0.0954525 0 -0.0100666 0.0954525 0.001 -0.0148962 0.0941584 0.001 0.0025 -9.03299e-17 0 0.0025 -9.03299e-17 0.001 -0.0100666 0.0954525 0.001 0.0010966 0.032143 0.001 -0.0031029 0.0640414 0.001 -0.0100666 0.0954525 0 0.0010966 0.032143 0 -0.0031029 0.0640414 0 + + + 2 0 3 1 0 2 16 4 5 16 7 4 17 8 7 17 7 16 6 8 17 13 6 17 10 6 13 14 10 13 15 11 10 15 10 14 9 11 15 12 9 15 21 19 18 21 18 24 22 24 25 22 21 24 20 25 23 20 22 25 38 26 27 38 29 26 39 30 29 39 29 38 28 30 39 35 28 39 32 28 35 36 32 35 37 33 32 37 32 36 31 33 37 34 31 37 43 41 40 43 40 46 44 46 47 44 43 46 42 47 45 42 44 47 51 49 48 51 48 54 52 54 55 52 51 54 50 55 53 50 52 55 58 56 59 57 56 58 63 61 60 63 60 66 64 66 67 64 63 66 62 67 65 62 64 67 + 3 6 9 12 15 18 21 24 27 30 33 36 39 42 45 48 51 54 57 60 63 66 69 72 75 78 81 84 87 90 93 96 99 102 105 108 111 114 117 120 123 126 129 132 135 138 141 144 147 150 153 156 + + + + + -0.0150257 -0.0951419 0 -0.010196 -0.096436 0 -0.010196 -0.096436 0.001 -0.0150257 -0.0951419 0.001 -0.0150257 -0.0951419 0 -0.010196 -0.096436 0 -0.0025 -9.0036e-17 0 -0.00808467 -0.0638331 0 -0.00389883 -0.0320385 0 -0.0150257 0.0951419 0 -0.00389883 0.0320385 0 -0.00808467 0.0638331 0 -0.010196 0.096436 0 0.0025 -9.12607e-17 0 0.00108214 0.0324742 0 -0.00316063 0.0647013 0 -0.00316063 -0.0647013 0 0.00108214 -0.0324742 0 -0.010196 -0.096436 0 -0.010196 -0.096436 0.001 0.0025 -9.12607e-17 0.001 -0.00316063 -0.0647013 0.001 0.00108214 -0.0324742 0.001 0.0025 -9.12607e-17 0 -0.00316063 -0.0647013 0 0.00108214 -0.0324742 0 -0.0150257 -0.0951419 0.001 -0.010196 -0.096436 0.001 -0.0025 -9.0036e-17 0.001 -0.00808467 -0.0638331 0.001 -0.00389883 -0.0320385 0.001 -0.0150257 0.0951419 0.001 -0.00389883 0.0320385 0.001 -0.00808467 0.0638331 0.001 -0.010196 0.096436 0.001 0.0025 -9.12607e-17 0.001 0.00108214 0.0324742 0.001 -0.00316063 0.0647013 0.001 -0.00316063 -0.0647013 0.001 0.00108214 -0.0324742 0.001 -0.0150257 -0.0951419 0 -0.0150257 -0.0951419 0.001 -0.0025 -9.0036e-17 0.001 -0.00808467 -0.0638331 0.001 -0.00389883 -0.0320385 0.001 -0.0025 -9.0036e-17 0 -0.00808467 -0.0638331 0 -0.00389883 -0.0320385 0 -0.0025 -9.0036e-17 0 -0.0025 -9.0036e-17 0.001 -0.0150257 0.0951419 0.001 -0.00389883 0.0320385 0.001 -0.00808467 0.0638331 0.001 -0.0150257 0.0951419 0 -0.00389883 0.0320385 0 -0.00808467 0.0638331 0 -0.0150257 0.0951419 0 -0.010196 0.096436 0 -0.010196 0.096436 0.001 -0.0150257 0.0951419 0.001 0.0025 -9.12607e-17 0 0.0025 -9.12607e-17 0.001 -0.010196 0.096436 0.001 0.00108214 0.0324742 0.001 -0.00316063 0.0647013 0.001 -0.010196 0.096436 0 0.00108214 0.0324742 0 -0.00316063 0.0647013 0 + + + 1 3 2 1 0 3 16 4 5 16 7 4 17 8 7 17 7 16 6 8 17 13 6 17 10 6 13 14 10 13 15 11 10 15 10 14 9 11 15 12 9 15 21 19 18 21 18 24 22 24 25 22 21 24 20 25 23 20 22 25 38 26 27 38 29 26 39 30 29 39 29 38 28 30 39 35 28 39 32 28 35 36 32 35 37 33 32 37 32 36 31 33 37 34 31 37 43 41 40 43 40 46 44 46 47 44 43 46 42 47 45 42 44 47 51 49 48 51 48 54 52 54 55 52 51 54 50 55 53 50 52 55 58 56 59 57 56 58 63 61 60 63 60 66 64 66 67 64 63 66 62 67 65 62 64 67 + 3 6 9 12 15 18 21 24 27 30 33 36 39 42 45 48 51 54 57 60 63 66 69 72 75 78 81 84 87 90 93 96 99 102 105 108 111 114 117 120 123 126 129 132 135 138 141 144 147 150 153 156 + + + + + -0.0152335 -0.0967207 0 -0.0104039 -0.0980148 0 -0.0104039 -0.0980148 0.001 -0.0152335 -0.0967207 0.001 -0.0152335 -0.0967207 0 -0.0104039 -0.0980148 0 -0.0025 -9.15301e-17 0 -0.00817734 -0.0648923 0 -0.00392204 -0.0325701 0 -0.0152335 0.0967207 0 -0.00392204 0.0325701 0 -0.00817734 0.0648923 0 -0.0104039 0.0980148 0 0.0025 -9.27547e-17 0 0.00105893 0.0330059 0 -0.0032533 0.0657606 0 -0.0032533 -0.0657606 0 0.00105893 -0.0330059 0 -0.0104039 -0.0980148 0 -0.0104039 -0.0980148 0.001 0.0025 -9.27547e-17 0.001 -0.0032533 -0.0657606 0.001 0.00105893 -0.0330059 0.001 0.0025 -9.27547e-17 0 -0.0032533 -0.0657606 0 0.00105893 -0.0330059 0 -0.0152335 -0.0967207 0.001 -0.0104039 -0.0980148 0.001 -0.0025 -9.15301e-17 0.001 -0.00817734 -0.0648923 0.001 -0.00392204 -0.0325701 0.001 -0.0152335 0.0967207 0.001 -0.00392204 0.0325701 0.001 -0.00817734 0.0648923 0.001 -0.0104039 0.0980148 0.001 0.0025 -9.27547e-17 0.001 0.00105893 0.0330059 0.001 -0.0032533 0.0657606 0.001 -0.0032533 -0.0657606 0.001 0.00105893 -0.0330059 0.001 -0.0152335 -0.0967207 0 -0.0152335 -0.0967207 0.001 -0.0025 -9.15301e-17 0.001 -0.00817734 -0.0648923 0.001 -0.00392204 -0.0325701 0.001 -0.0025 -9.15301e-17 0 -0.00817734 -0.0648923 0 -0.00392204 -0.0325701 0 -0.0025 -9.15301e-17 0 -0.0025 -9.15301e-17 0.001 -0.0152335 0.0967207 0.001 -0.00392204 0.0325701 0.001 -0.00817734 0.0648923 0.001 -0.0152335 0.0967207 0 -0.00392204 0.0325701 0 -0.00817734 0.0648923 0 -0.0152335 0.0967207 0 -0.0104039 0.0980148 0 -0.0104039 0.0980148 0.001 -0.0152335 0.0967207 0.001 0.0025 -9.27547e-17 0 0.0025 -9.27547e-17 0.001 -0.0104039 0.0980148 0.001 0.00105893 0.0330059 0.001 -0.0032533 0.0657606 0.001 -0.0104039 0.0980148 0 0.00105893 0.0330059 0 -0.0032533 0.0657606 0 + + + 1 3 2 1 0 3 16 4 5 16 7 4 17 8 7 17 7 16 6 8 17 13 6 17 10 6 13 14 10 13 11 10 14 15 11 14 12 9 11 12 11 15 21 19 18 21 18 24 22 24 25 22 21 24 20 25 23 20 22 25 38 26 27 38 29 26 39 30 29 39 29 38 28 30 39 35 28 39 32 28 35 36 32 35 33 32 36 37 33 36 34 31 33 34 33 37 43 41 40 43 40 46 44 46 47 44 43 46 42 47 45 42 44 47 51 49 48 51 48 54 52 54 55 52 51 54 50 55 53 50 52 55 58 56 59 57 56 58 63 61 60 63 60 66 64 66 67 64 63 66 62 67 65 62 64 67 + 3 6 9 12 15 18 21 24 27 30 33 36 39 42 45 48 51 54 57 60 63 66 69 72 75 78 81 84 87 90 93 96 99 102 105 108 111 114 117 120 123 126 129 132 135 138 141 144 147 150 153 156 + + + + + -0.0153596 -0.0976783 0 -0.01053 -0.0989724 0 -0.01053 -0.0989724 0.001 -0.0153596 -0.0976783 0.001 -0.0153596 -0.0976783 0 -0.01053 -0.0989724 0 -0.0025 -9.24363e-17 0 -0.00823355 -0.0655348 0 -0.00393612 -0.0328926 0 -0.0153596 0.0976783 0 -0.00393612 0.0328926 0 -0.00823355 0.0655348 0 -0.01053 0.0989724 0 0.0025 -9.3661e-17 0 0.00104485 0.0333284 0 -0.00330952 0.0664031 0 -0.00330952 -0.0664031 0 0.00104485 -0.0333284 0 -0.01053 -0.0989724 0 -0.01053 -0.0989724 0.001 0.0025 -9.3661e-17 0.001 -0.00330952 -0.0664031 0.001 0.00104485 -0.0333284 0.001 0.0025 -9.3661e-17 0 -0.00330952 -0.0664031 0 0.00104485 -0.0333284 0 -0.0153596 -0.0976783 0.001 -0.01053 -0.0989724 0.001 -0.0025 -9.24363e-17 0.001 -0.00823355 -0.0655348 0.001 -0.00393612 -0.0328926 0.001 -0.0153596 0.0976783 0.001 -0.00393612 0.0328926 0.001 -0.00823355 0.0655348 0.001 -0.01053 0.0989724 0.001 0.0025 -9.3661e-17 0.001 0.00104485 0.0333284 0.001 -0.00330952 0.0664031 0.001 -0.00330952 -0.0664031 0.001 0.00104485 -0.0333284 0.001 -0.0153596 -0.0976783 0 -0.0153596 -0.0976783 0.001 -0.0025 -9.24363e-17 0.001 -0.00823355 -0.0655348 0.001 -0.00393612 -0.0328926 0.001 -0.0025 -9.24363e-17 0 -0.00823355 -0.0655348 0 -0.00393612 -0.0328926 0 -0.0025 -9.24363e-17 0 -0.0025 -9.24363e-17 0.001 -0.0153596 0.0976783 0.001 -0.00393612 0.0328926 0.001 -0.00823355 0.0655348 0.001 -0.0153596 0.0976783 0 -0.00393612 0.0328926 0 -0.00823355 0.0655348 0 -0.0153596 0.0976783 0 -0.01053 0.0989724 0 -0.01053 0.0989724 0.001 -0.0153596 0.0976783 0.001 0.0025 -9.3661e-17 0 0.0025 -9.3661e-17 0.001 -0.01053 0.0989724 0.001 0.00104485 0.0333284 0.001 -0.00330952 0.0664031 0.001 -0.01053 0.0989724 0 0.00104485 0.0333284 0 -0.00330952 0.0664031 0 + + + 1 3 2 1 0 3 16 4 5 16 7 4 17 8 7 17 7 16 6 8 17 13 6 17 10 6 13 14 10 13 15 11 10 15 10 14 12 9 11 12 11 15 21 19 18 21 18 24 22 24 25 22 21 24 20 25 23 20 22 25 38 26 27 38 29 26 39 30 29 39 29 38 28 30 39 35 28 39 32 28 35 36 32 35 37 33 32 37 32 36 34 31 33 34 33 37 43 41 40 43 40 46 44 46 47 44 43 46 42 47 45 42 44 47 51 49 48 51 48 54 52 54 55 52 51 54 50 55 53 50 52 55 58 56 59 57 56 58 63 61 60 63 60 66 64 66 67 64 63 66 62 67 65 62 64 67 + 3 6 9 12 15 18 21 24 27 30 33 36 39 42 45 48 51 54 57 60 63 66 69 72 75 78 81 84 87 90 93 96 99 102 105 108 111 114 117 120 123 126 129 132 135 138 141 144 147 150 153 156 + + + + + -0.0155709 -0.099283 0 -0.0107412 -0.100577 0 -0.0107412 -0.100577 0.001 -0.0155709 -0.099283 0.001 -0.0155709 -0.099283 0 -0.0107412 -0.100577 0 -0.0025 -9.39549e-17 0 -0.00832775 -0.0666114 0 -0.00395971 -0.0334329 0 -0.0155709 0.099283 0 -0.00395971 0.0334329 0 -0.00832775 0.0666114 0 -0.0107412 0.100577 0 0.0025 -9.51795e-17 0 0.00102126 0.0338687 0 -0.00340371 0.0674797 0 -0.00340371 -0.0674797 0 0.00102126 -0.0338687 0 -0.0107412 -0.100577 0 -0.0107412 -0.100577 0.001 0.0025 -9.51795e-17 0.001 -0.00340371 -0.0674797 0.001 0.00102126 -0.0338687 0.001 0.0025 -9.51795e-17 0 -0.00340371 -0.0674797 0 0.00102126 -0.0338687 0 -0.0155709 -0.099283 0.001 -0.0107412 -0.100577 0.001 -0.0025 -9.39549e-17 0.001 -0.00832775 -0.0666114 0.001 -0.00395971 -0.0334329 0.001 -0.0155709 0.099283 0.001 -0.00395971 0.0334329 0.001 -0.00832775 0.0666114 0.001 -0.0107412 0.100577 0.001 0.0025 -9.51795e-17 0.001 0.00102126 0.0338687 0.001 -0.00340371 0.0674797 0.001 -0.00340371 -0.0674797 0.001 0.00102126 -0.0338687 0.001 -0.0155709 -0.099283 0 -0.0155709 -0.099283 0.001 -0.0025 -9.39549e-17 0.001 -0.00832775 -0.0666114 0.001 -0.00395971 -0.0334329 0.001 -0.0025 -9.39549e-17 0 -0.00832775 -0.0666114 0 -0.00395971 -0.0334329 0 -0.0025 -9.39549e-17 0 -0.0025 -9.39549e-17 0.001 -0.0155709 0.099283 0.001 -0.00395971 0.0334329 0.001 -0.00832775 0.0666114 0.001 -0.0155709 0.099283 0 -0.00395971 0.0334329 0 -0.00832775 0.0666114 0 -0.0155709 0.099283 0 -0.0107412 0.100577 0 -0.0107412 0.100577 0.001 -0.0155709 0.099283 0.001 0.0025 -9.51795e-17 0 0.0025 -9.51795e-17 0.001 -0.0107412 0.100577 0.001 0.00102126 0.0338687 0.001 -0.00340371 0.0674797 0.001 -0.0107412 0.100577 0 0.00102126 0.0338687 0 -0.00340371 0.0674797 0 + + + 1 3 2 1 0 3 16 4 5 16 7 4 17 8 7 17 7 16 6 8 17 13 6 17 10 6 13 14 10 13 15 11 10 15 10 14 12 9 11 12 11 15 21 19 18 21 18 24 22 24 25 22 21 24 20 25 23 20 22 25 38 26 27 38 29 26 39 30 29 39 29 38 28 30 39 35 28 39 32 28 35 36 32 35 37 33 32 37 32 36 34 31 33 34 33 37 43 41 40 43 40 46 44 46 47 44 43 46 42 47 45 42 44 47 51 49 48 51 48 54 52 54 55 52 51 54 50 55 53 50 52 55 58 56 59 57 56 58 63 61 60 63 60 66 64 66 67 64 63 66 62 67 65 62 64 67 + 3 6 9 12 15 18 21 24 27 30 33 36 39 42 45 48 51 54 57 60 63 66 69 72 75 78 81 84 87 90 93 96 99 102 105 108 111 114 117 120 123 126 129 132 135 138 141 144 147 150 153 156 + + + + + -0.0156935 -0.100215 0 -0.0108639 -0.101509 0 -0.0108639 -0.101509 0.001 -0.0156935 -0.100215 0.001 -0.0156935 -0.100215 0 -0.0108639 -0.101509 0 -0.0025 -9.48366e-17 0 -0.00838244 -0.0672366 0 -0.00397341 -0.0337467 0 -0.0156935 0.100215 0 -0.00397341 0.0337467 0 -0.00838244 0.0672366 0 -0.0108639 0.101509 0 0.0025 -9.60613e-17 0 0.00100756 0.0341825 0 -0.0034584 0.0681048 0 -0.0034584 -0.0681048 0 0.00100756 -0.0341825 0 -0.0108639 -0.101509 0 -0.0108639 -0.101509 0.001 0.0025 -9.60613e-17 0.001 -0.0034584 -0.0681048 0.001 0.00100756 -0.0341825 0.001 0.0025 -9.60613e-17 0 -0.0034584 -0.0681048 0 0.00100756 -0.0341825 0 -0.0156935 -0.100215 0.001 -0.0108639 -0.101509 0.001 -0.0025 -9.48366e-17 0.001 -0.00838244 -0.0672366 0.001 -0.00397341 -0.0337467 0.001 -0.0156935 0.100215 0.001 -0.00397341 0.0337467 0.001 -0.00838244 0.0672366 0.001 -0.0108639 0.101509 0.001 0.0025 -9.60613e-17 0.001 0.00100756 0.0341825 0.001 -0.0034584 0.0681048 0.001 -0.0034584 -0.0681048 0.001 0.00100756 -0.0341825 0.001 -0.0156935 -0.100215 0 -0.0156935 -0.100215 0.001 -0.0025 -9.48366e-17 0.001 -0.00838244 -0.0672366 0.001 -0.00397341 -0.0337467 0.001 -0.0025 -9.48366e-17 0 -0.00838244 -0.0672366 0 -0.00397341 -0.0337467 0 -0.0025 -9.48366e-17 0 -0.0025 -9.48366e-17 0.001 -0.0156935 0.100215 0.001 -0.00397341 0.0337467 0.001 -0.00838244 0.0672366 0.001 -0.0156935 0.100215 0 -0.00397341 0.0337467 0 -0.00838244 0.0672366 0 -0.0156935 0.100215 0 -0.0108639 0.101509 0 -0.0108639 0.101509 0.001 -0.0156935 0.100215 0.001 0.0025 -9.60613e-17 0 0.0025 -9.60613e-17 0.001 -0.0108639 0.101509 0.001 0.00100756 0.0341825 0.001 -0.0034584 0.0681048 0.001 -0.0108639 0.101509 0 0.00100756 0.0341825 0 -0.0034584 0.0681048 0 + + + 1 3 2 1 0 3 16 4 5 16 7 4 17 8 7 17 7 16 6 8 17 13 6 17 10 6 13 14 10 13 15 11 10 15 10 14 12 9 11 12 11 15 21 19 18 21 18 24 22 24 25 22 21 24 20 25 23 20 22 25 38 26 27 38 29 26 39 30 29 39 29 38 28 30 39 35 28 39 32 28 35 36 32 35 37 33 32 37 32 36 34 31 33 34 33 37 43 41 40 43 40 46 44 46 47 44 43 46 42 47 45 42 44 47 51 49 48 51 48 54 52 54 55 52 51 54 50 55 53 50 52 55 58 56 59 57 56 58 63 61 60 63 60 66 64 66 67 64 63 66 62 67 65 62 64 67 + 3 6 9 12 15 18 21 24 27 30 33 36 39 42 45 48 51 54 57 60 63 66 69 72 75 78 81 84 87 90 93 96 99 102 105 108 111 114 117 120 123 126 129 132 135 138 141 144 147 150 153 156 + + + + + -0.0159048 -0.101819 0 -0.0110752 -0.103114 0 -0.0110752 -0.103114 0.001 -0.0159048 -0.101819 0.001 -0.0159048 -0.101819 0 -0.0110752 -0.103114 0 -0.0025 -9.63552e-17 0 -0.00847663 -0.0683132 0 -0.00399701 -0.0342871 0 -0.0159048 0.101819 0 -0.00399701 0.0342871 0 -0.00847663 0.0683132 0 -0.0110752 0.103114 0 0.0025 -9.75799e-17 0 0.000983968 0.0347228 0 -0.00355259 0.0691814 0 -0.00355259 -0.0691814 0 0.000983968 -0.0347228 0 -0.0110752 -0.103114 0 -0.0110752 -0.103114 0.001 0.0025 -9.75799e-17 0.001 -0.00355259 -0.0691814 0.001 0.000983968 -0.0347228 0.001 0.0025 -9.75799e-17 0 -0.00355259 -0.0691814 0 0.000983968 -0.0347228 0 -0.0159048 -0.101819 0.001 -0.0110752 -0.103114 0.001 -0.0025 -9.63552e-17 0.001 -0.00847663 -0.0683132 0.001 -0.00399701 -0.0342871 0.001 -0.0159048 0.101819 0.001 -0.00399701 0.0342871 0.001 -0.00847663 0.0683132 0.001 -0.0110752 0.103114 0.001 0.0025 -9.75799e-17 0.001 0.000983968 0.0347228 0.001 -0.00355259 0.0691814 0.001 -0.00355259 -0.0691814 0.001 0.000983968 -0.0347228 0.001 -0.0159048 -0.101819 0 -0.0159048 -0.101819 0.001 -0.0025 -9.63552e-17 0.001 -0.00847663 -0.0683132 0.001 -0.00399701 -0.0342871 0.001 -0.0025 -9.63552e-17 0 -0.00847663 -0.0683132 0 -0.00399701 -0.0342871 0 -0.0025 -9.63552e-17 0 -0.0025 -9.63552e-17 0.001 -0.0159048 0.101819 0.001 -0.00399701 0.0342871 0.001 -0.00847663 0.0683132 0.001 -0.0159048 0.101819 0 -0.00399701 0.0342871 0 -0.00847663 0.0683132 0 -0.0159048 0.101819 0 -0.0110752 0.103114 0 -0.0110752 0.103114 0.001 -0.0159048 0.101819 0.001 0.0025 -9.75799e-17 0 0.0025 -9.75799e-17 0.001 -0.0110752 0.103114 0.001 0.000983968 0.0347228 0.001 -0.00355259 0.0691814 0.001 -0.0110752 0.103114 0 0.000983968 0.0347228 0 -0.00355259 0.0691814 0 + + + 2 0 3 1 0 2 16 4 5 16 7 4 17 8 7 17 7 16 6 8 17 13 6 17 10 6 13 14 10 13 15 11 10 15 10 14 12 9 11 12 11 15 21 19 18 21 18 24 22 24 25 22 21 24 20 25 23 20 22 25 38 26 27 38 29 26 39 30 29 39 29 38 28 30 39 35 28 39 32 28 35 36 32 35 37 33 32 37 32 36 34 31 33 34 33 37 43 41 40 43 40 46 44 46 47 44 43 46 42 47 45 42 44 47 51 49 48 51 48 54 52 54 55 52 51 54 50 55 53 50 52 55 58 56 59 57 56 58 63 61 60 63 60 66 64 66 67 64 63 66 62 67 65 62 64 67 + 3 6 9 12 15 18 21 24 27 30 33 36 39 42 45 48 51 54 57 60 63 66 69 72 75 78 81 84 87 90 93 96 99 102 105 108 111 114 117 120 123 126 129 132 135 138 141 144 147 150 153 156 + + + + + -0.0130085 -0.0798198 0 -0.00817885 -0.0811139 0 -0.00817885 -0.0811139 0.001 -0.0130085 -0.0798198 0.001 -0.0130085 -0.0798198 0 -0.00817885 -0.0811139 0 -0.0025 -7.55362e-17 0 -0.00718529 -0.0535531 0 -0.00367356 -0.0268788 0 -0.0130085 0.0798198 0 -0.00367356 0.0268788 0 -0.00718529 0.0535531 0 -0.00817885 0.0811139 0 0.0025 -7.67609e-17 0 0.00130742 0.0273146 0 -0.00226125 0.0544213 0 -0.00226125 -0.0544213 0 0.00130742 -0.0273146 0 -0.00817885 -0.0811139 0 -0.00817885 -0.0811139 0.001 0.0025 -7.67609e-17 0.001 -0.00226125 -0.0544213 0.001 0.00130742 -0.0273146 0.001 0.0025 -7.67609e-17 0 -0.00226125 -0.0544213 0 0.00130742 -0.0273146 0 -0.0130085 -0.0798198 0.001 -0.00817885 -0.0811139 0.001 -0.0025 -7.55362e-17 0.001 -0.00718529 -0.0535531 0.001 -0.00367356 -0.0268788 0.001 -0.0130085 0.0798198 0.001 -0.00367356 0.0268788 0.001 -0.00718529 0.0535531 0.001 -0.00817885 0.0811139 0.001 0.0025 -7.67609e-17 0.001 0.00130742 0.0273146 0.001 -0.00226125 0.0544213 0.001 -0.00226125 -0.0544213 0.001 0.00130742 -0.0273146 0.001 -0.0130085 -0.0798198 0 -0.0130085 -0.0798198 0.001 -0.0025 -7.55362e-17 0.001 -0.00718529 -0.0535531 0.001 -0.00367356 -0.0268788 0.001 -0.0025 -7.55362e-17 0 -0.00718529 -0.0535531 0 -0.00367356 -0.0268788 0 -0.0025 -7.55362e-17 0 -0.0025 -7.55362e-17 0.001 -0.0130085 0.0798198 0.001 -0.00367356 0.0268788 0.001 -0.00718529 0.0535531 0.001 -0.0130085 0.0798198 0 -0.00367356 0.0268788 0 -0.00718529 0.0535531 0 -0.0130085 0.0798198 0 -0.00817885 0.0811139 0 -0.00817885 0.0811139 0.001 -0.0130085 0.0798198 0.001 0.0025 -7.67609e-17 0 0.0025 -7.67609e-17 0.001 -0.00817885 0.0811139 0.001 0.00130742 0.0273146 0.001 -0.00226125 0.0544213 0.001 -0.00817885 0.0811139 0 0.00130742 0.0273146 0 -0.00226125 0.0544213 0 + + + 1 3 2 1 0 3 16 4 5 16 7 4 17 8 7 17 7 16 6 8 17 13 6 17 10 6 13 14 10 13 15 11 10 15 10 14 12 9 11 12 11 15 21 19 18 21 18 24 22 24 25 22 21 24 20 25 23 20 22 25 38 26 27 38 29 26 39 30 29 39 29 38 28 30 39 35 28 39 32 28 35 36 32 35 37 33 32 37 32 36 34 31 33 34 33 37 43 41 40 43 40 46 44 46 47 44 43 46 42 47 45 42 44 47 51 49 48 51 48 54 52 54 55 52 51 54 50 55 53 50 52 55 58 56 59 57 56 58 63 61 60 63 60 66 64 66 67 64 63 66 62 67 65 62 64 67 + 3 6 9 12 15 18 21 24 27 30 33 36 39 42 45 48 51 54 57 60 63 66 69 72 75 78 81 84 87 90 93 96 99 102 105 108 111 114 117 120 123 126 129 132 135 138 141 144 147 150 153 156 + + + + + -0.0160309 -0.102777 0 -0.0112012 -0.104071 0 -0.0112012 -0.104071 0.001 -0.0160309 -0.102777 0.001 -0.0160309 -0.102777 0 -0.0112012 -0.104071 0 -0.0025 -9.72614e-17 0 -0.00853284 -0.0689557 0 -0.00401109 -0.0346095 0 -0.0160309 0.102777 0 -0.00401109 0.0346095 0 -0.00853284 0.0689557 0 -0.0112012 0.104071 0 0.0025 -9.84861e-17 0 0.000969888 0.0350453 0 -0.0036088 0.0698239 0 -0.0036088 -0.0698239 0 0.000969888 -0.0350453 0 -0.0112012 -0.104071 0 -0.0112012 -0.104071 0.001 0.0025 -9.84861e-17 0.001 -0.0036088 -0.0698239 0.001 0.000969888 -0.0350453 0.001 0.0025 -9.84861e-17 0 -0.0036088 -0.0698239 0 0.000969888 -0.0350453 0 -0.0160309 -0.102777 0.001 -0.0112012 -0.104071 0.001 -0.0025 -9.72614e-17 0.001 -0.00853284 -0.0689557 0.001 -0.00401109 -0.0346095 0.001 -0.0160309 0.102777 0.001 -0.00401109 0.0346095 0.001 -0.00853284 0.0689557 0.001 -0.0112012 0.104071 0.001 0.0025 -9.84861e-17 0.001 0.000969888 0.0350453 0.001 -0.0036088 0.0698239 0.001 -0.0036088 -0.0698239 0.001 0.000969888 -0.0350453 0.001 -0.0160309 -0.102777 0 -0.0160309 -0.102777 0.001 -0.0025 -9.72614e-17 0.001 -0.00853284 -0.0689557 0.001 -0.00401109 -0.0346095 0.001 -0.0025 -9.72614e-17 0 -0.00853284 -0.0689557 0 -0.00401109 -0.0346095 0 -0.0025 -9.72614e-17 0 -0.0025 -9.72614e-17 0.001 -0.0160309 0.102777 0.001 -0.00401109 0.0346095 0.001 -0.00853284 0.0689557 0.001 -0.0160309 0.102777 0 -0.00401109 0.0346095 0 -0.00853284 0.0689557 0 -0.0160309 0.102777 0 -0.0112012 0.104071 0 -0.0112012 0.104071 0.001 -0.0160309 0.102777 0.001 0.0025 -9.84861e-17 0 0.0025 -9.84861e-17 0.001 -0.0112012 0.104071 0.001 0.000969888 0.0350453 0.001 -0.0036088 0.0698239 0.001 -0.0112012 0.104071 0 0.000969888 0.0350453 0 -0.0036088 0.0698239 0 + + + 2 0 3 1 0 2 16 4 5 16 7 4 17 8 7 17 7 16 6 8 17 13 6 17 10 6 13 14 10 13 15 11 10 15 10 14 12 9 11 12 11 15 21 19 18 21 18 24 22 24 25 22 21 24 20 25 23 20 22 25 38 26 27 38 29 26 39 30 29 39 29 38 28 30 39 35 28 39 32 28 35 36 32 35 37 33 32 37 32 36 34 31 33 34 33 37 43 41 40 43 40 46 44 46 47 44 43 46 42 47 45 42 44 47 51 49 48 51 48 54 52 54 55 52 51 54 50 55 53 50 52 55 58 56 59 57 56 58 63 61 60 63 60 66 64 66 67 64 63 66 62 67 65 62 64 67 + 3 6 9 12 15 18 21 24 27 30 33 36 39 42 45 48 51 54 57 60 63 66 69 72 75 78 81 84 87 90 93 96 99 102 105 108 111 114 117 120 123 126 129 132 135 138 141 144 147 150 153 156 + + + + + -0.0162421 -0.104382 0 -0.0114125 -0.105676 0 -0.0114125 -0.105676 0.001 -0.0162421 -0.104382 0.001 -0.0162421 -0.104382 0 -0.0114125 -0.105676 0 -0.0025 -9.878e-17 0 -0.00862703 -0.0700323 0 -0.00403468 -0.0351499 0 -0.0162421 0.104382 0 -0.00403468 0.0351499 0 -0.00862703 0.0700323 0 -0.0114125 0.105676 0 0.0025 -1.00005e-16 0 0.000946295 0.0355857 0 -0.00370299 0.0709006 0 -0.00370299 -0.0709006 0 0.000946295 -0.0355857 0 -0.0114125 -0.105676 0 -0.0114125 -0.105676 0.001 0.0025 -1.00005e-16 0.001 -0.00370299 -0.0709006 0.001 0.000946295 -0.0355857 0.001 0.0025 -1.00005e-16 0 -0.00370299 -0.0709006 0 0.000946295 -0.0355857 0 -0.0162421 -0.104382 0.001 -0.0114125 -0.105676 0.001 -0.0025 -9.878e-17 0.001 -0.00862703 -0.0700323 0.001 -0.00403468 -0.0351499 0.001 -0.0162421 0.104382 0.001 -0.00403468 0.0351499 0.001 -0.00862703 0.0700323 0.001 -0.0114125 0.105676 0.001 0.0025 -1.00005e-16 0.001 0.000946295 0.0355857 0.001 -0.00370299 0.0709006 0.001 -0.00370299 -0.0709006 0.001 0.000946295 -0.0355857 0.001 -0.0162421 -0.104382 0 -0.0162421 -0.104382 0.001 -0.0025 -9.878e-17 0.001 -0.00862703 -0.0700323 0.001 -0.00403468 -0.0351499 0.001 -0.0025 -9.878e-17 0 -0.00862703 -0.0700323 0 -0.00403468 -0.0351499 0 -0.0025 -9.878e-17 0 -0.0025 -9.878e-17 0.001 -0.0162421 0.104382 0.001 -0.00403468 0.0351499 0.001 -0.00862703 0.0700323 0.001 -0.0162421 0.104382 0 -0.00403468 0.0351499 0 -0.00862703 0.0700323 0 -0.0162421 0.104382 0 -0.0114125 0.105676 0 -0.0114125 0.105676 0.001 -0.0162421 0.104382 0.001 0.0025 -1.00005e-16 0 0.0025 -1.00005e-16 0.001 -0.0114125 0.105676 0.001 0.000946295 0.0355857 0.001 -0.00370299 0.0709006 0.001 -0.0114125 0.105676 0 0.000946295 0.0355857 0 -0.00370299 0.0709006 0 + + + 2 0 3 1 0 2 16 4 5 16 7 4 17 8 7 17 7 16 6 8 17 13 6 17 10 6 13 14 10 13 11 10 14 15 11 14 12 9 11 12 11 15 21 19 18 21 18 24 22 24 25 22 21 24 20 25 23 20 22 25 38 26 27 38 29 26 39 30 29 39 29 38 28 30 39 35 28 39 32 28 35 36 32 35 33 32 36 37 33 36 34 31 33 34 33 37 43 41 40 43 40 46 44 46 47 44 43 46 42 47 45 42 44 47 51 49 48 51 48 54 52 54 55 52 51 54 50 55 53 50 52 55 58 56 59 57 56 58 63 61 60 63 60 66 64 66 67 64 63 66 62 67 65 62 64 67 + 3 6 9 12 15 18 21 24 27 30 33 36 39 42 45 48 51 54 57 60 63 66 69 72 75 78 81 84 87 90 93 96 99 102 105 108 111 114 117 120 123 126 129 132 135 138 141 144 147 150 153 156 + + + + + -0.0163648 -0.105313 0 -0.0115352 -0.106608 0 -0.0115352 -0.106608 0.001 -0.0163648 -0.105313 0.001 -0.0163648 -0.105313 0 -0.0115352 -0.106608 0 -0.0025 -9.96618e-17 0 -0.00868173 -0.0706574 0 -0.00404838 -0.0354637 0 -0.0163648 0.105313 0 -0.00404838 0.0354637 0 -0.00868173 0.0706574 0 -0.0115352 0.106608 0 0.0025 -1.00886e-16 0 0.000932596 0.0358995 0 -0.00375769 0.0715257 0 -0.00375769 -0.0715257 0 0.000932596 -0.0358995 0 -0.0115352 -0.106608 0 -0.0115352 -0.106608 0.001 0.0025 -1.00886e-16 0.001 -0.00375769 -0.0715257 0.001 0.000932596 -0.0358995 0.001 0.0025 -1.00886e-16 0 -0.00375769 -0.0715257 0 0.000932596 -0.0358995 0 -0.0163648 -0.105313 0.001 -0.0115352 -0.106608 0.001 -0.0025 -9.96618e-17 0.001 -0.00868173 -0.0706574 0.001 -0.00404838 -0.0354637 0.001 -0.0163648 0.105313 0.001 -0.00404838 0.0354637 0.001 -0.00868173 0.0706574 0.001 -0.0115352 0.106608 0.001 0.0025 -1.00886e-16 0.001 0.000932596 0.0358995 0.001 -0.00375769 0.0715257 0.001 -0.00375769 -0.0715257 0.001 0.000932596 -0.0358995 0.001 -0.0163648 -0.105313 0 -0.0163648 -0.105313 0.001 -0.0025 -9.96618e-17 0.001 -0.00868173 -0.0706574 0.001 -0.00404838 -0.0354637 0.001 -0.0025 -9.96618e-17 0 -0.00868173 -0.0706574 0 -0.00404838 -0.0354637 0 -0.0025 -9.96618e-17 0 -0.0025 -9.96618e-17 0.001 -0.0163648 0.105313 0.001 -0.00404838 0.0354637 0.001 -0.00868173 0.0706574 0.001 -0.0163648 0.105313 0 -0.00404838 0.0354637 0 -0.00868173 0.0706574 0 -0.0163648 0.105313 0 -0.0115352 0.106608 0 -0.0115352 0.106608 0.001 -0.0163648 0.105313 0.001 0.0025 -1.00886e-16 0 0.0025 -1.00886e-16 0.001 -0.0115352 0.106608 0.001 0.000932596 0.0358995 0.001 -0.00375769 0.0715257 0.001 -0.0115352 0.106608 0 0.000932596 0.0358995 0 -0.00375769 0.0715257 0 + + + 2 0 3 1 0 2 16 4 5 16 7 4 17 8 7 17 7 16 6 8 17 13 6 17 10 6 13 14 10 13 15 11 10 15 10 14 12 9 11 12 11 15 21 19 18 21 18 24 22 24 25 22 21 24 20 25 23 20 22 25 38 26 27 38 29 26 39 30 29 39 29 38 28 30 39 35 28 39 32 28 35 36 32 35 37 33 32 37 32 36 34 31 33 34 33 37 43 41 40 43 40 46 44 46 47 44 43 46 42 47 45 42 44 47 51 49 48 51 48 54 52 54 55 52 51 54 50 55 53 50 52 55 58 56 59 57 56 58 63 61 60 63 60 66 64 66 67 64 63 66 62 67 65 62 64 67 + 3 6 9 12 15 18 21 24 27 30 33 36 39 42 45 48 51 54 57 60 63 66 69 72 75 78 81 84 87 90 93 96 99 102 105 108 111 114 117 120 123 126 129 132 135 138 141 144 147 150 153 156 + + + + + -0.016576 -0.106918 0 -0.0117464 -0.108212 0 -0.0117464 -0.108212 0.001 -0.016576 -0.106918 0.001 -0.016576 -0.106918 0 -0.0117464 -0.108212 0 -0.0025 -1.0118e-16 0 -0.00877592 -0.0717341 0 -0.00407197 -0.036004 0 -0.016576 0.106918 0 -0.00407197 0.036004 0 -0.00877592 0.0717341 0 -0.0117464 0.108212 0 0.0025 -1.02405e-16 0 0.000909003 0.0364398 0 -0.00385188 0.0726023 0 -0.00385188 -0.0726023 0 0.000909003 -0.0364398 0 -0.0117464 -0.108212 0 -0.0117464 -0.108212 0.001 0.0025 -1.02405e-16 0.001 -0.00385188 -0.0726023 0.001 0.000909003 -0.0364398 0.001 0.0025 -1.02405e-16 0 -0.00385188 -0.0726023 0 0.000909003 -0.0364398 0 -0.016576 -0.106918 0.001 -0.0117464 -0.108212 0.001 -0.0025 -1.0118e-16 0.001 -0.00877592 -0.0717341 0.001 -0.00407197 -0.036004 0.001 -0.016576 0.106918 0.001 -0.00407197 0.036004 0.001 -0.00877592 0.0717341 0.001 -0.0117464 0.108212 0.001 0.0025 -1.02405e-16 0.001 0.000909003 0.0364398 0.001 -0.00385188 0.0726023 0.001 -0.00385188 -0.0726023 0.001 0.000909003 -0.0364398 0.001 -0.016576 -0.106918 0 -0.016576 -0.106918 0.001 -0.0025 -1.0118e-16 0.001 -0.00877592 -0.0717341 0.001 -0.00407197 -0.036004 0.001 -0.0025 -1.0118e-16 0 -0.00877592 -0.0717341 0 -0.00407197 -0.036004 0 -0.0025 -1.0118e-16 0 -0.0025 -1.0118e-16 0.001 -0.016576 0.106918 0.001 -0.00407197 0.036004 0.001 -0.00877592 0.0717341 0.001 -0.016576 0.106918 0 -0.00407197 0.036004 0 -0.00877592 0.0717341 0 -0.016576 0.106918 0 -0.0117464 0.108212 0 -0.0117464 0.108212 0.001 -0.016576 0.106918 0.001 0.0025 -1.02405e-16 0 0.0025 -1.02405e-16 0.001 -0.0117464 0.108212 0.001 0.000909003 0.0364398 0.001 -0.00385188 0.0726023 0.001 -0.0117464 0.108212 0 0.000909003 0.0364398 0 -0.00385188 0.0726023 0 + + + 2 0 3 1 0 2 16 4 5 16 7 4 17 8 7 17 7 16 6 8 17 13 6 17 10 6 13 14 10 13 15 11 10 15 10 14 9 11 15 12 9 15 21 19 18 21 18 24 22 24 25 22 21 24 20 25 23 20 22 25 38 26 27 38 29 26 39 30 29 39 29 38 28 30 39 35 28 39 32 28 35 36 32 35 37 33 32 37 32 36 31 33 37 34 31 37 43 41 40 43 40 46 44 46 47 44 43 46 42 47 45 42 44 47 51 49 48 51 48 54 52 54 55 52 51 54 50 55 53 50 52 55 58 56 59 57 56 58 63 61 60 63 60 66 64 66 67 64 63 66 62 67 65 62 64 67 + 3 6 9 12 15 18 21 24 27 30 33 36 39 42 45 48 51 54 57 60 63 66 69 72 75 78 81 84 87 90 93 96 99 102 105 108 111 114 117 120 123 126 129 132 135 138 141 144 147 150 153 156 + + + + + -0.0166987 -0.10785 0 -0.0118691 -0.109144 0 -0.0118691 -0.109144 0.001 -0.0166987 -0.10785 0.001 -0.0166987 -0.10785 0 -0.0118691 -0.109144 0 -0.0025 -1.02062e-16 0 -0.00883061 -0.0723592 0 -0.00408567 -0.0363178 0 -0.0166987 0.10785 0 -0.00408567 0.0363178 0 -0.00883061 0.0723592 0 -0.0118691 0.109144 0 0.0025 -1.03287e-16 0 0.000895304 0.0367536 0 -0.00390657 0.0732274 0 -0.00390657 -0.0732274 0 0.000895304 -0.0367536 0 -0.0118691 -0.109144 0 -0.0118691 -0.109144 0.001 0.0025 -1.03287e-16 0.001 -0.00390657 -0.0732274 0.001 0.000895304 -0.0367536 0.001 0.0025 -1.03287e-16 0 -0.00390657 -0.0732274 0 0.000895304 -0.0367536 0 -0.0166987 -0.10785 0.001 -0.0118691 -0.109144 0.001 -0.0025 -1.02062e-16 0.001 -0.00883061 -0.0723592 0.001 -0.00408567 -0.0363178 0.001 -0.0166987 0.10785 0.001 -0.00408567 0.0363178 0.001 -0.00883061 0.0723592 0.001 -0.0118691 0.109144 0.001 0.0025 -1.03287e-16 0.001 0.000895304 0.0367536 0.001 -0.00390657 0.0732274 0.001 -0.00390657 -0.0732274 0.001 0.000895304 -0.0367536 0.001 -0.0166987 -0.10785 0 -0.0166987 -0.10785 0.001 -0.0025 -1.02062e-16 0.001 -0.00883061 -0.0723592 0.001 -0.00408567 -0.0363178 0.001 -0.0025 -1.02062e-16 0 -0.00883061 -0.0723592 0 -0.00408567 -0.0363178 0 -0.0025 -1.02062e-16 0 -0.0025 -1.02062e-16 0.001 -0.0166987 0.10785 0.001 -0.00408567 0.0363178 0.001 -0.00883061 0.0723592 0.001 -0.0166987 0.10785 0 -0.00408567 0.0363178 0 -0.00883061 0.0723592 0 -0.0166987 0.10785 0 -0.0118691 0.109144 0 -0.0118691 0.109144 0.001 -0.0166987 0.10785 0.001 0.0025 -1.03287e-16 0 0.0025 -1.03287e-16 0.001 -0.0118691 0.109144 0.001 0.000895304 0.0367536 0.001 -0.00390657 0.0732274 0.001 -0.0118691 0.109144 0 0.000895304 0.0367536 0 -0.00390657 0.0732274 0 + + + 2 0 3 1 0 2 16 4 5 16 7 4 17 8 7 17 7 16 6 8 17 13 6 17 10 6 13 14 10 13 15 11 10 15 10 14 12 9 11 12 11 15 21 19 18 21 18 24 22 24 25 22 21 24 20 25 23 20 22 25 38 26 27 38 29 26 39 30 29 39 29 38 28 30 39 35 28 39 32 28 35 36 32 35 37 33 32 37 32 36 34 31 33 34 33 37 43 41 40 43 40 46 44 46 47 44 43 46 42 47 45 42 44 47 51 49 48 51 48 54 52 54 55 52 51 54 50 55 53 50 52 55 58 56 59 57 56 58 63 61 60 63 60 66 64 66 67 64 63 66 62 67 65 62 64 67 + 3 6 9 12 15 18 21 24 27 30 33 36 39 42 45 48 51 54 57 60 63 66 69 72 75 78 81 84 87 90 93 96 99 102 105 108 111 114 117 120 123 126 129 132 135 138 141 144 147 150 153 156 + + + + + -0.0169134 -0.10948 0 -0.0120837 -0.110775 0 -0.0120837 -0.110775 0.001 -0.0169134 -0.10948 0.001 -0.0169134 -0.10948 0 -0.0120837 -0.110775 0 -0.0025 -1.03605e-16 0 -0.00892632 -0.0734532 0 -0.00410964 -0.0368669 0 -0.0169134 0.10948 0 -0.00410964 0.0368669 0 -0.00892632 0.0734532 0 -0.0120837 0.110775 0 0.0025 -1.0483e-16 0 0.000871331 0.0373027 0 -0.00400228 0.0743214 0 -0.00400228 -0.0743214 0 0.000871331 -0.0373027 0 -0.0120837 -0.110775 0 -0.0120837 -0.110775 0.001 0.0025 -1.0483e-16 0.001 -0.00400228 -0.0743214 0.001 0.000871331 -0.0373027 0.001 0.0025 -1.0483e-16 0 -0.00400228 -0.0743214 0 0.000871331 -0.0373027 0 -0.0169134 -0.10948 0.001 -0.0120837 -0.110775 0.001 -0.0025 -1.03605e-16 0.001 -0.00892632 -0.0734532 0.001 -0.00410964 -0.0368669 0.001 -0.0169134 0.10948 0.001 -0.00410964 0.0368669 0.001 -0.00892632 0.0734532 0.001 -0.0120837 0.110775 0.001 0.0025 -1.0483e-16 0.001 0.000871331 0.0373027 0.001 -0.00400228 0.0743214 0.001 -0.00400228 -0.0743214 0.001 0.000871331 -0.0373027 0.001 -0.0169134 -0.10948 0 -0.0169134 -0.10948 0.001 -0.0025 -1.03605e-16 0.001 -0.00892632 -0.0734532 0.001 -0.00410964 -0.0368669 0.001 -0.0025 -1.03605e-16 0 -0.00892632 -0.0734532 0 -0.00410964 -0.0368669 0 -0.0025 -1.03605e-16 0 -0.0025 -1.03605e-16 0.001 -0.0169134 0.10948 0.001 -0.00410964 0.0368669 0.001 -0.00892632 0.0734532 0.001 -0.0169134 0.10948 0 -0.00410964 0.0368669 0 -0.00892632 0.0734532 0 -0.0169134 0.10948 0 -0.0120837 0.110775 0 -0.0120837 0.110775 0.001 -0.0169134 0.10948 0.001 0.0025 -1.0483e-16 0 0.0025 -1.0483e-16 0.001 -0.0120837 0.110775 0.001 0.000871331 0.0373027 0.001 -0.00400228 0.0743214 0.001 -0.0120837 0.110775 0 0.000871331 0.0373027 0 -0.00400228 0.0743214 0 + + + 2 0 3 1 0 2 16 4 5 16 7 4 17 8 7 17 7 16 6 8 17 13 6 17 10 6 13 14 10 13 15 11 10 15 10 14 12 9 11 12 11 15 21 19 18 21 18 24 22 24 25 22 21 24 20 25 23 20 22 25 38 26 27 38 29 26 39 30 29 39 29 38 28 30 39 35 28 39 32 28 35 36 32 35 37 33 32 37 32 36 34 31 33 34 33 37 43 41 40 43 40 46 44 46 47 44 43 46 42 47 45 42 44 47 51 49 48 51 48 54 52 54 55 52 51 54 50 55 53 50 52 55 58 56 59 57 56 58 63 61 60 63 60 66 64 66 67 64 63 66 62 67 65 62 64 67 + 3 6 9 12 15 18 21 24 27 30 33 36 39 42 45 48 51 54 57 60 63 66 69 72 75 78 81 84 87 90 93 96 99 102 105 108 111 114 117 120 123 126 129 132 135 138 141 144 147 150 153 156 + + + + + -0.0170326 -0.110386 0 -0.012203 -0.11168 0 -0.012203 -0.11168 0.001 -0.0170326 -0.110386 0.001 -0.0170326 -0.110386 0 -0.012203 -0.11168 0 -0.0025 -1.04462e-16 0 -0.00897949 -0.0740609 0 -0.00412296 -0.0371719 0 -0.0170326 0.110386 0 -0.00412296 0.0371719 0 -0.00897949 0.0740609 0 -0.012203 0.11168 0 0.0025 -1.05687e-16 0 0.000858012 0.0376077 0 -0.00405545 0.0749292 0 -0.00405545 -0.0749292 0 0.000858012 -0.0376077 0 -0.012203 -0.11168 0 -0.012203 -0.11168 0.001 0.0025 -1.05687e-16 0.001 -0.00405545 -0.0749292 0.001 0.000858012 -0.0376077 0.001 0.0025 -1.05687e-16 0 -0.00405545 -0.0749292 0 0.000858012 -0.0376077 0 -0.0170326 -0.110386 0.001 -0.012203 -0.11168 0.001 -0.0025 -1.04462e-16 0.001 -0.00897949 -0.0740609 0.001 -0.00412296 -0.0371719 0.001 -0.0170326 0.110386 0.001 -0.00412296 0.0371719 0.001 -0.00897949 0.0740609 0.001 -0.012203 0.11168 0.001 0.0025 -1.05687e-16 0.001 0.000858012 0.0376077 0.001 -0.00405545 0.0749292 0.001 -0.00405545 -0.0749292 0.001 0.000858012 -0.0376077 0.001 -0.0170326 -0.110386 0 -0.0170326 -0.110386 0.001 -0.0025 -1.04462e-16 0.001 -0.00897949 -0.0740609 0.001 -0.00412296 -0.0371719 0.001 -0.0025 -1.04462e-16 0 -0.00897949 -0.0740609 0 -0.00412296 -0.0371719 0 -0.0025 -1.04462e-16 0 -0.0025 -1.04462e-16 0.001 -0.0170326 0.110386 0.001 -0.00412296 0.0371719 0.001 -0.00897949 0.0740609 0.001 -0.0170326 0.110386 0 -0.00412296 0.0371719 0 -0.00897949 0.0740609 0 -0.0170326 0.110386 0 -0.012203 0.11168 0 -0.012203 0.11168 0.001 -0.0170326 0.110386 0.001 0.0025 -1.05687e-16 0 0.0025 -1.05687e-16 0.001 -0.012203 0.11168 0.001 0.000858012 0.0376077 0.001 -0.00405545 0.0749292 0.001 -0.012203 0.11168 0 0.000858012 0.0376077 0 -0.00405545 0.0749292 0 + + + 2 0 3 1 0 2 16 4 5 16 7 4 17 8 7 17 7 16 6 8 17 13 6 17 10 6 13 14 10 13 15 11 10 15 10 14 12 9 11 12 11 15 21 19 18 21 18 24 22 24 25 22 21 24 20 25 23 20 22 25 38 26 27 38 29 26 39 30 29 39 29 38 28 30 39 35 28 39 32 28 35 36 32 35 37 33 32 37 32 36 34 31 33 34 33 37 43 41 40 43 40 46 44 46 47 44 43 46 42 47 45 42 44 47 51 49 48 51 48 54 52 54 55 52 51 54 50 55 53 50 52 55 58 56 59 57 56 58 63 61 60 63 60 66 64 66 67 64 63 66 62 67 65 62 64 67 + 3 6 9 12 15 18 21 24 27 30 33 36 39 42 45 48 51 54 57 60 63 66 69 72 75 78 81 84 87 90 93 96 99 102 105 108 111 114 117 120 123 126 129 132 135 138 141 144 147 150 153 156 + + + + + -0.0172473 -0.112017 0 -0.0124177 -0.113311 0 -0.0124177 -0.113311 0.001 -0.0172473 -0.112017 0.001 -0.0172473 -0.112017 0 -0.0124177 -0.113311 0 -0.0025 -1.06005e-16 0 -0.0090752 -0.0751549 0 -0.00414693 -0.037721 0 -0.0172473 0.112017 0 -0.00414693 0.037721 0 -0.0090752 0.0751549 0 -0.0124177 0.113311 0 0.0025 -1.0723e-16 0 0.000834039 0.0381568 0 -0.00415117 0.0760232 0 -0.00415117 -0.0760232 0 0.000834039 -0.0381568 0 -0.0124177 -0.113311 0 -0.0124177 -0.113311 0.001 0.0025 -1.0723e-16 0.001 -0.00415117 -0.0760232 0.001 0.000834039 -0.0381568 0.001 0.0025 -1.0723e-16 0 -0.00415117 -0.0760232 0 0.000834039 -0.0381568 0 -0.0172473 -0.112017 0.001 -0.0124177 -0.113311 0.001 -0.0025 -1.06005e-16 0.001 -0.0090752 -0.0751549 0.001 -0.00414693 -0.037721 0.001 -0.0172473 0.112017 0.001 -0.00414693 0.037721 0.001 -0.0090752 0.0751549 0.001 -0.0124177 0.113311 0.001 0.0025 -1.0723e-16 0.001 0.000834039 0.0381568 0.001 -0.00415117 0.0760232 0.001 -0.00415117 -0.0760232 0.001 0.000834039 -0.0381568 0.001 -0.0172473 -0.112017 0 -0.0172473 -0.112017 0.001 -0.0025 -1.06005e-16 0.001 -0.0090752 -0.0751549 0.001 -0.00414693 -0.037721 0.001 -0.0025 -1.06005e-16 0 -0.0090752 -0.0751549 0 -0.00414693 -0.037721 0 -0.0025 -1.06005e-16 0 -0.0025 -1.06005e-16 0.001 -0.0172473 0.112017 0.001 -0.00414693 0.037721 0.001 -0.0090752 0.0751549 0.001 -0.0172473 0.112017 0 -0.00414693 0.037721 0 -0.0090752 0.0751549 0 -0.0172473 0.112017 0 -0.0124177 0.113311 0 -0.0124177 0.113311 0.001 -0.0172473 0.112017 0.001 0.0025 -1.0723e-16 0 0.0025 -1.0723e-16 0.001 -0.0124177 0.113311 0.001 0.000834039 0.0381568 0.001 -0.00415117 0.0760232 0.001 -0.0124177 0.113311 0 0.000834039 0.0381568 0 -0.00415117 0.0760232 0 + + + 2 0 3 1 0 2 16 4 5 16 7 4 17 8 7 17 7 16 6 8 17 13 6 17 10 6 13 14 10 13 15 11 10 15 10 14 12 9 11 12 11 15 21 19 18 21 18 24 22 24 25 22 21 24 20 25 23 20 22 25 38 26 27 38 29 26 39 30 29 39 29 38 28 30 39 35 28 39 32 28 35 36 32 35 37 33 32 37 32 36 34 31 33 34 33 37 43 41 40 43 40 46 44 46 47 44 43 46 42 47 45 42 44 47 51 49 48 51 48 54 52 54 55 52 51 54 50 55 53 50 52 55 58 56 59 57 56 58 63 61 60 63 60 66 64 66 67 64 63 66 62 67 65 62 64 67 + 3 6 9 12 15 18 21 24 27 30 33 36 39 42 45 48 51 54 57 60 63 66 69 72 75 78 81 84 87 90 93 96 99 102 105 108 111 114 117 120 123 126 129 132 135 138 141 144 147 150 153 156 + + + + + -0.0173666 -0.112923 0 -0.0125369 -0.114217 0 -0.0125369 -0.114217 0.001 -0.0173666 -0.112923 0.001 -0.0173666 -0.112923 0 -0.0125369 -0.114217 0 -0.0025 -1.06863e-16 0 -0.00912838 -0.0757627 0 -0.00416025 -0.0380261 0 -0.0173666 0.112923 0 -0.00416025 0.0380261 0 -0.00912838 0.0757627 0 -0.0125369 0.114217 0 0.0025 -1.08087e-16 0 0.00082072 0.0384618 0 -0.00420434 0.0766309 0 -0.00420434 -0.0766309 0 0.00082072 -0.0384618 0 -0.0125369 -0.114217 0 -0.0125369 -0.114217 0.001 0.0025 -1.08087e-16 0.001 -0.00420434 -0.0766309 0.001 0.00082072 -0.0384618 0.001 0.0025 -1.08087e-16 0 -0.00420434 -0.0766309 0 0.00082072 -0.0384618 0 -0.0173666 -0.112923 0.001 -0.0125369 -0.114217 0.001 -0.0025 -1.06863e-16 0.001 -0.00912838 -0.0757627 0.001 -0.00416025 -0.0380261 0.001 -0.0173666 0.112923 0.001 -0.00416025 0.0380261 0.001 -0.00912838 0.0757627 0.001 -0.0125369 0.114217 0.001 0.0025 -1.08087e-16 0.001 0.00082072 0.0384618 0.001 -0.00420434 0.0766309 0.001 -0.00420434 -0.0766309 0.001 0.00082072 -0.0384618 0.001 -0.0173666 -0.112923 0 -0.0173666 -0.112923 0.001 -0.0025 -1.06863e-16 0.001 -0.00912838 -0.0757627 0.001 -0.00416025 -0.0380261 0.001 -0.0025 -1.06863e-16 0 -0.00912838 -0.0757627 0 -0.00416025 -0.0380261 0 -0.0025 -1.06863e-16 0 -0.0025 -1.06863e-16 0.001 -0.0173666 0.112923 0.001 -0.00416025 0.0380261 0.001 -0.00912838 0.0757627 0.001 -0.0173666 0.112923 0 -0.00416025 0.0380261 0 -0.00912838 0.0757627 0 -0.0173666 0.112923 0 -0.0125369 0.114217 0 -0.0125369 0.114217 0.001 -0.0173666 0.112923 0.001 0.0025 -1.08087e-16 0 0.0025 -1.08087e-16 0.001 -0.0125369 0.114217 0.001 0.00082072 0.0384618 0.001 -0.00420434 0.0766309 0.001 -0.0125369 0.114217 0 0.00082072 0.0384618 0 -0.00420434 0.0766309 0 + + + 2 0 3 1 0 2 16 4 5 16 7 4 17 8 7 17 7 16 6 8 17 13 6 17 10 6 13 14 10 13 15 11 10 15 10 14 12 9 11 12 11 15 21 19 18 21 18 24 22 24 25 22 21 24 20 25 23 20 22 25 38 26 27 38 29 26 39 30 29 39 29 38 28 30 39 35 28 39 32 28 35 36 32 35 37 33 32 37 32 36 34 31 33 34 33 37 43 41 40 43 40 46 44 46 47 44 43 46 42 47 45 42 44 47 51 49 48 51 48 54 52 54 55 52 51 54 50 55 53 50 52 55 58 56 59 57 56 58 63 61 60 63 60 66 64 66 67 64 63 66 62 67 65 62 64 67 + 3 6 9 12 15 18 21 24 27 30 33 36 39 42 45 48 51 54 57 60 63 66 69 72 75 78 81 84 87 90 93 96 99 102 105 108 111 114 117 120 123 126 129 132 135 138 141 144 147 150 153 156 + + + + + -0.0175812 -0.114553 0 -0.0127516 -0.115847 0 -0.0127516 -0.115847 0.001 -0.0175812 -0.114553 0.001 -0.0175812 -0.114553 0 -0.0127516 -0.115847 0 -0.0025 -1.08406e-16 0 -0.00922409 -0.0768567 0 -0.00418423 -0.0385751 0 -0.0175812 0.114553 0 -0.00418423 0.0385751 0 -0.00922409 0.0768567 0 -0.0127516 0.115847 0 0.0025 -1.0963e-16 0 0.000796747 0.0390109 0 -0.00430005 0.0777249 0 -0.00430005 -0.0777249 0 0.000796747 -0.0390109 0 -0.0127516 -0.115847 0 -0.0127516 -0.115847 0.001 0.0025 -1.0963e-16 0.001 -0.00430005 -0.0777249 0.001 0.000796747 -0.0390109 0.001 0.0025 -1.0963e-16 0 -0.00430005 -0.0777249 0 0.000796747 -0.0390109 0 -0.0175812 -0.114553 0.001 -0.0127516 -0.115847 0.001 -0.0025 -1.08406e-16 0.001 -0.00922409 -0.0768567 0.001 -0.00418423 -0.0385751 0.001 -0.0175812 0.114553 0.001 -0.00418423 0.0385751 0.001 -0.00922409 0.0768567 0.001 -0.0127516 0.115847 0.001 0.0025 -1.0963e-16 0.001 0.000796747 0.0390109 0.001 -0.00430005 0.0777249 0.001 -0.00430005 -0.0777249 0.001 0.000796747 -0.0390109 0.001 -0.0175812 -0.114553 0 -0.0175812 -0.114553 0.001 -0.0025 -1.08406e-16 0.001 -0.00922409 -0.0768567 0.001 -0.00418423 -0.0385751 0.001 -0.0025 -1.08406e-16 0 -0.00922409 -0.0768567 0 -0.00418423 -0.0385751 0 -0.0025 -1.08406e-16 0 -0.0025 -1.08406e-16 0.001 -0.0175812 0.114553 0.001 -0.00418423 0.0385751 0.001 -0.00922409 0.0768567 0.001 -0.0175812 0.114553 0 -0.00418423 0.0385751 0 -0.00922409 0.0768567 0 -0.0175812 0.114553 0 -0.0127516 0.115847 0 -0.0127516 0.115847 0.001 -0.0175812 0.114553 0.001 0.0025 -1.0963e-16 0 0.0025 -1.0963e-16 0.001 -0.0127516 0.115847 0.001 0.000796747 0.0390109 0.001 -0.00430005 0.0777249 0.001 -0.0127516 0.115847 0 0.000796747 0.0390109 0 -0.00430005 0.0777249 0 + + + 2 0 3 1 0 2 16 4 5 16 7 4 17 8 7 17 7 16 6 8 17 13 6 17 10 6 13 14 10 13 11 10 14 15 11 14 9 11 15 12 9 15 21 19 18 21 18 24 22 24 25 22 21 24 20 25 23 20 22 25 38 26 27 38 29 26 39 30 29 39 29 38 28 30 39 35 28 39 32 28 35 36 32 35 33 32 36 37 33 36 31 33 37 34 31 37 43 41 40 43 40 46 44 46 47 44 43 46 42 47 45 42 44 47 51 49 48 51 48 54 52 54 55 52 51 54 50 55 53 50 52 55 58 56 59 57 56 58 63 61 60 63 60 66 64 66 67 64 63 66 62 67 65 62 64 67 + 3 6 9 12 15 18 21 24 27 30 33 36 39 42 45 48 51 54 57 60 63 66 69 72 75 78 81 84 87 90 93 96 99 102 105 108 111 114 117 120 123 126 129 132 135 138 141 144 147 150 153 156 + + + + + -0.0132095 -0.0813468 0 -0.00837988 -0.0826409 0 -0.00837988 -0.0826409 0.001 -0.0132095 -0.0813468 0.001 -0.0132095 -0.0813468 0 -0.00837988 -0.0826409 0 -0.0025 -7.69813e-17 0 -0.00727492 -0.0545776 0 -0.00369601 -0.027393 0 -0.0132095 0.0813468 0 -0.00369601 0.027393 0 -0.00727492 0.0545776 0 -0.00837988 0.0826409 0 0.0025 -7.82059e-17 0 0.00128497 0.0278288 0 -0.00235088 0.0554459 0 -0.00235088 -0.0554459 0 0.00128497 -0.0278288 0 -0.00837988 -0.0826409 0 -0.00837988 -0.0826409 0.001 0.0025 -7.82059e-17 0.001 -0.00235088 -0.0554459 0.001 0.00128497 -0.0278288 0.001 0.0025 -7.82059e-17 0 -0.00235088 -0.0554459 0 0.00128497 -0.0278288 0 -0.0132095 -0.0813468 0.001 -0.00837988 -0.0826409 0.001 -0.0025 -7.69813e-17 0.001 -0.00727492 -0.0545776 0.001 -0.00369601 -0.027393 0.001 -0.0132095 0.0813468 0.001 -0.00369601 0.027393 0.001 -0.00727492 0.0545776 0.001 -0.00837988 0.0826409 0.001 0.0025 -7.82059e-17 0.001 0.00128497 0.0278288 0.001 -0.00235088 0.0554459 0.001 -0.00235088 -0.0554459 0.001 0.00128497 -0.0278288 0.001 -0.0132095 -0.0813468 0 -0.0132095 -0.0813468 0.001 -0.0025 -7.69813e-17 0.001 -0.00727492 -0.0545776 0.001 -0.00369601 -0.027393 0.001 -0.0025 -7.69813e-17 0 -0.00727492 -0.0545776 0 -0.00369601 -0.027393 0 -0.0025 -7.69813e-17 0 -0.0025 -7.69813e-17 0.001 -0.0132095 0.0813468 0.001 -0.00369601 0.027393 0.001 -0.00727492 0.0545776 0.001 -0.0132095 0.0813468 0 -0.00369601 0.027393 0 -0.00727492 0.0545776 0 -0.0132095 0.0813468 0 -0.00837988 0.0826409 0 -0.00837988 0.0826409 0.001 -0.0132095 0.0813468 0.001 0.0025 -7.82059e-17 0 0.0025 -7.82059e-17 0.001 -0.00837988 0.0826409 0.001 0.00128497 0.0278288 0.001 -0.00235088 0.0554459 0.001 -0.00837988 0.0826409 0 0.00128497 0.0278288 0 -0.00235088 0.0554459 0 + + + 1 3 2 1 0 3 16 4 5 16 7 4 17 8 7 17 7 16 6 8 17 13 6 17 10 6 13 14 10 13 15 11 10 15 10 14 12 9 11 12 11 15 21 19 18 21 18 24 22 24 25 22 21 24 20 25 23 20 22 25 38 26 27 38 29 26 39 30 29 39 29 38 28 30 39 35 28 39 32 28 35 36 32 35 37 33 32 37 32 36 34 31 33 34 33 37 43 41 40 43 40 46 44 46 47 44 43 46 42 47 45 42 44 47 51 49 48 51 48 54 52 54 55 52 51 54 50 55 53 50 52 55 58 56 59 57 56 58 63 61 60 63 60 66 64 66 67 64 63 66 62 67 65 62 64 67 + 3 6 9 12 15 18 21 24 27 30 33 36 39 42 45 48 51 54 57 60 63 66 69 72 75 78 81 84 87 90 93 96 99 102 105 108 111 114 117 120 123 126 129 132 135 138 141 144 147 150 153 156 + + + + + -0.0177005 -0.115459 0 -0.0128709 -0.116753 0 -0.0128709 -0.116753 0.001 -0.0177005 -0.115459 0.001 -0.0177005 -0.115459 0 -0.0128709 -0.116753 0 -0.0025 -1.09263e-16 0 -0.00927726 -0.0774645 0 -0.00419755 -0.0388802 0 -0.0177005 0.115459 0 -0.00419755 0.0388802 0 -0.00927726 0.0774645 0 -0.0128709 0.116753 0 0.0025 -1.10488e-16 0 0.000783428 0.039316 0 -0.00435322 0.0783327 0 -0.00435322 -0.0783327 0 0.000783428 -0.039316 0 -0.0128709 -0.116753 0 -0.0128709 -0.116753 0.001 0.0025 -1.10488e-16 0.001 -0.00435322 -0.0783327 0.001 0.000783428 -0.039316 0.001 0.0025 -1.10488e-16 0 -0.00435322 -0.0783327 0 0.000783428 -0.039316 0 -0.0177005 -0.115459 0.001 -0.0128709 -0.116753 0.001 -0.0025 -1.09263e-16 0.001 -0.00927726 -0.0774645 0.001 -0.00419755 -0.0388802 0.001 -0.0177005 0.115459 0.001 -0.00419755 0.0388802 0.001 -0.00927726 0.0774645 0.001 -0.0128709 0.116753 0.001 0.0025 -1.10488e-16 0.001 0.000783428 0.039316 0.001 -0.00435322 0.0783327 0.001 -0.00435322 -0.0783327 0.001 0.000783428 -0.039316 0.001 -0.0177005 -0.115459 0 -0.0177005 -0.115459 0.001 -0.0025 -1.09263e-16 0.001 -0.00927726 -0.0774645 0.001 -0.00419755 -0.0388802 0.001 -0.0025 -1.09263e-16 0 -0.00927726 -0.0774645 0 -0.00419755 -0.0388802 0 -0.0025 -1.09263e-16 0 -0.0025 -1.09263e-16 0.001 -0.0177005 0.115459 0.001 -0.00419755 0.0388802 0.001 -0.00927726 0.0774645 0.001 -0.0177005 0.115459 0 -0.00419755 0.0388802 0 -0.00927726 0.0774645 0 -0.0177005 0.115459 0 -0.0128709 0.116753 0 -0.0128709 0.116753 0.001 -0.0177005 0.115459 0.001 0.0025 -1.10488e-16 0 0.0025 -1.10488e-16 0.001 -0.0128709 0.116753 0.001 0.000783428 0.039316 0.001 -0.00435322 0.0783327 0.001 -0.0128709 0.116753 0 0.000783428 0.039316 0 -0.00435322 0.0783327 0 + + + 2 0 3 1 0 2 16 4 5 16 7 4 17 8 7 17 7 16 6 8 17 13 6 17 10 6 13 14 10 13 15 11 10 15 10 14 12 9 11 12 11 15 21 19 18 21 18 24 22 24 25 22 21 24 20 25 23 20 22 25 38 26 27 38 29 26 39 30 29 39 29 38 28 30 39 35 28 39 32 28 35 36 32 35 37 33 32 37 32 36 34 31 33 34 33 37 43 41 40 43 40 46 44 46 47 44 43 46 42 47 45 42 44 47 51 49 48 51 48 54 52 54 55 52 51 54 50 55 53 50 52 55 58 56 59 57 56 58 63 61 60 63 60 66 64 66 67 64 63 66 62 67 65 62 64 67 + 3 6 9 12 15 18 21 24 27 30 33 36 39 42 45 48 51 54 57 60 63 66 69 72 75 78 81 84 87 90 93 96 99 102 105 108 111 114 117 120 123 126 129 132 135 138 141 144 147 150 153 156 + + + + + -0.0179186 -0.117116 0 -0.0130889 -0.11841 0 -0.0130889 -0.11841 0.001 -0.0179186 -0.117116 0.001 -0.0179186 -0.117116 0 -0.0130889 -0.11841 0 -0.0025 -1.10831e-16 0 -0.00937449 -0.0785758 0 -0.0042219 -0.039438 0 -0.0179186 0.117116 0 -0.0042219 0.039438 0 -0.00937449 0.0785758 0 -0.0130889 0.11841 0 0.0025 -1.12055e-16 0 0.000759074 0.0398738 0 -0.00445045 0.079444 0 -0.00445045 -0.079444 0 0.000759074 -0.0398738 0 -0.0130889 -0.11841 0 -0.0130889 -0.11841 0.001 0.0025 -1.12055e-16 0.001 -0.00445045 -0.079444 0.001 0.000759074 -0.0398738 0.001 0.0025 -1.12055e-16 0 -0.00445045 -0.079444 0 0.000759074 -0.0398738 0 -0.0179186 -0.117116 0.001 -0.0130889 -0.11841 0.001 -0.0025 -1.10831e-16 0.001 -0.00937449 -0.0785758 0.001 -0.0042219 -0.039438 0.001 -0.0179186 0.117116 0.001 -0.0042219 0.039438 0.001 -0.00937449 0.0785758 0.001 -0.0130889 0.11841 0.001 0.0025 -1.12055e-16 0.001 0.000759074 0.0398738 0.001 -0.00445045 0.079444 0.001 -0.00445045 -0.079444 0.001 0.000759074 -0.0398738 0.001 -0.0179186 -0.117116 0 -0.0179186 -0.117116 0.001 -0.0025 -1.10831e-16 0.001 -0.00937449 -0.0785758 0.001 -0.0042219 -0.039438 0.001 -0.0025 -1.10831e-16 0 -0.00937449 -0.0785758 0 -0.0042219 -0.039438 0 -0.0025 -1.10831e-16 0 -0.0025 -1.10831e-16 0.001 -0.0179186 0.117116 0.001 -0.0042219 0.039438 0.001 -0.00937449 0.0785758 0.001 -0.0179186 0.117116 0 -0.0042219 0.039438 0 -0.00937449 0.0785758 0 -0.0179186 0.117116 0 -0.0130889 0.11841 0 -0.0130889 0.11841 0.001 -0.0179186 0.117116 0.001 0.0025 -1.12055e-16 0 0.0025 -1.12055e-16 0.001 -0.0130889 0.11841 0.001 0.000759074 0.0398738 0.001 -0.00445045 0.079444 0.001 -0.0130889 0.11841 0 0.000759074 0.0398738 0 -0.00445045 0.079444 0 + + + 2 0 3 1 0 2 16 4 5 16 7 4 17 8 7 17 7 16 6 8 17 13 6 17 10 6 13 14 10 13 15 11 10 15 10 14 12 9 11 12 11 15 21 19 18 21 18 24 22 24 25 22 21 24 20 25 23 20 22 25 38 26 27 38 29 26 39 30 29 39 29 38 28 30 39 35 28 39 32 28 35 36 32 35 37 33 32 37 32 36 34 31 33 34 33 37 43 41 40 43 40 46 44 46 47 44 43 46 42 47 45 42 44 47 51 49 48 51 48 54 52 54 55 52 51 54 50 55 53 50 52 55 58 56 59 57 56 58 63 61 60 63 60 66 64 66 67 64 63 66 62 67 65 62 64 67 + 3 6 9 12 15 18 21 24 27 30 33 36 39 42 45 48 51 54 57 60 63 66 69 72 75 78 81 84 87 90 93 96 99 102 105 108 111 114 117 120 123 126 129 132 135 138 141 144 147 150 153 156 + + + + + -0.0180344 -0.117996 0 -0.0132048 -0.11929 0 -0.0132048 -0.11929 0.001 -0.0180344 -0.117996 0.001 -0.0180344 -0.117996 0 -0.0132048 -0.11929 0 -0.0025 -1.11663e-16 0 -0.00942615 -0.0791662 0 -0.00423484 -0.0397343 0 -0.0180344 0.117996 0 -0.00423484 0.0397343 0 -0.00942615 0.0791662 0 -0.0132048 0.11929 0 0.0025 -1.12888e-16 0 0.000746136 0.0401701 0 -0.00450211 0.0800344 0 -0.00450211 -0.0800344 0 0.000746136 -0.0401701 0 -0.0132048 -0.11929 0 -0.0132048 -0.11929 0.001 0.0025 -1.12888e-16 0.001 -0.00450211 -0.0800344 0.001 0.000746136 -0.0401701 0.001 0.0025 -1.12888e-16 0 -0.00450211 -0.0800344 0 0.000746136 -0.0401701 0 -0.0180344 -0.117996 0.001 -0.0132048 -0.11929 0.001 -0.0025 -1.11663e-16 0.001 -0.00942615 -0.0791662 0.001 -0.00423484 -0.0397343 0.001 -0.0180344 0.117996 0.001 -0.00423484 0.0397343 0.001 -0.00942615 0.0791662 0.001 -0.0132048 0.11929 0.001 0.0025 -1.12888e-16 0.001 0.000746136 0.0401701 0.001 -0.00450211 0.0800344 0.001 -0.00450211 -0.0800344 0.001 0.000746136 -0.0401701 0.001 -0.0180344 -0.117996 0 -0.0180344 -0.117996 0.001 -0.0025 -1.11663e-16 0.001 -0.00942615 -0.0791662 0.001 -0.00423484 -0.0397343 0.001 -0.0025 -1.11663e-16 0 -0.00942615 -0.0791662 0 -0.00423484 -0.0397343 0 -0.0025 -1.11663e-16 0 -0.0025 -1.11663e-16 0.001 -0.0180344 0.117996 0.001 -0.00423484 0.0397343 0.001 -0.00942615 0.0791662 0.001 -0.0180344 0.117996 0 -0.00423484 0.0397343 0 -0.00942615 0.0791662 0 -0.0180344 0.117996 0 -0.0132048 0.11929 0 -0.0132048 0.11929 0.001 -0.0180344 0.117996 0.001 0.0025 -1.12888e-16 0 0.0025 -1.12888e-16 0.001 -0.0132048 0.11929 0.001 0.000746136 0.0401701 0.001 -0.00450211 0.0800344 0.001 -0.0132048 0.11929 0 0.000746136 0.0401701 0 -0.00450211 0.0800344 0 + + + 2 0 3 1 0 2 16 4 5 16 7 4 17 8 7 17 7 16 6 8 17 13 6 17 10 6 13 14 10 13 15 11 10 15 10 14 12 9 11 12 11 15 21 19 18 21 18 24 22 24 25 22 21 24 20 25 23 20 22 25 38 26 27 38 29 26 39 30 29 39 29 38 28 30 39 35 28 39 32 28 35 36 32 35 37 33 32 37 32 36 34 31 33 34 33 37 43 41 40 43 40 46 44 46 47 44 43 46 42 47 45 42 44 47 51 49 48 51 48 54 52 54 55 52 51 54 50 55 53 50 52 55 58 56 59 57 56 58 63 61 60 63 60 66 64 66 67 64 63 66 62 67 65 62 64 67 + 3 6 9 12 15 18 21 24 27 30 33 36 39 42 45 48 51 54 57 60 63 66 69 72 75 78 81 84 87 90 93 96 99 102 105 108 111 114 117 120 123 126 129 132 135 138 141 144 147 150 153 156 + + + + + -0.0182525 -0.119652 0 -0.0134229 -0.120946 0 -0.0134229 -0.120946 0.001 -0.0182525 -0.119652 0.001 -0.0182525 -0.119652 0 -0.0134229 -0.120946 0 -0.0025 -1.13231e-16 0 -0.00952338 -0.0802776 0 -0.00425919 -0.0402921 0 -0.0182525 0.119652 0 -0.00425919 0.0402921 0 -0.00952338 0.0802776 0 -0.0134229 0.120946 0 0.0025 -1.14455e-16 0 0.000721782 0.0407279 0 -0.00459934 0.0811458 0 -0.00459934 -0.0811458 0 0.000721782 -0.0407279 0 -0.0134229 -0.120946 0 -0.0134229 -0.120946 0.001 0.0025 -1.14455e-16 0.001 -0.00459934 -0.0811458 0.001 0.000721782 -0.0407279 0.001 0.0025 -1.14455e-16 0 -0.00459934 -0.0811458 0 0.000721782 -0.0407279 0 -0.0182525 -0.119652 0.001 -0.0134229 -0.120946 0.001 -0.0025 -1.13231e-16 0.001 -0.00952338 -0.0802776 0.001 -0.00425919 -0.0402921 0.001 -0.0182525 0.119652 0.001 -0.00425919 0.0402921 0.001 -0.00952338 0.0802776 0.001 -0.0134229 0.120946 0.001 0.0025 -1.14455e-16 0.001 0.000721782 0.0407279 0.001 -0.00459934 0.0811458 0.001 -0.00459934 -0.0811458 0.001 0.000721782 -0.0407279 0.001 -0.0182525 -0.119652 0 -0.0182525 -0.119652 0.001 -0.0025 -1.13231e-16 0.001 -0.00952338 -0.0802776 0.001 -0.00425919 -0.0402921 0.001 -0.0025 -1.13231e-16 0 -0.00952338 -0.0802776 0 -0.00425919 -0.0402921 0 -0.0025 -1.13231e-16 0 -0.0025 -1.13231e-16 0.001 -0.0182525 0.119652 0.001 -0.00425919 0.0402921 0.001 -0.00952338 0.0802776 0.001 -0.0182525 0.119652 0 -0.00425919 0.0402921 0 -0.00952338 0.0802776 0 -0.0182525 0.119652 0 -0.0134229 0.120946 0 -0.0134229 0.120946 0.001 -0.0182525 0.119652 0.001 0.0025 -1.14455e-16 0 0.0025 -1.14455e-16 0.001 -0.0134229 0.120946 0.001 0.000721782 0.0407279 0.001 -0.00459934 0.0811458 0.001 -0.0134229 0.120946 0 0.000721782 0.0407279 0 -0.00459934 0.0811458 0 + + + 2 0 3 1 0 2 16 4 5 16 7 4 17 8 7 17 7 16 6 8 17 13 6 17 10 6 13 14 10 13 15 11 10 15 10 14 12 9 11 12 11 15 21 19 18 21 18 24 22 24 25 22 21 24 20 25 23 20 22 25 38 26 27 38 29 26 39 30 29 39 29 38 28 30 39 35 28 39 32 28 35 36 32 35 37 33 32 37 32 36 34 31 33 34 33 37 43 41 40 43 40 46 44 46 47 44 43 46 42 47 45 42 44 47 51 49 48 51 48 54 52 54 55 52 51 54 50 55 53 50 52 55 58 56 59 57 56 58 63 61 60 63 60 66 64 66 67 64 63 66 62 67 65 62 64 67 + 3 6 9 12 15 18 21 24 27 30 33 36 39 42 45 48 51 54 57 60 63 66 69 72 75 78 81 84 87 90 93 96 99 102 105 108 111 114 117 120 123 126 129 132 135 138 141 144 147 150 153 156 + + + + + -0.0183649 -0.120506 0 -0.0135353 -0.1218 0 -0.0135353 -0.1218 0.001 -0.0183649 -0.120506 0.001 -0.0183649 -0.120506 0 -0.0135353 -0.1218 0 -0.0025 -1.14039e-16 0 -0.00957351 -0.0808506 0 -0.00427175 -0.0405797 0 -0.0183649 0.120506 0 -0.00427175 0.0405797 0 -0.00957351 0.0808506 0 -0.0135353 0.1218 0 0.0025 -1.15264e-16 0 0.000709225 0.0410155 0 -0.00464947 0.0817188 0 -0.00464947 -0.0817188 0 0.000709225 -0.0410155 0 -0.0135353 -0.1218 0 -0.0135353 -0.1218 0.001 0.0025 -1.15264e-16 0.001 -0.00464947 -0.0817188 0.001 0.000709225 -0.0410155 0.001 0.0025 -1.15264e-16 0 -0.00464947 -0.0817188 0 0.000709225 -0.0410155 0 -0.0183649 -0.120506 0.001 -0.0135353 -0.1218 0.001 -0.0025 -1.14039e-16 0.001 -0.00957351 -0.0808506 0.001 -0.00427175 -0.0405797 0.001 -0.0183649 0.120506 0.001 -0.00427175 0.0405797 0.001 -0.00957351 0.0808506 0.001 -0.0135353 0.1218 0.001 0.0025 -1.15264e-16 0.001 0.000709225 0.0410155 0.001 -0.00464947 0.0817188 0.001 -0.00464947 -0.0817188 0.001 0.000709225 -0.0410155 0.001 -0.0183649 -0.120506 0 -0.0183649 -0.120506 0.001 -0.0025 -1.14039e-16 0.001 -0.00957351 -0.0808506 0.001 -0.00427175 -0.0405797 0.001 -0.0025 -1.14039e-16 0 -0.00957351 -0.0808506 0 -0.00427175 -0.0405797 0 -0.0025 -1.14039e-16 0 -0.0025 -1.14039e-16 0.001 -0.0183649 0.120506 0.001 -0.00427175 0.0405797 0.001 -0.00957351 0.0808506 0.001 -0.0183649 0.120506 0 -0.00427175 0.0405797 0 -0.00957351 0.0808506 0 -0.0183649 0.120506 0 -0.0135353 0.1218 0 -0.0135353 0.1218 0.001 -0.0183649 0.120506 0.001 0.0025 -1.15264e-16 0 0.0025 -1.15264e-16 0.001 -0.0135353 0.1218 0.001 0.000709225 0.0410155 0.001 -0.00464947 0.0817188 0.001 -0.0135353 0.1218 0 0.000709225 0.0410155 0 -0.00464947 0.0817188 0 + + + 2 0 3 1 0 2 16 4 5 16 7 4 8 7 16 17 8 16 6 8 17 13 6 17 10 6 13 14 10 13 15 11 10 15 10 14 12 9 11 12 11 15 21 19 18 21 18 24 22 24 25 22 21 24 20 25 23 20 22 25 38 26 27 38 29 26 30 29 38 39 30 38 28 30 39 35 28 39 32 28 35 36 32 35 37 33 32 37 32 36 34 31 33 34 33 37 43 41 40 43 40 46 44 46 47 44 43 46 42 47 45 42 44 47 51 49 48 51 48 54 52 54 55 52 51 54 50 55 53 50 52 55 58 56 59 57 56 58 63 61 60 63 60 66 64 66 67 64 63 66 62 67 65 62 64 67 + 3 6 9 12 15 18 21 24 27 30 33 36 39 42 45 48 51 54 57 60 63 66 69 72 75 78 81 84 87 90 93 96 99 102 105 108 111 114 117 120 123 126 129 132 135 138 141 144 147 150 153 156 + + + + + -0.0185864 -0.122188 0 -0.0137568 -0.123483 0 -0.0137568 -0.123483 0.001 -0.0185864 -0.122188 0.001 -0.0185864 -0.122188 0 -0.0137568 -0.123483 0 -0.0025 -1.15631e-16 0 -0.00967226 -0.0819793 0 -0.00429648 -0.0411462 0 -0.0185864 0.122188 0 -0.00429648 0.0411462 0 -0.00967226 0.0819793 0 -0.0137568 0.123483 0 0.0025 -1.16856e-16 0 0.00068449 0.041582 0 -0.00474822 0.0828475 0 -0.00474822 -0.0828475 0 0.00068449 -0.041582 0 -0.0137568 -0.123483 0 -0.0137568 -0.123483 0.001 0.0025 -1.16856e-16 0.001 -0.00474822 -0.0828475 0.001 0.00068449 -0.041582 0.001 0.0025 -1.16856e-16 0 -0.00474822 -0.0828475 0 0.00068449 -0.041582 0 -0.0185864 -0.122188 0.001 -0.0137568 -0.123483 0.001 -0.0025 -1.15631e-16 0.001 -0.00967226 -0.0819793 0.001 -0.00429648 -0.0411462 0.001 -0.0185864 0.122188 0.001 -0.00429648 0.0411462 0.001 -0.00967226 0.0819793 0.001 -0.0137568 0.123483 0.001 0.0025 -1.16856e-16 0.001 0.00068449 0.041582 0.001 -0.00474822 0.0828475 0.001 -0.00474822 -0.0828475 0.001 0.00068449 -0.041582 0.001 -0.0185864 -0.122188 0 -0.0185864 -0.122188 0.001 -0.0025 -1.15631e-16 0.001 -0.00967226 -0.0819793 0.001 -0.00429648 -0.0411462 0.001 -0.0025 -1.15631e-16 0 -0.00967226 -0.0819793 0 -0.00429648 -0.0411462 0 -0.0025 -1.15631e-16 0 -0.0025 -1.15631e-16 0.001 -0.0185864 0.122188 0.001 -0.00429648 0.0411462 0.001 -0.00967226 0.0819793 0.001 -0.0185864 0.122188 0 -0.00429648 0.0411462 0 -0.00967226 0.0819793 0 -0.0185864 0.122188 0 -0.0137568 0.123483 0 -0.0137568 0.123483 0.001 -0.0185864 0.122188 0.001 0.0025 -1.16856e-16 0 0.0025 -1.16856e-16 0.001 -0.0137568 0.123483 0.001 0.00068449 0.041582 0.001 -0.00474822 0.0828475 0.001 -0.0137568 0.123483 0 0.00068449 0.041582 0 -0.00474822 0.0828475 0 + + + 2 0 3 1 0 2 16 4 5 16 7 4 8 7 16 17 8 16 6 8 17 13 6 17 10 6 13 14 10 13 15 11 10 15 10 14 12 9 11 12 11 15 21 19 18 21 18 24 22 24 25 22 21 24 20 25 23 20 22 25 38 26 27 38 29 26 30 29 38 39 30 38 28 30 39 35 28 39 32 28 35 36 32 35 37 33 32 37 32 36 34 31 33 34 33 37 43 41 40 43 40 46 44 46 47 44 43 46 42 47 45 42 44 47 51 49 48 51 48 54 52 54 55 52 51 54 50 55 53 50 52 55 58 56 59 57 56 58 63 61 60 63 60 66 64 66 67 64 63 66 62 67 65 62 64 67 + 3 6 9 12 15 18 21 24 27 30 33 36 39 42 45 48 51 54 57 60 63 66 69 72 75 78 81 84 87 90 93 96 99 102 105 108 111 114 117 120 123 126 129 132 135 138 141 144 147 150 153 156 + + + + + -0.0186989 -0.123043 0 -0.0138692 -0.124337 0 -0.0138692 -0.124337 0.001 -0.0186989 -0.123043 0.001 -0.0186989 -0.123043 0 -0.0138692 -0.124337 0 -0.0025 -1.16439e-16 0 -0.00972239 -0.0825523 0 -0.00430904 -0.0414338 0 -0.0186989 0.123043 0 -0.00430904 0.0414338 0 -0.00972239 0.0825523 0 -0.0138692 0.124337 0 0.0025 -1.17664e-16 0 0.000671933 0.0418696 0 -0.00479836 0.0834206 0 -0.00479836 -0.0834206 0 0.000671933 -0.0418696 0 -0.0138692 -0.124337 0 -0.0138692 -0.124337 0.001 0.0025 -1.17664e-16 0.001 -0.00479836 -0.0834206 0.001 0.000671933 -0.0418696 0.001 0.0025 -1.17664e-16 0 -0.00479836 -0.0834206 0 0.000671933 -0.0418696 0 -0.0186989 -0.123043 0.001 -0.0138692 -0.124337 0.001 -0.0025 -1.16439e-16 0.001 -0.00972239 -0.0825523 0.001 -0.00430904 -0.0414338 0.001 -0.0186989 0.123043 0.001 -0.00430904 0.0414338 0.001 -0.00972239 0.0825523 0.001 -0.0138692 0.124337 0.001 0.0025 -1.17664e-16 0.001 0.000671933 0.0418696 0.001 -0.00479836 0.0834206 0.001 -0.00479836 -0.0834206 0.001 0.000671933 -0.0418696 0.001 -0.0186989 -0.123043 0 -0.0186989 -0.123043 0.001 -0.0025 -1.16439e-16 0.001 -0.00972239 -0.0825523 0.001 -0.00430904 -0.0414338 0.001 -0.0025 -1.16439e-16 0 -0.00972239 -0.0825523 0 -0.00430904 -0.0414338 0 -0.0025 -1.16439e-16 0 -0.0025 -1.16439e-16 0.001 -0.0186989 0.123043 0.001 -0.00430904 0.0414338 0.001 -0.00972239 0.0825523 0.001 -0.0186989 0.123043 0 -0.00430904 0.0414338 0 -0.00972239 0.0825523 0 -0.0186989 0.123043 0 -0.0138692 0.124337 0 -0.0138692 0.124337 0.001 -0.0186989 0.123043 0.001 0.0025 -1.17664e-16 0 0.0025 -1.17664e-16 0.001 -0.0138692 0.124337 0.001 0.000671933 0.0418696 0.001 -0.00479836 0.0834206 0.001 -0.0138692 0.124337 0 0.000671933 0.0418696 0 -0.00479836 0.0834206 0 + + + 2 0 3 1 0 2 16 4 5 16 7 4 17 8 7 17 7 16 6 8 17 13 6 17 10 6 13 14 10 13 15 11 10 15 10 14 9 11 15 12 9 15 21 19 18 21 18 24 22 24 25 22 21 24 20 25 23 20 22 25 38 26 27 38 29 26 39 30 29 39 29 38 28 30 39 35 28 39 32 28 35 36 32 35 37 33 32 37 32 36 31 33 37 34 31 37 43 41 40 43 40 46 44 46 47 44 43 46 42 47 45 42 44 47 51 49 48 51 48 54 52 54 55 52 51 54 50 55 53 50 52 55 58 56 59 57 56 58 63 61 60 63 60 66 64 66 67 64 63 66 62 67 65 62 64 67 + 3 6 9 12 15 18 21 24 27 30 33 36 39 42 45 48 51 54 57 60 63 66 69 72 75 78 81 84 87 90 93 96 99 102 105 108 111 114 117 120 123 126 129 132 135 138 141 144 147 150 153 156 + + + + + -0.0189203 -0.124725 0 -0.0140907 -0.126019 0 -0.0140907 -0.126019 0.001 -0.0189203 -0.124725 0.001 -0.0189203 -0.124725 0 -0.0140907 -0.126019 0 -0.0025 -1.18031e-16 0 -0.00982114 -0.0836811 0 -0.00433377 -0.0420004 0 -0.0189203 0.124725 0 -0.00433377 0.0420004 0 -0.00982114 0.0836811 0 -0.0140907 0.126019 0 0.0025 -1.19256e-16 0 0.000647199 0.0424361 0 -0.00489711 0.0845493 0 -0.00489711 -0.0845493 0 0.000647199 -0.0424361 0 -0.0140907 -0.126019 0 -0.0140907 -0.126019 0.001 0.0025 -1.19256e-16 0.001 -0.00489711 -0.0845493 0.001 0.000647199 -0.0424361 0.001 0.0025 -1.19256e-16 0 -0.00489711 -0.0845493 0 0.000647199 -0.0424361 0 -0.0189203 -0.124725 0.001 -0.0140907 -0.126019 0.001 -0.0025 -1.18031e-16 0.001 -0.00982114 -0.0836811 0.001 -0.00433377 -0.0420004 0.001 -0.0189203 0.124725 0.001 -0.00433377 0.0420004 0.001 -0.00982114 0.0836811 0.001 -0.0140907 0.126019 0.001 0.0025 -1.19256e-16 0.001 0.000647199 0.0424361 0.001 -0.00489711 0.0845493 0.001 -0.00489711 -0.0845493 0.001 0.000647199 -0.0424361 0.001 -0.0189203 -0.124725 0 -0.0189203 -0.124725 0.001 -0.0025 -1.18031e-16 0.001 -0.00982114 -0.0836811 0.001 -0.00433377 -0.0420004 0.001 -0.0025 -1.18031e-16 0 -0.00982114 -0.0836811 0 -0.00433377 -0.0420004 0 -0.0025 -1.18031e-16 0 -0.0025 -1.18031e-16 0.001 -0.0189203 0.124725 0.001 -0.00433377 0.0420004 0.001 -0.00982114 0.0836811 0.001 -0.0189203 0.124725 0 -0.00433377 0.0420004 0 -0.00982114 0.0836811 0 -0.0189203 0.124725 0 -0.0140907 0.126019 0 -0.0140907 0.126019 0.001 -0.0189203 0.124725 0.001 0.0025 -1.19256e-16 0 0.0025 -1.19256e-16 0.001 -0.0140907 0.126019 0.001 0.000647199 0.0424361 0.001 -0.00489711 0.0845493 0.001 -0.0140907 0.126019 0 0.000647199 0.0424361 0 -0.00489711 0.0845493 0 + + + 2 0 3 1 0 2 16 4 5 16 7 4 17 8 7 17 7 16 6 8 17 13 6 17 10 6 13 14 10 13 15 11 10 15 10 14 12 9 11 12 11 15 21 19 18 21 18 24 22 24 25 22 21 24 20 25 23 20 22 25 38 26 27 38 29 26 39 30 29 39 29 38 28 30 39 35 28 39 32 28 35 36 32 35 37 33 32 37 32 36 34 31 33 34 33 37 43 41 40 43 40 46 44 46 47 44 43 46 42 47 45 42 44 47 51 49 48 51 48 54 52 54 55 52 51 54 50 55 53 50 52 55 58 56 59 57 56 58 63 61 60 63 60 66 64 66 67 64 63 66 62 67 65 62 64 67 + 3 6 9 12 15 18 21 24 27 30 33 36 39 42 45 48 51 54 57 60 63 66 69 72 75 78 81 84 87 90 93 96 99 102 105 108 111 114 117 120 123 126 129 132 135 138 141 144 147 150 153 156 + + + + + -0.0190328 -0.125579 0 -0.0142032 -0.126873 0 -0.0142032 -0.126873 0.001 -0.0190328 -0.125579 0.001 -0.0190328 -0.125579 0 -0.0142032 -0.126873 0 -0.0025 -1.1884e-16 0 -0.00987128 -0.0842541 0 -0.00434633 -0.042288 0 -0.0190328 0.125579 0 -0.00434633 0.042288 0 -0.00987128 0.0842541 0 -0.0142032 0.126873 0 0.0025 -1.20064e-16 0 0.000634641 0.0427237 0 -0.00494724 0.0851223 0 -0.00494724 -0.0851223 0 0.000634641 -0.0427237 0 -0.0142032 -0.126873 0 -0.0142032 -0.126873 0.001 0.0025 -1.20064e-16 0.001 -0.00494724 -0.0851223 0.001 0.000634641 -0.0427237 0.001 0.0025 -1.20064e-16 0 -0.00494724 -0.0851223 0 0.000634641 -0.0427237 0 -0.0190328 -0.125579 0.001 -0.0142032 -0.126873 0.001 -0.0025 -1.1884e-16 0.001 -0.00987128 -0.0842541 0.001 -0.00434633 -0.042288 0.001 -0.0190328 0.125579 0.001 -0.00434633 0.042288 0.001 -0.00987128 0.0842541 0.001 -0.0142032 0.126873 0.001 0.0025 -1.20064e-16 0.001 0.000634641 0.0427237 0.001 -0.00494724 0.0851223 0.001 -0.00494724 -0.0851223 0.001 0.000634641 -0.0427237 0.001 -0.0190328 -0.125579 0 -0.0190328 -0.125579 0.001 -0.0025 -1.1884e-16 0.001 -0.00987128 -0.0842541 0.001 -0.00434633 -0.042288 0.001 -0.0025 -1.1884e-16 0 -0.00987128 -0.0842541 0 -0.00434633 -0.042288 0 -0.0025 -1.1884e-16 0 -0.0025 -1.1884e-16 0.001 -0.0190328 0.125579 0.001 -0.00434633 0.042288 0.001 -0.00987128 0.0842541 0.001 -0.0190328 0.125579 0 -0.00434633 0.042288 0 -0.00987128 0.0842541 0 -0.0190328 0.125579 0 -0.0142032 0.126873 0 -0.0142032 0.126873 0.001 -0.0190328 0.125579 0.001 0.0025 -1.20064e-16 0 0.0025 -1.20064e-16 0.001 -0.0142032 0.126873 0.001 0.000634641 0.0427237 0.001 -0.00494724 0.0851223 0.001 -0.0142032 0.126873 0 0.000634641 0.0427237 0 -0.00494724 0.0851223 0 + + + 2 0 3 1 0 2 16 4 5 16 7 4 17 8 7 17 7 16 6 8 17 13 6 17 10 6 13 14 10 13 15 11 10 15 10 14 12 9 11 12 11 15 21 19 18 21 18 24 22 24 25 22 21 24 20 25 23 20 22 25 38 26 27 38 29 26 39 30 29 39 29 38 28 30 39 35 28 39 32 28 35 36 32 35 37 33 32 37 32 36 34 31 33 34 33 37 43 41 40 43 40 46 44 46 47 44 43 46 42 47 45 42 44 47 51 49 48 51 48 54 52 54 55 52 51 54 50 55 53 50 52 55 58 56 59 57 56 58 63 61 60 63 60 66 64 66 67 64 63 66 62 67 65 62 64 67 + 3 6 9 12 15 18 21 24 27 30 33 36 39 42 45 48 51 54 57 60 63 66 69 72 75 78 81 84 87 90 93 96 99 102 105 108 111 114 117 120 123 126 129 132 135 138 141 144 147 150 153 156 + + + + + -0.0192543 -0.127261 0 -0.0144246 -0.128555 0 -0.0144246 -0.128555 0.001 -0.0192543 -0.127261 0.001 -0.0192543 -0.127261 0 -0.0144246 -0.128555 0 -0.0025 -1.20432e-16 0 -0.00997003 -0.0853828 0 -0.00437107 -0.0428545 0 -0.0192543 0.127261 0 -0.00437107 0.0428545 0 -0.00997003 0.0853828 0 -0.0144246 0.128555 0 0.0025 -1.21656e-16 0 0.000609907 0.0432903 0 -0.00504599 0.086251 0 -0.00504599 -0.086251 0 0.000609907 -0.0432903 0 -0.0144246 -0.128555 0 -0.0144246 -0.128555 0.001 0.0025 -1.21656e-16 0.001 -0.00504599 -0.086251 0.001 0.000609907 -0.0432903 0.001 0.0025 -1.21656e-16 0 -0.00504599 -0.086251 0 0.000609907 -0.0432903 0 -0.0192543 -0.127261 0.001 -0.0144246 -0.128555 0.001 -0.0025 -1.20432e-16 0.001 -0.00997003 -0.0853828 0.001 -0.00437107 -0.0428545 0.001 -0.0192543 0.127261 0.001 -0.00437107 0.0428545 0.001 -0.00997003 0.0853828 0.001 -0.0144246 0.128555 0.001 0.0025 -1.21656e-16 0.001 0.000609907 0.0432903 0.001 -0.00504599 0.086251 0.001 -0.00504599 -0.086251 0.001 0.000609907 -0.0432903 0.001 -0.0192543 -0.127261 0 -0.0192543 -0.127261 0.001 -0.0025 -1.20432e-16 0.001 -0.00997003 -0.0853828 0.001 -0.00437107 -0.0428545 0.001 -0.0025 -1.20432e-16 0 -0.00997003 -0.0853828 0 -0.00437107 -0.0428545 0 -0.0025 -1.20432e-16 0 -0.0025 -1.20432e-16 0.001 -0.0192543 0.127261 0.001 -0.00437107 0.0428545 0.001 -0.00997003 0.0853828 0.001 -0.0192543 0.127261 0 -0.00437107 0.0428545 0 -0.00997003 0.0853828 0 -0.0192543 0.127261 0 -0.0144246 0.128555 0 -0.0144246 0.128555 0.001 -0.0192543 0.127261 0.001 0.0025 -1.21656e-16 0 0.0025 -1.21656e-16 0.001 -0.0144246 0.128555 0.001 0.000609907 0.0432903 0.001 -0.00504599 0.086251 0.001 -0.0144246 0.128555 0 0.000609907 0.0432903 0 -0.00504599 0.086251 0 + + + 2 0 3 1 0 2 16 4 5 16 7 4 17 8 7 17 7 16 6 8 17 13 6 17 10 6 13 14 10 13 11 10 14 15 11 14 9 11 15 12 9 15 21 19 18 21 18 24 22 24 25 22 21 24 20 25 23 20 22 25 38 26 27 38 29 26 39 30 29 39 29 38 28 30 39 35 28 39 32 28 35 36 32 35 33 32 36 37 33 36 31 33 37 34 31 37 43 41 40 43 40 46 44 46 47 44 43 46 42 47 45 42 44 47 51 49 48 51 48 54 52 54 55 52 51 54 50 55 53 50 52 55 58 56 59 57 56 58 63 61 60 63 60 66 64 66 67 64 63 66 62 67 65 62 64 67 + 3 6 9 12 15 18 21 24 27 30 33 36 39 42 45 48 51 54 57 60 63 66 69 72 75 78 81 84 87 90 93 96 99 102 105 108 111 114 117 120 123 126 129 132 135 138 141 144 147 150 153 156 + + + + + -0.0133458 -0.0823821 0 -0.00851618 -0.0836762 0 -0.00851618 -0.0836762 0.001 -0.0133458 -0.0823821 0.001 -0.0133458 -0.0823821 0 -0.00851618 -0.0836762 0 -0.0025 -7.7961e-17 0 -0.00733569 -0.0552722 0 -0.00371123 -0.0277417 0 -0.0133458 0.0823821 0 -0.00371123 0.0277417 0 -0.00733569 0.0552722 0 -0.00851618 0.0836762 0 0.0025 -7.91857e-17 0 0.00126975 0.0281775 0 -0.00241165 0.0561405 0 -0.00241165 -0.0561405 0 0.00126975 -0.0281775 0 -0.00851618 -0.0836762 0 -0.00851618 -0.0836762 0.001 0.0025 -7.91857e-17 0.001 -0.00241165 -0.0561405 0.001 0.00126975 -0.0281775 0.001 0.0025 -7.91857e-17 0 -0.00241165 -0.0561405 0 0.00126975 -0.0281775 0 -0.0133458 -0.0823821 0.001 -0.00851618 -0.0836762 0.001 -0.0025 -7.7961e-17 0.001 -0.00733569 -0.0552722 0.001 -0.00371123 -0.0277417 0.001 -0.0133458 0.0823821 0.001 -0.00371123 0.0277417 0.001 -0.00733569 0.0552722 0.001 -0.00851618 0.0836762 0.001 0.0025 -7.91857e-17 0.001 0.00126975 0.0281775 0.001 -0.00241165 0.0561405 0.001 -0.00241165 -0.0561405 0.001 0.00126975 -0.0281775 0.001 -0.0133458 -0.0823821 0 -0.0133458 -0.0823821 0.001 -0.0025 -7.7961e-17 0.001 -0.00733569 -0.0552722 0.001 -0.00371123 -0.0277417 0.001 -0.0025 -7.7961e-17 0 -0.00733569 -0.0552722 0 -0.00371123 -0.0277417 0 -0.0025 -7.7961e-17 0 -0.0025 -7.7961e-17 0.001 -0.0133458 0.0823821 0.001 -0.00371123 0.0277417 0.001 -0.00733569 0.0552722 0.001 -0.0133458 0.0823821 0 -0.00371123 0.0277417 0 -0.00733569 0.0552722 0 -0.0133458 0.0823821 0 -0.00851618 0.0836762 0 -0.00851618 0.0836762 0.001 -0.0133458 0.0823821 0.001 0.0025 -7.91857e-17 0 0.0025 -7.91857e-17 0.001 -0.00851618 0.0836762 0.001 0.00126975 0.0281775 0.001 -0.00241165 0.0561405 0.001 -0.00851618 0.0836762 0 0.00126975 0.0281775 0 -0.00241165 0.0561405 0 + + + 1 3 2 1 0 3 16 4 5 16 7 4 17 8 7 17 7 16 6 8 17 13 6 17 10 6 13 14 10 13 11 10 14 15 11 14 12 9 11 12 11 15 21 19 18 21 18 24 22 24 25 22 21 24 20 25 23 20 22 25 38 26 27 38 29 26 39 30 29 39 29 38 28 30 39 35 28 39 32 28 35 36 32 35 33 32 36 37 33 36 34 31 33 34 33 37 43 41 40 43 40 46 44 46 47 44 43 46 42 47 45 42 44 47 51 49 48 51 48 54 52 54 55 52 51 54 50 55 53 50 52 55 58 56 59 57 56 58 63 61 60 63 60 66 64 66 67 64 63 66 62 67 65 62 64 67 + 3 6 9 12 15 18 21 24 27 30 33 36 39 42 45 48 51 54 57 60 63 66 69 72 75 78 81 84 87 90 93 96 99 102 105 108 111 114 117 120 123 126 129 132 135 138 141 144 147 150 153 156 + + + + + -0.0193633 -0.12809 0 -0.0145337 -0.129384 0 -0.0145337 -0.129384 0.001 -0.0193633 -0.12809 0.001 -0.0193633 -0.12809 0 -0.0145337 -0.129384 0 -0.0025 -1.21216e-16 0 -0.0100186 -0.0859385 0 -0.00438324 -0.0431334 0 -0.0193633 0.12809 0 -0.00438324 0.0431334 0 -0.0100186 0.0859385 0 -0.0145337 0.129384 0 0.0025 -1.2244e-16 0 0.00059773 0.0435692 0 -0.0050946 0.0868067 0 -0.0050946 -0.0868067 0 0.00059773 -0.0435692 0 -0.0145337 -0.129384 0 -0.0145337 -0.129384 0.001 0.0025 -1.2244e-16 0.001 -0.0050946 -0.0868067 0.001 0.00059773 -0.0435692 0.001 0.0025 -1.2244e-16 0 -0.0050946 -0.0868067 0 0.00059773 -0.0435692 0 -0.0193633 -0.12809 0.001 -0.0145337 -0.129384 0.001 -0.0025 -1.21216e-16 0.001 -0.0100186 -0.0859385 0.001 -0.00438324 -0.0431334 0.001 -0.0193633 0.12809 0.001 -0.00438324 0.0431334 0.001 -0.0100186 0.0859385 0.001 -0.0145337 0.129384 0.001 0.0025 -1.2244e-16 0.001 0.00059773 0.0435692 0.001 -0.0050946 0.0868067 0.001 -0.0050946 -0.0868067 0.001 0.00059773 -0.0435692 0.001 -0.0193633 -0.12809 0 -0.0193633 -0.12809 0.001 -0.0025 -1.21216e-16 0.001 -0.0100186 -0.0859385 0.001 -0.00438324 -0.0431334 0.001 -0.0025 -1.21216e-16 0 -0.0100186 -0.0859385 0 -0.00438324 -0.0431334 0 -0.0025 -1.21216e-16 0 -0.0025 -1.21216e-16 0.001 -0.0193633 0.12809 0.001 -0.00438324 0.0431334 0.001 -0.0100186 0.0859385 0.001 -0.0193633 0.12809 0 -0.00438324 0.0431334 0 -0.0100186 0.0859385 0 -0.0193633 0.12809 0 -0.0145337 0.129384 0 -0.0145337 0.129384 0.001 -0.0193633 0.12809 0.001 0.0025 -1.2244e-16 0 0.0025 -1.2244e-16 0.001 -0.0145337 0.129384 0.001 0.00059773 0.0435692 0.001 -0.0050946 0.0868067 0.001 -0.0145337 0.129384 0 0.00059773 0.0435692 0 -0.0050946 0.0868067 0 + + + 2 0 3 1 0 2 16 4 5 16 7 4 17 8 7 17 7 16 6 8 17 13 6 17 10 6 13 14 10 13 15 11 10 15 10 14 12 9 11 12 11 15 21 19 18 21 18 24 22 24 25 22 21 24 20 25 23 20 22 25 38 26 27 38 29 26 39 30 29 39 29 38 28 30 39 35 28 39 32 28 35 36 32 35 37 33 32 37 32 36 34 31 33 34 33 37 43 41 40 43 40 46 44 46 47 44 43 46 42 47 45 42 44 47 51 49 48 51 48 54 52 54 55 52 51 54 50 55 53 50 52 55 58 56 59 57 56 58 63 61 60 63 60 66 64 66 67 64 63 66 62 67 65 62 64 67 + 3 6 9 12 15 18 21 24 27 30 33 36 39 42 45 48 51 54 57 60 63 66 69 72 75 78 81 84 87 90 93 96 99 102 105 108 111 114 117 120 123 126 129 132 135 138 141 144 147 150 153 156 + + + + + -0.0195848 -0.129772 0 -0.0147552 -0.131066 0 -0.0147552 -0.131066 0.001 -0.0195848 -0.129772 0.001 -0.0195848 -0.129772 0 -0.0147552 -0.131066 0 -0.0025 -1.22808e-16 0 -0.0101174 -0.0870672 0 -0.00440798 -0.0436999 0 -0.0195848 0.129772 0 -0.00440798 0.0436999 0 -0.0101174 0.0870672 0 -0.0147552 0.131066 0 0.0025 -1.24032e-16 0 0.000572995 0.0441357 0 -0.00519335 0.0879354 0 -0.00519335 -0.0879354 0 0.000572995 -0.0441357 0 -0.0147552 -0.131066 0 -0.0147552 -0.131066 0.001 0.0025 -1.24032e-16 0.001 -0.00519335 -0.0879354 0.001 0.000572995 -0.0441357 0.001 0.0025 -1.24032e-16 0 -0.00519335 -0.0879354 0 0.000572995 -0.0441357 0 -0.0195848 -0.129772 0.001 -0.0147552 -0.131066 0.001 -0.0025 -1.22808e-16 0.001 -0.0101174 -0.0870672 0.001 -0.00440798 -0.0436999 0.001 -0.0195848 0.129772 0.001 -0.00440798 0.0436999 0.001 -0.0101174 0.0870672 0.001 -0.0147552 0.131066 0.001 0.0025 -1.24032e-16 0.001 0.000572995 0.0441357 0.001 -0.00519335 0.0879354 0.001 -0.00519335 -0.0879354 0.001 0.000572995 -0.0441357 0.001 -0.0195848 -0.129772 0 -0.0195848 -0.129772 0.001 -0.0025 -1.22808e-16 0.001 -0.0101174 -0.0870672 0.001 -0.00440798 -0.0436999 0.001 -0.0025 -1.22808e-16 0 -0.0101174 -0.0870672 0 -0.00440798 -0.0436999 0 -0.0025 -1.22808e-16 0 -0.0025 -1.22808e-16 0.001 -0.0195848 0.129772 0.001 -0.00440798 0.0436999 0.001 -0.0101174 0.0870672 0.001 -0.0195848 0.129772 0 -0.00440798 0.0436999 0 -0.0101174 0.0870672 0 -0.0195848 0.129772 0 -0.0147552 0.131066 0 -0.0147552 0.131066 0.001 -0.0195848 0.129772 0.001 0.0025 -1.24032e-16 0 0.0025 -1.24032e-16 0.001 -0.0147552 0.131066 0.001 0.000572995 0.0441357 0.001 -0.00519335 0.0879354 0.001 -0.0147552 0.131066 0 0.000572995 0.0441357 0 -0.00519335 0.0879354 0 + + + 2 0 3 1 0 2 16 4 5 16 7 4 8 7 16 17 8 16 6 8 17 13 6 17 10 6 13 14 10 13 15 11 10 15 10 14 12 9 11 12 11 15 21 19 18 21 18 24 22 24 25 22 21 24 20 25 23 20 22 25 38 26 27 38 29 26 30 29 38 39 30 38 28 30 39 35 28 39 32 28 35 36 32 35 37 33 32 37 32 36 34 31 33 34 33 37 43 41 40 43 40 46 44 46 47 44 43 46 42 47 45 42 44 47 51 49 48 51 48 54 52 54 55 52 51 54 50 55 53 50 52 55 58 56 59 57 56 58 63 61 60 63 60 66 64 66 67 64 63 66 62 67 65 62 64 67 + 3 6 9 12 15 18 21 24 27 30 33 36 39 42 45 48 51 54 57 60 63 66 69 72 75 78 81 84 87 90 93 96 99 102 105 108 111 114 117 120 123 126 129 132 135 138 141 144 147 150 153 156 + + + + + -0.0196972 -0.130626 0 -0.0148676 -0.13192 0 -0.0148676 -0.13192 0.001 -0.0196972 -0.130626 0.001 -0.0196972 -0.130626 0 -0.0148676 -0.13192 0 -0.0025 -1.23616e-16 0 -0.0101675 -0.0876402 0 -0.00442054 -0.0439875 0 -0.0196972 0.130626 0 -0.00442054 0.0439875 0 -0.0101675 0.0876402 0 -0.0148676 0.13192 0 0.0025 -1.2484e-16 0 0.000560438 0.0444233 0 -0.00524349 0.0885085 0 -0.00524349 -0.0885085 0 0.000560438 -0.0444233 0 -0.0148676 -0.13192 0 -0.0148676 -0.13192 0.001 0.0025 -1.2484e-16 0.001 -0.00524349 -0.0885085 0.001 0.000560438 -0.0444233 0.001 0.0025 -1.2484e-16 0 -0.00524349 -0.0885085 0 0.000560438 -0.0444233 0 -0.0196972 -0.130626 0.001 -0.0148676 -0.13192 0.001 -0.0025 -1.23616e-16 0.001 -0.0101675 -0.0876402 0.001 -0.00442054 -0.0439875 0.001 -0.0196972 0.130626 0.001 -0.00442054 0.0439875 0.001 -0.0101675 0.0876402 0.001 -0.0148676 0.13192 0.001 0.0025 -1.2484e-16 0.001 0.000560438 0.0444233 0.001 -0.00524349 0.0885085 0.001 -0.00524349 -0.0885085 0.001 0.000560438 -0.0444233 0.001 -0.0196972 -0.130626 0 -0.0196972 -0.130626 0.001 -0.0025 -1.23616e-16 0.001 -0.0101675 -0.0876402 0.001 -0.00442054 -0.0439875 0.001 -0.0025 -1.23616e-16 0 -0.0101675 -0.0876402 0 -0.00442054 -0.0439875 0 -0.0025 -1.23616e-16 0 -0.0025 -1.23616e-16 0.001 -0.0196972 0.130626 0.001 -0.00442054 0.0439875 0.001 -0.0101675 0.0876402 0.001 -0.0196972 0.130626 0 -0.00442054 0.0439875 0 -0.0101675 0.0876402 0 -0.0196972 0.130626 0 -0.0148676 0.13192 0 -0.0148676 0.13192 0.001 -0.0196972 0.130626 0.001 0.0025 -1.2484e-16 0 0.0025 -1.2484e-16 0.001 -0.0148676 0.13192 0.001 0.000560438 0.0444233 0.001 -0.00524349 0.0885085 0.001 -0.0148676 0.13192 0 0.000560438 0.0444233 0 -0.00524349 0.0885085 0 + + + 2 0 3 1 0 2 16 4 5 16 7 4 8 7 16 17 8 16 6 8 17 13 6 17 10 6 13 14 10 13 15 11 10 15 10 14 12 9 11 12 11 15 21 19 18 21 18 24 22 24 25 22 21 24 20 25 23 20 22 25 38 26 27 38 29 26 30 29 38 39 30 38 28 30 39 35 28 39 32 28 35 36 32 35 37 33 32 37 32 36 34 31 33 34 33 37 43 41 40 43 40 46 44 46 47 44 43 46 42 47 45 42 44 47 51 49 48 51 48 54 52 54 55 52 51 54 50 55 53 50 52 55 58 56 59 57 56 58 63 61 60 63 60 66 64 66 67 64 63 66 62 67 65 62 64 67 + 3 6 9 12 15 18 21 24 27 30 33 36 39 42 45 48 51 54 57 60 63 66 69 72 75 78 81 84 87 90 93 96 99 102 105 108 111 114 117 120 123 126 129 132 135 138 141 144 147 150 153 156 + + + + + -0.0199187 -0.132308 0 -0.0150891 -0.133602 0 -0.0150891 -0.133602 0.001 -0.0199187 -0.132308 0.001 -0.0199187 -0.132308 0 -0.0150891 -0.133602 0 -0.0025 -1.25208e-16 0 -0.0102663 -0.0887689 0 -0.00444527 -0.044554 0 -0.0199187 0.132308 0 -0.00444527 0.044554 0 -0.0102663 0.0887689 0 -0.0150891 0.133602 0 0.0025 -1.26433e-16 0 0.000535703 0.0449898 0 -0.00534224 0.0896372 0 -0.00534224 -0.0896372 0 0.000535703 -0.0449898 0 -0.0150891 -0.133602 0 -0.0150891 -0.133602 0.001 0.0025 -1.26433e-16 0.001 -0.00534224 -0.0896372 0.001 0.000535703 -0.0449898 0.001 0.0025 -1.26433e-16 0 -0.00534224 -0.0896372 0 0.000535703 -0.0449898 0 -0.0199187 -0.132308 0.001 -0.0150891 -0.133602 0.001 -0.0025 -1.25208e-16 0.001 -0.0102663 -0.0887689 0.001 -0.00444527 -0.044554 0.001 -0.0199187 0.132308 0.001 -0.00444527 0.044554 0.001 -0.0102663 0.0887689 0.001 -0.0150891 0.133602 0.001 0.0025 -1.26433e-16 0.001 0.000535703 0.0449898 0.001 -0.00534224 0.0896372 0.001 -0.00534224 -0.0896372 0.001 0.000535703 -0.0449898 0.001 -0.0199187 -0.132308 0 -0.0199187 -0.132308 0.001 -0.0025 -1.25208e-16 0.001 -0.0102663 -0.0887689 0.001 -0.00444527 -0.044554 0.001 -0.0025 -1.25208e-16 0 -0.0102663 -0.0887689 0 -0.00444527 -0.044554 0 -0.0025 -1.25208e-16 0 -0.0025 -1.25208e-16 0.001 -0.0199187 0.132308 0.001 -0.00444527 0.044554 0.001 -0.0102663 0.0887689 0.001 -0.0199187 0.132308 0 -0.00444527 0.044554 0 -0.0102663 0.0887689 0 -0.0199187 0.132308 0 -0.0150891 0.133602 0 -0.0150891 0.133602 0.001 -0.0199187 0.132308 0.001 0.0025 -1.26433e-16 0 0.0025 -1.26433e-16 0.001 -0.0150891 0.133602 0.001 0.000535703 0.0449898 0.001 -0.00534224 0.0896372 0.001 -0.0150891 0.133602 0 0.000535703 0.0449898 0 -0.00534224 0.0896372 0 + + + 2 0 3 1 0 2 16 4 5 16 7 4 17 8 7 17 7 16 6 8 17 13 6 17 10 6 13 14 10 13 15 11 10 15 10 14 12 9 11 12 11 15 21 19 18 21 18 24 22 24 25 22 21 24 20 25 23 20 22 25 38 26 27 38 29 26 39 30 29 39 29 38 28 30 39 35 28 39 32 28 35 36 32 35 37 33 32 37 32 36 34 31 33 34 33 37 43 41 40 43 40 46 44 46 47 44 43 46 42 47 45 42 44 47 51 49 48 51 48 54 52 54 55 52 51 54 50 55 53 50 52 55 58 56 59 57 56 58 63 61 60 63 60 66 64 66 67 64 63 66 62 67 65 62 64 67 + 3 6 9 12 15 18 21 24 27 30 33 36 39 42 45 48 51 54 57 60 63 66 69 72 75 78 81 84 87 90 93 96 99 102 105 108 111 114 117 120 123 126 129 132 135 138 141 144 147 150 153 156 + + + + + -0.0200278 -0.133137 0 -0.0151981 -0.134431 0 -0.0151981 -0.134431 0.001 -0.0200278 -0.133137 0.001 -0.0200278 -0.133137 0 -0.0151981 -0.134431 0 -0.0025 -1.25992e-16 0 -0.0103149 -0.0893246 0 -0.00445745 -0.0448329 0 -0.0200278 0.133137 0 -0.00445745 0.0448329 0 -0.0103149 0.0893246 0 -0.0151981 0.134431 0 0.0025 -1.27216e-16 0 0.000523526 0.0452687 0 -0.00539085 0.0901929 0 -0.00539085 -0.0901929 0 0.000523526 -0.0452687 0 -0.0151981 -0.134431 0 -0.0151981 -0.134431 0.001 0.0025 -1.27216e-16 0.001 -0.00539085 -0.0901929 0.001 0.000523526 -0.0452687 0.001 0.0025 -1.27216e-16 0 -0.00539085 -0.0901929 0 0.000523526 -0.0452687 0 -0.0200278 -0.133137 0.001 -0.0151981 -0.134431 0.001 -0.0025 -1.25992e-16 0.001 -0.0103149 -0.0893246 0.001 -0.00445745 -0.0448329 0.001 -0.0200278 0.133137 0.001 -0.00445745 0.0448329 0.001 -0.0103149 0.0893246 0.001 -0.0151981 0.134431 0.001 0.0025 -1.27216e-16 0.001 0.000523526 0.0452687 0.001 -0.00539085 0.0901929 0.001 -0.00539085 -0.0901929 0.001 0.000523526 -0.0452687 0.001 -0.0200278 -0.133137 0 -0.0200278 -0.133137 0.001 -0.0025 -1.25992e-16 0.001 -0.0103149 -0.0893246 0.001 -0.00445745 -0.0448329 0.001 -0.0025 -1.25992e-16 0 -0.0103149 -0.0893246 0 -0.00445745 -0.0448329 0 -0.0025 -1.25992e-16 0 -0.0025 -1.25992e-16 0.001 -0.0200278 0.133137 0.001 -0.00445745 0.0448329 0.001 -0.0103149 0.0893246 0.001 -0.0200278 0.133137 0 -0.00445745 0.0448329 0 -0.0103149 0.0893246 0 -0.0200278 0.133137 0 -0.0151981 0.134431 0 -0.0151981 0.134431 0.001 -0.0200278 0.133137 0.001 0.0025 -1.27216e-16 0 0.0025 -1.27216e-16 0.001 -0.0151981 0.134431 0.001 0.000523526 0.0452687 0.001 -0.00539085 0.0901929 0.001 -0.0151981 0.134431 0 0.000523526 0.0452687 0 -0.00539085 0.0901929 0 + + + 2 0 3 1 0 2 7 4 5 16 7 5 17 8 7 17 7 16 6 8 17 13 6 17 10 6 13 14 10 13 15 11 10 15 10 14 12 9 11 12 11 15 21 19 18 21 18 24 22 24 25 22 21 24 20 25 23 20 22 25 29 26 27 38 29 27 39 30 29 39 29 38 28 30 39 35 28 39 32 28 35 36 32 35 37 33 32 37 32 36 34 31 33 34 33 37 43 41 40 43 40 46 44 46 47 44 43 46 42 47 45 42 44 47 51 49 48 51 48 54 52 54 55 52 51 54 50 55 53 50 52 55 58 56 59 57 56 58 63 61 60 63 60 66 64 66 67 64 63 66 62 67 65 62 64 67 + 3 6 9 12 15 18 21 24 27 30 33 36 39 42 45 48 51 54 57 60 63 66 69 72 75 78 81 84 87 90 93 96 99 102 105 108 111 114 117 120 123 126 129 132 135 138 141 144 147 150 153 156 + + + + + -0.0135503 -0.083935 0 -0.00872063 -0.0852291 0 -0.00872063 -0.0852291 0.001 -0.0135503 -0.083935 0.001 -0.0135503 -0.083935 0 -0.00872063 -0.0852291 0 -0.0025 -7.94306e-17 0 -0.00742685 -0.0563141 0 -0.00373406 -0.0282646 0 -0.0135503 0.083935 0 -0.00373406 0.0282646 0 -0.00742685 0.0563141 0 -0.00872063 0.0852291 0 0.0025 -8.06552e-17 0 0.00124691 0.0287004 0 -0.00250281 0.0571823 0 -0.00250281 -0.0571823 0 0.00124691 -0.0287004 0 -0.00872063 -0.0852291 0 -0.00872063 -0.0852291 0.001 0.0025 -8.06552e-17 0.001 -0.00250281 -0.0571823 0.001 0.00124691 -0.0287004 0.001 0.0025 -8.06552e-17 0 -0.00250281 -0.0571823 0 0.00124691 -0.0287004 0 -0.0135503 -0.083935 0.001 -0.00872063 -0.0852291 0.001 -0.0025 -7.94306e-17 0.001 -0.00742685 -0.0563141 0.001 -0.00373406 -0.0282646 0.001 -0.0135503 0.083935 0.001 -0.00373406 0.0282646 0.001 -0.00742685 0.0563141 0.001 -0.00872063 0.0852291 0.001 0.0025 -8.06552e-17 0.001 0.00124691 0.0287004 0.001 -0.00250281 0.0571823 0.001 -0.00250281 -0.0571823 0.001 0.00124691 -0.0287004 0.001 -0.0135503 -0.083935 0 -0.0135503 -0.083935 0.001 -0.0025 -7.94306e-17 0.001 -0.00742685 -0.0563141 0.001 -0.00373406 -0.0282646 0.001 -0.0025 -7.94306e-17 0 -0.00742685 -0.0563141 0 -0.00373406 -0.0282646 0 -0.0025 -7.94306e-17 0 -0.0025 -7.94306e-17 0.001 -0.0135503 0.083935 0.001 -0.00373406 0.0282646 0.001 -0.00742685 0.0563141 0.001 -0.0135503 0.083935 0 -0.00373406 0.0282646 0 -0.00742685 0.0563141 0 -0.0135503 0.083935 0 -0.00872063 0.0852291 0 -0.00872063 0.0852291 0.001 -0.0135503 0.083935 0.001 0.0025 -8.06552e-17 0 0.0025 -8.06552e-17 0.001 -0.00872063 0.0852291 0.001 0.00124691 0.0287004 0.001 -0.00250281 0.0571823 0.001 -0.00872063 0.0852291 0 0.00124691 0.0287004 0 -0.00250281 0.0571823 0 + + + 2 0 3 1 0 2 16 4 5 16 7 4 17 8 7 17 7 16 6 8 17 13 6 17 10 6 13 14 10 13 15 11 10 15 10 14 12 9 11 12 11 15 21 19 18 21 18 24 22 24 25 22 21 24 20 25 23 20 22 25 38 26 27 38 29 26 39 30 29 39 29 38 28 30 39 35 28 39 32 28 35 36 32 35 37 33 32 37 32 36 34 31 33 34 33 37 43 41 40 43 40 46 44 46 47 44 43 46 42 47 45 42 44 47 51 49 48 51 48 54 52 54 55 52 51 54 50 55 53 50 52 55 58 56 59 57 56 58 63 61 60 63 60 66 64 66 67 64 63 66 62 67 65 62 64 67 + 3 6 9 12 15 18 21 24 27 30 33 36 39 42 45 48 51 54 57 60 63 66 69 72 75 78 81 84 87 90 93 96 99 102 105 108 111 114 117 120 123 126 129 132 135 138 141 144 147 150 153 156 + + + + + -0.0136797 -0.0849185 0 -0.00885011 -0.0862126 0 -0.00885011 -0.0862126 0.001 -0.0136797 -0.0849185 0.001 -0.0136797 -0.0849185 0 -0.00885011 -0.0862126 0 -0.0025 -8.03613e-17 0 -0.00748458 -0.056974 0 -0.00374852 -0.0285958 0 -0.0136797 0.0849185 0 -0.00374852 0.0285958 0 -0.00748458 0.056974 0 -0.00885011 0.0862126 0 0.0025 -8.1586e-17 0 0.00123245 0.0290316 0 -0.00256054 0.0578422 0 -0.00256054 -0.0578422 0 0.00123245 -0.0290316 0 -0.00885011 -0.0862126 0 -0.00885011 -0.0862126 0.001 0.0025 -8.1586e-17 0.001 -0.00256054 -0.0578422 0.001 0.00123245 -0.0290316 0.001 0.0025 -8.1586e-17 0 -0.00256054 -0.0578422 0 0.00123245 -0.0290316 0 -0.0136797 -0.0849185 0.001 -0.00885011 -0.0862126 0.001 -0.0025 -8.03613e-17 0.001 -0.00748458 -0.056974 0.001 -0.00374852 -0.0285958 0.001 -0.0136797 0.0849185 0.001 -0.00374852 0.0285958 0.001 -0.00748458 0.056974 0.001 -0.00885011 0.0862126 0.001 0.0025 -8.1586e-17 0.001 0.00123245 0.0290316 0.001 -0.00256054 0.0578422 0.001 -0.00256054 -0.0578422 0.001 0.00123245 -0.0290316 0.001 -0.0136797 -0.0849185 0 -0.0136797 -0.0849185 0.001 -0.0025 -8.03613e-17 0.001 -0.00748458 -0.056974 0.001 -0.00374852 -0.0285958 0.001 -0.0025 -8.03613e-17 0 -0.00748458 -0.056974 0 -0.00374852 -0.0285958 0 -0.0025 -8.03613e-17 0 -0.0025 -8.03613e-17 0.001 -0.0136797 0.0849185 0.001 -0.00374852 0.0285958 0.001 -0.00748458 0.056974 0.001 -0.0136797 0.0849185 0 -0.00374852 0.0285958 0 -0.00748458 0.056974 0 -0.0136797 0.0849185 0 -0.00885011 0.0862126 0 -0.00885011 0.0862126 0.001 -0.0136797 0.0849185 0.001 0.0025 -8.1586e-17 0 0.0025 -8.1586e-17 0.001 -0.00885011 0.0862126 0.001 0.00123245 0.0290316 0.001 -0.00256054 0.0578422 0.001 -0.00885011 0.0862126 0 0.00123245 0.0290316 0 -0.00256054 0.0578422 0 + + + 2 0 3 1 0 2 16 4 5 16 7 4 17 8 7 17 7 16 6 8 17 13 6 17 10 6 13 14 10 13 11 10 14 15 11 14 12 9 11 12 11 15 21 19 18 21 18 24 22 24 25 22 21 24 20 25 23 20 22 25 38 26 27 38 29 26 39 30 29 39 29 38 28 30 39 35 28 39 32 28 35 36 32 35 33 32 36 37 33 36 34 31 33 34 33 37 43 41 40 43 40 46 44 46 47 44 43 46 42 47 45 42 44 47 51 49 48 51 48 54 52 54 55 52 51 54 50 55 53 50 52 55 58 56 59 57 56 58 63 61 60 63 60 66 64 66 67 64 63 66 62 67 65 62 64 67 + 3 6 9 12 15 18 21 24 27 30 33 36 39 42 45 48 51 54 57 60 63 66 69 72 75 78 81 84 87 90 93 96 99 102 105 108 111 114 117 120 123 126 129 132 135 138 141 144 147 150 153 156 + + + + + -0.0138876 -0.0864973 0 -0.00905796 -0.0877914 0 -0.00905796 -0.0877914 0.001 -0.0138876 -0.0864973 0.001 -0.0138876 -0.0864973 0 -0.00905796 -0.0877914 0 -0.0025 -8.18554e-17 0 -0.00757725 -0.0580332 0 -0.00377173 -0.0291274 0 -0.0138876 0.0864973 0 -0.00377173 0.0291274 0 -0.00757725 0.0580332 0 -0.00905796 0.0877914 0 0.0025 -8.308e-17 0 0.00120924 0.0295632 0 -0.00265321 0.0589015 0 -0.00265321 -0.0589015 0 0.00120924 -0.0295632 0 -0.00905796 -0.0877914 0 -0.00905796 -0.0877914 0.001 0.0025 -8.308e-17 0.001 -0.00265321 -0.0589015 0.001 0.00120924 -0.0295632 0.001 0.0025 -8.308e-17 0 -0.00265321 -0.0589015 0 0.00120924 -0.0295632 0 -0.0138876 -0.0864973 0.001 -0.00905796 -0.0877914 0.001 -0.0025 -8.18554e-17 0.001 -0.00757725 -0.0580332 0.001 -0.00377173 -0.0291274 0.001 -0.0138876 0.0864973 0.001 -0.00377173 0.0291274 0.001 -0.00757725 0.0580332 0.001 -0.00905796 0.0877914 0.001 0.0025 -8.308e-17 0.001 0.00120924 0.0295632 0.001 -0.00265321 0.0589015 0.001 -0.00265321 -0.0589015 0.001 0.00120924 -0.0295632 0.001 -0.0138876 -0.0864973 0 -0.0138876 -0.0864973 0.001 -0.0025 -8.18554e-17 0.001 -0.00757725 -0.0580332 0.001 -0.00377173 -0.0291274 0.001 -0.0025 -8.18554e-17 0 -0.00757725 -0.0580332 0 -0.00377173 -0.0291274 0 -0.0025 -8.18554e-17 0 -0.0025 -8.18554e-17 0.001 -0.0138876 0.0864973 0.001 -0.00377173 0.0291274 0.001 -0.00757725 0.0580332 0.001 -0.0138876 0.0864973 0 -0.00377173 0.0291274 0 -0.00757725 0.0580332 0 -0.0138876 0.0864973 0 -0.00905796 0.0877914 0 -0.00905796 0.0877914 0.001 -0.0138876 0.0864973 0.001 0.0025 -8.308e-17 0 0.0025 -8.308e-17 0.001 -0.00905796 0.0877914 0.001 0.00120924 0.0295632 0.001 -0.00265321 0.0589015 0.001 -0.00905796 0.0877914 0 0.00120924 0.0295632 0 -0.00265321 0.0589015 0 + + + 2 0 3 1 0 2 16 4 5 16 7 4 17 8 7 17 7 16 6 8 17 13 6 17 10 6 13 14 10 13 15 11 10 15 10 14 12 9 11 12 11 15 21 19 18 21 18 24 22 24 25 22 21 24 20 25 23 20 22 25 38 26 27 38 29 26 39 30 29 39 29 38 28 30 39 35 28 39 32 28 35 36 32 35 37 33 32 37 32 36 34 31 33 34 33 37 43 41 40 43 40 46 44 46 47 44 43 46 42 47 45 42 44 47 51 49 48 51 48 54 52 54 55 52 51 54 50 55 53 50 52 55 58 56 59 57 56 58 63 61 60 63 60 66 64 66 67 64 63 66 62 67 65 62 64 67 + 3 6 9 12 15 18 21 24 27 30 33 36 39 42 45 48 51 54 57 60 63 66 69 72 75 78 81 84 87 90 93 96 99 102 105 108 111 114 117 120 123 126 129 132 135 138 141 144 147 150 153 156 + + + + + -0.0140171 -0.0874808 0 -0.00918744 -0.0887749 0 -0.00918744 -0.0887749 0.001 -0.0140171 -0.0874808 0.001 -0.0140171 -0.0874808 0 -0.00918744 -0.0887749 0 -0.0025 -8.27861e-17 0 -0.00763498 -0.0586931 0 -0.00378619 -0.0294586 0 -0.0140171 0.0874808 0 -0.00378619 0.0294586 0 -0.00763498 0.0586931 0 -0.00918744 0.0887749 0 0.0025 -8.40108e-17 0 0.00119478 0.0298944 0 -0.00271094 0.0595613 0 -0.00271094 -0.0595613 0 0.00119478 -0.0298944 0 -0.00918744 -0.0887749 0 -0.00918744 -0.0887749 0.001 0.0025 -8.40108e-17 0.001 -0.00271094 -0.0595613 0.001 0.00119478 -0.0298944 0.001 0.0025 -8.40108e-17 0 -0.00271094 -0.0595613 0 0.00119478 -0.0298944 0 -0.0140171 -0.0874808 0.001 -0.00918744 -0.0887749 0.001 -0.0025 -8.27861e-17 0.001 -0.00763498 -0.0586931 0.001 -0.00378619 -0.0294586 0.001 -0.0140171 0.0874808 0.001 -0.00378619 0.0294586 0.001 -0.00763498 0.0586931 0.001 -0.00918744 0.0887749 0.001 0.0025 -8.40108e-17 0.001 0.00119478 0.0298944 0.001 -0.00271094 0.0595613 0.001 -0.00271094 -0.0595613 0.001 0.00119478 -0.0298944 0.001 -0.0140171 -0.0874808 0 -0.0140171 -0.0874808 0.001 -0.0025 -8.27861e-17 0.001 -0.00763498 -0.0586931 0.001 -0.00378619 -0.0294586 0.001 -0.0025 -8.27861e-17 0 -0.00763498 -0.0586931 0 -0.00378619 -0.0294586 0 -0.0025 -8.27861e-17 0 -0.0025 -8.27861e-17 0.001 -0.0140171 0.0874808 0.001 -0.00378619 0.0294586 0.001 -0.00763498 0.0586931 0.001 -0.0140171 0.0874808 0 -0.00378619 0.0294586 0 -0.00763498 0.0586931 0 -0.0140171 0.0874808 0 -0.00918744 0.0887749 0 -0.00918744 0.0887749 0.001 -0.0140171 0.0874808 0.001 0.0025 -8.40108e-17 0 0.0025 -8.40108e-17 0.001 -0.00918744 0.0887749 0.001 0.00119478 0.0298944 0.001 -0.00271094 0.0595613 0.001 -0.00918744 0.0887749 0 0.00119478 0.0298944 0 -0.00271094 0.0595613 0 + + + 1 3 2 1 0 3 16 4 5 16 7 4 17 8 7 17 7 16 6 8 17 13 6 17 10 6 13 14 10 13 15 11 10 15 10 14 12 9 11 12 11 15 21 19 18 21 18 24 22 24 25 22 21 24 20 25 23 20 22 25 38 26 27 38 29 26 39 30 29 39 29 38 28 30 39 35 28 39 32 28 35 36 32 35 37 33 32 37 32 36 34 31 33 34 33 37 43 41 40 43 40 46 44 46 47 44 43 46 42 47 45 42 44 47 51 49 48 51 48 54 52 54 55 52 51 54 50 55 53 50 52 55 58 56 59 57 56 58 63 61 60 63 60 66 64 66 67 64 63 66 62 67 65 62 64 67 + 3 6 9 12 15 18 21 24 27 30 33 36 39 42 45 48 51 54 57 60 63 66 69 72 75 78 81 84 87 90 93 96 99 102 105 108 111 114 117 120 123 126 129 132 135 138 141 144 147 150 153 156 + + + + + -0.0142249 -0.0890596 0 -0.00939529 -0.0903537 0 -0.00939529 -0.0903537 0.001 -0.0142249 -0.0890596 0.001 -0.0142249 -0.0890596 0 -0.00939529 -0.0903537 0 -0.0025 -8.42802e-17 0 -0.00772765 -0.0597523 0 -0.0038094 -0.0299903 0 -0.0142249 0.0890596 0 -0.0038094 0.0299903 0 -0.00772765 0.0597523 0 -0.00939529 0.0903537 0 0.0025 -8.55048e-17 0 0.00117157 0.0304261 0 -0.00280361 0.0606206 0 -0.00280361 -0.0606206 0 0.00117157 -0.0304261 0 -0.00939529 -0.0903537 0 -0.00939529 -0.0903537 0.001 0.0025 -8.55048e-17 0.001 -0.00280361 -0.0606206 0.001 0.00117157 -0.0304261 0.001 0.0025 -8.55048e-17 0 -0.00280361 -0.0606206 0 0.00117157 -0.0304261 0 -0.0142249 -0.0890596 0.001 -0.00939529 -0.0903537 0.001 -0.0025 -8.42802e-17 0.001 -0.00772765 -0.0597523 0.001 -0.0038094 -0.0299903 0.001 -0.0142249 0.0890596 0.001 -0.0038094 0.0299903 0.001 -0.00772765 0.0597523 0.001 -0.00939529 0.0903537 0.001 0.0025 -8.55048e-17 0.001 0.00117157 0.0304261 0.001 -0.00280361 0.0606206 0.001 -0.00280361 -0.0606206 0.001 0.00117157 -0.0304261 0.001 -0.0142249 -0.0890596 0 -0.0142249 -0.0890596 0.001 -0.0025 -8.42802e-17 0.001 -0.00772765 -0.0597523 0.001 -0.0038094 -0.0299903 0.001 -0.0025 -8.42802e-17 0 -0.00772765 -0.0597523 0 -0.0038094 -0.0299903 0 -0.0025 -8.42802e-17 0 -0.0025 -8.42802e-17 0.001 -0.0142249 0.0890596 0.001 -0.0038094 0.0299903 0.001 -0.00772765 0.0597523 0.001 -0.0142249 0.0890596 0 -0.0038094 0.0299903 0 -0.00772765 0.0597523 0 -0.0142249 0.0890596 0 -0.00939529 0.0903537 0 -0.00939529 0.0903537 0.001 -0.0142249 0.0890596 0.001 0.0025 -8.55048e-17 0 0.0025 -8.55048e-17 0.001 -0.00939529 0.0903537 0.001 0.00117157 0.0304261 0.001 -0.00280361 0.0606206 0.001 -0.00939529 0.0903537 0 0.00117157 0.0304261 0 -0.00280361 0.0606206 0 + + + 1 3 2 1 0 3 16 4 5 16 7 4 17 8 7 17 7 16 6 8 17 13 6 17 10 6 13 14 10 13 15 11 10 15 10 14 12 9 11 12 11 15 21 19 18 21 18 24 22 24 25 22 21 24 20 25 23 20 22 25 38 26 27 38 29 26 39 30 29 39 29 38 28 30 39 35 28 39 32 28 35 36 32 35 37 33 32 37 32 36 34 31 33 34 33 37 43 41 40 43 40 46 44 46 47 44 43 46 42 47 45 42 44 47 51 49 48 51 48 54 52 54 55 52 51 54 50 55 53 50 52 55 58 56 59 57 56 58 63 61 60 63 60 66 64 66 67 64 63 66 62 67 65 62 64 67 + 3 6 9 12 15 18 21 24 27 30 33 36 39 42 45 48 51 54 57 60 63 66 69 72 75 78 81 84 87 90 93 96 99 102 105 108 111 114 117 120 123 126 129 132 135 138 141 144 147 150 153 156 + + + + + -0.00689528 -0.0390311 0 -0.00202051 -0.0401431 0 -0.00202051 -0.0401431 0.01 -0.00689528 -0.0390311 0.01 -0.00689528 -0.0390311 0 -0.00202051 -0.0401431 0 -0.0025 -4.29851e-17 0 -0.00445802 -0.0261425 0 -0.00299019 -0.0131079 0 -0.00689528 0.0390311 0 -0.00299019 0.0131079 0 -0.00445802 0.0261425 0 -0.00202051 0.0401431 0 0.0025 -4.42097e-17 0 0.00199585 0.0134813 0 0.000486199 0.0268873 0 0.000486199 -0.0268873 0 0.00199585 -0.0134813 0 -0.00202051 -0.0401431 0 -0.00202051 -0.0401431 0.01 0.0025 -4.42097e-17 0.01 0.000486199 -0.0268873 0.01 0.00199585 -0.0134813 0.01 0.0025 -4.42097e-17 0 0.000486199 -0.0268873 0 0.00199585 -0.0134813 0 -0.00689528 -0.0390311 0.01 -0.00202051 -0.0401431 0.01 -0.0025 -4.29851e-17 0.01 -0.00445802 -0.0261425 0.01 -0.00299019 -0.0131079 0.01 -0.00689528 0.0390311 0.01 -0.00299019 0.0131079 0.01 -0.00445802 0.0261425 0.01 -0.00202051 0.0401431 0.01 0.0025 -4.42097e-17 0.01 0.00199585 0.0134813 0.01 0.000486199 0.0268873 0.01 0.000486199 -0.0268873 0.01 0.00199585 -0.0134813 0.01 -0.00689528 -0.0390311 0 -0.00689528 -0.0390311 0.01 -0.0025 -4.29851e-17 0.01 -0.00445802 -0.0261425 0.01 -0.00299019 -0.0131079 0.01 -0.0025 -4.29851e-17 0 -0.00445802 -0.0261425 0 -0.00299019 -0.0131079 0 -0.0025 -4.29851e-17 0 -0.0025 -4.29851e-17 0.01 -0.00689528 0.0390311 0.01 -0.00299019 0.0131079 0.01 -0.00445802 0.0261425 0.01 -0.00689528 0.0390311 0 -0.00299019 0.0131079 0 -0.00445802 0.0261425 0 -0.00689528 0.0390311 0 -0.00202051 0.0401431 0 -0.00202051 0.0401431 0.01 -0.00689528 0.0390311 0.01 0.0025 -4.42097e-17 0 0.0025 -4.42097e-17 0.01 -0.00202051 0.0401431 0.01 0.00199585 0.0134813 0.01 0.000486199 0.0268873 0.01 -0.00202051 0.0401431 0 0.00199585 0.0134813 0 0.000486199 0.0268873 0 + + + 1 3 2 1 0 3 16 4 5 16 7 4 17 8 7 17 7 16 13 6 8 13 8 17 14 10 6 14 6 13 15 11 10 15 10 14 12 9 11 12 11 15 21 19 18 21 18 24 22 24 25 22 21 24 20 25 23 20 22 25 38 26 27 38 29 26 39 30 29 39 29 38 35 28 30 35 30 39 36 32 28 36 28 35 37 33 32 37 32 36 34 31 33 34 33 37 43 41 40 43 40 46 44 46 47 44 43 46 42 47 45 42 44 47 51 49 48 51 48 54 52 54 55 52 51 54 50 55 53 50 52 55 56 59 58 57 56 58 63 61 60 63 60 66 64 66 67 64 63 66 62 67 65 62 64 67 + 3 6 9 12 15 18 21 24 27 30 33 36 39 42 45 48 51 54 57 60 63 66 69 72 75 78 81 84 87 90 93 96 99 102 105 108 111 114 117 120 123 126 129 132 135 138 141 144 147 150 153 156 + + + + + -0.00697292 -0.0397205 0 -0.00209814 -0.0408325 0 -0.00209814 -0.0408325 0.01 -0.00697292 -0.0397205 0.01 -0.00697292 -0.0397205 0 -0.00209814 -0.0408325 0 -0.0025 -4.37444e-17 0 -0.0044926 -0.0266043 0 -0.00299885 -0.0133394 0 -0.00697292 0.0397205 0 -0.00299885 0.0133394 0 -0.0044926 0.0266043 0 -0.00209814 0.0408325 0 0.0025 -4.4969e-17 0 0.00198719 0.0137128 0 0.000451613 0.0273491 0 0.000451613 -0.0273491 0 0.00198719 -0.0137128 0 -0.00209814 -0.0408325 0 -0.00209814 -0.0408325 0.01 0.0025 -4.4969e-17 0.01 0.000451613 -0.0273491 0.01 0.00198719 -0.0137128 0.01 0.0025 -4.4969e-17 0 0.000451613 -0.0273491 0 0.00198719 -0.0137128 0 -0.00697292 -0.0397205 0.01 -0.00209814 -0.0408325 0.01 -0.0025 -4.37444e-17 0.01 -0.0044926 -0.0266043 0.01 -0.00299885 -0.0133394 0.01 -0.00697292 0.0397205 0.01 -0.00299885 0.0133394 0.01 -0.0044926 0.0266043 0.01 -0.00209814 0.0408325 0.01 0.0025 -4.4969e-17 0.01 0.00198719 0.0137128 0.01 0.000451613 0.0273491 0.01 0.000451613 -0.0273491 0.01 0.00198719 -0.0137128 0.01 -0.00697292 -0.0397205 0 -0.00697292 -0.0397205 0.01 -0.0025 -4.37444e-17 0.01 -0.0044926 -0.0266043 0.01 -0.00299885 -0.0133394 0.01 -0.0025 -4.37444e-17 0 -0.0044926 -0.0266043 0 -0.00299885 -0.0133394 0 -0.0025 -4.37444e-17 0 -0.0025 -4.37444e-17 0.01 -0.00697292 0.0397205 0.01 -0.00299885 0.0133394 0.01 -0.0044926 0.0266043 0.01 -0.00697292 0.0397205 0 -0.00299885 0.0133394 0 -0.0044926 0.0266043 0 -0.00697292 0.0397205 0 -0.00209814 0.0408325 0 -0.00209814 0.0408325 0.01 -0.00697292 0.0397205 0.01 0.0025 -4.4969e-17 0 0.0025 -4.4969e-17 0.01 -0.00209814 0.0408325 0.01 0.00198719 0.0137128 0.01 0.000451613 0.0273491 0.01 -0.00209814 0.0408325 0 0.00198719 0.0137128 0 0.000451613 0.0273491 0 + + + 1 3 2 1 0 3 16 4 5 16 7 4 17 8 7 17 7 16 13 6 8 13 8 17 14 10 6 14 6 13 15 11 10 15 10 14 12 9 11 12 11 15 21 19 18 21 18 24 22 24 25 22 21 24 20 25 23 20 22 25 38 26 27 38 29 26 39 30 29 39 29 38 35 28 30 35 30 39 36 32 28 36 28 35 37 33 32 37 32 36 34 31 33 34 33 37 43 41 40 43 40 46 44 46 47 44 43 46 42 47 45 42 44 47 51 49 48 51 48 54 52 54 55 52 51 54 50 55 53 50 52 55 56 59 58 57 56 58 63 61 60 63 60 66 64 66 67 64 63 66 62 67 65 62 64 67 + 3 6 9 12 15 18 21 24 27 30 33 36 39 42 45 48 51 54 57 60 63 66 69 72 75 78 81 84 87 90 93 96 99 102 105 108 111 114 117 120 123 126 129 132 135 138 141 144 147 150 153 156 + + + + + -0.00811745 -0.0498842 0 -0.00324267 -0.0509962 0 -0.00324267 -0.0509962 0.01 -0.00811745 -0.0498842 0.01 -0.00811745 -0.0498842 0 -0.00324267 -0.0509962 0 -0.0025 -5.49377e-17 0 -0.00500247 -0.0334117 0 -0.00312649 -0.0167527 0 -0.00811745 0.0498842 0 -0.00312649 0.0167527 0 -0.00500247 0.0334117 0 -0.00324267 0.0509962 0 0.0025 -5.61623e-17 0 0.00185954 0.0171261 0 -5.8252e-05 0.0341565 0 -5.8252e-05 -0.0341565 0 0.00185954 -0.0171261 0 -0.00324267 -0.0509962 0 -0.00324267 -0.0509962 0.01 0.0025 -5.61623e-17 0.01 -5.8252e-05 -0.0341565 0.01 0.00185954 -0.0171261 0.01 0.0025 -5.61623e-17 0 -5.8252e-05 -0.0341565 0 0.00185954 -0.0171261 0 -0.00811745 -0.0498842 0.01 -0.00324267 -0.0509962 0.01 -0.0025 -5.49377e-17 0.01 -0.00500247 -0.0334117 0.01 -0.00312649 -0.0167527 0.01 -0.00811745 0.0498842 0.01 -0.00312649 0.0167527 0.01 -0.00500247 0.0334117 0.01 -0.00324267 0.0509962 0.01 0.0025 -5.61623e-17 0.01 0.00185954 0.0171261 0.01 -5.8252e-05 0.0341565 0.01 -5.8252e-05 -0.0341565 0.01 0.00185954 -0.0171261 0.01 -0.00811745 -0.0498842 0 -0.00811745 -0.0498842 0.01 -0.0025 -5.49377e-17 0.01 -0.00500247 -0.0334117 0.01 -0.00312649 -0.0167527 0.01 -0.0025 -5.49377e-17 0 -0.00500247 -0.0334117 0 -0.00312649 -0.0167527 0 -0.0025 -5.49377e-17 0 -0.0025 -5.49377e-17 0.01 -0.00811745 0.0498842 0.01 -0.00312649 0.0167527 0.01 -0.00500247 0.0334117 0.01 -0.00811745 0.0498842 0 -0.00312649 0.0167527 0 -0.00500247 0.0334117 0 -0.00811745 0.0498842 0 -0.00324267 0.0509962 0 -0.00324267 0.0509962 0.01 -0.00811745 0.0498842 0.01 0.0025 -5.61623e-17 0 0.0025 -5.61623e-17 0.01 -0.00324267 0.0509962 0.01 0.00185954 0.0171261 0.01 -5.8252e-05 0.0341565 0.01 -0.00324267 0.0509962 0 0.00185954 0.0171261 0 -5.8252e-05 0.0341565 0 + + + 1 3 2 1 0 3 16 4 5 16 7 4 17 8 7 17 7 16 13 6 8 13 8 17 10 6 13 14 10 13 15 11 10 15 10 14 12 9 11 12 11 15 21 19 18 21 18 24 22 24 25 22 21 24 20 25 23 20 22 25 38 26 27 38 29 26 39 30 29 39 29 38 35 28 30 35 30 39 32 28 35 36 32 35 37 33 32 37 32 36 34 31 33 34 33 37 43 41 40 43 40 46 44 46 47 44 43 46 42 47 45 42 44 47 51 49 48 51 48 54 52 54 55 52 51 54 50 55 53 50 52 55 56 59 58 57 56 58 63 61 60 63 60 66 64 66 67 64 63 66 62 67 65 62 64 67 + 3 6 9 12 15 18 21 24 27 30 33 36 39 42 45 48 51 54 57 60 63 66 69 72 75 78 81 84 87 90 93 96 99 102 105 108 111 114 117 120 123 126 129 132 135 138 141 144 147 150 153 156 + + + + + -0.00819759 -0.0505959 0 -0.00332281 -0.0517079 0 -0.00332281 -0.0517079 0.01 -0.00819759 -0.0505959 0.01 -0.00819759 -0.0505959 0 -0.00332281 -0.0517079 0 -0.0025 -5.57214e-17 0 -0.00503817 -0.0338884 0 -0.00313543 -0.0169917 0 -0.00819759 0.0505959 0 -0.00313543 0.0169917 0 -0.00503817 0.0338884 0 -0.00332281 0.0517079 0 0.0025 -5.69461e-17 0 0.0018506 0.0173651 0 -9.39537e-05 0.0346332 0 -9.39537e-05 -0.0346332 0 0.0018506 -0.0173651 0 -0.00332281 -0.0517079 0 -0.00332281 -0.0517079 0.01 0.0025 -5.69461e-17 0.01 -9.39537e-05 -0.0346332 0.01 0.0018506 -0.0173651 0.01 0.0025 -5.69461e-17 0 -9.39537e-05 -0.0346332 0 0.0018506 -0.0173651 0 -0.00819759 -0.0505959 0.01 -0.00332281 -0.0517079 0.01 -0.0025 -5.57214e-17 0.01 -0.00503817 -0.0338884 0.01 -0.00313543 -0.0169917 0.01 -0.00819759 0.0505959 0.01 -0.00313543 0.0169917 0.01 -0.00503817 0.0338884 0.01 -0.00332281 0.0517079 0.01 0.0025 -5.69461e-17 0.01 0.0018506 0.0173651 0.01 -9.39537e-05 0.0346332 0.01 -9.39537e-05 -0.0346332 0.01 0.0018506 -0.0173651 0.01 -0.00819759 -0.0505959 0 -0.00819759 -0.0505959 0.01 -0.0025 -5.57214e-17 0.01 -0.00503817 -0.0338884 0.01 -0.00313543 -0.0169917 0.01 -0.0025 -5.57214e-17 0 -0.00503817 -0.0338884 0 -0.00313543 -0.0169917 0 -0.0025 -5.57214e-17 0 -0.0025 -5.57214e-17 0.01 -0.00819759 0.0505959 0.01 -0.00313543 0.0169917 0.01 -0.00503817 0.0338884 0.01 -0.00819759 0.0505959 0 -0.00313543 0.0169917 0 -0.00503817 0.0338884 0 -0.00819759 0.0505959 0 -0.00332281 0.0517079 0 -0.00332281 0.0517079 0.01 -0.00819759 0.0505959 0.01 0.0025 -5.69461e-17 0 0.0025 -5.69461e-17 0.01 -0.00332281 0.0517079 0.01 0.0018506 0.0173651 0.01 -9.39537e-05 0.0346332 0.01 -0.00332281 0.0517079 0 0.0018506 0.0173651 0 -9.39537e-05 0.0346332 0 + + + 1 3 2 1 0 3 7 4 5 16 7 5 8 7 16 17 8 16 6 8 17 13 6 17 10 6 13 14 10 13 15 11 10 15 10 14 12 9 11 12 11 15 21 19 18 21 18 24 22 24 25 22 21 24 20 25 23 20 22 25 38 26 27 38 29 26 39 30 29 39 29 38 28 30 39 35 28 39 32 28 35 36 32 35 37 33 32 37 32 36 34 31 33 34 33 37 43 41 40 43 40 46 44 46 47 44 43 46 42 47 45 42 44 47 51 49 48 51 48 54 52 54 55 52 51 54 50 55 53 50 52 55 56 59 58 57 56 58 63 61 60 63 60 66 64 66 67 64 63 66 62 67 65 62 64 67 + 3 6 9 12 15 18 21 24 27 30 33 36 39 42 45 48 51 54 57 60 63 66 69 72 75 78 81 84 87 90 93 96 99 102 105 108 111 114 117 120 123 126 129 132 135 138 141 144 147 150 153 156 + + + + + -0.00836038 -0.0520415 0 -0.0034856 -0.0531535 0 -0.0034856 -0.0531535 0.01 -0.00836038 -0.0520415 0.01 -0.00836038 -0.0520415 0 -0.0034856 -0.0531535 0 -0.0025 -5.73135e-17 0 -0.00511069 -0.0348567 0 -0.00315358 -0.0174771 0 -0.00836038 0.0520415 0 -0.00315358 0.0174771 0 -0.00511069 0.0348567 0 -0.0034856 0.0531535 0 0.0025 -5.85381e-17 0 0.00183245 0.0178506 0 -0.000166473 0.0356015 0 -0.000166473 -0.0356015 0 0.00183245 -0.0178506 0 -0.0034856 -0.0531535 0 -0.0034856 -0.0531535 0.01 0.0025 -5.85381e-17 0.01 -0.000166473 -0.0356015 0.01 0.00183245 -0.0178506 0.01 0.0025 -5.85381e-17 0 -0.000166473 -0.0356015 0 0.00183245 -0.0178506 0 -0.00836038 -0.0520415 0.01 -0.0034856 -0.0531535 0.01 -0.0025 -5.73135e-17 0.01 -0.00511069 -0.0348567 0.01 -0.00315358 -0.0174771 0.01 -0.00836038 0.0520415 0.01 -0.00315358 0.0174771 0.01 -0.00511069 0.0348567 0.01 -0.0034856 0.0531535 0.01 0.0025 -5.85381e-17 0.01 0.00183245 0.0178506 0.01 -0.000166473 0.0356015 0.01 -0.000166473 -0.0356015 0.01 0.00183245 -0.0178506 0.01 -0.00836038 -0.0520415 0 -0.00836038 -0.0520415 0.01 -0.0025 -5.73135e-17 0.01 -0.00511069 -0.0348567 0.01 -0.00315358 -0.0174771 0.01 -0.0025 -5.73135e-17 0 -0.00511069 -0.0348567 0 -0.00315358 -0.0174771 0 -0.0025 -5.73135e-17 0 -0.0025 -5.73135e-17 0.01 -0.00836038 0.0520415 0.01 -0.00315358 0.0174771 0.01 -0.00511069 0.0348567 0.01 -0.00836038 0.0520415 0 -0.00315358 0.0174771 0 -0.00511069 0.0348567 0 -0.00836038 0.0520415 0 -0.0034856 0.0531535 0 -0.0034856 0.0531535 0.01 -0.00836038 0.0520415 0.01 0.0025 -5.85381e-17 0 0.0025 -5.85381e-17 0.01 -0.0034856 0.0531535 0.01 0.00183245 0.0178506 0.01 -0.000166473 0.0356015 0.01 -0.0034856 0.0531535 0 0.00183245 0.0178506 0 -0.000166473 0.0356015 0 + + + 0 3 2 1 0 2 16 4 5 16 7 4 17 8 7 17 7 16 13 6 8 13 8 17 10 6 13 14 10 13 15 11 10 15 10 14 12 9 11 12 11 15 21 19 18 21 18 24 22 24 25 22 21 24 20 25 23 20 22 25 38 26 27 38 29 26 39 30 29 39 29 38 35 28 30 35 30 39 32 28 35 36 32 35 37 33 32 37 32 36 34 31 33 34 33 37 43 41 40 43 40 46 44 46 47 44 43 46 42 47 45 42 44 47 51 49 48 51 48 54 52 54 55 52 51 54 50 55 53 50 52 55 56 59 58 57 56 58 63 61 60 63 60 66 64 66 67 64 63 66 62 67 65 62 64 67 + 3 6 9 12 15 18 21 24 27 30 33 36 39 42 45 48 51 54 57 60 63 66 69 72 75 78 81 84 87 90 93 96 99 102 105 108 111 114 117 120 123 126 129 132 135 138 141 144 147 150 153 156 + + + + + -0.00844303 -0.0527754 0 -0.00356825 -0.0538874 0 -0.00356825 -0.0538874 0.01 -0.00844303 -0.0527754 0.01 -0.00844303 -0.0527754 0 -0.00356825 -0.0538874 0 -0.0025 -5.81217e-17 0 -0.00514751 -0.0353482 0 -0.0031628 -0.0177236 0 -0.00844303 0.0527754 0 -0.0031628 0.0177236 0 -0.00514751 0.0353482 0 -0.00356825 0.0538874 0 0.0025 -5.93464e-17 0 0.00182323 0.0180971 0 -0.00020329 0.036093 0 -0.00020329 -0.036093 0 0.00182323 -0.0180971 0 -0.00356825 -0.0538874 0 -0.00356825 -0.0538874 0.01 0.0025 -5.93464e-17 0.01 -0.00020329 -0.036093 0.01 0.00182323 -0.0180971 0.01 0.0025 -5.93464e-17 0 -0.00020329 -0.036093 0 0.00182323 -0.0180971 0 -0.00844303 -0.0527754 0.01 -0.00356825 -0.0538874 0.01 -0.0025 -5.81217e-17 0.01 -0.00514751 -0.0353482 0.01 -0.0031628 -0.0177236 0.01 -0.00844303 0.0527754 0.01 -0.0031628 0.0177236 0.01 -0.00514751 0.0353482 0.01 -0.00356825 0.0538874 0.01 0.0025 -5.93464e-17 0.01 0.00182323 0.0180971 0.01 -0.00020329 0.036093 0.01 -0.00020329 -0.036093 0.01 0.00182323 -0.0180971 0.01 -0.00844303 -0.0527754 0 -0.00844303 -0.0527754 0.01 -0.0025 -5.81217e-17 0.01 -0.00514751 -0.0353482 0.01 -0.0031628 -0.0177236 0.01 -0.0025 -5.81217e-17 0 -0.00514751 -0.0353482 0 -0.0031628 -0.0177236 0 -0.0025 -5.81217e-17 0 -0.0025 -5.81217e-17 0.01 -0.00844303 0.0527754 0.01 -0.0031628 0.0177236 0.01 -0.00514751 0.0353482 0.01 -0.00844303 0.0527754 0 -0.0031628 0.0177236 0 -0.00514751 0.0353482 0 -0.00844303 0.0527754 0 -0.00356825 0.0538874 0 -0.00356825 0.0538874 0.01 -0.00844303 0.0527754 0.01 0.0025 -5.93464e-17 0 0.0025 -5.93464e-17 0.01 -0.00356825 0.0538874 0.01 0.00182323 0.0180971 0.01 -0.00020329 0.036093 0.01 -0.00356825 0.0538874 0 0.00182323 0.0180971 0 -0.00020329 0.036093 0 + + + 1 3 2 1 0 3 16 4 5 16 7 4 17 8 7 17 7 16 13 6 8 13 8 17 14 10 6 14 6 13 15 11 10 15 10 14 12 9 11 12 11 15 21 19 18 21 18 24 22 24 25 22 21 24 20 25 23 20 22 25 38 26 27 38 29 26 39 30 29 39 29 38 28 30 39 35 28 39 36 32 28 36 28 35 37 33 32 37 32 36 34 31 33 34 33 37 43 41 40 43 40 46 44 46 47 44 43 46 42 47 45 42 44 47 51 49 48 51 48 54 52 54 55 52 51 54 50 55 53 50 52 55 56 59 58 57 56 58 63 61 60 63 60 66 64 66 67 64 63 66 62 67 65 62 64 67 + 3 6 9 12 15 18 21 24 27 30 33 36 39 42 45 48 51 54 57 60 63 66 69 72 75 78 81 84 87 90 93 96 99 102 105 108 111 114 117 120 123 126 129 132 135 138 141 144 147 150 153 156 + + + + + -0.00860581 -0.054221 0 -0.00373104 -0.055333 0 -0.00373104 -0.055333 0.01 -0.00860581 -0.054221 0.01 -0.00860581 -0.054221 0 -0.00373104 -0.055333 0 -0.0025 -5.97138e-17 0 -0.00522003 -0.0363165 0 -0.00318096 -0.0182091 0 -0.00860581 0.054221 0 -0.00318096 0.0182091 0 -0.00522003 0.0363165 0 -0.00373104 0.055333 0 0.0025 -6.09384e-17 0 0.00180508 0.0185825 0 -0.000275809 0.0370613 0 -0.000275809 -0.0370613 0 0.00180508 -0.0185825 0 -0.00373104 -0.055333 0 -0.00373104 -0.055333 0.01 0.0025 -6.09384e-17 0.01 -0.000275809 -0.0370613 0.01 0.00180508 -0.0185825 0.01 0.0025 -6.09384e-17 0 -0.000275809 -0.0370613 0 0.00180508 -0.0185825 0 -0.00860581 -0.054221 0.01 -0.00373104 -0.055333 0.01 -0.0025 -5.97138e-17 0.01 -0.00522003 -0.0363165 0.01 -0.00318096 -0.0182091 0.01 -0.00860581 0.054221 0.01 -0.00318096 0.0182091 0.01 -0.00522003 0.0363165 0.01 -0.00373104 0.055333 0.01 0.0025 -6.09384e-17 0.01 0.00180508 0.0185825 0.01 -0.000275809 0.0370613 0.01 -0.000275809 -0.0370613 0.01 0.00180508 -0.0185825 0.01 -0.00860581 -0.054221 0 -0.00860581 -0.054221 0.01 -0.0025 -5.97138e-17 0.01 -0.00522003 -0.0363165 0.01 -0.00318096 -0.0182091 0.01 -0.0025 -5.97138e-17 0 -0.00522003 -0.0363165 0 -0.00318096 -0.0182091 0 -0.0025 -5.97138e-17 0 -0.0025 -5.97138e-17 0.01 -0.00860581 0.054221 0.01 -0.00318096 0.0182091 0.01 -0.00522003 0.0363165 0.01 -0.00860581 0.054221 0 -0.00318096 0.0182091 0 -0.00522003 0.0363165 0 -0.00860581 0.054221 0 -0.00373104 0.055333 0 -0.00373104 0.055333 0.01 -0.00860581 0.054221 0.01 0.0025 -6.09384e-17 0 0.0025 -6.09384e-17 0.01 -0.00373104 0.055333 0.01 0.00180508 0.0185825 0.01 -0.000275809 0.0370613 0.01 -0.00373104 0.055333 0 0.00180508 0.0185825 0 -0.000275809 0.0370613 0 + + + 1 3 2 1 0 3 16 4 5 16 7 4 17 8 7 17 7 16 6 8 17 13 6 17 10 6 13 14 10 13 15 11 10 15 10 14 12 9 11 12 11 15 21 19 18 21 18 24 22 24 25 22 21 24 20 25 23 20 22 25 38 26 27 38 29 26 39 30 29 39 29 38 28 30 39 35 28 39 32 28 35 36 32 35 37 33 32 37 32 36 34 31 33 34 33 37 43 41 40 43 40 46 44 46 47 44 43 46 42 47 45 42 44 47 51 49 48 51 48 54 52 54 55 52 51 54 50 55 53 50 52 55 56 59 58 57 56 58 63 61 60 63 60 66 64 66 67 64 63 66 62 67 65 62 64 67 + 3 6 9 12 15 18 21 24 27 30 33 36 39 42 45 48 51 54 57 60 63 66 69 72 75 78 81 84 87 90 93 96 99 102 105 108 111 114 117 120 123 126 129 132 135 138 141 144 147 150 153 156 + + + + + -0.00868596 -0.0549326 0 -0.00381118 -0.0560446 0 -0.00381118 -0.0560446 0.01 -0.00868596 -0.0549326 0.01 -0.00868596 -0.0549326 0 -0.00381118 -0.0560446 0 -0.0025 -6.04976e-17 0 -0.00525573 -0.0367931 0 -0.0031899 -0.0184481 0 -0.00868596 0.0549326 0 -0.0031899 0.0184481 0 -0.00525573 0.0367931 0 -0.00381118 0.0560446 0 0.0025 -6.17222e-17 0 0.00179614 0.0188215 0 -0.000311511 0.0375379 0 -0.000311511 -0.0375379 0 0.00179614 -0.0188215 0 -0.00381118 -0.0560446 0 -0.00381118 -0.0560446 0.01 0.0025 -6.17222e-17 0.01 -0.000311511 -0.0375379 0.01 0.00179614 -0.0188215 0.01 0.0025 -6.17222e-17 0 -0.000311511 -0.0375379 0 0.00179614 -0.0188215 0 -0.00868596 -0.0549326 0.01 -0.00381118 -0.0560446 0.01 -0.0025 -6.04976e-17 0.01 -0.00525573 -0.0367931 0.01 -0.0031899 -0.0184481 0.01 -0.00868596 0.0549326 0.01 -0.0031899 0.0184481 0.01 -0.00525573 0.0367931 0.01 -0.00381118 0.0560446 0.01 0.0025 -6.17222e-17 0.01 0.00179614 0.0188215 0.01 -0.000311511 0.0375379 0.01 -0.000311511 -0.0375379 0.01 0.00179614 -0.0188215 0.01 -0.00868596 -0.0549326 0 -0.00868596 -0.0549326 0.01 -0.0025 -6.04976e-17 0.01 -0.00525573 -0.0367931 0.01 -0.0031899 -0.0184481 0.01 -0.0025 -6.04976e-17 0 -0.00525573 -0.0367931 0 -0.0031899 -0.0184481 0 -0.0025 -6.04976e-17 0 -0.0025 -6.04976e-17 0.01 -0.00868596 0.0549326 0.01 -0.0031899 0.0184481 0.01 -0.00525573 0.0367931 0.01 -0.00868596 0.0549326 0 -0.0031899 0.0184481 0 -0.00525573 0.0367931 0 -0.00868596 0.0549326 0 -0.00381118 0.0560446 0 -0.00381118 0.0560446 0.01 -0.00868596 0.0549326 0.01 0.0025 -6.17222e-17 0 0.0025 -6.17222e-17 0.01 -0.00381118 0.0560446 0.01 0.00179614 0.0188215 0.01 -0.000311511 0.0375379 0.01 -0.00381118 0.0560446 0 0.00179614 0.0188215 0 -0.000311511 0.0375379 0 + + + 0 3 2 1 0 2 16 4 5 16 7 4 17 8 7 17 7 16 13 6 8 13 8 17 10 6 13 14 10 13 15 11 10 15 10 14 12 9 11 12 11 15 21 19 18 21 18 24 22 24 25 22 21 24 20 25 23 20 22 25 38 26 27 38 29 26 39 30 29 39 29 38 35 28 30 35 30 39 32 28 35 36 32 35 37 33 32 37 32 36 34 31 33 34 33 37 43 41 40 43 40 46 44 46 47 44 43 46 42 47 45 42 44 47 51 49 48 51 48 54 52 54 55 52 51 54 50 55 53 50 52 55 56 59 58 57 56 58 63 61 60 63 60 66 64 66 67 64 63 66 62 67 65 62 64 67 + 3 6 9 12 15 18 21 24 27 30 33 36 39 42 45 48 51 54 57 60 63 66 69 72 75 78 81 84 87 90 93 96 99 102 105 108 111 114 117 120 123 126 129 132 135 138 141 144 147 150 153 156 + + + + + -0.00885125 -0.0564005 0 -0.00397647 -0.0575125 0 -0.00397647 -0.0575125 0.01 -0.00885125 -0.0564005 0.01 -0.00885125 -0.0564005 0 -0.00397647 -0.0575125 0 -0.0025 -6.21141e-17 0 -0.00532936 -0.0377763 0 -0.00320833 -0.018941 0 -0.00885125 0.0564005 0 -0.00320833 0.018941 0 -0.00532936 0.0377763 0 -0.00397647 0.0575125 0 0.0025 -6.33387e-17 0 0.0017777 0.0193145 0 -0.000385146 0.0385211 0 -0.000385146 -0.0385211 0 0.0017777 -0.0193145 0 -0.00397647 -0.0575125 0 -0.00397647 -0.0575125 0.01 0.0025 -6.33387e-17 0.01 -0.000385146 -0.0385211 0.01 0.0017777 -0.0193145 0.01 0.0025 -6.33387e-17 0 -0.000385146 -0.0385211 0 0.0017777 -0.0193145 0 -0.00885125 -0.0564005 0.01 -0.00397647 -0.0575125 0.01 -0.0025 -6.21141e-17 0.01 -0.00532936 -0.0377763 0.01 -0.00320833 -0.018941 0.01 -0.00885125 0.0564005 0.01 -0.00320833 0.018941 0.01 -0.00532936 0.0377763 0.01 -0.00397647 0.0575125 0.01 0.0025 -6.33387e-17 0.01 0.0017777 0.0193145 0.01 -0.000385146 0.0385211 0.01 -0.000385146 -0.0385211 0.01 0.0017777 -0.0193145 0.01 -0.00885125 -0.0564005 0 -0.00885125 -0.0564005 0.01 -0.0025 -6.21141e-17 0.01 -0.00532936 -0.0377763 0.01 -0.00320833 -0.018941 0.01 -0.0025 -6.21141e-17 0 -0.00532936 -0.0377763 0 -0.00320833 -0.018941 0 -0.0025 -6.21141e-17 0 -0.0025 -6.21141e-17 0.01 -0.00885125 0.0564005 0.01 -0.00320833 0.018941 0.01 -0.00532936 0.0377763 0.01 -0.00885125 0.0564005 0 -0.00320833 0.018941 0 -0.00532936 0.0377763 0 -0.00885125 0.0564005 0 -0.00397647 0.0575125 0 -0.00397647 0.0575125 0.01 -0.00885125 0.0564005 0.01 0.0025 -6.33387e-17 0 0.0025 -6.33387e-17 0.01 -0.00397647 0.0575125 0.01 0.0017777 0.0193145 0.01 -0.000385146 0.0385211 0.01 -0.00397647 0.0575125 0 0.0017777 0.0193145 0 -0.000385146 0.0385211 0 + + + 0 3 2 1 0 2 16 4 5 16 7 4 17 8 7 17 7 16 6 8 17 13 6 17 10 6 13 14 10 13 15 11 10 15 10 14 12 9 11 12 11 15 21 19 18 21 18 24 22 24 25 22 21 24 20 25 23 20 22 25 38 26 27 38 29 26 39 30 29 39 29 38 28 30 39 35 28 39 32 28 35 36 32 35 37 33 32 37 32 36 34 31 33 34 33 37 43 41 40 43 40 46 44 46 47 44 43 46 42 47 45 42 44 47 51 49 48 51 48 54 52 54 55 52 51 54 50 55 53 50 52 55 56 59 58 57 56 58 63 61 60 63 60 66 64 66 67 64 63 66 62 67 65 62 64 67 + 3 6 9 12 15 18 21 24 27 30 33 36 39 42 45 48 51 54 57 60 63 66 69 72 75 78 81 84 87 90 93 96 99 102 105 108 111 114 117 120 123 126 129 132 135 138 141 144 147 150 153 156 + + + + + -0.00893139 -0.0571122 0 -0.00405661 -0.0582242 0 -0.00405661 -0.0582242 0.01 -0.00893139 -0.0571122 0.01 -0.00893139 -0.0571122 0 -0.00405661 -0.0582242 0 -0.0025 -6.28979e-17 0 -0.00536506 -0.0382529 0 -0.00321727 -0.01918 0 -0.00893139 0.0571122 0 -0.00321727 0.01918 0 -0.00536506 0.0382529 0 -0.00405661 0.0582242 0 0.0025 -6.41225e-17 0 0.00176877 0.0195535 0 -0.000420848 0.0389977 0 -0.000420848 -0.0389977 0 0.00176877 -0.0195535 0 -0.00405661 -0.0582242 0 -0.00405661 -0.0582242 0.01 0.0025 -6.41225e-17 0.01 -0.000420848 -0.0389977 0.01 0.00176877 -0.0195535 0.01 0.0025 -6.41225e-17 0 -0.000420848 -0.0389977 0 0.00176877 -0.0195535 0 -0.00893139 -0.0571122 0.01 -0.00405661 -0.0582242 0.01 -0.0025 -6.28979e-17 0.01 -0.00536506 -0.0382529 0.01 -0.00321727 -0.01918 0.01 -0.00893139 0.0571122 0.01 -0.00321727 0.01918 0.01 -0.00536506 0.0382529 0.01 -0.00405661 0.0582242 0.01 0.0025 -6.41225e-17 0.01 0.00176877 0.0195535 0.01 -0.000420848 0.0389977 0.01 -0.000420848 -0.0389977 0.01 0.00176877 -0.0195535 0.01 -0.00893139 -0.0571122 0 -0.00893139 -0.0571122 0.01 -0.0025 -6.28979e-17 0.01 -0.00536506 -0.0382529 0.01 -0.00321727 -0.01918 0.01 -0.0025 -6.28979e-17 0 -0.00536506 -0.0382529 0 -0.00321727 -0.01918 0 -0.0025 -6.28979e-17 0 -0.0025 -6.28979e-17 0.01 -0.00893139 0.0571122 0.01 -0.00321727 0.01918 0.01 -0.00536506 0.0382529 0.01 -0.00893139 0.0571122 0 -0.00321727 0.01918 0 -0.00536506 0.0382529 0 -0.00893139 0.0571122 0 -0.00405661 0.0582242 0 -0.00405661 0.0582242 0.01 -0.00893139 0.0571122 0.01 0.0025 -6.41225e-17 0 0.0025 -6.41225e-17 0.01 -0.00405661 0.0582242 0.01 0.00176877 0.0195535 0.01 -0.000420848 0.0389977 0.01 -0.00405661 0.0582242 0 0.00176877 0.0195535 0 -0.000420848 0.0389977 0 + + + 0 3 2 1 0 2 16 4 5 16 7 4 17 8 7 17 7 16 6 8 17 13 6 17 10 6 13 14 10 13 15 11 10 15 10 14 9 11 15 12 9 15 21 19 18 21 18 24 22 24 25 22 21 24 20 25 23 20 22 25 38 26 27 38 29 26 39 30 29 39 29 38 28 30 39 35 28 39 32 28 35 36 32 35 37 33 32 37 32 36 31 33 37 34 31 37 43 41 40 43 40 46 44 46 47 44 43 46 42 47 45 42 44 47 51 49 48 51 48 54 52 54 55 52 51 54 50 55 53 50 52 55 56 59 58 57 56 58 63 61 60 63 60 66 64 66 67 64 63 66 62 67 65 62 64 67 + 3 6 9 12 15 18 21 24 27 30 33 36 39 42 45 48 51 54 57 60 63 66 69 72 75 78 81 84 87 90 93 96 99 102 105 108 111 114 117 120 123 126 129 132 135 138 141 144 147 150 153 156 + + + + + -0.00909418 -0.0585578 0 -0.0042194 -0.0596698 0 -0.0042194 -0.0596698 0.01 -0.00909418 -0.0585578 0.01 -0.00909418 -0.0585578 0 -0.0042194 -0.0596698 0 -0.0025 -6.44899e-17 0 -0.00543758 -0.0392212 0 -0.00323542 -0.0196655 0 -0.00909418 0.0585578 0 -0.00323542 0.0196655 0 -0.00543758 0.0392212 0 -0.0042194 0.0596698 0 0.0025 -6.57145e-17 0 0.00175061 0.020039 0 -0.000493367 0.039966 0 -0.000493367 -0.039966 0 0.00175061 -0.020039 0 -0.0042194 -0.0596698 0 -0.0042194 -0.0596698 0.01 0.0025 -6.57145e-17 0.01 -0.000493367 -0.039966 0.01 0.00175061 -0.020039 0.01 0.0025 -6.57145e-17 0 -0.000493367 -0.039966 0 0.00175061 -0.020039 0 -0.00909418 -0.0585578 0.01 -0.0042194 -0.0596698 0.01 -0.0025 -6.44899e-17 0.01 -0.00543758 -0.0392212 0.01 -0.00323542 -0.0196655 0.01 -0.00909418 0.0585578 0.01 -0.00323542 0.0196655 0.01 -0.00543758 0.0392212 0.01 -0.0042194 0.0596698 0.01 0.0025 -6.57145e-17 0.01 0.00175061 0.020039 0.01 -0.000493367 0.039966 0.01 -0.000493367 -0.039966 0.01 0.00175061 -0.020039 0.01 -0.00909418 -0.0585578 0 -0.00909418 -0.0585578 0.01 -0.0025 -6.44899e-17 0.01 -0.00543758 -0.0392212 0.01 -0.00323542 -0.0196655 0.01 -0.0025 -6.44899e-17 0 -0.00543758 -0.0392212 0 -0.00323542 -0.0196655 0 -0.0025 -6.44899e-17 0 -0.0025 -6.44899e-17 0.01 -0.00909418 0.0585578 0.01 -0.00323542 0.0196655 0.01 -0.00543758 0.0392212 0.01 -0.00909418 0.0585578 0 -0.00323542 0.0196655 0 -0.00543758 0.0392212 0 -0.00909418 0.0585578 0 -0.0042194 0.0596698 0 -0.0042194 0.0596698 0.01 -0.00909418 0.0585578 0.01 0.0025 -6.57145e-17 0 0.0025 -6.57145e-17 0.01 -0.0042194 0.0596698 0.01 0.00175061 0.020039 0.01 -0.000493367 0.039966 0.01 -0.0042194 0.0596698 0 0.00175061 0.020039 0 -0.000493367 0.039966 0 + + + 0 3 2 1 0 2 16 4 5 16 7 4 17 8 7 17 7 16 6 8 17 13 6 17 10 6 13 14 10 13 15 11 10 15 10 14 12 9 11 12 11 15 21 19 18 21 18 24 22 24 25 22 21 24 20 25 23 20 22 25 38 26 27 38 29 26 39 30 29 39 29 38 28 30 39 35 28 39 32 28 35 36 32 35 37 33 32 37 32 36 34 31 33 34 33 37 43 41 40 43 40 46 44 46 47 44 43 46 42 47 45 42 44 47 51 49 48 51 48 54 52 54 55 52 51 54 50 55 53 50 52 55 56 59 58 57 56 58 63 61 60 63 60 66 64 66 67 64 63 66 62 67 65 62 64 67 + 3 6 9 12 15 18 21 24 27 30 33 36 39 42 45 48 51 54 57 60 63 66 69 72 75 78 81 84 87 90 93 96 99 102 105 108 111 114 117 120 123 126 129 132 135 138 141 144 147 150 153 156 + + + + + -0.00917432 -0.0592694 0 -0.00429954 -0.0603814 0 -0.00429954 -0.0603814 0.01 -0.00917432 -0.0592694 0.01 -0.00917432 -0.0592694 0 -0.00429954 -0.0603814 0 -0.0025 -6.52737e-17 0 -0.00547328 -0.0396979 0 -0.00324436 -0.0199045 0 -0.00917432 0.0592694 0 -0.00324436 0.0199045 0 -0.00547328 0.0396979 0 -0.00429954 0.0603814 0 0.0025 -6.64983e-17 0 0.00174167 0.020278 0 -0.000529069 0.0404427 0 -0.000529069 -0.0404427 0 0.00174167 -0.020278 0 -0.00429954 -0.0603814 0 -0.00429954 -0.0603814 0.01 0.0025 -6.64983e-17 0.01 -0.000529069 -0.0404427 0.01 0.00174167 -0.020278 0.01 0.0025 -6.64983e-17 0 -0.000529069 -0.0404427 0 0.00174167 -0.020278 0 -0.00917432 -0.0592694 0.01 -0.00429954 -0.0603814 0.01 -0.0025 -6.52737e-17 0.01 -0.00547328 -0.0396979 0.01 -0.00324436 -0.0199045 0.01 -0.00917432 0.0592694 0.01 -0.00324436 0.0199045 0.01 -0.00547328 0.0396979 0.01 -0.00429954 0.0603814 0.01 0.0025 -6.64983e-17 0.01 0.00174167 0.020278 0.01 -0.000529069 0.0404427 0.01 -0.000529069 -0.0404427 0.01 0.00174167 -0.020278 0.01 -0.00917432 -0.0592694 0 -0.00917432 -0.0592694 0.01 -0.0025 -6.52737e-17 0.01 -0.00547328 -0.0396979 0.01 -0.00324436 -0.0199045 0.01 -0.0025 -6.52737e-17 0 -0.00547328 -0.0396979 0 -0.00324436 -0.0199045 0 -0.0025 -6.52737e-17 0 -0.0025 -6.52737e-17 0.01 -0.00917432 0.0592694 0.01 -0.00324436 0.0199045 0.01 -0.00547328 0.0396979 0.01 -0.00917432 0.0592694 0 -0.00324436 0.0199045 0 -0.00547328 0.0396979 0 -0.00917432 0.0592694 0 -0.00429954 0.0603814 0 -0.00429954 0.0603814 0.01 -0.00917432 0.0592694 0.01 0.0025 -6.64983e-17 0 0.0025 -6.64983e-17 0.01 -0.00429954 0.0603814 0.01 0.00174167 0.020278 0.01 -0.000529069 0.0404427 0.01 -0.00429954 0.0603814 0 0.00174167 0.020278 0 -0.000529069 0.0404427 0 + + + 1 3 2 1 0 3 7 4 5 16 7 5 8 7 16 17 8 16 6 8 17 13 6 17 10 6 13 14 10 13 15 11 10 15 10 14 12 9 11 12 11 15 21 19 18 21 18 24 22 24 25 22 21 24 20 25 23 20 22 25 38 26 27 38 29 26 39 30 29 39 29 38 28 30 39 35 28 39 32 28 35 36 32 35 37 33 32 37 32 36 34 31 33 34 33 37 43 41 40 43 40 46 44 46 47 44 43 46 42 47 45 42 44 47 51 49 48 51 48 54 52 54 55 52 51 54 50 55 53 50 52 55 56 59 58 57 56 58 63 61 60 63 60 66 64 66 67 64 63 66 62 67 65 62 64 67 + 3 6 9 12 15 18 21 24 27 30 33 36 39 42 45 48 51 54 57 60 63 66 69 72 75 78 81 84 87 90 93 96 99 102 105 108 111 114 117 120 123 126 129 132 135 138 141 144 147 150 153 156 + + + + + -0.00713821 -0.0411884 0 -0.00226344 -0.0423004 0 -0.00226344 -0.0423004 0.01 -0.00713821 -0.0411884 0.01 -0.00713821 -0.0411884 0 -0.00226344 -0.0423004 0 -0.0025 -4.53609e-17 0 -0.00456624 -0.0275874 0 -0.00301728 -0.0138323 0 -0.00713821 0.0411884 0 -0.00301728 0.0138323 0 -0.00456624 0.0275874 0 -0.00226344 0.0423004 0 0.0025 -4.65856e-17 0 0.00196875 0.0142058 0 0.000377979 0.0283322 0 0.000377979 -0.0283322 0 0.00196875 -0.0142058 0 -0.00226344 -0.0423004 0 -0.00226344 -0.0423004 0.01 0.0025 -4.65856e-17 0.01 0.000377979 -0.0283322 0.01 0.00196875 -0.0142058 0.01 0.0025 -4.65856e-17 0 0.000377979 -0.0283322 0 0.00196875 -0.0142058 0 -0.00713821 -0.0411884 0.01 -0.00226344 -0.0423004 0.01 -0.0025 -4.53609e-17 0.01 -0.00456624 -0.0275874 0.01 -0.00301728 -0.0138323 0.01 -0.00713821 0.0411884 0.01 -0.00301728 0.0138323 0.01 -0.00456624 0.0275874 0.01 -0.00226344 0.0423004 0.01 0.0025 -4.65856e-17 0.01 0.00196875 0.0142058 0.01 0.000377979 0.0283322 0.01 0.000377979 -0.0283322 0.01 0.00196875 -0.0142058 0.01 -0.00713821 -0.0411884 0 -0.00713821 -0.0411884 0.01 -0.0025 -4.53609e-17 0.01 -0.00456624 -0.0275874 0.01 -0.00301728 -0.0138323 0.01 -0.0025 -4.53609e-17 0 -0.00456624 -0.0275874 0 -0.00301728 -0.0138323 0 -0.0025 -4.53609e-17 0 -0.0025 -4.53609e-17 0.01 -0.00713821 0.0411884 0.01 -0.00301728 0.0138323 0.01 -0.00456624 0.0275874 0.01 -0.00713821 0.0411884 0 -0.00301728 0.0138323 0 -0.00456624 0.0275874 0 -0.00713821 0.0411884 0 -0.00226344 0.0423004 0 -0.00226344 0.0423004 0.01 -0.00713821 0.0411884 0.01 0.0025 -4.65856e-17 0 0.0025 -4.65856e-17 0.01 -0.00226344 0.0423004 0.01 0.00196875 0.0142058 0.01 0.000377979 0.0283322 0.01 -0.00226344 0.0423004 0 0.00196875 0.0142058 0 0.000377979 0.0283322 0 + + + 1 3 2 1 0 3 16 4 5 16 7 4 17 8 7 17 7 16 13 6 8 13 8 17 14 10 6 14 6 13 15 11 10 15 10 14 12 9 11 12 11 15 21 19 18 21 18 24 22 24 25 22 21 24 20 25 23 20 22 25 38 26 27 38 29 26 39 30 29 39 29 38 35 28 30 35 30 39 36 32 28 36 28 35 37 33 32 37 32 36 34 31 33 34 33 37 43 41 40 43 40 46 44 46 47 44 43 46 42 47 45 42 44 47 51 49 48 51 48 54 52 54 55 52 51 54 50 55 53 50 52 55 56 59 58 57 56 58 63 61 60 63 60 66 64 66 67 64 63 66 62 67 65 62 64 67 + 3 6 9 12 15 18 21 24 27 30 33 36 39 42 45 48 51 54 57 60 63 66 69 72 75 78 81 84 87 90 93 96 99 102 105 108 111 114 117 120 123 126 129 132 135 138 141 144 147 150 153 156 + + + + + -0.00721836 -0.0419 0 -0.00234358 -0.043012 0 -0.00234358 -0.043012 0.01 -0.00721836 -0.0419 0.01 -0.00721836 -0.0419 0 -0.00234358 -0.043012 0 -0.0025 -4.61447e-17 0 -0.00460194 -0.0280641 0 -0.00302622 -0.0140713 0 -0.00721836 0.0419 0 -0.00302622 0.0140713 0 -0.00460194 0.0280641 0 -0.00234358 0.043012 0 0.0025 -4.73693e-17 0 0.00195981 0.0144448 0 0.000342277 0.0288089 0 0.000342277 -0.0288089 0 0.00195981 -0.0144448 0 -0.00234358 -0.043012 0 -0.00234358 -0.043012 0.01 0.0025 -4.73693e-17 0.01 0.000342277 -0.0288089 0.01 0.00195981 -0.0144448 0.01 0.0025 -4.73693e-17 0 0.000342277 -0.0288089 0 0.00195981 -0.0144448 0 -0.00721836 -0.0419 0.01 -0.00234358 -0.043012 0.01 -0.0025 -4.61447e-17 0.01 -0.00460194 -0.0280641 0.01 -0.00302622 -0.0140713 0.01 -0.00721836 0.0419 0.01 -0.00302622 0.0140713 0.01 -0.00460194 0.0280641 0.01 -0.00234358 0.043012 0.01 0.0025 -4.73693e-17 0.01 0.00195981 0.0144448 0.01 0.000342277 0.0288089 0.01 0.000342277 -0.0288089 0.01 0.00195981 -0.0144448 0.01 -0.00721836 -0.0419 0 -0.00721836 -0.0419 0.01 -0.0025 -4.61447e-17 0.01 -0.00460194 -0.0280641 0.01 -0.00302622 -0.0140713 0.01 -0.0025 -4.61447e-17 0 -0.00460194 -0.0280641 0 -0.00302622 -0.0140713 0 -0.0025 -4.61447e-17 0 -0.0025 -4.61447e-17 0.01 -0.00721836 0.0419 0.01 -0.00302622 0.0140713 0.01 -0.00460194 0.0280641 0.01 -0.00721836 0.0419 0 -0.00302622 0.0140713 0 -0.00460194 0.0280641 0 -0.00721836 0.0419 0 -0.00234358 0.043012 0 -0.00234358 0.043012 0.01 -0.00721836 0.0419 0.01 0.0025 -4.73693e-17 0 0.0025 -4.73693e-17 0.01 -0.00234358 0.043012 0.01 0.00195981 0.0144448 0.01 0.000342277 0.0288089 0.01 -0.00234358 0.043012 0 0.00195981 0.0144448 0 0.000342277 0.0288089 0 + + + 1 3 2 1 0 3 16 4 5 16 7 4 17 8 7 17 7 16 13 6 8 13 8 17 14 10 6 14 6 13 15 11 10 15 10 14 12 9 11 12 11 15 21 19 18 21 18 24 22 24 25 22 21 24 20 25 23 20 22 25 38 26 27 38 29 26 39 30 29 39 29 38 35 28 30 35 30 39 36 32 28 36 28 35 37 33 32 37 32 36 34 31 33 34 33 37 43 41 40 43 40 46 44 46 47 44 43 46 42 47 45 42 44 47 51 49 48 51 48 54 52 54 55 52 51 54 50 55 53 50 52 55 56 59 58 57 56 58 63 61 60 63 60 66 64 66 67 64 63 66 62 67 65 62 64 67 + 3 6 9 12 15 18 21 24 27 30 33 36 39 42 45 48 51 54 57 60 63 66 69 72 75 78 81 84 87 90 93 96 99 102 105 108 111 114 117 120 123 126 129 132 135 138 141 144 147 150 153 156 + + + + + -0.00738365 -0.0433679 0 -0.00250887 -0.0444799 0 -0.00250887 -0.0444799 0.01 -0.00738365 -0.0433679 0.01 -0.00738365 -0.0433679 0 -0.00250887 -0.0444799 0 -0.0025 -4.77612e-17 0 -0.00467557 -0.0290472 0 -0.00304465 -0.0145643 0 -0.00738365 0.0433679 0 -0.00304465 0.0145643 0 -0.00467557 0.0290472 0 -0.00250887 0.0444799 0 0.0025 -4.89859e-17 0 0.00194138 0.0149377 0 0.000268642 0.029792 0 0.000268642 -0.029792 0 0.00194138 -0.0149377 0 -0.00250887 -0.0444799 0 -0.00250887 -0.0444799 0.01 0.0025 -4.89859e-17 0.01 0.000268642 -0.029792 0.01 0.00194138 -0.0149377 0.01 0.0025 -4.89859e-17 0 0.000268642 -0.029792 0 0.00194138 -0.0149377 0 -0.00738365 -0.0433679 0.01 -0.00250887 -0.0444799 0.01 -0.0025 -4.77612e-17 0.01 -0.00467557 -0.0290472 0.01 -0.00304465 -0.0145643 0.01 -0.00738365 0.0433679 0.01 -0.00304465 0.0145643 0.01 -0.00467557 0.0290472 0.01 -0.00250887 0.0444799 0.01 0.0025 -4.89859e-17 0.01 0.00194138 0.0149377 0.01 0.000268642 0.029792 0.01 0.000268642 -0.029792 0.01 0.00194138 -0.0149377 0.01 -0.00738365 -0.0433679 0 -0.00738365 -0.0433679 0.01 -0.0025 -4.77612e-17 0.01 -0.00467557 -0.0290472 0.01 -0.00304465 -0.0145643 0.01 -0.0025 -4.77612e-17 0 -0.00467557 -0.0290472 0 -0.00304465 -0.0145643 0 -0.0025 -4.77612e-17 0 -0.0025 -4.77612e-17 0.01 -0.00738365 0.0433679 0.01 -0.00304465 0.0145643 0.01 -0.00467557 0.0290472 0.01 -0.00738365 0.0433679 0 -0.00304465 0.0145643 0 -0.00467557 0.0290472 0 -0.00738365 0.0433679 0 -0.00250887 0.0444799 0 -0.00250887 0.0444799 0.01 -0.00738365 0.0433679 0.01 0.0025 -4.89859e-17 0 0.0025 -4.89859e-17 0.01 -0.00250887 0.0444799 0.01 0.00194138 0.0149377 0.01 0.000268642 0.029792 0.01 -0.00250887 0.0444799 0 0.00194138 0.0149377 0 0.000268642 0.029792 0 + + + 1 3 2 1 0 3 16 4 5 16 7 4 17 8 7 17 7 16 13 6 8 13 8 17 14 10 6 14 6 13 15 11 10 15 10 14 12 9 11 12 11 15 21 19 18 21 18 24 22 24 25 22 21 24 20 25 23 20 22 25 38 26 27 38 29 26 39 30 29 39 29 38 35 28 30 35 30 39 36 32 28 36 28 35 37 33 32 37 32 36 34 31 33 34 33 37 43 41 40 43 40 46 44 46 47 44 43 46 42 47 45 42 44 47 51 49 48 51 48 54 52 54 55 52 51 54 50 55 53 50 52 55 56 59 58 57 56 58 63 61 60 63 60 66 64 66 67 64 63 66 62 67 65 62 64 67 + 3 6 9 12 15 18 21 24 27 30 33 36 39 42 45 48 51 54 57 60 63 66 69 72 75 78 81 84 87 90 93 96 99 102 105 108 111 114 117 120 123 126 129 132 135 138 141 144 147 150 153 156 + + + + + -0.00746379 -0.0440796 0 -0.00258901 -0.0451916 0 -0.00258901 -0.0451916 0.01 -0.00746379 -0.0440796 0.01 -0.00746379 -0.0440796 0 -0.00258901 -0.0451916 0 -0.0025 -4.8545e-17 0 -0.00471128 -0.0295239 0 -0.00305359 -0.0148033 0 -0.00746379 0.0440796 0 -0.00305359 0.0148033 0 -0.00471128 0.0295239 0 -0.00258901 0.0451916 0 0.0025 -4.97696e-17 0 0.00193244 0.0151767 0 0.00023294 0.0302687 0 0.00023294 -0.0302687 0 0.00193244 -0.0151767 0 -0.00258901 -0.0451916 0 -0.00258901 -0.0451916 0.01 0.0025 -4.97696e-17 0.01 0.00023294 -0.0302687 0.01 0.00193244 -0.0151767 0.01 0.0025 -4.97696e-17 0 0.00023294 -0.0302687 0 0.00193244 -0.0151767 0 -0.00746379 -0.0440796 0.01 -0.00258901 -0.0451916 0.01 -0.0025 -4.8545e-17 0.01 -0.00471128 -0.0295239 0.01 -0.00305359 -0.0148033 0.01 -0.00746379 0.0440796 0.01 -0.00305359 0.0148033 0.01 -0.00471128 0.0295239 0.01 -0.00258901 0.0451916 0.01 0.0025 -4.97696e-17 0.01 0.00193244 0.0151767 0.01 0.00023294 0.0302687 0.01 0.00023294 -0.0302687 0.01 0.00193244 -0.0151767 0.01 -0.00746379 -0.0440796 0 -0.00746379 -0.0440796 0.01 -0.0025 -4.8545e-17 0.01 -0.00471128 -0.0295239 0.01 -0.00305359 -0.0148033 0.01 -0.0025 -4.8545e-17 0 -0.00471128 -0.0295239 0 -0.00305359 -0.0148033 0 -0.0025 -4.8545e-17 0 -0.0025 -4.8545e-17 0.01 -0.00746379 0.0440796 0.01 -0.00305359 0.0148033 0.01 -0.00471128 0.0295239 0.01 -0.00746379 0.0440796 0 -0.00305359 0.0148033 0 -0.00471128 0.0295239 0 -0.00746379 0.0440796 0 -0.00258901 0.0451916 0 -0.00258901 0.0451916 0.01 -0.00746379 0.0440796 0.01 0.0025 -4.97696e-17 0 0.0025 -4.97696e-17 0.01 -0.00258901 0.0451916 0.01 0.00193244 0.0151767 0.01 0.00023294 0.0302687 0.01 -0.00258901 0.0451916 0 0.00193244 0.0151767 0 0.00023294 0.0302687 0 + + + 0 3 2 1 0 2 7 4 5 16 7 5 8 7 16 17 8 16 6 8 17 13 6 17 10 6 13 14 10 13 15 11 10 15 10 14 12 9 11 12 11 15 21 19 18 21 18 24 22 24 25 22 21 24 20 25 23 20 22 25 29 26 27 38 29 27 30 29 38 39 30 38 28 30 39 35 28 39 32 28 35 36 32 35 37 33 32 37 32 36 34 31 33 34 33 37 43 41 40 43 40 46 44 46 47 44 43 46 42 47 45 42 44 47 51 49 48 51 48 54 52 54 55 52 51 54 50 55 53 50 52 55 56 59 58 57 56 58 63 61 60 63 60 66 64 66 67 64 63 66 62 67 65 62 64 67 + 3 6 9 12 15 18 21 24 27 30 33 36 39 42 45 48 51 54 57 60 63 66 69 72 75 78 81 84 87 90 93 96 99 102 105 108 111 114 117 120 123 126 129 132 135 138 141 144 147 150 153 156 + + + + + -0.00762658 -0.0455252 0 -0.0027518 -0.0466372 0 -0.0027518 -0.0466372 0.01 -0.00762658 -0.0455252 0.01 -0.00762658 -0.0455252 0 -0.0027518 -0.0466372 0 -0.0025 -5.0137e-17 0 -0.00478379 -0.0304921 0 -0.00307175 -0.0152888 0 -0.00762658 0.0455252 0 -0.00307175 0.0152888 0 -0.00478379 0.0304921 0 -0.0027518 0.0466372 0 0.0025 -5.13617e-17 0 0.00191429 0.0156622 0 0.000160421 0.0312369 0 0.000160421 -0.0312369 0 0.00191429 -0.0156622 0 -0.0027518 -0.0466372 0 -0.0027518 -0.0466372 0.01 0.0025 -5.13617e-17 0.01 0.000160421 -0.0312369 0.01 0.00191429 -0.0156622 0.01 0.0025 -5.13617e-17 0 0.000160421 -0.0312369 0 0.00191429 -0.0156622 0 -0.00762658 -0.0455252 0.01 -0.0027518 -0.0466372 0.01 -0.0025 -5.0137e-17 0.01 -0.00478379 -0.0304921 0.01 -0.00307175 -0.0152888 0.01 -0.00762658 0.0455252 0.01 -0.00307175 0.0152888 0.01 -0.00478379 0.0304921 0.01 -0.0027518 0.0466372 0.01 0.0025 -5.13617e-17 0.01 0.00191429 0.0156622 0.01 0.000160421 0.0312369 0.01 0.000160421 -0.0312369 0.01 0.00191429 -0.0156622 0.01 -0.00762658 -0.0455252 0 -0.00762658 -0.0455252 0.01 -0.0025 -5.0137e-17 0.01 -0.00478379 -0.0304921 0.01 -0.00307175 -0.0152888 0.01 -0.0025 -5.0137e-17 0 -0.00478379 -0.0304921 0 -0.00307175 -0.0152888 0 -0.0025 -5.0137e-17 0 -0.0025 -5.0137e-17 0.01 -0.00762658 0.0455252 0.01 -0.00307175 0.0152888 0.01 -0.00478379 0.0304921 0.01 -0.00762658 0.0455252 0 -0.00307175 0.0152888 0 -0.00478379 0.0304921 0 -0.00762658 0.0455252 0 -0.0027518 0.0466372 0 -0.0027518 0.0466372 0.01 -0.00762658 0.0455252 0.01 0.0025 -5.13617e-17 0 0.0025 -5.13617e-17 0.01 -0.0027518 0.0466372 0.01 0.00191429 0.0156622 0.01 0.000160421 0.0312369 0.01 -0.0027518 0.0466372 0 0.00191429 0.0156622 0 0.000160421 0.0312369 0 + + + 1 3 2 1 0 3 7 4 5 16 7 5 8 7 16 17 8 16 6 8 17 13 6 17 14 10 6 14 6 13 15 11 10 15 10 14 12 9 11 12 11 15 21 19 18 21 18 24 22 24 25 22 21 24 20 25 23 20 22 25 38 26 27 38 29 26 39 30 29 39 29 38 35 28 30 35 30 39 36 32 28 36 28 35 37 33 32 37 32 36 34 31 33 34 33 37 43 41 40 43 40 46 44 46 47 44 43 46 42 47 45 42 44 47 51 49 48 51 48 54 52 54 55 52 51 54 50 55 53 50 52 55 56 59 58 57 56 58 63 61 60 63 60 66 64 66 67 64 63 66 62 67 65 62 64 67 + 3 6 9 12 15 18 21 24 27 30 33 36 39 42 45 48 51 54 57 60 63 66 69 72 75 78 81 84 87 90 93 96 99 102 105 108 111 114 117 120 123 126 129 132 135 138 141 144 147 150 153 156 + + + + + -0.00770923 -0.0462591 0 -0.00283445 -0.0473711 0 -0.00283445 -0.0473711 0.01 -0.00770923 -0.0462591 0.01 -0.00770923 -0.0462591 0 -0.00283445 -0.0473711 0 -0.0025 -5.09453e-17 0 -0.00482061 -0.0309837 0 -0.00308096 -0.0155352 0 -0.00770923 0.0462591 0 -0.00308096 0.0155352 0 -0.00482061 0.0309837 0 -0.00283445 0.0473711 0 0.0025 -5.217e-17 0 0.00190507 0.0159087 0 0.000123604 0.0317285 0 0.000123604 -0.0317285 0 0.00190507 -0.0159087 0 -0.00283445 -0.0473711 0 -0.00283445 -0.0473711 0.01 0.0025 -5.217e-17 0.01 0.000123604 -0.0317285 0.01 0.00190507 -0.0159087 0.01 0.0025 -5.217e-17 0 0.000123604 -0.0317285 0 0.00190507 -0.0159087 0 -0.00770923 -0.0462591 0.01 -0.00283445 -0.0473711 0.01 -0.0025 -5.09453e-17 0.01 -0.00482061 -0.0309837 0.01 -0.00308096 -0.0155352 0.01 -0.00770923 0.0462591 0.01 -0.00308096 0.0155352 0.01 -0.00482061 0.0309837 0.01 -0.00283445 0.0473711 0.01 0.0025 -5.217e-17 0.01 0.00190507 0.0159087 0.01 0.000123604 0.0317285 0.01 0.000123604 -0.0317285 0.01 0.00190507 -0.0159087 0.01 -0.00770923 -0.0462591 0 -0.00770923 -0.0462591 0.01 -0.0025 -5.09453e-17 0.01 -0.00482061 -0.0309837 0.01 -0.00308096 -0.0155352 0.01 -0.0025 -5.09453e-17 0 -0.00482061 -0.0309837 0 -0.00308096 -0.0155352 0 -0.0025 -5.09453e-17 0 -0.0025 -5.09453e-17 0.01 -0.00770923 0.0462591 0.01 -0.00308096 0.0155352 0.01 -0.00482061 0.0309837 0.01 -0.00770923 0.0462591 0 -0.00308096 0.0155352 0 -0.00482061 0.0309837 0 -0.00770923 0.0462591 0 -0.00283445 0.0473711 0 -0.00283445 0.0473711 0.01 -0.00770923 0.0462591 0.01 0.0025 -5.217e-17 0 0.0025 -5.217e-17 0.01 -0.00283445 0.0473711 0.01 0.00190507 0.0159087 0.01 0.000123604 0.0317285 0.01 -0.00283445 0.0473711 0 0.00190507 0.0159087 0 0.000123604 0.0317285 0 + + + 0 3 2 1 0 2 16 4 5 16 7 4 17 8 7 17 7 16 13 6 8 13 8 17 10 6 13 14 10 13 15 11 10 15 10 14 12 9 11 12 11 15 21 19 18 21 18 24 22 24 25 22 21 24 20 25 23 20 22 25 38 26 27 38 29 26 39 30 29 39 29 38 35 28 30 35 30 39 32 28 35 36 32 35 37 33 32 37 32 36 34 31 33 34 33 37 43 41 40 43 40 46 44 46 47 44 43 46 42 47 45 42 44 47 51 49 48 51 48 54 52 54 55 52 51 54 50 55 53 50 52 55 56 59 58 57 56 58 63 61 60 63 60 66 64 66 67 64 63 66 62 67 65 62 64 67 + 3 6 9 12 15 18 21 24 27 30 33 36 39 42 45 48 51 54 57 60 63 66 69 72 75 78 81 84 87 90 93 96 99 102 105 108 111 114 117 120 123 126 129 132 135 138 141 144 147 150 153 156 + + + + + -0.00787201 -0.0477047 0 -0.00299724 -0.0488167 0 -0.00299724 -0.0488167 0.01 -0.00787201 -0.0477047 0.01 -0.00787201 -0.0477047 0 -0.00299724 -0.0488167 0 -0.0025 -5.25373e-17 0 -0.00489313 -0.0319519 0 -0.00309912 -0.0160207 0 -0.00787201 0.0477047 0 -0.00309912 0.0160207 0 -0.00489313 0.0319519 0 -0.00299724 0.0488167 0 0.0025 -5.3762e-17 0 0.00188691 0.0163942 0 5.10846e-05 0.0326967 0 5.10846e-05 -0.0326967 0 0.00188691 -0.0163942 0 -0.00299724 -0.0488167 0 -0.00299724 -0.0488167 0.01 0.0025 -5.3762e-17 0.01 5.10846e-05 -0.0326967 0.01 0.00188691 -0.0163942 0.01 0.0025 -5.3762e-17 0 5.10846e-05 -0.0326967 0 0.00188691 -0.0163942 0 -0.00787201 -0.0477047 0.01 -0.00299724 -0.0488167 0.01 -0.0025 -5.25373e-17 0.01 -0.00489313 -0.0319519 0.01 -0.00309912 -0.0160207 0.01 -0.00787201 0.0477047 0.01 -0.00309912 0.0160207 0.01 -0.00489313 0.0319519 0.01 -0.00299724 0.0488167 0.01 0.0025 -5.3762e-17 0.01 0.00188691 0.0163942 0.01 5.10846e-05 0.0326967 0.01 5.10846e-05 -0.0326967 0.01 0.00188691 -0.0163942 0.01 -0.00787201 -0.0477047 0 -0.00787201 -0.0477047 0.01 -0.0025 -5.25373e-17 0.01 -0.00489313 -0.0319519 0.01 -0.00309912 -0.0160207 0.01 -0.0025 -5.25373e-17 0 -0.00489313 -0.0319519 0 -0.00309912 -0.0160207 0 -0.0025 -5.25373e-17 0 -0.0025 -5.25373e-17 0.01 -0.00787201 0.0477047 0.01 -0.00309912 0.0160207 0.01 -0.00489313 0.0319519 0.01 -0.00787201 0.0477047 0 -0.00309912 0.0160207 0 -0.00489313 0.0319519 0 -0.00787201 0.0477047 0 -0.00299724 0.0488167 0 -0.00299724 0.0488167 0.01 -0.00787201 0.0477047 0.01 0.0025 -5.3762e-17 0 0.0025 -5.3762e-17 0.01 -0.00299724 0.0488167 0.01 0.00188691 0.0163942 0.01 5.10846e-05 0.0326967 0.01 -0.00299724 0.0488167 0 0.00188691 0.0163942 0 5.10846e-05 0.0326967 0 + + + 1 3 2 1 0 3 16 4 5 16 7 4 17 8 7 17 7 16 13 6 8 13 8 17 14 10 6 14 6 13 15 11 10 15 10 14 12 9 11 12 11 15 21 19 18 21 18 24 22 24 25 22 21 24 20 25 23 20 22 25 38 26 27 38 29 26 39 30 29 39 29 38 35 28 30 35 30 39 36 32 28 36 28 35 37 33 32 37 32 36 34 31 33 34 33 37 43 41 40 43 40 46 44 46 47 44 43 46 42 47 45 42 44 47 51 49 48 51 48 54 52 54 55 52 51 54 50 55 53 50 52 55 56 59 58 57 56 58 63 61 60 63 60 66 64 66 67 64 63 66 62 67 65 62 64 67 + 3 6 9 12 15 18 21 24 27 30 33 36 39 42 45 48 51 54 57 60 63 66 69 72 75 78 81 84 87 90 93 96 99 102 105 108 111 114 117 120 123 126 129 132 135 138 141 144 147 150 153 156 + + + + + -0.00795216 -0.0484163 0 -0.00307738 -0.0495283 0 -0.00307738 -0.0495283 0.01 -0.00795216 -0.0484163 0.01 -0.00795216 -0.0484163 0 -0.00307738 -0.0495283 0 -0.0025 -5.33211e-17 0 -0.00492883 -0.0324286 0 -0.00310806 -0.0162597 0 -0.00795216 0.0484163 0 -0.00310806 0.0162597 0 -0.00492883 0.0324286 0 -0.00307738 0.0495283 0 0.0025 -5.45458e-17 0 0.00187798 0.0166332 0 1.53828e-05 0.0331734 0 1.53828e-05 -0.0331734 0 0.00187798 -0.0166332 0 -0.00307738 -0.0495283 0 -0.00307738 -0.0495283 0.01 0.0025 -5.45458e-17 0.01 1.53828e-05 -0.0331734 0.01 0.00187798 -0.0166332 0.01 0.0025 -5.45458e-17 0 1.53828e-05 -0.0331734 0 0.00187798 -0.0166332 0 -0.00795216 -0.0484163 0.01 -0.00307738 -0.0495283 0.01 -0.0025 -5.33211e-17 0.01 -0.00492883 -0.0324286 0.01 -0.00310806 -0.0162597 0.01 -0.00795216 0.0484163 0.01 -0.00310806 0.0162597 0.01 -0.00492883 0.0324286 0.01 -0.00307738 0.0495283 0.01 0.0025 -5.45458e-17 0.01 0.00187798 0.0166332 0.01 1.53828e-05 0.0331734 0.01 1.53828e-05 -0.0331734 0.01 0.00187798 -0.0166332 0.01 -0.00795216 -0.0484163 0 -0.00795216 -0.0484163 0.01 -0.0025 -5.33211e-17 0.01 -0.00492883 -0.0324286 0.01 -0.00310806 -0.0162597 0.01 -0.0025 -5.33211e-17 0 -0.00492883 -0.0324286 0 -0.00310806 -0.0162597 0 -0.0025 -5.33211e-17 0 -0.0025 -5.33211e-17 0.01 -0.00795216 0.0484163 0.01 -0.00310806 0.0162597 0.01 -0.00492883 0.0324286 0.01 -0.00795216 0.0484163 0 -0.00310806 0.0162597 0 -0.00492883 0.0324286 0 -0.00795216 0.0484163 0 -0.00307738 0.0495283 0 -0.00307738 0.0495283 0.01 -0.00795216 0.0484163 0.01 0.0025 -5.45458e-17 0 0.0025 -5.45458e-17 0.01 -0.00307738 0.0495283 0.01 0.00187798 0.0166332 0.01 1.53828e-05 0.0331734 0.01 -0.00307738 0.0495283 0 0.00187798 0.0166332 0 1.53828e-05 0.0331734 0 + + + 0 3 2 1 0 2 16 4 5 16 7 4 17 8 7 17 7 16 13 6 8 13 8 17 14 10 6 14 6 13 15 11 10 15 10 14 12 9 11 12 11 15 21 19 18 21 18 24 22 24 25 22 21 24 20 25 23 20 22 25 38 26 27 38 29 26 39 30 29 39 29 38 35 28 30 35 30 39 36 32 28 36 28 35 37 33 32 37 32 36 34 31 33 34 33 37 43 41 40 43 40 46 44 46 47 44 43 46 42 47 45 42 44 47 51 49 48 51 48 54 52 54 55 52 51 54 50 55 53 50 52 55 56 59 58 57 56 58 63 61 60 63 60 66 64 66 67 64 63 66 62 67 65 62 64 67 + 3 6 9 12 15 18 21 24 27 30 33 36 39 42 45 48 51 54 57 60 63 66 69 72 75 78 81 84 87 90 93 96 99 102 105 108 111 114 117 120 123 126 129 132 135 138 141 144 147 150 153 156 + + + + + -0.0103489 -0.0697 0 -0.00547412 -0.070812 0 -0.00547412 -0.070812 0.01 -0.0103489 -0.0697 0.01 -0.0103489 -0.0697 0 -0.00547412 -0.070812 0 -0.0025 -7.67609e-17 0 -0.00599654 -0.0466841 0 -0.00337536 -0.0234074 0 -0.0103489 0.0697 0 -0.00337536 0.0234074 0 -0.00599654 0.0466841 0 -0.00547412 0.070812 0 0.0025 -7.79855e-17 0 0.00161068 0.0237809 0 -0.00105232 0.0474289 0 -0.00105232 -0.0474289 0 0.00161068 -0.0237809 0 -0.00547412 -0.070812 0 -0.00547412 -0.070812 0.01 0.0025 -7.79855e-17 0.01 -0.00105232 -0.0474289 0.01 0.00161068 -0.0237809 0.01 0.0025 -7.79855e-17 0 -0.00105232 -0.0474289 0 0.00161068 -0.0237809 0 -0.0103489 -0.0697 0.01 -0.00547412 -0.070812 0.01 -0.0025 -7.67609e-17 0.01 -0.00599654 -0.0466841 0.01 -0.00337536 -0.0234074 0.01 -0.0103489 0.0697 0.01 -0.00337536 0.0234074 0.01 -0.00599654 0.0466841 0.01 -0.00547412 0.070812 0.01 0.0025 -7.79855e-17 0.01 0.00161068 0.0237809 0.01 -0.00105232 0.0474289 0.01 -0.00105232 -0.0474289 0.01 0.00161068 -0.0237809 0.01 -0.0103489 -0.0697 0 -0.0103489 -0.0697 0.01 -0.0025 -7.67609e-17 0.01 -0.00599654 -0.0466841 0.01 -0.00337536 -0.0234074 0.01 -0.0025 -7.67609e-17 0 -0.00599654 -0.0466841 0 -0.00337536 -0.0234074 0 -0.0025 -7.67609e-17 0 -0.0025 -7.67609e-17 0.01 -0.0103489 0.0697 0.01 -0.00337536 0.0234074 0.01 -0.00599654 0.0466841 0.01 -0.0103489 0.0697 0 -0.00337536 0.0234074 0 -0.00599654 0.0466841 0 -0.0103489 0.0697 0 -0.00547412 0.070812 0 -0.00547412 0.070812 0.01 -0.0103489 0.0697 0.01 0.0025 -7.79855e-17 0 0.0025 -7.79855e-17 0.01 -0.00547412 0.070812 0.01 0.00161068 0.0237809 0.01 -0.00105232 0.0474289 0.01 -0.00547412 0.070812 0 0.00161068 0.0237809 0 -0.00105232 0.0474289 0 + + + 1 3 2 1 0 3 7 4 5 16 7 5 8 7 16 17 8 16 6 8 17 13 6 17 10 6 13 14 10 13 15 11 10 15 10 14 12 9 11 12 11 15 21 19 18 21 18 24 22 24 25 22 21 24 20 25 23 20 22 25 38 26 27 38 29 26 39 30 29 39 29 38 28 30 39 35 28 39 32 28 35 36 32 35 37 33 32 37 32 36 34 31 33 34 33 37 43 41 40 43 40 46 44 46 47 44 43 46 42 47 45 42 44 47 51 49 48 51 48 54 52 54 55 52 51 54 50 55 53 50 52 55 56 59 58 57 56 58 63 61 60 63 60 66 64 66 67 64 63 66 62 67 65 62 64 67 + 3 6 9 12 15 18 21 24 27 30 33 36 39 42 45 48 51 54 57 60 63 66 69 72 75 78 81 84 87 90 93 96 99 102 105 108 111 114 117 120 123 126 129 132 135 138 141 144 147 150 153 156 + + + + + -0.0104065 -0.0702115 0 -0.00553172 -0.0713235 0 -0.00553172 -0.0713235 0.01 -0.0104065 -0.0702115 0.01 -0.0104065 -0.0702115 0 -0.00553172 -0.0713235 0 -0.0025 -7.73242e-17 0 -0.0060222 -0.0470267 0 -0.00338178 -0.0235792 0 -0.0104065 0.0702115 0 -0.00338178 0.0235792 0 -0.0060222 0.0470267 0 -0.00553172 0.0713235 0 0.0025 -7.85488e-17 0 0.00160425 0.0239527 0 -0.00107798 0.0477715 0 -0.00107798 -0.0477715 0 0.00160425 -0.0239527 0 -0.00553172 -0.0713235 0 -0.00553172 -0.0713235 0.01 0.0025 -7.85488e-17 0.01 -0.00107798 -0.0477715 0.01 0.00160425 -0.0239527 0.01 0.0025 -7.85488e-17 0 -0.00107798 -0.0477715 0 0.00160425 -0.0239527 0 -0.0104065 -0.0702115 0.01 -0.00553172 -0.0713235 0.01 -0.0025 -7.73242e-17 0.01 -0.0060222 -0.0470267 0.01 -0.00338178 -0.0235792 0.01 -0.0104065 0.0702115 0.01 -0.00338178 0.0235792 0.01 -0.0060222 0.0470267 0.01 -0.00553172 0.0713235 0.01 0.0025 -7.85488e-17 0.01 0.00160425 0.0239527 0.01 -0.00107798 0.0477715 0.01 -0.00107798 -0.0477715 0.01 0.00160425 -0.0239527 0.01 -0.0104065 -0.0702115 0 -0.0104065 -0.0702115 0.01 -0.0025 -7.73242e-17 0.01 -0.0060222 -0.0470267 0.01 -0.00338178 -0.0235792 0.01 -0.0025 -7.73242e-17 0 -0.0060222 -0.0470267 0 -0.00338178 -0.0235792 0 -0.0025 -7.73242e-17 0 -0.0025 -7.73242e-17 0.01 -0.0104065 0.0702115 0.01 -0.00338178 0.0235792 0.01 -0.0060222 0.0470267 0.01 -0.0104065 0.0702115 0 -0.00338178 0.0235792 0 -0.0060222 0.0470267 0 -0.0104065 0.0702115 0 -0.00553172 0.0713235 0 -0.00553172 0.0713235 0.01 -0.0104065 0.0702115 0.01 0.0025 -7.85488e-17 0 0.0025 -7.85488e-17 0.01 -0.00553172 0.0713235 0.01 0.00160425 0.0239527 0.01 -0.00107798 0.0477715 0.01 -0.00553172 0.0713235 0 0.00160425 0.0239527 0 -0.00107798 0.0477715 0 + + + 1 3 2 1 0 3 16 4 5 16 7 4 17 8 7 17 7 16 6 8 17 13 6 17 10 6 13 14 10 13 15 11 10 15 10 14 12 9 11 12 11 15 21 19 18 21 18 24 22 24 25 22 21 24 20 25 23 20 22 25 38 26 27 38 29 26 39 30 29 39 29 38 28 30 39 35 28 39 32 28 35 36 32 35 37 33 32 37 32 36 34 31 33 34 33 37 43 41 40 43 40 46 44 46 47 44 43 46 42 47 45 42 44 47 51 49 48 51 48 54 52 54 55 52 51 54 50 55 53 50 52 55 56 59 58 57 56 58 63 61 60 63 60 66 64 66 67 64 63 66 62 67 65 62 64 67 + 3 6 9 12 15 18 21 24 27 30 33 36 39 42 45 48 51 54 57 60 63 66 69 72 75 78 81 84 87 90 93 96 99 102 105 108 111 114 117 120 123 126 129 132 135 138 141 144 147 150 153 156 + + + + + -0.011536 -0.0802417 0 -0.00666122 -0.0813537 0 -0.00666122 -0.0813537 0.01 -0.011536 -0.0802417 0.01 -0.011536 -0.0802417 0 -0.00666122 -0.0813537 0 -0.0025 -8.83705e-17 0 -0.00652537 -0.0537448 0 -0.00350775 -0.0269477 0 -0.011536 0.0802417 0 -0.00350775 0.0269477 0 -0.00652537 0.0537448 0 -0.00666122 0.0813537 0 0.0025 -8.95952e-17 0 0.00147828 0.0273211 0 -0.00158115 0.0544896 0 -0.00158115 -0.0544896 0 0.00147828 -0.0273211 0 -0.00666122 -0.0813537 0 -0.00666122 -0.0813537 0.01 0.0025 -8.95952e-17 0.01 -0.00158115 -0.0544896 0.01 0.00147828 -0.0273211 0.01 0.0025 -8.95952e-17 0 -0.00158115 -0.0544896 0 0.00147828 -0.0273211 0 -0.011536 -0.0802417 0.01 -0.00666122 -0.0813537 0.01 -0.0025 -8.83705e-17 0.01 -0.00652537 -0.0537448 0.01 -0.00350775 -0.0269477 0.01 -0.011536 0.0802417 0.01 -0.00350775 0.0269477 0.01 -0.00652537 0.0537448 0.01 -0.00666122 0.0813537 0.01 0.0025 -8.95952e-17 0.01 0.00147828 0.0273211 0.01 -0.00158115 0.0544896 0.01 -0.00158115 -0.0544896 0.01 0.00147828 -0.0273211 0.01 -0.011536 -0.0802417 0 -0.011536 -0.0802417 0.01 -0.0025 -8.83705e-17 0.01 -0.00652537 -0.0537448 0.01 -0.00350775 -0.0269477 0.01 -0.0025 -8.83705e-17 0 -0.00652537 -0.0537448 0 -0.00350775 -0.0269477 0 -0.0025 -8.83705e-17 0 -0.0025 -8.83705e-17 0.01 -0.011536 0.0802417 0.01 -0.00350775 0.0269477 0.01 -0.00652537 0.0537448 0.01 -0.011536 0.0802417 0 -0.00350775 0.0269477 0 -0.00652537 0.0537448 0 -0.011536 0.0802417 0 -0.00666122 0.0813537 0 -0.00666122 0.0813537 0.01 -0.011536 0.0802417 0.01 0.0025 -8.95952e-17 0 0.0025 -8.95952e-17 0.01 -0.00666122 0.0813537 0.01 0.00147828 0.0273211 0.01 -0.00158115 0.0544896 0.01 -0.00666122 0.0813537 0 0.00147828 0.0273211 0 -0.00158115 0.0544896 0 + + + 0 3 2 1 0 2 16 4 5 16 7 4 17 8 7 17 7 16 13 6 8 13 8 17 10 6 13 14 10 13 15 11 10 15 10 14 12 9 11 12 11 15 21 19 18 21 18 24 22 24 25 22 21 24 20 25 23 20 22 25 38 26 27 38 29 26 39 30 29 39 29 38 28 30 39 35 28 39 32 28 35 36 32 35 37 33 32 37 32 36 31 33 37 34 31 37 43 41 40 43 40 46 44 46 47 44 43 46 42 47 45 42 44 47 51 49 48 51 48 54 52 54 55 52 51 54 50 55 53 50 52 55 56 59 58 57 56 58 63 61 60 63 60 66 64 66 67 64 63 66 62 67 65 62 64 67 + 3 6 9 12 15 18 21 24 27 30 33 36 39 42 45 48 51 54 57 60 63 66 69 72 75 78 81 84 87 90 93 96 99 102 105 108 111 114 117 120 123 126 129 132 135 138 141 144 147 150 153 156 + + + + + -0.0115936 -0.0807532 0 -0.00671883 -0.0818652 0 -0.00671883 -0.0818652 0.01 -0.0115936 -0.0807532 0.01 -0.0115936 -0.0807532 0 -0.00671883 -0.0818652 0 -0.0025 -8.89339e-17 0 -0.00655103 -0.0540874 0 -0.00351417 -0.0271195 0 -0.0115936 0.0807532 0 -0.00351417 0.0271195 0 -0.00655103 0.0540874 0 -0.00671883 0.0818652 0 0.0025 -9.01585e-17 0 0.00147186 0.0274929 0 -0.00160681 0.0548322 0 -0.00160681 -0.0548322 0 0.00147186 -0.0274929 0 -0.00671883 -0.0818652 0 -0.00671883 -0.0818652 0.01 0.0025 -9.01585e-17 0.01 -0.00160681 -0.0548322 0.01 0.00147186 -0.0274929 0.01 0.0025 -9.01585e-17 0 -0.00160681 -0.0548322 0 0.00147186 -0.0274929 0 -0.0115936 -0.0807532 0.01 -0.00671883 -0.0818652 0.01 -0.0025 -8.89339e-17 0.01 -0.00655103 -0.0540874 0.01 -0.00351417 -0.0271195 0.01 -0.0115936 0.0807532 0.01 -0.00351417 0.0271195 0.01 -0.00655103 0.0540874 0.01 -0.00671883 0.0818652 0.01 0.0025 -9.01585e-17 0.01 0.00147186 0.0274929 0.01 -0.00160681 0.0548322 0.01 -0.00160681 -0.0548322 0.01 0.00147186 -0.0274929 0.01 -0.0115936 -0.0807532 0 -0.0115936 -0.0807532 0.01 -0.0025 -8.89339e-17 0.01 -0.00655103 -0.0540874 0.01 -0.00351417 -0.0271195 0.01 -0.0025 -8.89339e-17 0 -0.00655103 -0.0540874 0 -0.00351417 -0.0271195 0 -0.0025 -8.89339e-17 0 -0.0025 -8.89339e-17 0.01 -0.0115936 0.0807532 0.01 -0.00351417 0.0271195 0.01 -0.00655103 0.0540874 0.01 -0.0115936 0.0807532 0 -0.00351417 0.0271195 0 -0.00655103 0.0540874 0 -0.0115936 0.0807532 0 -0.00671883 0.0818652 0 -0.00671883 0.0818652 0.01 -0.0115936 0.0807532 0.01 0.0025 -9.01585e-17 0 0.0025 -9.01585e-17 0.01 -0.00671883 0.0818652 0.01 0.00147186 0.0274929 0.01 -0.00160681 0.0548322 0.01 -0.00671883 0.0818652 0 0.00147186 0.0274929 0 -0.00160681 0.0548322 0 + + + 1 3 2 1 0 3 16 4 5 16 7 4 17 8 7 17 7 16 13 6 8 13 8 17 10 6 13 14 10 13 15 11 10 15 10 14 9 11 15 12 9 15 21 19 18 21 18 24 22 24 25 22 21 24 20 25 23 20 22 25 38 26 27 38 29 26 39 30 29 39 29 38 35 28 30 35 30 39 32 28 35 36 32 35 37 33 32 37 32 36 31 33 37 34 31 37 43 41 40 43 40 46 44 46 47 44 43 46 42 47 45 42 44 47 51 49 48 51 48 54 52 54 55 52 51 54 50 55 53 50 52 55 56 59 58 57 56 58 63 61 60 63 60 66 64 66 67 64 63 66 62 67 65 62 64 67 + 3 6 9 12 15 18 21 24 27 30 33 36 39 42 45 48 51 54 57 60 63 66 69 72 75 78 81 84 87 90 93 96 99 102 105 108 111 114 117 120 123 126 129 132 135 138 141 144 147 150 153 156 + + + + + -0.0117739 -0.0823545 0 -0.00689915 -0.0834665 0 -0.00689915 -0.0834665 0.01 -0.0117739 -0.0823545 0.01 -0.0117739 -0.0823545 0 -0.00689915 -0.0834665 0 -0.0025 -9.06973e-17 0 -0.00663136 -0.0551599 0 -0.00353428 -0.0276572 0 -0.0117739 0.0823545 0 -0.00353428 0.0276572 0 -0.00663136 0.0551599 0 -0.00689915 0.0834665 0 0.0025 -9.1922e-17 0 0.00145175 0.0280307 0 -0.00168714 0.0559047 0 -0.00168714 -0.0559047 0 0.00145175 -0.0280307 0 -0.00689915 -0.0834665 0 -0.00689915 -0.0834665 0.01 0.0025 -9.1922e-17 0.01 -0.00168714 -0.0559047 0.01 0.00145175 -0.0280307 0.01 0.0025 -9.1922e-17 0 -0.00168714 -0.0559047 0 0.00145175 -0.0280307 0 -0.0117739 -0.0823545 0.01 -0.00689915 -0.0834665 0.01 -0.0025 -9.06973e-17 0.01 -0.00663136 -0.0551599 0.01 -0.00353428 -0.0276572 0.01 -0.0117739 0.0823545 0.01 -0.00353428 0.0276572 0.01 -0.00663136 0.0551599 0.01 -0.00689915 0.0834665 0.01 0.0025 -9.1922e-17 0.01 0.00145175 0.0280307 0.01 -0.00168714 0.0559047 0.01 -0.00168714 -0.0559047 0.01 0.00145175 -0.0280307 0.01 -0.0117739 -0.0823545 0 -0.0117739 -0.0823545 0.01 -0.0025 -9.06973e-17 0.01 -0.00663136 -0.0551599 0.01 -0.00353428 -0.0276572 0.01 -0.0025 -9.06973e-17 0 -0.00663136 -0.0551599 0 -0.00353428 -0.0276572 0 -0.0025 -9.06973e-17 0 -0.0025 -9.06973e-17 0.01 -0.0117739 0.0823545 0.01 -0.00353428 0.0276572 0.01 -0.00663136 0.0551599 0.01 -0.0117739 0.0823545 0 -0.00353428 0.0276572 0 -0.00663136 0.0551599 0 -0.0117739 0.0823545 0 -0.00689915 0.0834665 0 -0.00689915 0.0834665 0.01 -0.0117739 0.0823545 0.01 0.0025 -9.1922e-17 0 0.0025 -9.1922e-17 0.01 -0.00689915 0.0834665 0.01 0.00145175 0.0280307 0.01 -0.00168714 0.0559047 0.01 -0.00689915 0.0834665 0 0.00145175 0.0280307 0 -0.00168714 0.0559047 0 + + + 1 3 2 1 0 3 16 4 5 16 7 4 17 8 7 17 7 16 6 8 17 13 6 17 10 6 13 14 10 13 15 11 10 15 10 14 12 9 11 12 11 15 21 19 18 21 18 24 22 24 25 22 21 24 20 25 23 20 22 25 38 26 27 38 29 26 39 30 29 39 29 38 28 30 39 35 28 39 32 28 35 36 32 35 37 33 32 37 32 36 34 31 33 34 33 37 43 41 40 43 40 46 44 46 47 44 43 46 42 47 45 42 44 47 51 49 48 51 48 54 52 54 55 52 51 54 50 55 53 50 52 55 56 59 58 57 56 58 63 61 60 63 60 66 64 66 67 64 63 66 62 67 65 62 64 67 + 3 6 9 12 15 18 21 24 27 30 33 36 39 42 45 48 51 54 57 60 63 66 69 72 75 78 81 84 87 90 93 96 99 102 105 108 111 114 117 120 123 126 129 132 135 138 141 144 147 150 153 156 + + + + + -0.0118315 -0.082866 0 -0.00695675 -0.083978 0 -0.00695675 -0.083978 0.01 -0.0118315 -0.082866 0.01 -0.0118315 -0.082866 0 -0.00695675 -0.083978 0 -0.0025 -9.12607e-17 0 -0.00665702 -0.0555025 0 -0.00354071 -0.027829 0 -0.0118315 0.082866 0 -0.00354071 0.027829 0 -0.00665702 0.0555025 0 -0.00695675 0.083978 0 0.0025 -9.24853e-17 0 0.00144533 0.0282024 0 -0.0017128 0.0562473 0 -0.0017128 -0.0562473 0 0.00144533 -0.0282024 0 -0.00695675 -0.083978 0 -0.00695675 -0.083978 0.01 0.0025 -9.24853e-17 0.01 -0.0017128 -0.0562473 0.01 0.00144533 -0.0282024 0.01 0.0025 -9.24853e-17 0 -0.0017128 -0.0562473 0 0.00144533 -0.0282024 0 -0.0118315 -0.082866 0.01 -0.00695675 -0.083978 0.01 -0.0025 -9.12607e-17 0.01 -0.00665702 -0.0555025 0.01 -0.00354071 -0.027829 0.01 -0.0118315 0.082866 0.01 -0.00354071 0.027829 0.01 -0.00665702 0.0555025 0.01 -0.00695675 0.083978 0.01 0.0025 -9.24853e-17 0.01 0.00144533 0.0282024 0.01 -0.0017128 0.0562473 0.01 -0.0017128 -0.0562473 0.01 0.00144533 -0.0282024 0.01 -0.0118315 -0.082866 0 -0.0118315 -0.082866 0.01 -0.0025 -9.12607e-17 0.01 -0.00665702 -0.0555025 0.01 -0.00354071 -0.027829 0.01 -0.0025 -9.12607e-17 0 -0.00665702 -0.0555025 0 -0.00354071 -0.027829 0 -0.0025 -9.12607e-17 0 -0.0025 -9.12607e-17 0.01 -0.0118315 0.082866 0.01 -0.00354071 0.027829 0.01 -0.00665702 0.0555025 0.01 -0.0118315 0.082866 0 -0.00354071 0.027829 0 -0.00665702 0.0555025 0 -0.0118315 0.082866 0 -0.00695675 0.083978 0 -0.00695675 0.083978 0.01 -0.0118315 0.082866 0.01 0.0025 -9.24853e-17 0 0.0025 -9.24853e-17 0.01 -0.00695675 0.083978 0.01 0.00144533 0.0282024 0.01 -0.0017128 0.0562473 0.01 -0.00695675 0.083978 0 0.00144533 0.0282024 0 -0.0017128 0.0562473 0 + + + 0 3 2 1 0 2 16 4 5 16 7 4 17 8 7 17 7 16 6 8 17 13 6 17 10 6 13 14 10 13 15 11 10 15 10 14 12 9 11 12 11 15 21 19 18 21 18 24 22 24 25 22 21 24 20 25 23 20 22 25 38 26 27 38 29 26 39 30 29 39 29 38 28 30 39 35 28 39 32 28 35 36 32 35 37 33 32 37 32 36 34 31 33 34 33 37 43 41 40 43 40 46 44 46 47 44 43 46 42 47 45 42 44 47 51 49 48 51 48 54 52 54 55 52 51 54 50 55 53 50 52 55 56 59 58 57 56 58 63 61 60 63 60 66 64 66 67 64 63 66 62 67 65 62 64 67 + 3 6 9 12 15 18 21 24 27 30 33 36 39 42 45 48 51 54 57 60 63 66 69 72 75 78 81 84 87 90 93 96 99 102 105 108 111 114 117 120 123 126 129 132 135 138 141 144 147 150 153 156 + + + + + -0.0120118 -0.0844673 0 -0.00713707 -0.0855793 0 -0.00713707 -0.0855793 0.01 -0.0120118 -0.0844673 0.01 -0.0120118 -0.0844673 0 -0.00713707 -0.0855793 0 -0.0025 -9.30242e-17 0 -0.00673735 -0.056575 0 -0.00356082 -0.0283668 0 -0.0120118 0.0844673 0 -0.00356082 0.0283668 0 -0.00673735 0.056575 0 -0.00713707 0.0855793 0 0.0025 -9.42488e-17 0 0.00142522 0.0287402 0 -0.00179313 0.0573198 0 -0.00179313 -0.0573198 0 0.00142522 -0.0287402 0 -0.00713707 -0.0855793 0 -0.00713707 -0.0855793 0.01 0.0025 -9.42488e-17 0.01 -0.00179313 -0.0573198 0.01 0.00142522 -0.0287402 0.01 0.0025 -9.42488e-17 0 -0.00179313 -0.0573198 0 0.00142522 -0.0287402 0 -0.0120118 -0.0844673 0.01 -0.00713707 -0.0855793 0.01 -0.0025 -9.30242e-17 0.01 -0.00673735 -0.056575 0.01 -0.00356082 -0.0283668 0.01 -0.0120118 0.0844673 0.01 -0.00356082 0.0283668 0.01 -0.00673735 0.056575 0.01 -0.00713707 0.0855793 0.01 0.0025 -9.42488e-17 0.01 0.00142522 0.0287402 0.01 -0.00179313 0.0573198 0.01 -0.00179313 -0.0573198 0.01 0.00142522 -0.0287402 0.01 -0.0120118 -0.0844673 0 -0.0120118 -0.0844673 0.01 -0.0025 -9.30242e-17 0.01 -0.00673735 -0.056575 0.01 -0.00356082 -0.0283668 0.01 -0.0025 -9.30242e-17 0 -0.00673735 -0.056575 0 -0.00356082 -0.0283668 0 -0.0025 -9.30242e-17 0 -0.0025 -9.30242e-17 0.01 -0.0120118 0.0844673 0.01 -0.00356082 0.0283668 0.01 -0.00673735 0.056575 0.01 -0.0120118 0.0844673 0 -0.00356082 0.0283668 0 -0.00673735 0.056575 0 -0.0120118 0.0844673 0 -0.00713707 0.0855793 0 -0.00713707 0.0855793 0.01 -0.0120118 0.0844673 0.01 0.0025 -9.42488e-17 0 0.0025 -9.42488e-17 0.01 -0.00713707 0.0855793 0.01 0.00142522 0.0287402 0.01 -0.00179313 0.0573198 0.01 -0.00713707 0.0855793 0 0.00142522 0.0287402 0 -0.00179313 0.0573198 0 + + + 0 3 2 1 0 2 16 4 5 16 7 4 17 8 7 17 7 16 6 8 17 13 6 17 10 6 13 14 10 13 15 11 10 15 10 14 12 9 11 12 11 15 21 19 18 21 18 24 22 24 25 22 21 24 20 25 23 20 22 25 38 26 27 38 29 26 39 30 29 39 29 38 28 30 39 35 28 39 32 28 35 36 32 35 37 33 32 37 32 36 34 31 33 34 33 37 43 41 40 43 40 46 44 46 47 44 43 46 42 47 45 42 44 47 51 49 48 51 48 54 52 54 55 52 51 54 50 55 53 50 52 55 56 59 58 57 56 58 63 61 60 63 60 66 64 66 67 64 63 66 62 67 65 62 64 67 + 3 6 9 12 15 18 21 24 27 30 33 36 39 42 45 48 51 54 57 60 63 66 69 72 75 78 81 84 87 90 93 96 99 102 105 108 111 114 117 120 123 126 129 132 135 138 141 144 147 150 153 156 + + + + + -0.0120669 -0.0849566 0 -0.00719217 -0.0860686 0 -0.00719217 -0.0860686 0.01 -0.0120669 -0.0849566 0.01 -0.0120669 -0.0849566 0 -0.00719217 -0.0860686 0 -0.0025 -9.3563e-17 0 -0.00676189 -0.0569028 0 -0.00356696 -0.0285311 0 -0.0120669 0.0849566 0 -0.00356696 0.0285311 0 -0.00676189 0.0569028 0 -0.00719217 0.0860686 0 0.0025 -9.47877e-17 0 0.00141907 0.0289045 0 -0.00181768 0.0576476 0 -0.00181768 -0.0576476 0 0.00141907 -0.0289045 0 -0.00719217 -0.0860686 0 -0.00719217 -0.0860686 0.01 0.0025 -9.47877e-17 0.01 -0.00181768 -0.0576476 0.01 0.00141907 -0.0289045 0.01 0.0025 -9.47877e-17 0 -0.00181768 -0.0576476 0 0.00141907 -0.0289045 0 -0.0120669 -0.0849566 0.01 -0.00719217 -0.0860686 0.01 -0.0025 -9.3563e-17 0.01 -0.00676189 -0.0569028 0.01 -0.00356696 -0.0285311 0.01 -0.0120669 0.0849566 0.01 -0.00356696 0.0285311 0.01 -0.00676189 0.0569028 0.01 -0.00719217 0.0860686 0.01 0.0025 -9.47877e-17 0.01 0.00141907 0.0289045 0.01 -0.00181768 0.0576476 0.01 -0.00181768 -0.0576476 0.01 0.00141907 -0.0289045 0.01 -0.0120669 -0.0849566 0 -0.0120669 -0.0849566 0.01 -0.0025 -9.3563e-17 0.01 -0.00676189 -0.0569028 0.01 -0.00356696 -0.0285311 0.01 -0.0025 -9.3563e-17 0 -0.00676189 -0.0569028 0 -0.00356696 -0.0285311 0 -0.0025 -9.3563e-17 0 -0.0025 -9.3563e-17 0.01 -0.0120669 0.0849566 0.01 -0.00356696 0.0285311 0.01 -0.00676189 0.0569028 0.01 -0.0120669 0.0849566 0 -0.00356696 0.0285311 0 -0.00676189 0.0569028 0 -0.0120669 0.0849566 0 -0.00719217 0.0860686 0 -0.00719217 0.0860686 0.01 -0.0120669 0.0849566 0.01 0.0025 -9.47877e-17 0 0.0025 -9.47877e-17 0.01 -0.00719217 0.0860686 0.01 0.00141907 0.0289045 0.01 -0.00181768 0.0576476 0.01 -0.00719217 0.0860686 0 0.00141907 0.0289045 0 -0.00181768 0.0576476 0 + + + 0 3 2 1 0 2 16 4 5 16 7 4 17 8 7 17 7 16 13 6 8 13 8 17 10 6 13 14 10 13 15 11 10 15 10 14 12 9 11 12 11 15 21 19 18 21 18 24 22 24 25 22 21 24 20 25 23 20 22 25 38 26 27 38 29 26 39 30 29 39 29 38 35 28 30 35 30 39 32 28 35 36 32 35 37 33 32 37 32 36 34 31 33 34 33 37 43 41 40 43 40 46 44 46 47 44 43 46 42 47 45 42 44 47 51 49 48 51 48 54 52 54 55 52 51 54 50 55 53 50 52 55 56 59 58 57 56 58 63 61 60 63 60 66 64 66 67 64 63 66 62 67 65 62 64 67 + 3 6 9 12 15 18 21 24 27 30 33 36 39 42 45 48 51 54 57 60 63 66 69 72 75 78 81 84 87 90 93 96 99 102 105 108 111 114 117 120 123 126 129 132 135 138 141 144 147 150 153 156 + + + + + -0.0122473 -0.0865578 0 -0.00737248 -0.0876698 0 -0.00737248 -0.0876698 0.01 -0.0122473 -0.0865578 0.01 -0.0122473 -0.0865578 0 -0.00737248 -0.0876698 0 -0.0025 -9.53265e-17 0 -0.00684222 -0.0579753 0 -0.00358707 -0.0290688 0 -0.0122473 0.0865578 0 -0.00358707 0.0290688 0 -0.00684222 0.0579753 0 -0.00737248 0.0876698 0 0.0025 -9.65512e-17 0 0.00139896 0.0294423 0 -0.00189801 0.0587201 0 -0.00189801 -0.0587201 0 0.00139896 -0.0294423 0 -0.00737248 -0.0876698 0 -0.00737248 -0.0876698 0.01 0.0025 -9.65512e-17 0.01 -0.00189801 -0.0587201 0.01 0.00139896 -0.0294423 0.01 0.0025 -9.65512e-17 0 -0.00189801 -0.0587201 0 0.00139896 -0.0294423 0 -0.0122473 -0.0865578 0.01 -0.00737248 -0.0876698 0.01 -0.0025 -9.53265e-17 0.01 -0.00684222 -0.0579753 0.01 -0.00358707 -0.0290688 0.01 -0.0122473 0.0865578 0.01 -0.00358707 0.0290688 0.01 -0.00684222 0.0579753 0.01 -0.00737248 0.0876698 0.01 0.0025 -9.65512e-17 0.01 0.00139896 0.0294423 0.01 -0.00189801 0.0587201 0.01 -0.00189801 -0.0587201 0.01 0.00139896 -0.0294423 0.01 -0.0122473 -0.0865578 0 -0.0122473 -0.0865578 0.01 -0.0025 -9.53265e-17 0.01 -0.00684222 -0.0579753 0.01 -0.00358707 -0.0290688 0.01 -0.0025 -9.53265e-17 0 -0.00684222 -0.0579753 0 -0.00358707 -0.0290688 0 -0.0025 -9.53265e-17 0 -0.0025 -9.53265e-17 0.01 -0.0122473 0.0865578 0.01 -0.00358707 0.0290688 0.01 -0.00684222 0.0579753 0.01 -0.0122473 0.0865578 0 -0.00358707 0.0290688 0 -0.00684222 0.0579753 0 -0.0122473 0.0865578 0 -0.00737248 0.0876698 0 -0.00737248 0.0876698 0.01 -0.0122473 0.0865578 0.01 0.0025 -9.65512e-17 0 0.0025 -9.65512e-17 0.01 -0.00737248 0.0876698 0.01 0.00139896 0.0294423 0.01 -0.00189801 0.0587201 0.01 -0.00737248 0.0876698 0 0.00139896 0.0294423 0 -0.00189801 0.0587201 0 + + + 1 3 2 1 0 3 7 4 5 16 7 5 8 7 16 17 8 16 6 8 17 13 6 17 10 6 13 14 10 13 15 11 10 15 10 14 9 11 15 12 9 15 21 19 18 21 18 24 22 24 25 22 21 24 20 25 23 20 22 25 29 26 27 38 29 27 30 29 38 39 30 38 28 30 39 35 28 39 32 28 35 36 32 35 37 33 32 37 32 36 31 33 37 34 31 37 43 41 40 43 40 46 44 46 47 44 43 46 42 47 45 42 44 47 51 49 48 51 48 54 52 54 55 52 51 54 50 55 53 50 52 55 56 59 58 57 56 58 63 61 60 63 60 66 64 66 67 64 63 66 62 67 65 62 64 67 + 3 6 9 12 15 18 21 24 27 30 33 36 39 42 45 48 51 54 57 60 63 66 69 72 75 78 81 84 87 90 93 96 99 102 105 108 111 114 117 120 123 126 129 132 135 138 141 144 147 150 153 156 + + + + + -0.0123049 -0.0870694 0 -0.00743009 -0.0881814 0 -0.00743009 -0.0881814 0.01 -0.0123049 -0.0870694 0.01 -0.0123049 -0.0870694 0 -0.00743009 -0.0881814 0 -0.0025 -9.58898e-17 0 -0.00686788 -0.0583179 0 -0.0035935 -0.0292406 0 -0.0123049 0.0870694 0 -0.0035935 0.0292406 0 -0.00686788 0.0583179 0 -0.00743009 0.0881814 0 0.0025 -9.71145e-17 0 0.00139254 0.0296141 0 -0.00192367 0.0590627 0 -0.00192367 -0.0590627 0 0.00139254 -0.0296141 0 -0.00743009 -0.0881814 0 -0.00743009 -0.0881814 0.01 0.0025 -9.71145e-17 0.01 -0.00192367 -0.0590627 0.01 0.00139254 -0.0296141 0.01 0.0025 -9.71145e-17 0 -0.00192367 -0.0590627 0 0.00139254 -0.0296141 0 -0.0123049 -0.0870694 0.01 -0.00743009 -0.0881814 0.01 -0.0025 -9.58898e-17 0.01 -0.00686788 -0.0583179 0.01 -0.0035935 -0.0292406 0.01 -0.0123049 0.0870694 0.01 -0.0035935 0.0292406 0.01 -0.00686788 0.0583179 0.01 -0.00743009 0.0881814 0.01 0.0025 -9.71145e-17 0.01 0.00139254 0.0296141 0.01 -0.00192367 0.0590627 0.01 -0.00192367 -0.0590627 0.01 0.00139254 -0.0296141 0.01 -0.0123049 -0.0870694 0 -0.0123049 -0.0870694 0.01 -0.0025 -9.58898e-17 0.01 -0.00686788 -0.0583179 0.01 -0.0035935 -0.0292406 0.01 -0.0025 -9.58898e-17 0 -0.00686788 -0.0583179 0 -0.0035935 -0.0292406 0 -0.0025 -9.58898e-17 0 -0.0025 -9.58898e-17 0.01 -0.0123049 0.0870694 0.01 -0.0035935 0.0292406 0.01 -0.00686788 0.0583179 0.01 -0.0123049 0.0870694 0 -0.0035935 0.0292406 0 -0.00686788 0.0583179 0 -0.0123049 0.0870694 0 -0.00743009 0.0881814 0 -0.00743009 0.0881814 0.01 -0.0123049 0.0870694 0.01 0.0025 -9.71145e-17 0 0.0025 -9.71145e-17 0.01 -0.00743009 0.0881814 0.01 0.00139254 0.0296141 0.01 -0.00192367 0.0590627 0.01 -0.00743009 0.0881814 0 0.00139254 0.0296141 0 -0.00192367 0.0590627 0 + + + 1 3 2 1 0 3 16 4 5 16 7 4 17 8 7 17 7 16 6 8 17 13 6 17 10 6 13 14 10 13 15 11 10 15 10 14 9 11 15 12 9 15 21 19 18 21 18 24 22 24 25 22 21 24 20 25 23 20 22 25 38 26 27 38 29 26 39 30 29 39 29 38 28 30 39 35 28 39 32 28 35 36 32 35 37 33 32 37 32 36 31 33 37 34 31 37 43 41 40 43 40 46 44 46 47 44 43 46 42 47 45 42 44 47 51 49 48 51 48 54 52 54 55 52 51 54 50 55 53 50 52 55 56 59 58 57 56 58 63 61 60 63 60 66 64 66 67 64 63 66 62 67 65 62 64 67 + 3 6 9 12 15 18 21 24 27 30 33 36 39 42 45 48 51 54 57 60 63 66 69 72 75 78 81 84 87 90 93 96 99 102 105 108 111 114 117 120 123 126 129 132 135 138 141 144 147 150 153 156 + + + + + -0.0124852 -0.0886706 0 -0.00761041 -0.0897826 0 -0.00761041 -0.0897826 0.01 -0.0124852 -0.0886706 0.01 -0.0124852 -0.0886706 0 -0.00761041 -0.0897826 0 -0.0025 -9.76533e-17 0 -0.00694821 -0.0593904 0 -0.00361361 -0.0297784 0 -0.0124852 0.0886706 0 -0.00361361 0.0297784 0 -0.00694821 0.0593904 0 -0.00761041 0.0897826 0 0.0025 -9.8878e-17 0 0.00137243 0.0301518 0 -0.002004 0.0601352 0 -0.002004 -0.0601352 0 0.00137243 -0.0301518 0 -0.00761041 -0.0897826 0 -0.00761041 -0.0897826 0.01 0.0025 -9.8878e-17 0.01 -0.002004 -0.0601352 0.01 0.00137243 -0.0301518 0.01 0.0025 -9.8878e-17 0 -0.002004 -0.0601352 0 0.00137243 -0.0301518 0 -0.0124852 -0.0886706 0.01 -0.00761041 -0.0897826 0.01 -0.0025 -9.76533e-17 0.01 -0.00694821 -0.0593904 0.01 -0.00361361 -0.0297784 0.01 -0.0124852 0.0886706 0.01 -0.00361361 0.0297784 0.01 -0.00694821 0.0593904 0.01 -0.00761041 0.0897826 0.01 0.0025 -9.8878e-17 0.01 0.00137243 0.0301518 0.01 -0.002004 0.0601352 0.01 -0.002004 -0.0601352 0.01 0.00137243 -0.0301518 0.01 -0.0124852 -0.0886706 0 -0.0124852 -0.0886706 0.01 -0.0025 -9.76533e-17 0.01 -0.00694821 -0.0593904 0.01 -0.00361361 -0.0297784 0.01 -0.0025 -9.76533e-17 0 -0.00694821 -0.0593904 0 -0.00361361 -0.0297784 0 -0.0025 -9.76533e-17 0 -0.0025 -9.76533e-17 0.01 -0.0124852 0.0886706 0.01 -0.00361361 0.0297784 0.01 -0.00694821 0.0593904 0.01 -0.0124852 0.0886706 0 -0.00361361 0.0297784 0 -0.00694821 0.0593904 0 -0.0124852 0.0886706 0 -0.00761041 0.0897826 0 -0.00761041 0.0897826 0.01 -0.0124852 0.0886706 0.01 0.0025 -9.8878e-17 0 0.0025 -9.8878e-17 0.01 -0.00761041 0.0897826 0.01 0.00137243 0.0301518 0.01 -0.002004 0.0601352 0.01 -0.00761041 0.0897826 0 0.00137243 0.0301518 0 -0.002004 0.0601352 0 + + + 1 3 2 1 0 3 16 4 5 16 7 4 17 8 7 17 7 16 6 8 17 13 6 17 10 6 13 14 10 13 15 11 10 15 10 14 12 9 11 12 11 15 21 19 18 21 18 24 22 24 25 22 21 24 20 25 23 20 22 25 29 26 27 38 29 27 30 29 38 39 30 38 28 30 39 35 28 39 32 28 35 36 32 35 33 32 36 37 33 36 34 31 33 34 33 37 43 41 40 43 40 46 44 46 47 44 43 46 42 47 45 42 44 47 51 49 48 51 48 54 52 54 55 52 51 54 50 55 53 50 52 55 56 59 58 57 56 58 63 61 60 63 60 66 64 66 67 64 63 66 62 67 65 62 64 67 + 3 6 9 12 15 18 21 24 27 30 33 36 39 42 45 48 51 54 57 60 63 66 69 72 75 78 81 84 87 90 93 96 99 102 105 108 111 114 117 120 123 126 129 132 135 138 141 144 147 150 153 156 + + + + + -0.0125428 -0.0891822 0 -0.00766801 -0.0902942 0 -0.00766801 -0.0902942 0.01 -0.0125428 -0.0891822 0.01 -0.0125428 -0.0891822 0 -0.00766801 -0.0902942 0 -0.0025 -9.82167e-17 0 -0.00697387 -0.059733 0 -0.00362003 -0.0299502 0 -0.0125428 0.0891822 0 -0.00362003 0.0299502 0 -0.00697387 0.059733 0 -0.00766801 0.0902942 0 0.0025 -9.94413e-17 0 0.001366 0.0303236 0 -0.00202966 0.0604778 0 -0.00202966 -0.0604778 0 0.001366 -0.0303236 0 -0.00766801 -0.0902942 0 -0.00766801 -0.0902942 0.01 0.0025 -9.94413e-17 0.01 -0.00202966 -0.0604778 0.01 0.001366 -0.0303236 0.01 0.0025 -9.94413e-17 0 -0.00202966 -0.0604778 0 0.001366 -0.0303236 0 -0.0125428 -0.0891822 0.01 -0.00766801 -0.0902942 0.01 -0.0025 -9.82167e-17 0.01 -0.00697387 -0.059733 0.01 -0.00362003 -0.0299502 0.01 -0.0125428 0.0891822 0.01 -0.00362003 0.0299502 0.01 -0.00697387 0.059733 0.01 -0.00766801 0.0902942 0.01 0.0025 -9.94413e-17 0.01 0.001366 0.0303236 0.01 -0.00202966 0.0604778 0.01 -0.00202966 -0.0604778 0.01 0.001366 -0.0303236 0.01 -0.0125428 -0.0891822 0 -0.0125428 -0.0891822 0.01 -0.0025 -9.82167e-17 0.01 -0.00697387 -0.059733 0.01 -0.00362003 -0.0299502 0.01 -0.0025 -9.82167e-17 0 -0.00697387 -0.059733 0 -0.00362003 -0.0299502 0 -0.0025 -9.82167e-17 0 -0.0025 -9.82167e-17 0.01 -0.0125428 0.0891822 0.01 -0.00362003 0.0299502 0.01 -0.00697387 0.059733 0.01 -0.0125428 0.0891822 0 -0.00362003 0.0299502 0 -0.00697387 0.059733 0 -0.0125428 0.0891822 0 -0.00766801 0.0902942 0 -0.00766801 0.0902942 0.01 -0.0125428 0.0891822 0.01 0.0025 -9.94413e-17 0 0.0025 -9.94413e-17 0.01 -0.00766801 0.0902942 0.01 0.001366 0.0303236 0.01 -0.00202966 0.0604778 0.01 -0.00766801 0.0902942 0 0.001366 0.0303236 0 -0.00202966 0.0604778 0 + + + 1 3 2 1 0 3 16 4 5 16 7 4 17 8 7 17 7 16 6 8 17 13 6 17 10 6 13 14 10 13 15 11 10 15 10 14 12 9 11 12 11 15 21 19 18 21 18 24 22 24 25 22 21 24 20 25 23 20 22 25 38 26 27 38 29 26 39 30 29 39 29 38 35 28 30 35 30 39 32 28 35 36 32 35 37 33 32 37 32 36 31 33 37 34 31 37 43 41 40 43 40 46 44 46 47 44 43 46 42 47 45 42 44 47 51 49 48 51 48 54 52 54 55 52 51 54 50 55 53 50 52 55 56 59 58 57 56 58 63 61 60 63 60 66 64 66 67 64 63 66 62 67 65 62 64 67 + 3 6 9 12 15 18 21 24 27 30 33 36 39 42 45 48 51 54 57 60 63 66 69 72 75 78 81 84 87 90 93 96 99 102 105 108 111 114 117 120 123 126 129 132 135 138 141 144 147 150 153 156 + + + + + -0.0105868 -0.0718128 0 -0.00571204 -0.0729248 0 -0.00571204 -0.0729248 0.01 -0.0105868 -0.0718128 0.01 -0.0105868 -0.0718128 0 -0.00571204 -0.0729248 0 -0.0025 -7.90877e-17 0 -0.00610253 -0.0480992 0 -0.00340189 -0.024117 0 -0.0105868 0.0718128 0 -0.00340189 0.024117 0 -0.00610253 0.0480992 0 -0.00571204 0.0729248 0 0.0025 -8.03123e-17 0 0.00158414 0.0244904 0 -0.00115831 0.048844 0 -0.00115831 -0.048844 0 0.00158414 -0.0244904 0 -0.00571204 -0.0729248 0 -0.00571204 -0.0729248 0.01 0.0025 -8.03123e-17 0.01 -0.00115831 -0.048844 0.01 0.00158414 -0.0244904 0.01 0.0025 -8.03123e-17 0 -0.00115831 -0.048844 0 0.00158414 -0.0244904 0 -0.0105868 -0.0718128 0.01 -0.00571204 -0.0729248 0.01 -0.0025 -7.90877e-17 0.01 -0.00610253 -0.0480992 0.01 -0.00340189 -0.024117 0.01 -0.0105868 0.0718128 0.01 -0.00340189 0.024117 0.01 -0.00610253 0.0480992 0.01 -0.00571204 0.0729248 0.01 0.0025 -8.03123e-17 0.01 0.00158414 0.0244904 0.01 -0.00115831 0.048844 0.01 -0.00115831 -0.048844 0.01 0.00158414 -0.0244904 0.01 -0.0105868 -0.0718128 0 -0.0105868 -0.0718128 0.01 -0.0025 -7.90877e-17 0.01 -0.00610253 -0.0480992 0.01 -0.00340189 -0.024117 0.01 -0.0025 -7.90877e-17 0 -0.00610253 -0.0480992 0 -0.00340189 -0.024117 0 -0.0025 -7.90877e-17 0 -0.0025 -7.90877e-17 0.01 -0.0105868 0.0718128 0.01 -0.00340189 0.024117 0.01 -0.00610253 0.0480992 0.01 -0.0105868 0.0718128 0 -0.00340189 0.024117 0 -0.00610253 0.0480992 0 -0.0105868 0.0718128 0 -0.00571204 0.0729248 0 -0.00571204 0.0729248 0.01 -0.0105868 0.0718128 0.01 0.0025 -8.03123e-17 0 0.0025 -8.03123e-17 0.01 -0.00571204 0.0729248 0.01 0.00158414 0.0244904 0.01 -0.00115831 0.048844 0.01 -0.00571204 0.0729248 0 0.00158414 0.0244904 0 -0.00115831 0.048844 0 + + + 0 3 2 1 0 2 16 4 5 16 7 4 17 8 7 17 7 16 6 8 17 13 6 17 10 6 13 14 10 13 15 11 10 15 10 14 12 9 11 12 11 15 21 19 18 21 18 24 22 24 25 22 21 24 20 25 23 20 22 25 38 26 27 38 29 26 39 30 29 39 29 38 28 30 39 35 28 39 32 28 35 36 32 35 37 33 32 37 32 36 34 31 33 34 33 37 43 41 40 43 40 46 44 46 47 44 43 46 42 47 45 42 44 47 51 49 48 51 48 54 52 54 55 52 51 54 50 55 53 50 52 55 56 59 58 57 56 58 63 61 60 63 60 66 64 66 67 64 63 66 62 67 65 62 64 67 + 3 6 9 12 15 18 21 24 27 30 33 36 39 42 45 48 51 54 57 60 63 66 69 72 75 78 81 84 87 90 93 96 99 102 105 108 111 114 117 120 123 126 129 132 135 138 141 144 147 150 153 156 + + + + + -0.0106444 -0.0723243 0 -0.00576965 -0.0734363 0 -0.00576965 -0.0734363 0.01 -0.0106444 -0.0723243 0.01 -0.0106444 -0.0723243 0 -0.00576965 -0.0734363 0 -0.0025 -7.9651e-17 0 -0.00612819 -0.0484418 0 -0.00340832 -0.0242888 0 -0.0106444 0.0723243 0 -0.00340832 0.0242888 0 -0.00612819 0.0484418 0 -0.00576965 0.0734363 0 0.0025 -8.08757e-17 0 0.00157772 0.0246622 0 -0.00118397 0.0491866 0 -0.00118397 -0.0491866 0 0.00157772 -0.0246622 0 -0.00576965 -0.0734363 0 -0.00576965 -0.0734363 0.01 0.0025 -8.08757e-17 0.01 -0.00118397 -0.0491866 0.01 0.00157772 -0.0246622 0.01 0.0025 -8.08757e-17 0 -0.00118397 -0.0491866 0 0.00157772 -0.0246622 0 -0.0106444 -0.0723243 0.01 -0.00576965 -0.0734363 0.01 -0.0025 -7.9651e-17 0.01 -0.00612819 -0.0484418 0.01 -0.00340832 -0.0242888 0.01 -0.0106444 0.0723243 0.01 -0.00340832 0.0242888 0.01 -0.00612819 0.0484418 0.01 -0.00576965 0.0734363 0.01 0.0025 -8.08757e-17 0.01 0.00157772 0.0246622 0.01 -0.00118397 0.0491866 0.01 -0.00118397 -0.0491866 0.01 0.00157772 -0.0246622 0.01 -0.0106444 -0.0723243 0 -0.0106444 -0.0723243 0.01 -0.0025 -7.9651e-17 0.01 -0.00612819 -0.0484418 0.01 -0.00340832 -0.0242888 0.01 -0.0025 -7.9651e-17 0 -0.00612819 -0.0484418 0 -0.00340832 -0.0242888 0 -0.0025 -7.9651e-17 0 -0.0025 -7.9651e-17 0.01 -0.0106444 0.0723243 0.01 -0.00340832 0.0242888 0.01 -0.00612819 0.0484418 0.01 -0.0106444 0.0723243 0 -0.00340832 0.0242888 0 -0.00612819 0.0484418 0 -0.0106444 0.0723243 0 -0.00576965 0.0734363 0 -0.00576965 0.0734363 0.01 -0.0106444 0.0723243 0.01 0.0025 -8.08757e-17 0 0.0025 -8.08757e-17 0.01 -0.00576965 0.0734363 0.01 0.00157772 0.0246622 0.01 -0.00118397 0.0491866 0.01 -0.00576965 0.0734363 0 0.00157772 0.0246622 0 -0.00118397 0.0491866 0 + + + 1 3 2 1 0 3 16 4 5 16 7 4 17 8 7 17 7 16 6 8 17 13 6 17 10 6 13 14 10 13 15 11 10 15 10 14 12 9 11 12 11 15 21 19 18 21 18 24 22 24 25 22 21 24 20 25 23 20 22 25 38 26 27 38 29 26 39 30 29 39 29 38 28 30 39 35 28 39 32 28 35 36 32 35 37 33 32 37 32 36 34 31 33 34 33 37 43 41 40 43 40 46 44 46 47 44 43 46 42 47 45 42 44 47 51 49 48 51 48 54 52 54 55 52 51 54 50 55 53 50 52 55 56 59 58 57 56 58 63 61 60 63 60 66 64 66 67 64 63 66 62 67 65 62 64 67 + 3 6 9 12 15 18 21 24 27 30 33 36 39 42 45 48 51 54 57 60 63 66 69 72 75 78 81 84 87 90 93 96 99 102 105 108 111 114 117 120 123 126 129 132 135 138 141 144 147 150 153 156 + + + + + -0.0108247 -0.0739256 0 -0.00594997 -0.0750376 0 -0.00594997 -0.0750376 0.01 -0.0108247 -0.0739256 0.01 -0.0108247 -0.0739256 0 -0.00594997 -0.0750376 0 -0.0025 -8.14145e-17 0 -0.00620852 -0.0495143 0 -0.00342843 -0.0248265 0 -0.0108247 0.0739256 0 -0.00342843 0.0248265 0 -0.00620852 0.0495143 0 -0.00594997 0.0750376 0 0.0025 -8.26392e-17 0 0.00155761 0.0252 0 -0.0012643 0.0502591 0 -0.0012643 -0.0502591 0 0.00155761 -0.0252 0 -0.00594997 -0.0750376 0 -0.00594997 -0.0750376 0.01 0.0025 -8.26392e-17 0.01 -0.0012643 -0.0502591 0.01 0.00155761 -0.0252 0.01 0.0025 -8.26392e-17 0 -0.0012643 -0.0502591 0 0.00155761 -0.0252 0 -0.0108247 -0.0739256 0.01 -0.00594997 -0.0750376 0.01 -0.0025 -8.14145e-17 0.01 -0.00620852 -0.0495143 0.01 -0.00342843 -0.0248265 0.01 -0.0108247 0.0739256 0.01 -0.00342843 0.0248265 0.01 -0.00620852 0.0495143 0.01 -0.00594997 0.0750376 0.01 0.0025 -8.26392e-17 0.01 0.00155761 0.0252 0.01 -0.0012643 0.0502591 0.01 -0.0012643 -0.0502591 0.01 0.00155761 -0.0252 0.01 -0.0108247 -0.0739256 0 -0.0108247 -0.0739256 0.01 -0.0025 -8.14145e-17 0.01 -0.00620852 -0.0495143 0.01 -0.00342843 -0.0248265 0.01 -0.0025 -8.14145e-17 0 -0.00620852 -0.0495143 0 -0.00342843 -0.0248265 0 -0.0025 -8.14145e-17 0 -0.0025 -8.14145e-17 0.01 -0.0108247 0.0739256 0.01 -0.00342843 0.0248265 0.01 -0.00620852 0.0495143 0.01 -0.0108247 0.0739256 0 -0.00342843 0.0248265 0 -0.00620852 0.0495143 0 -0.0108247 0.0739256 0 -0.00594997 0.0750376 0 -0.00594997 0.0750376 0.01 -0.0108247 0.0739256 0.01 0.0025 -8.26392e-17 0 0.0025 -8.26392e-17 0.01 -0.00594997 0.0750376 0.01 0.00155761 0.0252 0.01 -0.0012643 0.0502591 0.01 -0.00594997 0.0750376 0 0.00155761 0.0252 0 -0.0012643 0.0502591 0 + + + 0 3 2 1 0 2 16 4 5 16 7 4 17 8 7 17 7 16 6 8 17 13 6 17 10 6 13 14 10 13 15 11 10 15 10 14 12 9 11 12 11 15 21 19 18 21 18 24 22 24 25 22 21 24 20 25 23 20 22 25 38 26 27 38 29 26 39 30 29 39 29 38 28 30 39 35 28 39 32 28 35 36 32 35 37 33 32 37 32 36 34 31 33 34 33 37 43 41 40 43 40 46 44 46 47 44 43 46 42 47 45 42 44 47 51 49 48 51 48 54 52 54 55 52 51 54 50 55 53 50 52 55 56 59 58 57 56 58 63 61 60 63 60 66 64 66 67 64 63 66 62 67 65 62 64 67 + 3 6 9 12 15 18 21 24 27 30 33 36 39 42 45 48 51 54 57 60 63 66 69 72 75 78 81 84 87 90 93 96 99 102 105 108 111 114 117 120 123 126 129 132 135 138 141 144 147 150 153 156 + + + + + -0.0108798 -0.0744148 0 -0.00600506 -0.0755268 0 -0.00600506 -0.0755268 0.01 -0.0108798 -0.0744148 0.01 -0.0108798 -0.0744148 0 -0.00600506 -0.0755268 0 -0.0025 -8.19534e-17 0 -0.00623306 -0.049842 0 -0.00343457 -0.0249908 0 -0.0108798 0.0744148 0 -0.00343457 0.0249908 0 -0.00623306 0.049842 0 -0.00600506 0.0755268 0 0.0025 -8.3178e-17 0 0.00155146 0.0253643 0 -0.00128885 0.0505868 0 -0.00128885 -0.0505868 0 0.00155146 -0.0253643 0 -0.00600506 -0.0755268 0 -0.00600506 -0.0755268 0.01 0.0025 -8.3178e-17 0.01 -0.00128885 -0.0505868 0.01 0.00155146 -0.0253643 0.01 0.0025 -8.3178e-17 0 -0.00128885 -0.0505868 0 0.00155146 -0.0253643 0 -0.0108798 -0.0744148 0.01 -0.00600506 -0.0755268 0.01 -0.0025 -8.19534e-17 0.01 -0.00623306 -0.049842 0.01 -0.00343457 -0.0249908 0.01 -0.0108798 0.0744148 0.01 -0.00343457 0.0249908 0.01 -0.00623306 0.049842 0.01 -0.00600506 0.0755268 0.01 0.0025 -8.3178e-17 0.01 0.00155146 0.0253643 0.01 -0.00128885 0.0505868 0.01 -0.00128885 -0.0505868 0.01 0.00155146 -0.0253643 0.01 -0.0108798 -0.0744148 0 -0.0108798 -0.0744148 0.01 -0.0025 -8.19534e-17 0.01 -0.00623306 -0.049842 0.01 -0.00343457 -0.0249908 0.01 -0.0025 -8.19534e-17 0 -0.00623306 -0.049842 0 -0.00343457 -0.0249908 0 -0.0025 -8.19534e-17 0 -0.0025 -8.19534e-17 0.01 -0.0108798 0.0744148 0.01 -0.00343457 0.0249908 0.01 -0.00623306 0.049842 0.01 -0.0108798 0.0744148 0 -0.00343457 0.0249908 0 -0.00623306 0.049842 0 -0.0108798 0.0744148 0 -0.00600506 0.0755268 0 -0.00600506 0.0755268 0.01 -0.0108798 0.0744148 0.01 0.0025 -8.3178e-17 0 0.0025 -8.3178e-17 0.01 -0.00600506 0.0755268 0.01 0.00155146 0.0253643 0.01 -0.00128885 0.0505868 0.01 -0.00600506 0.0755268 0 0.00155146 0.0253643 0 -0.00128885 0.0505868 0 + + + 0 3 2 1 0 2 7 4 5 16 7 5 8 7 16 17 8 16 6 8 17 13 6 17 10 6 13 14 10 13 15 11 10 15 10 14 12 9 11 12 11 15 21 19 18 21 18 24 22 24 25 22 21 24 20 25 23 20 22 25 38 26 27 38 29 26 39 30 29 39 29 38 28 30 39 35 28 39 32 28 35 36 32 35 37 33 32 37 32 36 34 31 33 34 33 37 43 41 40 43 40 46 44 46 47 44 43 46 42 47 45 42 44 47 51 49 48 51 48 54 52 54 55 52 51 54 50 55 53 50 52 55 56 59 58 57 56 58 63 61 60 63 60 66 64 66 67 64 63 66 62 67 65 62 64 67 + 3 6 9 12 15 18 21 24 27 30 33 36 39 42 45 48 51 54 57 60 63 66 69 72 75 78 81 84 87 90 93 96 99 102 105 108 111 114 117 120 123 126 129 132 135 138 141 144 147 150 153 156 + + + + + -0.0110602 -0.0760161 0 -0.00618538 -0.0771281 0 -0.00618538 -0.0771281 0.01 -0.0110602 -0.0760161 0.01 -0.0110602 -0.0760161 0 -0.00618538 -0.0771281 0 -0.0025 -8.37169e-17 0 -0.00631339 -0.0509146 0 -0.00345468 -0.0255286 0 -0.0110602 0.0760161 0 -0.00345468 0.0255286 0 -0.00631339 0.0509146 0 -0.00618538 0.0771281 0 0.0025 -8.49415e-17 0 0.00153135 0.025902 0 -0.00136917 0.0516594 0 -0.00136917 -0.0516594 0 0.00153135 -0.025902 0 -0.00618538 -0.0771281 0 -0.00618538 -0.0771281 0.01 0.0025 -8.49415e-17 0.01 -0.00136917 -0.0516594 0.01 0.00153135 -0.025902 0.01 0.0025 -8.49415e-17 0 -0.00136917 -0.0516594 0 0.00153135 -0.025902 0 -0.0110602 -0.0760161 0.01 -0.00618538 -0.0771281 0.01 -0.0025 -8.37169e-17 0.01 -0.00631339 -0.0509146 0.01 -0.00345468 -0.0255286 0.01 -0.0110602 0.0760161 0.01 -0.00345468 0.0255286 0.01 -0.00631339 0.0509146 0.01 -0.00618538 0.0771281 0.01 0.0025 -8.49415e-17 0.01 0.00153135 0.025902 0.01 -0.00136917 0.0516594 0.01 -0.00136917 -0.0516594 0.01 0.00153135 -0.025902 0.01 -0.0110602 -0.0760161 0 -0.0110602 -0.0760161 0.01 -0.0025 -8.37169e-17 0.01 -0.00631339 -0.0509146 0.01 -0.00345468 -0.0255286 0.01 -0.0025 -8.37169e-17 0 -0.00631339 -0.0509146 0 -0.00345468 -0.0255286 0 -0.0025 -8.37169e-17 0 -0.0025 -8.37169e-17 0.01 -0.0110602 0.0760161 0.01 -0.00345468 0.0255286 0.01 -0.00631339 0.0509146 0.01 -0.0110602 0.0760161 0 -0.00345468 0.0255286 0 -0.00631339 0.0509146 0 -0.0110602 0.0760161 0 -0.00618538 0.0771281 0 -0.00618538 0.0771281 0.01 -0.0110602 0.0760161 0.01 0.0025 -8.49415e-17 0 0.0025 -8.49415e-17 0.01 -0.00618538 0.0771281 0.01 0.00153135 0.025902 0.01 -0.00136917 0.0516594 0.01 -0.00618538 0.0771281 0 0.00153135 0.025902 0 -0.00136917 0.0516594 0 + + + 1 3 2 1 0 3 16 4 5 16 7 4 17 8 7 17 7 16 6 8 17 13 6 17 10 6 13 14 10 13 15 11 10 15 10 14 9 11 15 12 9 15 21 19 18 21 18 24 22 24 25 22 21 24 20 25 23 20 22 25 38 26 27 38 29 26 39 30 29 39 29 38 28 30 39 35 28 39 32 28 35 36 32 35 37 33 32 37 32 36 31 33 37 34 31 37 43 41 40 43 40 46 44 46 47 44 43 46 42 47 45 42 44 47 51 49 48 51 48 54 52 54 55 52 51 54 50 55 53 50 52 55 56 59 58 57 56 58 63 61 60 63 60 66 64 66 67 64 63 66 62 67 65 62 64 67 + 3 6 9 12 15 18 21 24 27 30 33 36 39 42 45 48 51 54 57 60 63 66 69 72 75 78 81 84 87 90 93 96 99 102 105 108 111 114 117 120 123 126 129 132 135 138 141 144 147 150 153 156 + + + + + -0.0111178 -0.0765276 0 -0.00624298 -0.0776396 0 -0.00624298 -0.0776396 0.01 -0.0111178 -0.0765276 0.01 -0.0111178 -0.0765276 0 -0.00624298 -0.0776396 0 -0.0025 -8.42802e-17 0 -0.00633905 -0.0512572 0 -0.00346111 -0.0257004 0 -0.0111178 0.0765276 0 -0.00346111 0.0257004 0 -0.00633905 0.0512572 0 -0.00624298 0.0776396 0 0.0025 -8.55048e-17 0 0.00152493 0.0260738 0 -0.00139484 0.052002 0 -0.00139484 -0.052002 0 0.00152493 -0.0260738 0 -0.00624298 -0.0776396 0 -0.00624298 -0.0776396 0.01 0.0025 -8.55048e-17 0.01 -0.00139484 -0.052002 0.01 0.00152493 -0.0260738 0.01 0.0025 -8.55048e-17 0 -0.00139484 -0.052002 0 0.00152493 -0.0260738 0 -0.0111178 -0.0765276 0.01 -0.00624298 -0.0776396 0.01 -0.0025 -8.42802e-17 0.01 -0.00633905 -0.0512572 0.01 -0.00346111 -0.0257004 0.01 -0.0111178 0.0765276 0.01 -0.00346111 0.0257004 0.01 -0.00633905 0.0512572 0.01 -0.00624298 0.0776396 0.01 0.0025 -8.55048e-17 0.01 0.00152493 0.0260738 0.01 -0.00139484 0.052002 0.01 -0.00139484 -0.052002 0.01 0.00152493 -0.0260738 0.01 -0.0111178 -0.0765276 0 -0.0111178 -0.0765276 0.01 -0.0025 -8.42802e-17 0.01 -0.00633905 -0.0512572 0.01 -0.00346111 -0.0257004 0.01 -0.0025 -8.42802e-17 0 -0.00633905 -0.0512572 0 -0.00346111 -0.0257004 0 -0.0025 -8.42802e-17 0 -0.0025 -8.42802e-17 0.01 -0.0111178 0.0765276 0.01 -0.00346111 0.0257004 0.01 -0.00633905 0.0512572 0.01 -0.0111178 0.0765276 0 -0.00346111 0.0257004 0 -0.00633905 0.0512572 0 -0.0111178 0.0765276 0 -0.00624298 0.0776396 0 -0.00624298 0.0776396 0.01 -0.0111178 0.0765276 0.01 0.0025 -8.55048e-17 0 0.0025 -8.55048e-17 0.01 -0.00624298 0.0776396 0.01 0.00152493 0.0260738 0.01 -0.00139484 0.052002 0.01 -0.00624298 0.0776396 0 0.00152493 0.0260738 0 -0.00139484 0.052002 0 + + + 0 3 2 1 0 2 7 4 5 16 7 5 8 7 16 17 8 16 6 8 17 13 6 17 10 6 13 14 10 13 15 11 10 15 10 14 12 9 11 12 11 15 21 19 18 21 18 24 22 24 25 22 21 24 20 25 23 20 22 25 29 26 27 38 29 27 30 29 38 39 30 38 28 30 39 35 28 39 32 28 35 36 32 35 37 33 32 37 32 36 34 31 33 34 33 37 43 41 40 43 40 46 44 46 47 44 43 46 42 47 45 42 44 47 51 49 48 51 48 54 52 54 55 52 51 54 50 55 53 50 52 55 56 59 58 57 56 58 63 61 60 63 60 66 64 66 67 64 63 66 62 67 65 62 64 67 + 3 6 9 12 15 18 21 24 27 30 33 36 39 42 45 48 51 54 57 60 63 66 69 72 75 78 81 84 87 90 93 96 99 102 105 108 111 114 117 120 123 126 129 132 135 138 141 144 147 150 153 156 + + + + + -0.0112981 -0.0781289 0 -0.0064233 -0.0792409 0 -0.0064233 -0.0792409 0.01 -0.0112981 -0.0781289 0.01 -0.0112981 -0.0781289 0 -0.0064233 -0.0792409 0 -0.0025 -8.60437e-17 0 -0.00641938 -0.0523297 0 -0.00348122 -0.0262381 0 -0.0112981 0.0781289 0 -0.00348122 0.0262381 0 -0.00641938 0.0523297 0 -0.0064233 0.0792409 0 0.0025 -8.72683e-17 0 0.00150482 0.0266116 0 -0.00147516 0.0530745 0 -0.00147516 -0.0530745 0 0.00150482 -0.0266116 0 -0.0064233 -0.0792409 0 -0.0064233 -0.0792409 0.01 0.0025 -8.72683e-17 0.01 -0.00147516 -0.0530745 0.01 0.00150482 -0.0266116 0.01 0.0025 -8.72683e-17 0 -0.00147516 -0.0530745 0 0.00150482 -0.0266116 0 -0.0112981 -0.0781289 0.01 -0.0064233 -0.0792409 0.01 -0.0025 -8.60437e-17 0.01 -0.00641938 -0.0523297 0.01 -0.00348122 -0.0262381 0.01 -0.0112981 0.0781289 0.01 -0.00348122 0.0262381 0.01 -0.00641938 0.0523297 0.01 -0.0064233 0.0792409 0.01 0.0025 -8.72683e-17 0.01 0.00150482 0.0266116 0.01 -0.00147516 0.0530745 0.01 -0.00147516 -0.0530745 0.01 0.00150482 -0.0266116 0.01 -0.0112981 -0.0781289 0 -0.0112981 -0.0781289 0.01 -0.0025 -8.60437e-17 0.01 -0.00641938 -0.0523297 0.01 -0.00348122 -0.0262381 0.01 -0.0025 -8.60437e-17 0 -0.00641938 -0.0523297 0 -0.00348122 -0.0262381 0 -0.0025 -8.60437e-17 0 -0.0025 -8.60437e-17 0.01 -0.0112981 0.0781289 0.01 -0.00348122 0.0262381 0.01 -0.00641938 0.0523297 0.01 -0.0112981 0.0781289 0 -0.00348122 0.0262381 0 -0.00641938 0.0523297 0 -0.0112981 0.0781289 0 -0.0064233 0.0792409 0 -0.0064233 0.0792409 0.01 -0.0112981 0.0781289 0.01 0.0025 -8.72683e-17 0 0.0025 -8.72683e-17 0.01 -0.0064233 0.0792409 0.01 0.00150482 0.0266116 0.01 -0.00147516 0.0530745 0.01 -0.0064233 0.0792409 0 0.00150482 0.0266116 0 -0.00147516 0.0530745 0 + + + 1 3 2 1 0 3 16 4 5 16 7 4 17 8 7 17 7 16 6 8 17 13 6 17 10 6 13 14 10 13 15 11 10 15 10 14 12 9 11 12 11 15 21 19 18 21 18 24 22 24 25 22 21 24 20 25 23 20 22 25 38 26 27 38 29 26 39 30 29 39 29 38 28 30 39 35 28 39 32 28 35 36 32 35 37 33 32 37 32 36 34 31 33 34 33 37 43 41 40 43 40 46 44 46 47 44 43 46 42 47 45 42 44 47 51 49 48 51 48 54 52 54 55 52 51 54 50 55 53 50 52 55 56 59 58 57 56 58 63 61 60 63 60 66 64 66 67 64 63 66 62 67 65 62 64 67 + 3 6 9 12 15 18 21 24 27 30 33 36 39 42 45 48 51 54 57 60 63 66 69 72 75 78 81 84 87 90 93 96 99 102 105 108 111 114 117 120 123 126 129 132 135 138 141 144 147 150 153 156 + + + + + -0.0113557 -0.0786404 0 -0.00648091 -0.0797524 0 -0.00648091 -0.0797524 0.01 -0.0113557 -0.0786404 0.01 -0.0113557 -0.0786404 0 -0.00648091 -0.0797524 0 -0.0025 -8.6607e-17 0 -0.00644504 -0.0526723 0 -0.00348764 -0.0264099 0 -0.0113557 0.0786404 0 -0.00348764 0.0264099 0 -0.00644504 0.0526723 0 -0.00648091 0.0797524 0 0.0025 -8.78317e-17 0 0.00149839 0.0267834 0 -0.00150082 0.0534171 0 -0.00150082 -0.0534171 0 0.00149839 -0.0267834 0 -0.00648091 -0.0797524 0 -0.00648091 -0.0797524 0.01 0.0025 -8.78317e-17 0.01 -0.00150082 -0.0534171 0.01 0.00149839 -0.0267834 0.01 0.0025 -8.78317e-17 0 -0.00150082 -0.0534171 0 0.00149839 -0.0267834 0 -0.0113557 -0.0786404 0.01 -0.00648091 -0.0797524 0.01 -0.0025 -8.6607e-17 0.01 -0.00644504 -0.0526723 0.01 -0.00348764 -0.0264099 0.01 -0.0113557 0.0786404 0.01 -0.00348764 0.0264099 0.01 -0.00644504 0.0526723 0.01 -0.00648091 0.0797524 0.01 0.0025 -8.78317e-17 0.01 0.00149839 0.0267834 0.01 -0.00150082 0.0534171 0.01 -0.00150082 -0.0534171 0.01 0.00149839 -0.0267834 0.01 -0.0113557 -0.0786404 0 -0.0113557 -0.0786404 0.01 -0.0025 -8.6607e-17 0.01 -0.00644504 -0.0526723 0.01 -0.00348764 -0.0264099 0.01 -0.0025 -8.6607e-17 0 -0.00644504 -0.0526723 0 -0.00348764 -0.0264099 0 -0.0025 -8.6607e-17 0 -0.0025 -8.6607e-17 0.01 -0.0113557 0.0786404 0.01 -0.00348764 0.0264099 0.01 -0.00644504 0.0526723 0.01 -0.0113557 0.0786404 0 -0.00348764 0.0264099 0 -0.00644504 0.0526723 0 -0.0113557 0.0786404 0 -0.00648091 0.0797524 0 -0.00648091 0.0797524 0.01 -0.0113557 0.0786404 0.01 0.0025 -8.78317e-17 0 0.0025 -8.78317e-17 0.01 -0.00648091 0.0797524 0.01 0.00149839 0.0267834 0.01 -0.00150082 0.0534171 0.01 -0.00648091 0.0797524 0 0.00149839 0.0267834 0 -0.00150082 0.0534171 0 + + + 0 3 2 1 0 2 16 4 5 16 7 4 8 7 16 17 8 16 6 8 17 13 6 17 10 6 13 14 10 13 15 11 10 15 10 14 12 9 11 12 11 15 21 19 18 21 18 24 22 24 25 22 21 24 20 25 23 20 22 25 38 26 27 38 29 26 39 30 29 39 29 38 28 30 39 35 28 39 32 28 35 36 32 35 37 33 32 37 32 36 34 31 33 34 33 37 43 41 40 43 40 46 44 46 47 44 43 46 42 47 45 42 44 47 51 49 48 51 48 54 52 54 55 52 51 54 50 55 53 50 52 55 56 59 58 57 56 58 63 61 60 63 60 66 64 66 67 64 63 66 62 67 65 62 64 67 + 3 6 9 12 15 18 21 24 27 30 33 36 39 42 45 48 51 54 57 60 63 66 69 72 75 78 81 84 87 90 93 96 99 102 105 108 111 114 117 120 123 126 129 132 135 138 141 144 147 150 153 156 + + + + + -0.0138476 -0.100769 0 -0.00897282 -0.101881 0 -0.00897282 -0.101881 0.01 -0.0138476 -0.100769 0.01 -0.0138476 -0.100769 0 -0.00897282 -0.101881 0 -0.0025 -1.10977e-16 0 -0.00755514 -0.0674938 0 -0.00376555 -0.0338414 0 -0.0138476 0.100769 0 -0.00376555 0.0338414 0 -0.00755514 0.0674938 0 -0.00897282 0.101881 0 0.0025 -1.12202e-16 0 0.00122048 0.0342149 0 -0.00261093 0.0682386 0 -0.00261093 -0.0682386 0 0.00122048 -0.0342149 0 -0.00897282 -0.101881 0 -0.00897282 -0.101881 0.01 0.0025 -1.12202e-16 0.01 -0.00261093 -0.0682386 0.01 0.00122048 -0.0342149 0.01 0.0025 -1.12202e-16 0 -0.00261093 -0.0682386 0 0.00122048 -0.0342149 0 -0.0138476 -0.100769 0.01 -0.00897282 -0.101881 0.01 -0.0025 -1.10977e-16 0.01 -0.00755514 -0.0674938 0.01 -0.00376555 -0.0338414 0.01 -0.0138476 0.100769 0.01 -0.00376555 0.0338414 0.01 -0.00755514 0.0674938 0.01 -0.00897282 0.101881 0.01 0.0025 -1.12202e-16 0.01 0.00122048 0.0342149 0.01 -0.00261093 0.0682386 0.01 -0.00261093 -0.0682386 0.01 0.00122048 -0.0342149 0.01 -0.0138476 -0.100769 0 -0.0138476 -0.100769 0.01 -0.0025 -1.10977e-16 0.01 -0.00755514 -0.0674938 0.01 -0.00376555 -0.0338414 0.01 -0.0025 -1.10977e-16 0 -0.00755514 -0.0674938 0 -0.00376555 -0.0338414 0 -0.0025 -1.10977e-16 0 -0.0025 -1.10977e-16 0.01 -0.0138476 0.100769 0.01 -0.00376555 0.0338414 0.01 -0.00755514 0.0674938 0.01 -0.0138476 0.100769 0 -0.00376555 0.0338414 0 -0.00755514 0.0674938 0 -0.0138476 0.100769 0 -0.00897282 0.101881 0 -0.00897282 0.101881 0.01 -0.0138476 0.100769 0.01 0.0025 -1.12202e-16 0 0.0025 -1.12202e-16 0.01 -0.00897282 0.101881 0.01 0.00122048 0.0342149 0.01 -0.00261093 0.0682386 0.01 -0.00897282 0.101881 0 0.00122048 0.0342149 0 -0.00261093 0.0682386 0 + + + 0 3 2 1 0 2 16 4 5 16 7 4 17 8 7 17 7 16 6 8 17 13 6 17 10 6 13 14 10 13 15 11 10 15 10 14 9 11 15 12 9 15 21 19 18 21 18 24 22 24 25 22 21 24 20 25 23 20 22 25 38 26 27 38 29 26 39 30 29 39 29 38 28 30 39 35 28 39 32 28 35 36 32 35 37 33 32 37 32 36 31 33 37 34 31 37 43 41 40 43 40 46 44 46 47 44 43 46 42 47 45 42 44 47 51 49 48 51 48 54 52 54 55 52 51 54 50 55 53 50 52 55 56 59 58 57 56 58 63 61 60 63 60 66 64 66 67 64 63 66 62 67 65 62 64 67 + 3 6 9 12 15 18 21 24 27 30 33 36 39 42 45 48 51 54 57 60 63 66 69 72 75 78 81 84 87 90 93 96 99 102 105 108 111 114 117 120 123 126 129 132 135 138 141 144 147 150 153 156 + + + + + -0.0138852 -0.101103 0 -0.00901039 -0.102215 0 -0.00901039 -0.102215 0.01 -0.0138852 -0.101103 0.01 -0.0138852 -0.101103 0 -0.00901039 -0.102215 0 -0.0025 -1.11345e-16 0 -0.00757188 -0.0677173 0 -0.00376974 -0.0339535 0 -0.0138852 0.101103 0 -0.00376974 0.0339535 0 -0.00757188 0.0677173 0 -0.00901039 0.102215 0 0.0025 -1.1257e-16 0 0.00121629 0.0343269 0 -0.00262766 0.0684621 0 -0.00262766 -0.0684621 0 0.00121629 -0.0343269 0 -0.00901039 -0.102215 0 -0.00901039 -0.102215 0.01 0.0025 -1.1257e-16 0.01 -0.00262766 -0.0684621 0.01 0.00121629 -0.0343269 0.01 0.0025 -1.1257e-16 0 -0.00262766 -0.0684621 0 0.00121629 -0.0343269 0 -0.0138852 -0.101103 0.01 -0.00901039 -0.102215 0.01 -0.0025 -1.11345e-16 0.01 -0.00757188 -0.0677173 0.01 -0.00376974 -0.0339535 0.01 -0.0138852 0.101103 0.01 -0.00376974 0.0339535 0.01 -0.00757188 0.0677173 0.01 -0.00901039 0.102215 0.01 0.0025 -1.1257e-16 0.01 0.00121629 0.0343269 0.01 -0.00262766 0.0684621 0.01 -0.00262766 -0.0684621 0.01 0.00121629 -0.0343269 0.01 -0.0138852 -0.101103 0 -0.0138852 -0.101103 0.01 -0.0025 -1.11345e-16 0.01 -0.00757188 -0.0677173 0.01 -0.00376974 -0.0339535 0.01 -0.0025 -1.11345e-16 0 -0.00757188 -0.0677173 0 -0.00376974 -0.0339535 0 -0.0025 -1.11345e-16 0 -0.0025 -1.11345e-16 0.01 -0.0138852 0.101103 0.01 -0.00376974 0.0339535 0.01 -0.00757188 0.0677173 0.01 -0.0138852 0.101103 0 -0.00376974 0.0339535 0 -0.00757188 0.0677173 0 -0.0138852 0.101103 0 -0.00901039 0.102215 0 -0.00901039 0.102215 0.01 -0.0138852 0.101103 0.01 0.0025 -1.1257e-16 0 0.0025 -1.1257e-16 0.01 -0.00901039 0.102215 0.01 0.00121629 0.0343269 0.01 -0.00262766 0.0684621 0.01 -0.00901039 0.102215 0 0.00121629 0.0343269 0 -0.00262766 0.0684621 0 + + + 1 3 2 1 0 3 16 4 5 16 7 4 17 8 7 17 7 16 13 6 8 13 8 17 10 6 13 14 10 13 15 11 10 15 10 14 9 11 15 12 9 15 21 19 18 21 18 24 22 24 25 22 21 24 20 25 23 20 22 25 38 26 27 38 29 26 39 30 29 39 29 38 28 30 39 35 28 39 32 28 35 36 32 35 37 33 32 37 32 36 31 33 37 34 31 37 43 41 40 43 40 46 44 46 47 44 43 46 42 47 45 42 44 47 51 49 48 51 48 54 52 54 55 52 51 54 50 55 53 50 52 55 56 59 58 57 56 58 63 61 60 63 60 66 64 66 67 64 63 66 62 67 65 62 64 67 + 3 6 9 12 15 18 21 24 27 30 33 36 39 42 45 48 51 54 57 60 63 66 69 72 75 78 81 84 87 90 93 96 99 102 105 108 111 114 117 120 123 126 129 132 135 138 141 144 147 150 153 156 + + + + + -0.0149946 -0.110955 0 -0.0101199 -0.112067 0 -0.0101199 -0.112067 0.01 -0.0149946 -0.110955 0.01 -0.0149946 -0.110955 0 -0.0101199 -0.112067 0 -0.0025 -1.22195e-16 0 -0.00806612 -0.0743162 0 -0.00389348 -0.0372622 0 -0.0149946 0.110955 0 -0.00389348 0.0372622 0 -0.00806612 0.0743162 0 -0.0101199 0.112067 0 0.0025 -1.2342e-16 0 0.00109256 0.0376356 0 -0.00312191 0.075061 0 -0.00312191 -0.075061 0 0.00109256 -0.0376356 0 -0.0101199 -0.112067 0 -0.0101199 -0.112067 0.01 0.0025 -1.2342e-16 0.01 -0.00312191 -0.075061 0.01 0.00109256 -0.0376356 0.01 0.0025 -1.2342e-16 0 -0.00312191 -0.075061 0 0.00109256 -0.0376356 0 -0.0149946 -0.110955 0.01 -0.0101199 -0.112067 0.01 -0.0025 -1.22195e-16 0.01 -0.00806612 -0.0743162 0.01 -0.00389348 -0.0372622 0.01 -0.0149946 0.110955 0.01 -0.00389348 0.0372622 0.01 -0.00806612 0.0743162 0.01 -0.0101199 0.112067 0.01 0.0025 -1.2342e-16 0.01 0.00109256 0.0376356 0.01 -0.00312191 0.075061 0.01 -0.00312191 -0.075061 0.01 0.00109256 -0.0376356 0.01 -0.0149946 -0.110955 0 -0.0149946 -0.110955 0.01 -0.0025 -1.22195e-16 0.01 -0.00806612 -0.0743162 0.01 -0.00389348 -0.0372622 0.01 -0.0025 -1.22195e-16 0 -0.00806612 -0.0743162 0 -0.00389348 -0.0372622 0 -0.0025 -1.22195e-16 0 -0.0025 -1.22195e-16 0.01 -0.0149946 0.110955 0.01 -0.00389348 0.0372622 0.01 -0.00806612 0.0743162 0.01 -0.0149946 0.110955 0 -0.00389348 0.0372622 0 -0.00806612 0.0743162 0 -0.0149946 0.110955 0 -0.0101199 0.112067 0 -0.0101199 0.112067 0.01 -0.0149946 0.110955 0.01 0.0025 -1.2342e-16 0 0.0025 -1.2342e-16 0.01 -0.0101199 0.112067 0.01 0.00109256 0.0376356 0.01 -0.00312191 0.075061 0.01 -0.0101199 0.112067 0 0.00109256 0.0376356 0 -0.00312191 0.075061 0 + + + 1 3 2 1 0 3 16 4 5 16 7 4 8 7 16 17 8 16 6 8 17 13 6 17 10 6 13 14 10 13 15 11 10 15 10 14 12 9 11 12 11 15 21 19 18 21 18 24 22 24 25 22 21 24 20 25 23 20 22 25 38 26 27 38 29 26 30 29 38 39 30 38 28 30 39 35 28 39 32 28 35 36 32 35 37 33 32 37 32 36 34 31 33 34 33 37 43 41 40 43 40 46 44 46 47 44 43 46 42 47 45 42 44 47 51 49 48 51 48 54 52 54 55 52 51 54 50 55 53 50 52 55 56 59 58 57 56 58 63 61 60 63 60 66 64 66 67 64 63 66 62 67 65 62 64 67 + 3 6 9 12 15 18 21 24 27 30 33 36 39 42 45 48 51 54 57 60 63 66 69 72 75 78 81 84 87 90 93 96 99 102 105 108 111 114 117 120 123 126 129 132 135 138 141 144 147 150 153 156 + + + + + -0.0150322 -0.111289 0 -0.0101574 -0.112401 0 -0.0101574 -0.112401 0.01 -0.0150322 -0.111289 0.01 -0.0150322 -0.111289 0 -0.0101574 -0.112401 0 -0.0025 -1.22563e-16 0 -0.00808286 -0.0745396 0 -0.00389767 -0.0373742 0 -0.0150322 0.111289 0 -0.00389767 0.0373742 0 -0.00808286 0.0745396 0 -0.0101574 0.112401 0 0.0025 -1.23787e-16 0 0.00108837 0.0377476 0 -0.00313864 0.0752844 0 -0.00313864 -0.0752844 0 0.00108837 -0.0377476 0 -0.0101574 -0.112401 0 -0.0101574 -0.112401 0.01 0.0025 -1.23787e-16 0.01 -0.00313864 -0.0752844 0.01 0.00108837 -0.0377476 0.01 0.0025 -1.23787e-16 0 -0.00313864 -0.0752844 0 0.00108837 -0.0377476 0 -0.0150322 -0.111289 0.01 -0.0101574 -0.112401 0.01 -0.0025 -1.22563e-16 0.01 -0.00808286 -0.0745396 0.01 -0.00389767 -0.0373742 0.01 -0.0150322 0.111289 0.01 -0.00389767 0.0373742 0.01 -0.00808286 0.0745396 0.01 -0.0101574 0.112401 0.01 0.0025 -1.23787e-16 0.01 0.00108837 0.0377476 0.01 -0.00313864 0.0752844 0.01 -0.00313864 -0.0752844 0.01 0.00108837 -0.0377476 0.01 -0.0150322 -0.111289 0 -0.0150322 -0.111289 0.01 -0.0025 -1.22563e-16 0.01 -0.00808286 -0.0745396 0.01 -0.00389767 -0.0373742 0.01 -0.0025 -1.22563e-16 0 -0.00808286 -0.0745396 0 -0.00389767 -0.0373742 0 -0.0025 -1.22563e-16 0 -0.0025 -1.22563e-16 0.01 -0.0150322 0.111289 0.01 -0.00389767 0.0373742 0.01 -0.00808286 0.0745396 0.01 -0.0150322 0.111289 0 -0.00389767 0.0373742 0 -0.00808286 0.0745396 0 -0.0150322 0.111289 0 -0.0101574 0.112401 0 -0.0101574 0.112401 0.01 -0.0150322 0.111289 0.01 0.0025 -1.23787e-16 0 0.0025 -1.23787e-16 0.01 -0.0101574 0.112401 0.01 0.00108837 0.0377476 0.01 -0.00313864 0.0752844 0.01 -0.0101574 0.112401 0 0.00108837 0.0377476 0 -0.00313864 0.0752844 0 + + + 1 3 2 1 0 3 16 4 5 16 7 4 17 8 7 17 7 16 6 8 17 13 6 17 10 6 13 14 10 13 15 11 10 15 10 14 9 11 15 12 9 15 21 19 18 21 18 24 22 24 25 22 21 24 20 25 23 20 22 25 38 26 27 38 29 26 39 30 29 39 29 38 28 30 39 35 28 39 32 28 35 36 32 35 37 33 32 37 32 36 31 33 37 34 31 37 43 41 40 43 40 46 44 46 47 44 43 46 42 47 45 42 44 47 51 49 48 51 48 54 52 54 55 52 51 54 50 55 53 50 52 55 56 59 58 57 56 58 63 61 60 63 60 66 64 66 67 64 63 66 62 67 65 62 64 67 + 3 6 9 12 15 18 21 24 27 30 33 36 39 42 45 48 51 54 57 60 63 66 69 72 75 78 81 84 87 90 93 96 99 102 105 108 111 114 117 120 123 126 129 132 135 138 141 144 147 150 153 156 + + + + + -0.015225 -0.113001 0 -0.0103503 -0.114113 0 -0.0103503 -0.114113 0.01 -0.015225 -0.113001 0.01 -0.015225 -0.113001 0 -0.0103503 -0.114113 0 -0.0025 -1.24449e-16 0 -0.00816877 -0.0756866 0 -0.00391917 -0.0379493 0 -0.015225 0.113001 0 -0.00391917 0.0379493 0 -0.00816877 0.0756866 0 -0.0103503 0.114113 0 0.0025 -1.25673e-16 0 0.00106686 0.0383227 0 -0.00322455 0.0764314 0 -0.00322455 -0.0764314 0 0.00106686 -0.0383227 0 -0.0103503 -0.114113 0 -0.0103503 -0.114113 0.01 0.0025 -1.25673e-16 0.01 -0.00322455 -0.0764314 0.01 0.00106686 -0.0383227 0.01 0.0025 -1.25673e-16 0 -0.00322455 -0.0764314 0 0.00106686 -0.0383227 0 -0.015225 -0.113001 0.01 -0.0103503 -0.114113 0.01 -0.0025 -1.24449e-16 0.01 -0.00816877 -0.0756866 0.01 -0.00391917 -0.0379493 0.01 -0.015225 0.113001 0.01 -0.00391917 0.0379493 0.01 -0.00816877 0.0756866 0.01 -0.0103503 0.114113 0.01 0.0025 -1.25673e-16 0.01 0.00106686 0.0383227 0.01 -0.00322455 0.0764314 0.01 -0.00322455 -0.0764314 0.01 0.00106686 -0.0383227 0.01 -0.015225 -0.113001 0 -0.015225 -0.113001 0.01 -0.0025 -1.24449e-16 0.01 -0.00816877 -0.0756866 0.01 -0.00391917 -0.0379493 0.01 -0.0025 -1.24449e-16 0 -0.00816877 -0.0756866 0 -0.00391917 -0.0379493 0 -0.0025 -1.24449e-16 0 -0.0025 -1.24449e-16 0.01 -0.015225 0.113001 0.01 -0.00391917 0.0379493 0.01 -0.00816877 0.0756866 0.01 -0.015225 0.113001 0 -0.00391917 0.0379493 0 -0.00816877 0.0756866 0 -0.015225 0.113001 0 -0.0103503 0.114113 0 -0.0103503 0.114113 0.01 -0.015225 0.113001 0.01 0.0025 -1.25673e-16 0 0.0025 -1.25673e-16 0.01 -0.0103503 0.114113 0.01 0.00106686 0.0383227 0.01 -0.00322455 0.0764314 0.01 -0.0103503 0.114113 0 0.00106686 0.0383227 0 -0.00322455 0.0764314 0 + + + 0 3 2 1 0 2 16 4 5 16 7 4 17 8 7 17 7 16 6 8 17 13 6 17 10 6 13 14 10 13 15 11 10 15 10 14 12 9 11 12 11 15 21 19 18 21 18 24 22 24 25 22 21 24 20 25 23 20 22 25 29 26 27 38 29 27 30 29 38 39 30 38 28 30 39 35 28 39 32 28 35 36 32 35 37 33 32 37 32 36 34 31 33 34 33 37 43 41 40 43 40 46 44 46 47 44 43 46 42 47 45 42 44 47 51 49 48 51 48 54 52 54 55 52 51 54 50 55 53 50 52 55 56 59 58 57 56 58 63 61 60 63 60 66 64 66 67 64 63 66 62 67 65 62 64 67 + 3 6 9 12 15 18 21 24 27 30 33 36 39 42 45 48 51 54 57 60 63 66 69 72 75 78 81 84 87 90 93 96 99 102 105 108 111 114 117 120 123 126 129 132 135 138 141 144 147 150 153 156 + + + + + -0.0152626 -0.113335 0 -0.0103878 -0.114447 0 -0.0103878 -0.114447 0.01 -0.0152626 -0.113335 0.01 -0.0152626 -0.113335 0 -0.0103878 -0.114447 0 -0.0025 -1.24816e-16 0 -0.0081855 -0.0759101 0 -0.00392336 -0.0380613 0 -0.0152626 0.113335 0 -0.00392336 0.0380613 0 -0.0081855 0.0759101 0 -0.0103878 0.114447 0 0.0025 -1.26041e-16 0 0.00106267 0.0384348 0 -0.00324128 0.0766549 0 -0.00324128 -0.0766549 0 0.00106267 -0.0384348 0 -0.0103878 -0.114447 0 -0.0103878 -0.114447 0.01 0.0025 -1.26041e-16 0.01 -0.00324128 -0.0766549 0.01 0.00106267 -0.0384348 0.01 0.0025 -1.26041e-16 0 -0.00324128 -0.0766549 0 0.00106267 -0.0384348 0 -0.0152626 -0.113335 0.01 -0.0103878 -0.114447 0.01 -0.0025 -1.24816e-16 0.01 -0.0081855 -0.0759101 0.01 -0.00392336 -0.0380613 0.01 -0.0152626 0.113335 0.01 -0.00392336 0.0380613 0.01 -0.0081855 0.0759101 0.01 -0.0103878 0.114447 0.01 0.0025 -1.26041e-16 0.01 0.00106267 0.0384348 0.01 -0.00324128 0.0766549 0.01 -0.00324128 -0.0766549 0.01 0.00106267 -0.0384348 0.01 -0.0152626 -0.113335 0 -0.0152626 -0.113335 0.01 -0.0025 -1.24816e-16 0.01 -0.0081855 -0.0759101 0.01 -0.00392336 -0.0380613 0.01 -0.0025 -1.24816e-16 0 -0.0081855 -0.0759101 0 -0.00392336 -0.0380613 0 -0.0025 -1.24816e-16 0 -0.0025 -1.24816e-16 0.01 -0.0152626 0.113335 0.01 -0.00392336 0.0380613 0.01 -0.0081855 0.0759101 0.01 -0.0152626 0.113335 0 -0.00392336 0.0380613 0 -0.0081855 0.0759101 0 -0.0152626 0.113335 0 -0.0103878 0.114447 0 -0.0103878 0.114447 0.01 -0.0152626 0.113335 0.01 0.0025 -1.26041e-16 0 0.0025 -1.26041e-16 0.01 -0.0103878 0.114447 0.01 0.00106267 0.0384348 0.01 -0.00324128 0.0766549 0.01 -0.0103878 0.114447 0 0.00106267 0.0384348 0 -0.00324128 0.0766549 0 + + + 1 3 2 1 0 3 16 4 5 16 7 4 17 8 7 17 7 16 6 8 17 13 6 17 10 6 13 14 10 13 15 11 10 15 10 14 12 9 11 12 11 15 21 19 18 21 18 24 22 24 25 22 21 24 20 25 23 20 22 25 38 26 27 38 29 26 39 30 29 39 29 38 35 28 30 35 30 39 32 28 35 36 32 35 37 33 32 37 32 36 34 31 33 34 33 37 43 41 40 43 40 46 44 46 47 44 43 46 42 47 45 42 44 47 51 49 48 51 48 54 52 54 55 52 51 54 50 55 53 50 52 55 56 59 58 57 56 58 63 61 60 63 60 66 64 66 67 64 63 66 62 67 65 62 64 67 + 3 6 9 12 15 18 21 24 27 30 33 36 39 42 45 48 51 54 57 60 63 66 69 72 75 78 81 84 87 90 93 96 99 102 105 108 111 114 117 120 123 126 129 132 135 138 141 144 147 150 153 156 + + + + + -0.0154554 -0.115047 0 -0.0105807 -0.116159 0 -0.0105807 -0.116159 0.01 -0.0154554 -0.115047 0.01 -0.0154554 -0.115047 0 -0.0105807 -0.116159 0 -0.0025 -1.26702e-16 0 -0.00827141 -0.0770571 0 -0.00394487 -0.0386364 0 -0.0154554 0.115047 0 -0.00394487 0.0386364 0 -0.00827141 0.0770571 0 -0.0105807 0.116159 0 0.0025 -1.27927e-16 0 0.00104116 0.0390099 0 -0.00332719 0.0778019 0 -0.00332719 -0.0778019 0 0.00104116 -0.0390099 0 -0.0105807 -0.116159 0 -0.0105807 -0.116159 0.01 0.0025 -1.27927e-16 0.01 -0.00332719 -0.0778019 0.01 0.00104116 -0.0390099 0.01 0.0025 -1.27927e-16 0 -0.00332719 -0.0778019 0 0.00104116 -0.0390099 0 -0.0154554 -0.115047 0.01 -0.0105807 -0.116159 0.01 -0.0025 -1.26702e-16 0.01 -0.00827141 -0.0770571 0.01 -0.00394487 -0.0386364 0.01 -0.0154554 0.115047 0.01 -0.00394487 0.0386364 0.01 -0.00827141 0.0770571 0.01 -0.0105807 0.116159 0.01 0.0025 -1.27927e-16 0.01 0.00104116 0.0390099 0.01 -0.00332719 0.0778019 0.01 -0.00332719 -0.0778019 0.01 0.00104116 -0.0390099 0.01 -0.0154554 -0.115047 0 -0.0154554 -0.115047 0.01 -0.0025 -1.26702e-16 0.01 -0.00827141 -0.0770571 0.01 -0.00394487 -0.0386364 0.01 -0.0025 -1.26702e-16 0 -0.00827141 -0.0770571 0 -0.00394487 -0.0386364 0 -0.0025 -1.26702e-16 0 -0.0025 -1.26702e-16 0.01 -0.0154554 0.115047 0.01 -0.00394487 0.0386364 0.01 -0.00827141 0.0770571 0.01 -0.0154554 0.115047 0 -0.00394487 0.0386364 0 -0.00827141 0.0770571 0 -0.0154554 0.115047 0 -0.0105807 0.116159 0 -0.0105807 0.116159 0.01 -0.0154554 0.115047 0.01 0.0025 -1.27927e-16 0 0.0025 -1.27927e-16 0.01 -0.0105807 0.116159 0.01 0.00104116 0.0390099 0.01 -0.00332719 0.0778019 0.01 -0.0105807 0.116159 0 0.00104116 0.0390099 0 -0.00332719 0.0778019 0 + + + 0 3 2 1 0 2 16 4 5 16 7 4 17 8 7 17 7 16 6 8 17 13 6 17 10 6 13 14 10 13 15 11 10 15 10 14 12 9 11 12 11 15 21 19 18 21 18 24 22 24 25 22 21 24 20 25 23 20 22 25 38 26 27 38 29 26 39 30 29 39 29 38 28 30 39 35 28 39 32 28 35 36 32 35 37 33 32 37 32 36 34 31 33 34 33 37 43 41 40 43 40 46 44 46 47 44 43 46 42 47 45 42 44 47 51 49 48 51 48 54 52 54 55 52 51 54 50 55 53 50 52 55 56 59 58 57 56 58 63 61 60 63 60 66 64 66 67 64 63 66 62 67 65 62 64 67 + 3 6 9 12 15 18 21 24 27 30 33 36 39 42 45 48 51 54 57 60 63 66 69 72 75 78 81 84 87 90 93 96 99 102 105 108 111 114 117 120 123 126 129 132 135 138 141 144 147 150 153 156 + + + + + -0.015493 -0.115381 0 -0.0106182 -0.116493 0 -0.0106182 -0.116493 0.01 -0.015493 -0.115381 0.01 -0.015493 -0.115381 0 -0.0106182 -0.116493 0 -0.0025 -1.27069e-16 0 -0.00828814 -0.0772805 0 -0.00394906 -0.0387485 0 -0.015493 0.115381 0 -0.00394906 0.0387485 0 -0.00828814 0.0772805 0 -0.0106182 0.116493 0 0.0025 -1.28294e-16 0 0.00103698 0.0391219 0 -0.00334393 0.0780253 0 -0.00334393 -0.0780253 0 0.00103698 -0.0391219 0 -0.0106182 -0.116493 0 -0.0106182 -0.116493 0.01 0.0025 -1.28294e-16 0.01 -0.00334393 -0.0780253 0.01 0.00103698 -0.0391219 0.01 0.0025 -1.28294e-16 0 -0.00334393 -0.0780253 0 0.00103698 -0.0391219 0 -0.015493 -0.115381 0.01 -0.0106182 -0.116493 0.01 -0.0025 -1.27069e-16 0.01 -0.00828814 -0.0772805 0.01 -0.00394906 -0.0387485 0.01 -0.015493 0.115381 0.01 -0.00394906 0.0387485 0.01 -0.00828814 0.0772805 0.01 -0.0106182 0.116493 0.01 0.0025 -1.28294e-16 0.01 0.00103698 0.0391219 0.01 -0.00334393 0.0780253 0.01 -0.00334393 -0.0780253 0.01 0.00103698 -0.0391219 0.01 -0.015493 -0.115381 0 -0.015493 -0.115381 0.01 -0.0025 -1.27069e-16 0.01 -0.00828814 -0.0772805 0.01 -0.00394906 -0.0387485 0.01 -0.0025 -1.27069e-16 0 -0.00828814 -0.0772805 0 -0.00394906 -0.0387485 0 -0.0025 -1.27069e-16 0 -0.0025 -1.27069e-16 0.01 -0.015493 0.115381 0.01 -0.00394906 0.0387485 0.01 -0.00828814 0.0772805 0.01 -0.015493 0.115381 0 -0.00394906 0.0387485 0 -0.00828814 0.0772805 0 -0.015493 0.115381 0 -0.0106182 0.116493 0 -0.0106182 0.116493 0.01 -0.015493 0.115381 0.01 0.0025 -1.28294e-16 0 0.0025 -1.28294e-16 0.01 -0.0106182 0.116493 0.01 0.00103698 0.0391219 0.01 -0.00334393 0.0780253 0.01 -0.0106182 0.116493 0 0.00103698 0.0391219 0 -0.00334393 0.0780253 0 + + + 1 3 2 1 0 3 7 4 5 16 7 5 17 8 7 17 7 16 6 8 17 13 6 17 10 6 13 14 10 13 11 10 14 15 11 14 9 11 15 12 9 15 21 19 18 21 18 24 22 24 25 22 21 24 20 25 23 20 22 25 29 26 27 38 29 27 39 30 29 39 29 38 28 30 39 35 28 39 32 28 35 36 32 35 33 32 36 37 33 36 31 33 37 34 31 37 43 41 40 43 40 46 44 46 47 44 43 46 42 47 45 42 44 47 51 49 48 51 48 54 52 54 55 52 51 54 50 55 53 50 52 55 56 59 58 57 56 58 63 61 60 63 60 66 64 66 67 64 63 66 62 67 65 62 64 67 + 3 6 9 12 15 18 21 24 27 30 33 36 39 42 45 48 51 54 57 60 63 66 69 72 75 78 81 84 87 90 93 96 99 102 105 108 111 114 117 120 123 126 129 132 135 138 141 144 147 150 153 156 + + + + + -0.0156833 -0.117071 0 -0.0108086 -0.118183 0 -0.0108086 -0.118183 0.01 -0.0156833 -0.117071 0.01 -0.0156833 -0.117071 0 -0.0108086 -0.118183 0 -0.0025 -1.28931e-16 0 -0.00837293 -0.0784126 0 -0.00397029 -0.0393161 0 -0.0156833 0.117071 0 -0.00397029 0.0393161 0 -0.00837293 0.0784126 0 -0.0108086 0.118183 0 0.0025 -1.30155e-16 0 0.00101575 0.0396896 0 -0.00342872 0.0791574 0 -0.00342872 -0.0791574 0 0.00101575 -0.0396896 0 -0.0108086 -0.118183 0 -0.0108086 -0.118183 0.01 0.0025 -1.30155e-16 0.01 -0.00342872 -0.0791574 0.01 0.00101575 -0.0396896 0.01 0.0025 -1.30155e-16 0 -0.00342872 -0.0791574 0 0.00101575 -0.0396896 0 -0.0156833 -0.117071 0.01 -0.0108086 -0.118183 0.01 -0.0025 -1.28931e-16 0.01 -0.00837293 -0.0784126 0.01 -0.00397029 -0.0393161 0.01 -0.0156833 0.117071 0.01 -0.00397029 0.0393161 0.01 -0.00837293 0.0784126 0.01 -0.0108086 0.118183 0.01 0.0025 -1.30155e-16 0.01 0.00101575 0.0396896 0.01 -0.00342872 0.0791574 0.01 -0.00342872 -0.0791574 0.01 0.00101575 -0.0396896 0.01 -0.0156833 -0.117071 0 -0.0156833 -0.117071 0.01 -0.0025 -1.28931e-16 0.01 -0.00837293 -0.0784126 0.01 -0.00397029 -0.0393161 0.01 -0.0025 -1.28931e-16 0 -0.00837293 -0.0784126 0 -0.00397029 -0.0393161 0 -0.0025 -1.28931e-16 0 -0.0025 -1.28931e-16 0.01 -0.0156833 0.117071 0.01 -0.00397029 0.0393161 0.01 -0.00837293 0.0784126 0.01 -0.0156833 0.117071 0 -0.00397029 0.0393161 0 -0.00837293 0.0784126 0 -0.0156833 0.117071 0 -0.0108086 0.118183 0 -0.0108086 0.118183 0.01 -0.0156833 0.117071 0.01 0.0025 -1.30155e-16 0 0.0025 -1.30155e-16 0.01 -0.0108086 0.118183 0.01 0.00101575 0.0396896 0.01 -0.00342872 0.0791574 0.01 -0.0108086 0.118183 0 0.00101575 0.0396896 0 -0.00342872 0.0791574 0 + + + 1 3 2 1 0 3 16 4 5 16 7 4 17 8 7 17 7 16 6 8 17 13 6 17 10 6 13 14 10 13 15 11 10 15 10 14 9 11 15 12 9 15 21 19 18 21 18 24 22 24 25 22 21 24 20 25 23 20 22 25 29 26 27 38 29 27 30 29 38 39 30 38 28 30 39 35 28 39 32 28 35 36 32 35 37 33 32 37 32 36 31 33 37 34 31 37 43 41 40 43 40 46 44 46 47 44 43 46 42 47 45 42 44 47 51 49 48 51 48 54 52 54 55 52 51 54 50 55 53 50 52 55 56 59 58 57 56 58 63 61 60 63 60 66 64 66 67 64 63 66 62 67 65 62 64 67 + 3 6 9 12 15 18 21 24 27 30 33 36 39 42 45 48 51 54 57 60 63 66 69 72 75 78 81 84 87 90 93 96 99 102 105 108 111 114 117 120 123 126 129 132 135 138 141 144 147 150 153 156 + + + + + -0.0157234 -0.117427 0 -0.0108486 -0.118539 0 -0.0108486 -0.118539 0.01 -0.0157234 -0.117427 0.01 -0.0157234 -0.117427 0 -0.0108486 -0.118539 0 -0.0025 -1.29323e-16 0 -0.00839079 -0.0786509 0 -0.00397476 -0.0394356 0 -0.0157234 0.117427 0 -0.00397476 0.0394356 0 -0.00839079 0.0786509 0 -0.0108486 0.118539 0 0.0025 -1.30547e-16 0 0.00101128 0.0398091 0 -0.00344657 0.0793957 0 -0.00344657 -0.0793957 0 0.00101128 -0.0398091 0 -0.0108486 -0.118539 0 -0.0108486 -0.118539 0.01 0.0025 -1.30547e-16 0.01 -0.00344657 -0.0793957 0.01 0.00101128 -0.0398091 0.01 0.0025 -1.30547e-16 0 -0.00344657 -0.0793957 0 0.00101128 -0.0398091 0 -0.0157234 -0.117427 0.01 -0.0108486 -0.118539 0.01 -0.0025 -1.29323e-16 0.01 -0.00839079 -0.0786509 0.01 -0.00397476 -0.0394356 0.01 -0.0157234 0.117427 0.01 -0.00397476 0.0394356 0.01 -0.00839079 0.0786509 0.01 -0.0108486 0.118539 0.01 0.0025 -1.30547e-16 0.01 0.00101128 0.0398091 0.01 -0.00344657 0.0793957 0.01 -0.00344657 -0.0793957 0.01 0.00101128 -0.0398091 0.01 -0.0157234 -0.117427 0 -0.0157234 -0.117427 0.01 -0.0025 -1.29323e-16 0.01 -0.00839079 -0.0786509 0.01 -0.00397476 -0.0394356 0.01 -0.0025 -1.29323e-16 0 -0.00839079 -0.0786509 0 -0.00397476 -0.0394356 0 -0.0025 -1.29323e-16 0 -0.0025 -1.29323e-16 0.01 -0.0157234 0.117427 0.01 -0.00397476 0.0394356 0.01 -0.00839079 0.0786509 0.01 -0.0157234 0.117427 0 -0.00397476 0.0394356 0 -0.00839079 0.0786509 0 -0.0157234 0.117427 0 -0.0108486 0.118539 0 -0.0108486 0.118539 0.01 -0.0157234 0.117427 0.01 0.0025 -1.30547e-16 0 0.0025 -1.30547e-16 0.01 -0.0108486 0.118539 0.01 0.00101128 0.0398091 0.01 -0.00344657 0.0793957 0.01 -0.0108486 0.118539 0 0.00101128 0.0398091 0 -0.00344657 0.0793957 0 + + + 1 3 2 1 0 3 16 4 5 16 7 4 17 8 7 17 7 16 6 8 17 13 6 17 10 6 13 14 10 13 15 11 10 15 10 14 9 11 15 12 9 15 21 19 18 21 18 24 22 24 25 22 21 24 20 25 23 20 22 25 38 26 27 38 29 26 39 30 29 39 29 38 28 30 39 35 28 39 32 28 35 36 32 35 37 33 32 37 32 36 31 33 37 34 31 37 43 41 40 43 40 46 44 46 47 44 43 46 42 47 45 42 44 47 51 49 48 51 48 54 52 54 55 52 51 54 50 55 53 50 52 55 56 59 58 57 56 58 63 61 60 63 60 66 64 66 67 64 63 66 62 67 65 62 64 67 + 3 6 9 12 15 18 21 24 27 30 33 36 39 42 45 48 51 54 57 60 63 66 69 72 75 78 81 84 87 90 93 96 99 102 105 108 111 114 117 120 123 126 129 132 135 138 141 144 147 150 153 156 + + + + + -0.0159138 -0.119117 0 -0.011039 -0.120229 0 -0.011039 -0.120229 0.01 -0.0159138 -0.119117 0.01 -0.0159138 -0.119117 0 -0.011039 -0.120229 0 -0.0025 -1.31184e-16 0 -0.00847558 -0.079783 0 -0.00399598 -0.0400032 0 -0.0159138 0.119117 0 -0.00399598 0.0400032 0 -0.00847558 0.079783 0 -0.011039 0.120229 0 0.0025 -1.32409e-16 0 0.000990051 0.0403767 0 -0.00353136 0.0805278 0 -0.00353136 -0.0805278 0 0.000990051 -0.0403767 0 -0.011039 -0.120229 0 -0.011039 -0.120229 0.01 0.0025 -1.32409e-16 0.01 -0.00353136 -0.0805278 0.01 0.000990051 -0.0403767 0.01 0.0025 -1.32409e-16 0 -0.00353136 -0.0805278 0 0.000990051 -0.0403767 0 -0.0159138 -0.119117 0.01 -0.011039 -0.120229 0.01 -0.0025 -1.31184e-16 0.01 -0.00847558 -0.079783 0.01 -0.00399598 -0.0400032 0.01 -0.0159138 0.119117 0.01 -0.00399598 0.0400032 0.01 -0.00847558 0.079783 0.01 -0.011039 0.120229 0.01 0.0025 -1.32409e-16 0.01 0.000990051 0.0403767 0.01 -0.00353136 0.0805278 0.01 -0.00353136 -0.0805278 0.01 0.000990051 -0.0403767 0.01 -0.0159138 -0.119117 0 -0.0159138 -0.119117 0.01 -0.0025 -1.31184e-16 0.01 -0.00847558 -0.079783 0.01 -0.00399598 -0.0400032 0.01 -0.0025 -1.31184e-16 0 -0.00847558 -0.079783 0 -0.00399598 -0.0400032 0 -0.0025 -1.31184e-16 0 -0.0025 -1.31184e-16 0.01 -0.0159138 0.119117 0.01 -0.00399598 0.0400032 0.01 -0.00847558 0.079783 0.01 -0.0159138 0.119117 0 -0.00399598 0.0400032 0 -0.00847558 0.079783 0 -0.0159138 0.119117 0 -0.011039 0.120229 0 -0.011039 0.120229 0.01 -0.0159138 0.119117 0.01 0.0025 -1.32409e-16 0 0.0025 -1.32409e-16 0.01 -0.011039 0.120229 0.01 0.000990051 0.0403767 0.01 -0.00353136 0.0805278 0.01 -0.011039 0.120229 0 0.000990051 0.0403767 0 -0.00353136 0.0805278 0 + + + 1 3 2 1 0 3 16 4 5 16 7 4 17 8 7 17 7 16 6 8 17 13 6 17 10 6 13 14 10 13 11 10 14 15 11 14 12 9 11 12 11 15 21 19 18 21 18 24 22 24 25 22 21 24 20 25 23 20 22 25 38 26 27 38 29 26 39 30 29 39 29 38 28 30 39 35 28 39 32 28 35 36 32 35 33 32 36 37 33 36 34 31 33 34 33 37 43 41 40 43 40 46 44 46 47 44 43 46 42 47 45 42 44 47 51 49 48 51 48 54 52 54 55 52 51 54 50 55 53 50 52 55 56 59 58 57 56 58 63 61 60 63 60 66 64 66 67 64 63 66 62 67 65 62 64 67 + 3 6 9 12 15 18 21 24 27 30 33 36 39 42 45 48 51 54 57 60 63 66 69 72 75 78 81 84 87 90 93 96 99 102 105 108 111 114 117 120 123 126 129 132 135 138 141 144 147 150 153 156 + + + + + -0.0159513 -0.119451 0 -0.0110765 -0.120563 0 -0.0110765 -0.120563 0.01 -0.0159513 -0.119451 0.01 -0.0159513 -0.119451 0 -0.0110765 -0.120563 0 -0.0025 -1.31552e-16 0 -0.00849231 -0.0800065 0 -0.00400017 -0.0401153 0 -0.0159513 0.119451 0 -0.00400017 0.0401153 0 -0.00849231 0.0800065 0 -0.0110765 0.120563 0 0.0025 -1.32776e-16 0 0.000985861 0.0404887 0 -0.0035481 0.0807513 0 -0.0035481 -0.0807513 0 0.000985861 -0.0404887 0 -0.0110765 -0.120563 0 -0.0110765 -0.120563 0.01 0.0025 -1.32776e-16 0.01 -0.0035481 -0.0807513 0.01 0.000985861 -0.0404887 0.01 0.0025 -1.32776e-16 0 -0.0035481 -0.0807513 0 0.000985861 -0.0404887 0 -0.0159513 -0.119451 0.01 -0.0110765 -0.120563 0.01 -0.0025 -1.31552e-16 0.01 -0.00849231 -0.0800065 0.01 -0.00400017 -0.0401153 0.01 -0.0159513 0.119451 0.01 -0.00400017 0.0401153 0.01 -0.00849231 0.0800065 0.01 -0.0110765 0.120563 0.01 0.0025 -1.32776e-16 0.01 0.000985861 0.0404887 0.01 -0.0035481 0.0807513 0.01 -0.0035481 -0.0807513 0.01 0.000985861 -0.0404887 0.01 -0.0159513 -0.119451 0 -0.0159513 -0.119451 0.01 -0.0025 -1.31552e-16 0.01 -0.00849231 -0.0800065 0.01 -0.00400017 -0.0401153 0.01 -0.0025 -1.31552e-16 0 -0.00849231 -0.0800065 0 -0.00400017 -0.0401153 0 -0.0025 -1.31552e-16 0 -0.0025 -1.31552e-16 0.01 -0.0159513 0.119451 0.01 -0.00400017 0.0401153 0.01 -0.00849231 0.0800065 0.01 -0.0159513 0.119451 0 -0.00400017 0.0401153 0 -0.00849231 0.0800065 0 -0.0159513 0.119451 0 -0.0110765 0.120563 0 -0.0110765 0.120563 0.01 -0.0159513 0.119451 0.01 0.0025 -1.32776e-16 0 0.0025 -1.32776e-16 0.01 -0.0110765 0.120563 0.01 0.000985861 0.0404887 0.01 -0.0035481 0.0807513 0.01 -0.0110765 0.120563 0 0.000985861 0.0404887 0 -0.0035481 0.0807513 0 + + + 0 3 2 1 0 2 16 4 5 16 7 4 17 8 7 17 7 16 13 6 8 13 8 17 10 6 13 14 10 13 15 11 10 15 10 14 12 9 11 12 11 15 21 19 18 21 18 24 22 24 25 22 21 24 20 25 23 20 22 25 38 26 27 38 29 26 39 30 29 39 29 38 35 28 30 35 30 39 32 28 35 36 32 35 37 33 32 37 32 36 34 31 33 34 33 37 43 41 40 43 40 46 44 46 47 44 43 46 42 47 45 42 44 47 51 49 48 51 48 54 52 54 55 52 51 54 50 55 53 50 52 55 56 59 58 57 56 58 63 61 60 63 60 66 64 66 67 64 63 66 62 67 65 62 64 67 + 3 6 9 12 15 18 21 24 27 30 33 36 39 42 45 48 51 54 57 60 63 66 69 72 75 78 81 84 87 90 93 96 99 102 105 108 111 114 117 120 123 126 129 132 135 138 141 144 147 150 153 156 + + + + + -0.0140755 -0.102793 0 -0.00920072 -0.103905 0 -0.00920072 -0.103905 0.01 -0.0140755 -0.102793 0.01 -0.0140755 -0.102793 0 -0.00920072 -0.103905 0 -0.0025 -1.13206e-16 0 -0.00765667 -0.0688494 0 -0.00379097 -0.0345211 0 -0.0140755 0.102793 0 -0.00379097 0.0345211 0 -0.00765667 0.0688494 0 -0.00920072 0.103905 0 0.0025 -1.14431e-16 0 0.00119506 0.0348945 0 -0.00271245 0.0695942 0 -0.00271245 -0.0695942 0 0.00119506 -0.0348945 0 -0.00920072 -0.103905 0 -0.00920072 -0.103905 0.01 0.0025 -1.14431e-16 0.01 -0.00271245 -0.0695942 0.01 0.00119506 -0.0348945 0.01 0.0025 -1.14431e-16 0 -0.00271245 -0.0695942 0 0.00119506 -0.0348945 0 -0.0140755 -0.102793 0.01 -0.00920072 -0.103905 0.01 -0.0025 -1.13206e-16 0.01 -0.00765667 -0.0688494 0.01 -0.00379097 -0.0345211 0.01 -0.0140755 0.102793 0.01 -0.00379097 0.0345211 0.01 -0.00765667 0.0688494 0.01 -0.00920072 0.103905 0.01 0.0025 -1.14431e-16 0.01 0.00119506 0.0348945 0.01 -0.00271245 0.0695942 0.01 -0.00271245 -0.0695942 0.01 0.00119506 -0.0348945 0.01 -0.0140755 -0.102793 0 -0.0140755 -0.102793 0.01 -0.0025 -1.13206e-16 0.01 -0.00765667 -0.0688494 0.01 -0.00379097 -0.0345211 0.01 -0.0025 -1.13206e-16 0 -0.00765667 -0.0688494 0 -0.00379097 -0.0345211 0 -0.0025 -1.13206e-16 0 -0.0025 -1.13206e-16 0.01 -0.0140755 0.102793 0.01 -0.00379097 0.0345211 0.01 -0.00765667 0.0688494 0.01 -0.0140755 0.102793 0 -0.00379097 0.0345211 0 -0.00765667 0.0688494 0 -0.0140755 0.102793 0 -0.00920072 0.103905 0 -0.00920072 0.103905 0.01 -0.0140755 0.102793 0.01 0.0025 -1.14431e-16 0 0.0025 -1.14431e-16 0.01 -0.00920072 0.103905 0.01 0.00119506 0.0348945 0.01 -0.00271245 0.0695942 0.01 -0.00920072 0.103905 0 0.00119506 0.0348945 0 -0.00271245 0.0695942 0 + + + 0 3 2 1 0 2 16 4 5 16 7 4 8 7 16 17 8 16 6 8 17 13 6 17 10 6 13 14 10 13 15 11 10 15 10 14 9 11 15 12 9 15 21 19 18 21 18 24 22 24 25 22 21 24 20 25 23 20 22 25 38 26 27 38 29 26 39 30 29 39 29 38 35 28 30 35 30 39 32 28 35 36 32 35 37 33 32 37 32 36 31 33 37 34 31 37 43 41 40 43 40 46 44 46 47 44 43 46 42 47 45 42 44 47 51 49 48 51 48 54 52 54 55 52 51 54 50 55 53 50 52 55 56 59 58 57 56 58 63 61 60 63 60 66 64 66 67 64 63 66 62 67 65 62 64 67 + 3 6 9 12 15 18 21 24 27 30 33 36 39 42 45 48 51 54 57 60 63 66 69 72 75 78 81 84 87 90 93 96 99 102 105 108 111 114 117 120 123 126 129 132 135 138 141 144 147 150 153 156 + + + + + -0.0141156 -0.103149 0 -0.00924079 -0.104261 0 -0.00924079 -0.104261 0.01 -0.0141156 -0.103149 0.01 -0.0141156 -0.103149 0 -0.00924079 -0.104261 0 -0.0025 -1.13598e-16 0 -0.00767452 -0.0690877 0 -0.00379544 -0.0346406 0 -0.0141156 0.103149 0 -0.00379544 0.0346406 0 -0.00767452 0.0690877 0 -0.00924079 0.104261 0 0.0025 -1.14823e-16 0 0.0011906 0.035014 0 -0.0027303 0.0698325 0 -0.0027303 -0.0698325 0 0.0011906 -0.035014 0 -0.00924079 -0.104261 0 -0.00924079 -0.104261 0.01 0.0025 -1.14823e-16 0.01 -0.0027303 -0.0698325 0.01 0.0011906 -0.035014 0.01 0.0025 -1.14823e-16 0 -0.0027303 -0.0698325 0 0.0011906 -0.035014 0 -0.0141156 -0.103149 0.01 -0.00924079 -0.104261 0.01 -0.0025 -1.13598e-16 0.01 -0.00767452 -0.0690877 0.01 -0.00379544 -0.0346406 0.01 -0.0141156 0.103149 0.01 -0.00379544 0.0346406 0.01 -0.00767452 0.0690877 0.01 -0.00924079 0.104261 0.01 0.0025 -1.14823e-16 0.01 0.0011906 0.035014 0.01 -0.0027303 0.0698325 0.01 -0.0027303 -0.0698325 0.01 0.0011906 -0.035014 0.01 -0.0141156 -0.103149 0 -0.0141156 -0.103149 0.01 -0.0025 -1.13598e-16 0.01 -0.00767452 -0.0690877 0.01 -0.00379544 -0.0346406 0.01 -0.0025 -1.13598e-16 0 -0.00767452 -0.0690877 0 -0.00379544 -0.0346406 0 -0.0025 -1.13598e-16 0 -0.0025 -1.13598e-16 0.01 -0.0141156 0.103149 0.01 -0.00379544 0.0346406 0.01 -0.00767452 0.0690877 0.01 -0.0141156 0.103149 0 -0.00379544 0.0346406 0 -0.00767452 0.0690877 0 -0.0141156 0.103149 0 -0.00924079 0.104261 0 -0.00924079 0.104261 0.01 -0.0141156 0.103149 0.01 0.0025 -1.14823e-16 0 0.0025 -1.14823e-16 0.01 -0.00924079 0.104261 0.01 0.0011906 0.035014 0.01 -0.0027303 0.0698325 0.01 -0.00924079 0.104261 0 0.0011906 0.035014 0 -0.0027303 0.0698325 0 + + + 1 3 2 1 0 3 16 4 5 16 7 4 17 8 7 17 7 16 6 8 17 13 6 17 10 6 13 14 10 13 15 11 10 15 10 14 9 11 15 12 9 15 21 19 18 21 18 24 22 24 25 22 21 24 20 25 23 20 22 25 38 26 27 38 29 26 39 30 29 39 29 38 28 30 39 35 28 39 32 28 35 36 32 35 37 33 32 37 32 36 31 33 37 34 31 37 43 41 40 43 40 46 44 46 47 44 43 46 42 47 45 42 44 47 51 49 48 51 48 54 52 54 55 52 51 54 50 55 53 50 52 55 56 59 58 57 56 58 63 61 60 63 60 66 64 66 67 64 63 66 62 67 65 62 64 67 + 3 6 9 12 15 18 21 24 27 30 33 36 39 42 45 48 51 54 57 60 63 66 69 72 75 78 81 84 87 90 93 96 99 102 105 108 111 114 117 120 123 126 129 132 135 138 141 144 147 150 153 156 + + + + + -0.0143059 -0.104839 0 -0.00943113 -0.105951 0 -0.00943113 -0.105951 0.01 -0.0143059 -0.104839 0.01 -0.0143059 -0.104839 0 -0.00943113 -0.105951 0 -0.0025 -1.1546e-16 0 -0.00775931 -0.0702198 0 -0.00381667 -0.0352082 0 -0.0143059 0.104839 0 -0.00381667 0.0352082 0 -0.00775931 0.0702198 0 -0.00943113 0.105951 0 0.0025 -1.16684e-16 0 0.00116937 0.0355817 0 -0.00281509 0.0709646 0 -0.00281509 -0.0709646 0 0.00116937 -0.0355817 0 -0.00943113 -0.105951 0 -0.00943113 -0.105951 0.01 0.0025 -1.16684e-16 0.01 -0.00281509 -0.0709646 0.01 0.00116937 -0.0355817 0.01 0.0025 -1.16684e-16 0 -0.00281509 -0.0709646 0 0.00116937 -0.0355817 0 -0.0143059 -0.104839 0.01 -0.00943113 -0.105951 0.01 -0.0025 -1.1546e-16 0.01 -0.00775931 -0.0702198 0.01 -0.00381667 -0.0352082 0.01 -0.0143059 0.104839 0.01 -0.00381667 0.0352082 0.01 -0.00775931 0.0702198 0.01 -0.00943113 0.105951 0.01 0.0025 -1.16684e-16 0.01 0.00116937 0.0355817 0.01 -0.00281509 0.0709646 0.01 -0.00281509 -0.0709646 0.01 0.00116937 -0.0355817 0.01 -0.0143059 -0.104839 0 -0.0143059 -0.104839 0.01 -0.0025 -1.1546e-16 0.01 -0.00775931 -0.0702198 0.01 -0.00381667 -0.0352082 0.01 -0.0025 -1.1546e-16 0 -0.00775931 -0.0702198 0 -0.00381667 -0.0352082 0 -0.0025 -1.1546e-16 0 -0.0025 -1.1546e-16 0.01 -0.0143059 0.104839 0.01 -0.00381667 0.0352082 0.01 -0.00775931 0.0702198 0.01 -0.0143059 0.104839 0 -0.00381667 0.0352082 0 -0.00775931 0.0702198 0 -0.0143059 0.104839 0 -0.00943113 0.105951 0 -0.00943113 0.105951 0.01 -0.0143059 0.104839 0.01 0.0025 -1.16684e-16 0 0.0025 -1.16684e-16 0.01 -0.00943113 0.105951 0.01 0.00116937 0.0355817 0.01 -0.00281509 0.0709646 0.01 -0.00943113 0.105951 0 0.00116937 0.0355817 0 -0.00281509 0.0709646 0 + + + 1 3 2 1 0 3 16 4 5 16 7 4 17 8 7 17 7 16 6 8 17 13 6 17 10 6 13 14 10 13 15 11 10 15 10 14 12 9 11 12 11 15 21 19 18 21 18 24 22 24 25 22 21 24 20 25 23 20 22 25 38 26 27 38 29 26 39 30 29 39 29 38 28 30 39 35 28 39 32 28 35 36 32 35 37 33 32 37 32 36 34 31 33 34 33 37 43 41 40 43 40 46 44 46 47 44 43 46 42 47 45 42 44 47 51 49 48 51 48 54 52 54 55 52 51 54 50 55 53 50 52 55 56 59 58 57 56 58 63 61 60 63 60 66 64 66 67 64 63 66 62 67 65 62 64 67 + 3 6 9 12 15 18 21 24 27 30 33 36 39 42 45 48 51 54 57 60 63 66 69 72 75 78 81 84 87 90 93 96 99 102 105 108 111 114 117 120 123 126 129 132 135 138 141 144 147 150 153 156 + + + + + -0.0143435 -0.105173 0 -0.0094687 -0.106285 0 -0.0094687 -0.106285 0.01 -0.0143435 -0.105173 0.01 -0.0143435 -0.105173 0 -0.0094687 -0.106285 0 -0.0025 -1.15827e-16 0 -0.00777605 -0.0704432 0 -0.00382086 -0.0353203 0 -0.0143435 0.105173 0 -0.00382086 0.0353203 0 -0.00777605 0.0704432 0 -0.0094687 0.106285 0 0.0025 -1.17052e-16 0 0.00116518 0.0356937 0 -0.00283183 0.071188 0 -0.00283183 -0.071188 0 0.00116518 -0.0356937 0 -0.0094687 -0.106285 0 -0.0094687 -0.106285 0.01 0.0025 -1.17052e-16 0.01 -0.00283183 -0.071188 0.01 0.00116518 -0.0356937 0.01 0.0025 -1.17052e-16 0 -0.00283183 -0.071188 0 0.00116518 -0.0356937 0 -0.0143435 -0.105173 0.01 -0.0094687 -0.106285 0.01 -0.0025 -1.15827e-16 0.01 -0.00777605 -0.0704432 0.01 -0.00382086 -0.0353203 0.01 -0.0143435 0.105173 0.01 -0.00382086 0.0353203 0.01 -0.00777605 0.0704432 0.01 -0.0094687 0.106285 0.01 0.0025 -1.17052e-16 0.01 0.00116518 0.0356937 0.01 -0.00283183 0.071188 0.01 -0.00283183 -0.071188 0.01 0.00116518 -0.0356937 0.01 -0.0143435 -0.105173 0 -0.0143435 -0.105173 0.01 -0.0025 -1.15827e-16 0.01 -0.00777605 -0.0704432 0.01 -0.00382086 -0.0353203 0.01 -0.0025 -1.15827e-16 0 -0.00777605 -0.0704432 0 -0.00382086 -0.0353203 0 -0.0025 -1.15827e-16 0 -0.0025 -1.15827e-16 0.01 -0.0143435 0.105173 0.01 -0.00382086 0.0353203 0.01 -0.00777605 0.0704432 0.01 -0.0143435 0.105173 0 -0.00382086 0.0353203 0 -0.00777605 0.0704432 0 -0.0143435 0.105173 0 -0.0094687 0.106285 0 -0.0094687 0.106285 0.01 -0.0143435 0.105173 0.01 0.0025 -1.17052e-16 0 0.0025 -1.17052e-16 0.01 -0.0094687 0.106285 0.01 0.00116518 0.0356937 0.01 -0.00283183 0.071188 0.01 -0.0094687 0.106285 0 0.00116518 0.0356937 0 -0.00283183 0.071188 0 + + + 1 3 2 1 0 3 16 4 5 16 7 4 17 8 7 17 7 16 6 8 17 13 6 17 10 6 13 14 10 13 15 11 10 15 10 14 12 9 11 12 11 15 21 19 18 21 18 24 22 24 25 22 21 24 20 25 23 20 22 25 29 26 27 38 29 27 30 29 38 39 30 38 28 30 39 35 28 39 32 28 35 36 32 35 37 33 32 37 32 36 34 31 33 34 33 37 43 41 40 43 40 46 44 46 47 44 43 46 42 47 45 42 44 47 51 49 48 51 48 54 52 54 55 52 51 54 50 55 53 50 52 55 56 59 58 57 56 58 63 61 60 63 60 66 64 66 67 64 63 66 62 67 65 62 64 67 + 3 6 9 12 15 18 21 24 27 30 33 36 39 42 45 48 51 54 57 60 63 66 69 72 75 78 81 84 87 90 93 96 99 102 105 108 111 114 117 120 123 126 129 132 135 138 141 144 147 150 153 156 + + + + + -0.0145363 -0.106885 0 -0.00966154 -0.107997 0 -0.00966154 -0.107997 0.01 -0.0145363 -0.106885 0.01 -0.0145363 -0.106885 0 -0.00966154 -0.107997 0 -0.0025 -1.17713e-16 0 -0.00786195 -0.0715902 0 -0.00384236 -0.0358954 0 -0.0145363 0.106885 0 -0.00384236 0.0358954 0 -0.00786195 0.0715902 0 -0.00966154 0.107997 0 0.0025 -1.18938e-16 0 0.00114367 0.0362688 0 -0.00291774 0.072335 0 -0.00291774 -0.072335 0 0.00114367 -0.0362688 0 -0.00966154 -0.107997 0 -0.00966154 -0.107997 0.01 0.0025 -1.18938e-16 0.01 -0.00291774 -0.072335 0.01 0.00114367 -0.0362688 0.01 0.0025 -1.18938e-16 0 -0.00291774 -0.072335 0 0.00114367 -0.0362688 0 -0.0145363 -0.106885 0.01 -0.00966154 -0.107997 0.01 -0.0025 -1.17713e-16 0.01 -0.00786195 -0.0715902 0.01 -0.00384236 -0.0358954 0.01 -0.0145363 0.106885 0.01 -0.00384236 0.0358954 0.01 -0.00786195 0.0715902 0.01 -0.00966154 0.107997 0.01 0.0025 -1.18938e-16 0.01 0.00114367 0.0362688 0.01 -0.00291774 0.072335 0.01 -0.00291774 -0.072335 0.01 0.00114367 -0.0362688 0.01 -0.0145363 -0.106885 0 -0.0145363 -0.106885 0.01 -0.0025 -1.17713e-16 0.01 -0.00786195 -0.0715902 0.01 -0.00384236 -0.0358954 0.01 -0.0025 -1.17713e-16 0 -0.00786195 -0.0715902 0 -0.00384236 -0.0358954 0 -0.0025 -1.17713e-16 0 -0.0025 -1.17713e-16 0.01 -0.0145363 0.106885 0.01 -0.00384236 0.0358954 0.01 -0.00786195 0.0715902 0.01 -0.0145363 0.106885 0 -0.00384236 0.0358954 0 -0.00786195 0.0715902 0 -0.0145363 0.106885 0 -0.00966154 0.107997 0 -0.00966154 0.107997 0.01 -0.0145363 0.106885 0.01 0.0025 -1.18938e-16 0 0.0025 -1.18938e-16 0.01 -0.00966154 0.107997 0.01 0.00114367 0.0362688 0.01 -0.00291774 0.072335 0.01 -0.00966154 0.107997 0 0.00114367 0.0362688 0 -0.00291774 0.072335 0 + + + 1 3 2 1 0 3 7 4 5 16 7 5 8 7 16 17 8 16 6 8 17 13 6 17 10 6 13 14 10 13 15 11 10 15 10 14 9 11 15 12 9 15 21 19 18 21 18 24 22 24 25 22 21 24 20 25 23 20 22 25 29 26 27 38 29 27 30 29 38 39 30 38 28 30 39 35 28 39 32 28 35 36 32 35 37 33 32 37 32 36 31 33 37 34 31 37 43 41 40 43 40 46 44 46 47 44 43 46 42 47 45 42 44 47 51 49 48 51 48 54 52 54 55 52 51 54 50 55 53 50 52 55 56 59 58 57 56 58 63 61 60 63 60 66 64 66 67 64 63 66 62 67 65 62 64 67 + 3 6 9 12 15 18 21 24 27 30 33 36 39 42 45 48 51 54 57 60 63 66 69 72 75 78 81 84 87 90 93 96 99 102 105 108 111 114 117 120 123 126 129 132 135 138 141 144 147 150 153 156 + + + + + -0.0145739 -0.107219 0 -0.00969911 -0.108331 0 -0.00969911 -0.108331 0.01 -0.0145739 -0.107219 0.01 -0.0145739 -0.107219 0 -0.00969911 -0.108331 0 -0.0025 -1.1808e-16 0 -0.00787869 -0.0718137 0 -0.00384655 -0.0360074 0 -0.0145739 0.107219 0 -0.00384655 0.0360074 0 -0.00787869 0.0718137 0 -0.00969911 0.108331 0 0.0025 -1.19305e-16 0 0.00113948 0.0363808 0 -0.00293447 0.0725585 0 -0.00293447 -0.0725585 0 0.00113948 -0.0363808 0 -0.00969911 -0.108331 0 -0.00969911 -0.108331 0.01 0.0025 -1.19305e-16 0.01 -0.00293447 -0.0725585 0.01 0.00113948 -0.0363808 0.01 0.0025 -1.19305e-16 0 -0.00293447 -0.0725585 0 0.00113948 -0.0363808 0 -0.0145739 -0.107219 0.01 -0.00969911 -0.108331 0.01 -0.0025 -1.1808e-16 0.01 -0.00787869 -0.0718137 0.01 -0.00384655 -0.0360074 0.01 -0.0145739 0.107219 0.01 -0.00384655 0.0360074 0.01 -0.00787869 0.0718137 0.01 -0.00969911 0.108331 0.01 0.0025 -1.19305e-16 0.01 0.00113948 0.0363808 0.01 -0.00293447 0.0725585 0.01 -0.00293447 -0.0725585 0.01 0.00113948 -0.0363808 0.01 -0.0145739 -0.107219 0 -0.0145739 -0.107219 0.01 -0.0025 -1.1808e-16 0.01 -0.00787869 -0.0718137 0.01 -0.00384655 -0.0360074 0.01 -0.0025 -1.1808e-16 0 -0.00787869 -0.0718137 0 -0.00384655 -0.0360074 0 -0.0025 -1.1808e-16 0 -0.0025 -1.1808e-16 0.01 -0.0145739 0.107219 0.01 -0.00384655 0.0360074 0.01 -0.00787869 0.0718137 0.01 -0.0145739 0.107219 0 -0.00384655 0.0360074 0 -0.00787869 0.0718137 0 -0.0145739 0.107219 0 -0.00969911 0.108331 0 -0.00969911 0.108331 0.01 -0.0145739 0.107219 0.01 0.0025 -1.19305e-16 0 0.0025 -1.19305e-16 0.01 -0.00969911 0.108331 0.01 0.00113948 0.0363808 0.01 -0.00293447 0.0725585 0.01 -0.00969911 0.108331 0 0.00113948 0.0363808 0 -0.00293447 0.0725585 0 + + + 0 3 2 1 0 2 7 4 5 16 7 5 8 7 16 17 8 16 6 8 17 13 6 17 10 6 13 14 10 13 15 11 10 15 10 14 9 11 15 12 9 15 21 19 18 21 18 24 22 24 25 22 21 24 20 25 23 20 22 25 38 26 27 38 29 26 39 30 29 39 29 38 28 30 39 35 28 39 32 28 35 36 32 35 37 33 32 37 32 36 31 33 37 34 31 37 43 41 40 43 40 46 44 46 47 44 43 46 42 47 45 42 44 47 51 49 48 51 48 54 52 54 55 52 51 54 50 55 53 50 52 55 56 59 58 57 56 58 63 61 60 63 60 66 64 66 67 64 63 66 62 67 65 62 64 67 + 3 6 9 12 15 18 21 24 27 30 33 36 39 42 45 48 51 54 57 60 63 66 69 72 75 78 81 84 87 90 93 96 99 102 105 108 111 114 117 120 123 126 129 132 135 138 141 144 147 150 153 156 + + + + + -0.0147667 -0.108931 0 -0.00989195 -0.110043 0 -0.00989195 -0.110043 0.01 -0.0147667 -0.108931 0.01 -0.0147667 -0.108931 0 -0.00989195 -0.110043 0 -0.0025 -1.19966e-16 0 -0.0079646 -0.0729606 0 -0.00386806 -0.0365825 0 -0.0147667 0.108931 0 -0.00386806 0.0365825 0 -0.0079646 0.0729606 0 -0.00989195 0.110043 0 0.0025 -1.21191e-16 0 0.00111797 0.0369559 0 -0.00302038 0.0737054 0 -0.00302038 -0.0737054 0 0.00111797 -0.0369559 0 -0.00989195 -0.110043 0 -0.00989195 -0.110043 0.01 0.0025 -1.21191e-16 0.01 -0.00302038 -0.0737054 0.01 0.00111797 -0.0369559 0.01 0.0025 -1.21191e-16 0 -0.00302038 -0.0737054 0 0.00111797 -0.0369559 0 -0.0147667 -0.108931 0.01 -0.00989195 -0.110043 0.01 -0.0025 -1.19966e-16 0.01 -0.0079646 -0.0729606 0.01 -0.00386806 -0.0365825 0.01 -0.0147667 0.108931 0.01 -0.00386806 0.0365825 0.01 -0.0079646 0.0729606 0.01 -0.00989195 0.110043 0.01 0.0025 -1.21191e-16 0.01 0.00111797 0.0369559 0.01 -0.00302038 0.0737054 0.01 -0.00302038 -0.0737054 0.01 0.00111797 -0.0369559 0.01 -0.0147667 -0.108931 0 -0.0147667 -0.108931 0.01 -0.0025 -1.19966e-16 0.01 -0.0079646 -0.0729606 0.01 -0.00386806 -0.0365825 0.01 -0.0025 -1.19966e-16 0 -0.0079646 -0.0729606 0 -0.00386806 -0.0365825 0 -0.0025 -1.19966e-16 0 -0.0025 -1.19966e-16 0.01 -0.0147667 0.108931 0.01 -0.00386806 0.0365825 0.01 -0.0079646 0.0729606 0.01 -0.0147667 0.108931 0 -0.00386806 0.0365825 0 -0.0079646 0.0729606 0 -0.0147667 0.108931 0 -0.00989195 0.110043 0 -0.00989195 0.110043 0.01 -0.0147667 0.108931 0.01 0.0025 -1.21191e-16 0 0.0025 -1.21191e-16 0.01 -0.00989195 0.110043 0.01 0.00111797 0.0369559 0.01 -0.00302038 0.0737054 0.01 -0.00989195 0.110043 0 0.00111797 0.0369559 0 -0.00302038 0.0737054 0 + + + 1 3 2 1 0 3 16 4 5 16 7 4 17 8 7 17 7 16 6 8 17 13 6 17 10 6 13 14 10 13 15 11 10 15 10 14 9 11 15 12 9 15 21 19 18 21 18 24 22 24 25 22 21 24 20 25 23 20 22 25 38 26 27 38 29 26 39 30 29 39 29 38 28 30 39 35 28 39 32 28 35 36 32 35 37 33 32 37 32 36 31 33 37 34 31 37 43 41 40 43 40 46 44 46 47 44 43 46 42 47 45 42 44 47 51 49 48 51 48 54 52 54 55 52 51 54 50 55 53 50 52 55 56 59 58 57 56 58 63 61 60 63 60 66 64 66 67 64 63 66 62 67 65 62 64 67 + 3 6 9 12 15 18 21 24 27 30 33 36 39 42 45 48 51 54 57 60 63 66 69 72 75 78 81 84 87 90 93 96 99 102 105 108 111 114 117 120 123 126 129 132 135 138 141 144 147 150 153 156 + + + + + -0.0148043 -0.109265 0 -0.00992951 -0.110377 0 -0.00992951 -0.110377 0.01 -0.0148043 -0.109265 0.01 -0.0148043 -0.109265 0 -0.00992951 -0.110377 0 -0.0025 -1.20334e-16 0 -0.00798133 -0.0731841 0 -0.00387225 -0.0366945 0 -0.0148043 0.109265 0 -0.00387225 0.0366945 0 -0.00798133 0.0731841 0 -0.00992951 0.110377 0 0.0025 -1.21558e-16 0 0.00111379 0.037068 0 -0.00303711 0.0739289 0 -0.00303711 -0.0739289 0 0.00111379 -0.037068 0 -0.00992951 -0.110377 0 -0.00992951 -0.110377 0.01 0.0025 -1.21558e-16 0.01 -0.00303711 -0.0739289 0.01 0.00111379 -0.037068 0.01 0.0025 -1.21558e-16 0 -0.00303711 -0.0739289 0 0.00111379 -0.037068 0 -0.0148043 -0.109265 0.01 -0.00992951 -0.110377 0.01 -0.0025 -1.20334e-16 0.01 -0.00798133 -0.0731841 0.01 -0.00387225 -0.0366945 0.01 -0.0148043 0.109265 0.01 -0.00387225 0.0366945 0.01 -0.00798133 0.0731841 0.01 -0.00992951 0.110377 0.01 0.0025 -1.21558e-16 0.01 0.00111379 0.037068 0.01 -0.00303711 0.0739289 0.01 -0.00303711 -0.0739289 0.01 0.00111379 -0.037068 0.01 -0.0148043 -0.109265 0 -0.0148043 -0.109265 0.01 -0.0025 -1.20334e-16 0.01 -0.00798133 -0.0731841 0.01 -0.00387225 -0.0366945 0.01 -0.0025 -1.20334e-16 0 -0.00798133 -0.0731841 0 -0.00387225 -0.0366945 0 -0.0025 -1.20334e-16 0 -0.0025 -1.20334e-16 0.01 -0.0148043 0.109265 0.01 -0.00387225 0.0366945 0.01 -0.00798133 0.0731841 0.01 -0.0148043 0.109265 0 -0.00387225 0.0366945 0 -0.00798133 0.0731841 0 -0.0148043 0.109265 0 -0.00992951 0.110377 0 -0.00992951 0.110377 0.01 -0.0148043 0.109265 0.01 0.0025 -1.21558e-16 0 0.0025 -1.21558e-16 0.01 -0.00992951 0.110377 0.01 0.00111379 0.037068 0.01 -0.00303711 0.0739289 0.01 -0.00992951 0.110377 0 0.00111379 0.037068 0 -0.00303711 0.0739289 0 + + + 1 3 2 1 0 3 16 4 5 16 7 4 17 8 7 17 7 16 13 6 8 13 8 17 10 6 13 14 10 13 15 11 10 15 10 14 9 11 15 12 9 15 21 19 18 21 18 24 22 24 25 22 21 24 20 25 23 20 22 25 38 26 27 38 29 26 39 30 29 39 29 38 28 30 39 35 28 39 32 28 35 36 32 35 37 33 32 37 32 36 31 33 37 34 31 37 43 41 40 43 40 46 44 46 47 44 43 46 42 47 45 42 44 47 51 49 48 51 48 54 52 54 55 52 51 54 50 55 53 50 52 55 56 59 58 57 56 58 63 61 60 63 60 66 64 66 67 64 63 66 62 67 65 62 64 67 + 3 6 9 12 15 18 21 24 27 30 33 36 39 42 45 48 51 54 57 60 63 66 69 72 75 78 81 84 87 90 93 96 99 102 105 108 111 114 117 120 123 126 129 132 135 138 141 144 147 150 153 156 + + + + + -0.017742 -0.135352 0 -0.0128672 -0.136464 0 -0.0128672 -0.136464 0.01 -0.017742 -0.135352 0.01 -0.017742 -0.135352 0 -0.0128672 -0.136464 0 -0.0025 -1.49064e-16 0 -0.00929002 -0.0906571 0 -0.00419988 -0.0454555 0 -0.017742 0.135352 0 -0.00419988 0.0454555 0 -0.00929002 0.0906571 0 -0.0128672 0.136464 0 0.0025 -1.50289e-16 0 0.000786155 0.045829 0 -0.00434581 0.0914019 0 -0.00434581 -0.0914019 0 0.000786155 -0.045829 0 -0.0128672 -0.136464 0 -0.0128672 -0.136464 0.01 0.0025 -1.50289e-16 0.01 -0.00434581 -0.0914019 0.01 0.000786155 -0.045829 0.01 0.0025 -1.50289e-16 0 -0.00434581 -0.0914019 0 0.000786155 -0.045829 0 -0.017742 -0.135352 0.01 -0.0128672 -0.136464 0.01 -0.0025 -1.49064e-16 0.01 -0.00929002 -0.0906571 0.01 -0.00419988 -0.0454555 0.01 -0.017742 0.135352 0.01 -0.00419988 0.0454555 0.01 -0.00929002 0.0906571 0.01 -0.0128672 0.136464 0.01 0.0025 -1.50289e-16 0.01 0.000786155 0.045829 0.01 -0.00434581 0.0914019 0.01 -0.00434581 -0.0914019 0.01 0.000786155 -0.045829 0.01 -0.017742 -0.135352 0 -0.017742 -0.135352 0.01 -0.0025 -1.49064e-16 0.01 -0.00929002 -0.0906571 0.01 -0.00419988 -0.0454555 0.01 -0.0025 -1.49064e-16 0 -0.00929002 -0.0906571 0 -0.00419988 -0.0454555 0 -0.0025 -1.49064e-16 0 -0.0025 -1.49064e-16 0.01 -0.017742 0.135352 0.01 -0.00419988 0.0454555 0.01 -0.00929002 0.0906571 0.01 -0.017742 0.135352 0 -0.00419988 0.0454555 0 -0.00929002 0.0906571 0 -0.017742 0.135352 0 -0.0128672 0.136464 0 -0.0128672 0.136464 0.01 -0.017742 0.135352 0.01 0.0025 -1.50289e-16 0 0.0025 -1.50289e-16 0.01 -0.0128672 0.136464 0.01 0.000786155 0.045829 0.01 -0.00434581 0.0914019 0.01 -0.0128672 0.136464 0 0.000786155 0.045829 0 -0.00434581 0.0914019 0 + + + 1 3 2 1 0 3 16 4 5 16 7 4 17 8 7 17 7 16 13 6 8 13 8 17 10 6 13 14 10 13 15 11 10 15 10 14 12 9 11 12 11 15 21 19 18 21 18 24 22 24 25 22 21 24 20 25 23 20 22 25 38 26 27 38 29 26 39 30 29 39 29 38 35 28 30 35 30 39 32 28 35 36 32 35 37 33 32 37 32 36 31 33 37 34 31 37 43 41 40 43 40 46 44 46 47 44 43 46 42 47 45 42 44 47 51 49 48 51 48 54 52 54 55 52 51 54 50 55 53 50 52 55 56 59 58 57 56 58 63 61 60 63 60 66 64 66 67 64 63 66 62 67 65 62 64 67 + 3 6 9 12 15 18 21 24 27 30 33 36 39 42 45 48 51 54 57 60 63 66 69 72 75 78 81 84 87 90 93 96 99 102 105 108 111 114 117 120 123 126 129 132 135 138 141 144 147 150 153 156 + + + + + -0.017762 -0.13553 0 -0.0128873 -0.136642 0 -0.0128873 -0.136642 0.01 -0.017762 -0.13553 0.01 -0.017762 -0.13553 0 -0.0128873 -0.136642 0 -0.0025 -1.4926e-16 0 -0.00929895 -0.0907763 0 -0.00420211 -0.0455153 0 -0.017762 0.13553 0 -0.00420211 0.0455153 0 -0.00929895 0.0907763 0 -0.0128873 0.136642 0 0.0025 -1.50485e-16 0 0.00078392 0.0458887 0 -0.00435473 0.0915211 0 -0.00435473 -0.0915211 0 0.00078392 -0.0458887 0 -0.0128873 -0.136642 0 -0.0128873 -0.136642 0.01 0.0025 -1.50485e-16 0.01 -0.00435473 -0.0915211 0.01 0.00078392 -0.0458887 0.01 0.0025 -1.50485e-16 0 -0.00435473 -0.0915211 0 0.00078392 -0.0458887 0 -0.017762 -0.13553 0.01 -0.0128873 -0.136642 0.01 -0.0025 -1.4926e-16 0.01 -0.00929895 -0.0907763 0.01 -0.00420211 -0.0455153 0.01 -0.017762 0.13553 0.01 -0.00420211 0.0455153 0.01 -0.00929895 0.0907763 0.01 -0.0128873 0.136642 0.01 0.0025 -1.50485e-16 0.01 0.00078392 0.0458887 0.01 -0.00435473 0.0915211 0.01 -0.00435473 -0.0915211 0.01 0.00078392 -0.0458887 0.01 -0.017762 -0.13553 0 -0.017762 -0.13553 0.01 -0.0025 -1.4926e-16 0.01 -0.00929895 -0.0907763 0.01 -0.00420211 -0.0455153 0.01 -0.0025 -1.4926e-16 0 -0.00929895 -0.0907763 0 -0.00420211 -0.0455153 0 -0.0025 -1.4926e-16 0 -0.0025 -1.4926e-16 0.01 -0.017762 0.13553 0.01 -0.00420211 0.0455153 0.01 -0.00929895 0.0907763 0.01 -0.017762 0.13553 0 -0.00420211 0.0455153 0 -0.00929895 0.0907763 0 -0.017762 0.13553 0 -0.0128873 0.136642 0 -0.0128873 0.136642 0.01 -0.017762 0.13553 0.01 0.0025 -1.50485e-16 0 0.0025 -1.50485e-16 0.01 -0.0128873 0.136642 0.01 0.00078392 0.0458887 0.01 -0.00435473 0.0915211 0.01 -0.0128873 0.136642 0 0.00078392 0.0458887 0 -0.00435473 0.0915211 0 + + + 0 3 2 1 0 2 16 4 5 16 7 4 17 8 7 17 7 16 13 6 8 13 8 17 10 6 13 14 10 13 15 11 10 15 10 14 9 11 15 12 9 15 21 19 18 21 18 24 22 24 25 22 21 24 20 25 23 20 22 25 38 26 27 38 29 26 39 30 29 39 29 38 35 28 30 35 30 39 32 28 35 36 32 35 37 33 32 37 32 36 31 33 37 34 31 37 43 41 40 43 40 46 44 46 47 44 43 46 42 47 45 42 44 47 51 49 48 51 48 54 52 54 55 52 51 54 50 55 53 50 52 55 56 59 58 57 56 58 63 61 60 63 60 66 64 66 67 64 63 66 62 67 65 62 64 67 + 3 6 9 12 15 18 21 24 27 30 33 36 39 42 45 48 51 54 57 60 63 66 69 72 75 78 81 84 87 90 93 96 99 102 105 108 111 114 117 120 123 126 129 132 135 138 141 144 147 150 153 156 + + + + + -0.0188465 -0.14516 0 -0.0139717 -0.146272 0 -0.0139717 -0.146272 0.01 -0.0188465 -0.14516 0.01 -0.0188465 -0.14516 0 -0.0139717 -0.146272 0 -0.0025 -1.59865e-16 0 -0.00978204 -0.0972262 0 -0.00432306 -0.0487493 0 -0.0188465 0.14516 0 -0.00432306 0.0487493 0 -0.00978204 0.0972262 0 -0.0139717 0.146272 0 0.0025 -1.6109e-16 0 0.000662979 0.0491227 0 -0.00483782 0.097971 0 -0.00483782 -0.097971 0 0.000662979 -0.0491227 0 -0.0139717 -0.146272 0 -0.0139717 -0.146272 0.01 0.0025 -1.6109e-16 0.01 -0.00483782 -0.097971 0.01 0.000662979 -0.0491227 0.01 0.0025 -1.6109e-16 0 -0.00483782 -0.097971 0 0.000662979 -0.0491227 0 -0.0188465 -0.14516 0.01 -0.0139717 -0.146272 0.01 -0.0025 -1.59865e-16 0.01 -0.00978204 -0.0972262 0.01 -0.00432306 -0.0487493 0.01 -0.0188465 0.14516 0.01 -0.00432306 0.0487493 0.01 -0.00978204 0.0972262 0.01 -0.0139717 0.146272 0.01 0.0025 -1.6109e-16 0.01 0.000662979 0.0491227 0.01 -0.00483782 0.097971 0.01 -0.00483782 -0.097971 0.01 0.000662979 -0.0491227 0.01 -0.0188465 -0.14516 0 -0.0188465 -0.14516 0.01 -0.0025 -1.59865e-16 0.01 -0.00978204 -0.0972262 0.01 -0.00432306 -0.0487493 0.01 -0.0025 -1.59865e-16 0 -0.00978204 -0.0972262 0 -0.00432306 -0.0487493 0 -0.0025 -1.59865e-16 0 -0.0025 -1.59865e-16 0.01 -0.0188465 0.14516 0.01 -0.00432306 0.0487493 0.01 -0.00978204 0.0972262 0.01 -0.0188465 0.14516 0 -0.00432306 0.0487493 0 -0.00978204 0.0972262 0 -0.0188465 0.14516 0 -0.0139717 0.146272 0 -0.0139717 0.146272 0.01 -0.0188465 0.14516 0.01 0.0025 -1.6109e-16 0 0.0025 -1.6109e-16 0.01 -0.0139717 0.146272 0.01 0.000662979 0.0491227 0.01 -0.00483782 0.097971 0.01 -0.0139717 0.146272 0 0.000662979 0.0491227 0 -0.00483782 0.097971 0 + + + 1 3 2 1 0 3 16 4 5 16 7 4 17 8 7 17 7 16 6 8 17 13 6 17 10 6 13 14 10 13 11 10 14 15 11 14 12 9 11 12 11 15 21 19 18 21 18 24 22 24 25 22 21 24 20 25 23 20 22 25 38 26 27 38 29 26 39 30 29 39 29 38 28 30 39 35 28 39 32 28 35 36 32 35 33 32 36 37 33 36 34 31 33 34 33 37 43 41 40 43 40 46 44 46 47 44 43 46 42 47 45 42 44 47 51 49 48 51 48 54 52 54 55 52 51 54 50 55 53 50 52 55 56 59 58 57 56 58 63 61 60 63 60 66 64 66 67 64 63 66 62 67 65 62 64 67 + 3 6 9 12 15 18 21 24 27 30 33 36 39 42 45 48 51 54 57 60 63 66 69 72 75 78 81 84 87 90 93 96 99 102 105 108 111 114 117 120 123 126 129 132 135 138 141 144 147 150 153 156 + + + + + -0.0188665 -0.145338 0 -0.0139917 -0.14645 0 -0.0139917 -0.14645 0.01 -0.0188665 -0.145338 0.01 -0.0188665 -0.145338 0 -0.0139917 -0.14645 0 -0.0025 -1.60061e-16 0 -0.00979096 -0.0973454 0 -0.00432529 -0.048809 0 -0.0188665 0.145338 0 -0.00432529 0.048809 0 -0.00979096 0.0973454 0 -0.0139917 0.14645 0 0.0025 -1.61286e-16 0 0.000660745 0.0491825 0 -0.00484675 0.0980902 0 -0.00484675 -0.0980902 0 0.000660745 -0.0491825 0 -0.0139917 -0.14645 0 -0.0139917 -0.14645 0.01 0.0025 -1.61286e-16 0.01 -0.00484675 -0.0980902 0.01 0.000660745 -0.0491825 0.01 0.0025 -1.61286e-16 0 -0.00484675 -0.0980902 0 0.000660745 -0.0491825 0 -0.0188665 -0.145338 0.01 -0.0139917 -0.14645 0.01 -0.0025 -1.60061e-16 0.01 -0.00979096 -0.0973454 0.01 -0.00432529 -0.048809 0.01 -0.0188665 0.145338 0.01 -0.00432529 0.048809 0.01 -0.00979096 0.0973454 0.01 -0.0139917 0.14645 0.01 0.0025 -1.61286e-16 0.01 0.000660745 0.0491825 0.01 -0.00484675 0.0980902 0.01 -0.00484675 -0.0980902 0.01 0.000660745 -0.0491825 0.01 -0.0188665 -0.145338 0 -0.0188665 -0.145338 0.01 -0.0025 -1.60061e-16 0.01 -0.00979096 -0.0973454 0.01 -0.00432529 -0.048809 0.01 -0.0025 -1.60061e-16 0 -0.00979096 -0.0973454 0 -0.00432529 -0.048809 0 -0.0025 -1.60061e-16 0 -0.0025 -1.60061e-16 0.01 -0.0188665 0.145338 0.01 -0.00432529 0.048809 0.01 -0.00979096 0.0973454 0.01 -0.0188665 0.145338 0 -0.00432529 0.048809 0 -0.00979096 0.0973454 0 -0.0188665 0.145338 0 -0.0139917 0.14645 0 -0.0139917 0.14645 0.01 -0.0188665 0.145338 0.01 0.0025 -1.61286e-16 0 0.0025 -1.61286e-16 0.01 -0.0139917 0.14645 0.01 0.000660745 0.0491825 0.01 -0.00484675 0.0980902 0.01 -0.0139917 0.14645 0 0.000660745 0.0491825 0 -0.00484675 0.0980902 0 + + + 0 3 2 1 0 2 16 4 5 16 7 4 17 8 7 17 7 16 13 6 8 13 8 17 10 6 13 14 10 13 15 11 10 15 10 14 12 9 11 12 11 15 21 19 18 21 18 24 22 24 25 22 21 24 20 25 23 20 22 25 38 26 27 38 29 26 39 30 29 39 29 38 28 30 39 35 28 39 32 28 35 36 32 35 37 33 32 37 32 36 34 31 33 34 33 37 43 41 40 43 40 46 44 46 47 44 43 46 42 47 45 42 44 47 51 49 48 51 48 54 52 54 55 52 51 54 50 55 53 50 52 55 56 59 58 57 56 58 63 61 60 63 60 66 64 66 67 64 63 66 62 67 65 62 64 67 + 3 6 9 12 15 18 21 24 27 30 33 36 39 42 45 48 51 54 57 60 63 66 69 72 75 78 81 84 87 90 93 96 99 102 105 108 111 114 117 120 123 126 129 132 135 138 141 144 147 150 153 156 + + + + + -0.0190668 -0.147117 0 -0.0141921 -0.148229 0 -0.0141921 -0.148229 0.01 -0.0190668 -0.147117 0.01 -0.0190668 -0.147117 0 -0.0141921 -0.148229 0 -0.0025 -1.62021e-16 0 -0.00988022 -0.0985371 0 -0.00434763 -0.0494065 0 -0.0190668 0.147117 0 -0.00434763 0.0494065 0 -0.00988022 0.0985371 0 -0.0141921 0.148229 0 0.0025 -1.63245e-16 0 0.0006384 0.04978 0 -0.004936 0.0992819 0 -0.004936 -0.0992819 0 0.0006384 -0.04978 0 -0.0141921 -0.148229 0 -0.0141921 -0.148229 0.01 0.0025 -1.63245e-16 0.01 -0.004936 -0.0992819 0.01 0.0006384 -0.04978 0.01 0.0025 -1.63245e-16 0 -0.004936 -0.0992819 0 0.0006384 -0.04978 0 -0.0190668 -0.147117 0.01 -0.0141921 -0.148229 0.01 -0.0025 -1.62021e-16 0.01 -0.00988022 -0.0985371 0.01 -0.00434763 -0.0494065 0.01 -0.0190668 0.147117 0.01 -0.00434763 0.0494065 0.01 -0.00988022 0.0985371 0.01 -0.0141921 0.148229 0.01 0.0025 -1.63245e-16 0.01 0.0006384 0.04978 0.01 -0.004936 0.0992819 0.01 -0.004936 -0.0992819 0.01 0.0006384 -0.04978 0.01 -0.0190668 -0.147117 0 -0.0190668 -0.147117 0.01 -0.0025 -1.62021e-16 0.01 -0.00988022 -0.0985371 0.01 -0.00434763 -0.0494065 0.01 -0.0025 -1.62021e-16 0 -0.00988022 -0.0985371 0 -0.00434763 -0.0494065 0 -0.0025 -1.62021e-16 0 -0.0025 -1.62021e-16 0.01 -0.0190668 0.147117 0.01 -0.00434763 0.0494065 0.01 -0.00988022 0.0985371 0.01 -0.0190668 0.147117 0 -0.00434763 0.0494065 0 -0.00988022 0.0985371 0 -0.0190668 0.147117 0 -0.0141921 0.148229 0 -0.0141921 0.148229 0.01 -0.0190668 0.147117 0.01 0.0025 -1.63245e-16 0 0.0025 -1.63245e-16 0.01 -0.0141921 0.148229 0.01 0.0006384 0.04978 0.01 -0.004936 0.0992819 0.01 -0.0141921 0.148229 0 0.0006384 0.04978 0 -0.004936 0.0992819 0 + + + 0 3 2 1 0 2 7 4 5 16 7 5 8 7 16 17 8 16 6 8 17 13 6 17 10 6 13 14 10 13 15 11 10 15 10 14 9 11 15 12 9 15 21 19 18 21 18 24 22 24 25 22 21 24 20 25 23 20 22 25 38 26 27 38 29 26 39 30 29 39 29 38 28 30 39 35 28 39 32 28 35 36 32 35 37 33 32 37 32 36 31 33 37 34 31 37 43 41 40 43 40 46 43 46 47 44 43 47 42 47 45 42 44 47 51 49 48 51 48 54 52 54 55 52 51 54 50 55 53 50 52 55 56 59 58 57 56 58 63 61 60 63 60 66 64 66 67 64 63 66 62 67 65 62 64 67 + 3 6 9 12 15 18 21 24 27 30 33 36 39 42 45 48 51 54 57 60 63 66 69 72 75 78 81 84 87 90 93 96 99 102 105 108 111 114 117 120 123 126 129 132 135 138 141 144 147 150 153 156 + + + + + -0.0190869 -0.147295 0 -0.0142121 -0.148407 0 -0.0142121 -0.148407 0.01 -0.0190869 -0.147295 0.01 -0.0190869 -0.147295 0 -0.0142121 -0.148407 0 -0.0025 -1.62217e-16 0 -0.00988914 -0.0986563 0 -0.00434987 -0.0494663 0 -0.0190869 0.147295 0 -0.00434987 0.0494663 0 -0.00988914 0.0986563 0 -0.0142121 0.148407 0 0.0025 -1.63441e-16 0 0.000636166 0.0498397 0 -0.00494493 0.0994011 0 -0.00494493 -0.0994011 0 0.000636166 -0.0498397 0 -0.0142121 -0.148407 0 -0.0142121 -0.148407 0.01 0.0025 -1.63441e-16 0.01 -0.00494493 -0.0994011 0.01 0.000636166 -0.0498397 0.01 0.0025 -1.63441e-16 0 -0.00494493 -0.0994011 0 0.000636166 -0.0498397 0 -0.0190869 -0.147295 0.01 -0.0142121 -0.148407 0.01 -0.0025 -1.62217e-16 0.01 -0.00988914 -0.0986563 0.01 -0.00434987 -0.0494663 0.01 -0.0190869 0.147295 0.01 -0.00434987 0.0494663 0.01 -0.00988914 0.0986563 0.01 -0.0142121 0.148407 0.01 0.0025 -1.63441e-16 0.01 0.000636166 0.0498397 0.01 -0.00494493 0.0994011 0.01 -0.00494493 -0.0994011 0.01 0.000636166 -0.0498397 0.01 -0.0190869 -0.147295 0 -0.0190869 -0.147295 0.01 -0.0025 -1.62217e-16 0.01 -0.00988914 -0.0986563 0.01 -0.00434987 -0.0494663 0.01 -0.0025 -1.62217e-16 0 -0.00988914 -0.0986563 0 -0.00434987 -0.0494663 0 -0.0025 -1.62217e-16 0 -0.0025 -1.62217e-16 0.01 -0.0190869 0.147295 0.01 -0.00434987 0.0494663 0.01 -0.00988914 0.0986563 0.01 -0.0190869 0.147295 0 -0.00434987 0.0494663 0 -0.00988914 0.0986563 0 -0.0190869 0.147295 0 -0.0142121 0.148407 0 -0.0142121 0.148407 0.01 -0.0190869 0.147295 0.01 0.0025 -1.63441e-16 0 0.0025 -1.63441e-16 0.01 -0.0142121 0.148407 0.01 0.000636166 0.0498397 0.01 -0.00494493 0.0994011 0.01 -0.0142121 0.148407 0 0.000636166 0.0498397 0 -0.00494493 0.0994011 0 + + + 1 3 2 1 0 3 16 4 5 16 7 4 17 8 7 17 7 16 13 6 8 13 8 17 10 6 13 14 10 13 11 10 14 15 11 14 9 11 15 12 9 15 21 19 18 21 18 24 22 24 25 22 21 24 20 25 23 20 22 25 38 26 27 38 29 26 39 30 29 39 29 38 35 28 30 35 30 39 32 28 35 36 32 35 33 32 36 37 33 36 31 33 37 34 31 37 43 41 40 43 40 46 44 46 47 44 43 46 42 47 45 42 44 47 51 49 48 51 48 54 52 54 55 52 51 54 50 55 53 50 52 55 56 59 58 57 56 58 63 61 60 63 60 66 64 66 67 64 63 66 62 67 65 62 64 67 + 3 6 9 12 15 18 21 24 27 30 33 36 39 42 45 48 51 54 57 60 63 66 69 72 75 78 81 84 87 90 93 96 99 102 105 108 111 114 117 120 123 126 129 132 135 138 141 144 147 150 153 156 + + + + + -0.0192897 -0.149097 0 -0.014415 -0.150209 0 -0.014415 -0.150209 0.01 -0.0192897 -0.149097 0.01 -0.0192897 -0.149097 0 -0.014415 -0.150209 0 -0.0025 -1.64201e-16 0 -0.00997951 -0.0998628 0 -0.00437249 -0.0500713 0 -0.0192897 0.149097 0 -0.00437249 0.0500713 0 -0.00997951 0.0998628 0 -0.014415 0.150209 0 0.0025 -1.65425e-16 0 0.000613541 0.0504447 0 -0.0050353 0.100608 0 -0.0050353 -0.100608 0 0.000613541 -0.0504447 0 -0.014415 -0.150209 0 -0.014415 -0.150209 0.01 0.0025 -1.65425e-16 0.01 -0.0050353 -0.100608 0.01 0.000613541 -0.0504447 0.01 0.0025 -1.65425e-16 0 -0.0050353 -0.100608 0 0.000613541 -0.0504447 0 -0.0192897 -0.149097 0.01 -0.014415 -0.150209 0.01 -0.0025 -1.64201e-16 0.01 -0.00997951 -0.0998628 0.01 -0.00437249 -0.0500713 0.01 -0.0192897 0.149097 0.01 -0.00437249 0.0500713 0.01 -0.00997951 0.0998628 0.01 -0.014415 0.150209 0.01 0.0025 -1.65425e-16 0.01 0.000613541 0.0504447 0.01 -0.0050353 0.100608 0.01 -0.0050353 -0.100608 0.01 0.000613541 -0.0504447 0.01 -0.0192897 -0.149097 0 -0.0192897 -0.149097 0.01 -0.0025 -1.64201e-16 0.01 -0.00997951 -0.0998628 0.01 -0.00437249 -0.0500713 0.01 -0.0025 -1.64201e-16 0 -0.00997951 -0.0998628 0 -0.00437249 -0.0500713 0 -0.0025 -1.64201e-16 0 -0.0025 -1.64201e-16 0.01 -0.0192897 0.149097 0.01 -0.00437249 0.0500713 0.01 -0.00997951 0.0998628 0.01 -0.0192897 0.149097 0 -0.00437249 0.0500713 0 -0.00997951 0.0998628 0 -0.0192897 0.149097 0 -0.014415 0.150209 0 -0.014415 0.150209 0.01 -0.0192897 0.149097 0.01 0.0025 -1.65425e-16 0 0.0025 -1.65425e-16 0.01 -0.014415 0.150209 0.01 0.000613541 0.0504447 0.01 -0.0050353 0.100608 0.01 -0.014415 0.150209 0 0.000613541 0.0504447 0 -0.0050353 0.100608 0 + + + 1 3 2 1 0 3 16 4 5 16 7 4 17 8 7 17 7 16 13 6 8 13 8 17 10 6 13 14 10 13 15 11 10 15 10 14 12 9 11 12 11 15 21 19 18 21 18 24 21 24 25 22 21 25 20 25 23 20 22 25 38 26 27 38 29 26 39 30 29 39 29 38 28 30 39 35 28 39 32 28 35 36 32 35 37 33 32 37 32 36 34 31 33 34 33 37 43 41 40 43 40 46 44 46 47 44 43 46 42 47 45 42 44 47 51 49 48 51 48 54 52 54 55 52 51 54 50 55 53 50 52 55 56 59 58 57 56 58 63 61 60 63 60 66 64 66 67 64 63 66 62 67 65 62 64 67 + 3 6 9 12 15 18 21 24 27 30 33 36 39 42 45 48 51 54 57 60 63 66 69 72 75 78 81 84 87 90 93 96 99 102 105 108 111 114 117 120 123 126 129 132 135 138 141 144 147 150 153 156 + + + + + -0.0193098 -0.149274 0 -0.014435 -0.150386 0 -0.014435 -0.150386 0.01 -0.0193098 -0.149274 0.01 -0.0193098 -0.149274 0 -0.014435 -0.150386 0 -0.0025 -1.64397e-16 0 -0.00998844 -0.099982 0 -0.00437473 -0.050131 0 -0.0193098 0.149274 0 -0.00437473 0.050131 0 -0.00998844 0.099982 0 -0.014435 0.150386 0 0.0025 -1.65621e-16 0 0.000611307 0.0505045 0 -0.00504422 0.100727 0 -0.00504422 -0.100727 0 0.000611307 -0.0505045 0 -0.014435 -0.150386 0 -0.014435 -0.150386 0.01 0.0025 -1.65621e-16 0.01 -0.00504422 -0.100727 0.01 0.000611307 -0.0505045 0.01 0.0025 -1.65621e-16 0 -0.00504422 -0.100727 0 0.000611307 -0.0505045 0 -0.0193098 -0.149274 0.01 -0.014435 -0.150386 0.01 -0.0025 -1.64397e-16 0.01 -0.00998844 -0.099982 0.01 -0.00437473 -0.050131 0.01 -0.0193098 0.149274 0.01 -0.00437473 0.050131 0.01 -0.00998844 0.099982 0.01 -0.014435 0.150386 0.01 0.0025 -1.65621e-16 0.01 0.000611307 0.0505045 0.01 -0.00504422 0.100727 0.01 -0.00504422 -0.100727 0.01 0.000611307 -0.0505045 0.01 -0.0193098 -0.149274 0 -0.0193098 -0.149274 0.01 -0.0025 -1.64397e-16 0.01 -0.00998844 -0.099982 0.01 -0.00437473 -0.050131 0.01 -0.0025 -1.64397e-16 0 -0.00998844 -0.099982 0 -0.00437473 -0.050131 0 -0.0025 -1.64397e-16 0 -0.0025 -1.64397e-16 0.01 -0.0193098 0.149274 0.01 -0.00437473 0.050131 0.01 -0.00998844 0.099982 0.01 -0.0193098 0.149274 0 -0.00437473 0.050131 0 -0.00998844 0.099982 0 -0.0193098 0.149274 0 -0.014435 0.150386 0 -0.014435 0.150386 0.01 -0.0193098 0.149274 0.01 0.0025 -1.65621e-16 0 0.0025 -1.65621e-16 0.01 -0.014435 0.150386 0.01 0.000611307 0.0505045 0.01 -0.00504422 0.100727 0.01 -0.014435 0.150386 0 0.000611307 0.0505045 0 -0.00504422 0.100727 0 + + + 1 3 2 1 0 3 16 4 5 16 7 4 17 8 7 17 7 16 13 6 8 13 8 17 10 6 13 14 10 13 11 10 14 15 11 14 12 9 11 12 11 15 21 19 18 21 18 24 21 24 25 22 21 25 20 25 23 20 22 25 38 26 27 38 29 26 39 30 29 39 29 38 28 30 39 35 28 39 32 28 35 36 32 35 33 32 36 37 33 36 34 31 33 34 33 37 43 41 40 43 40 46 44 46 47 44 43 46 42 47 45 42 44 47 51 49 48 51 48 54 52 54 55 52 51 54 50 55 53 50 52 55 56 59 58 57 56 58 63 61 60 63 60 66 64 66 67 64 63 66 62 67 65 62 64 67 + 3 6 9 12 15 18 21 24 27 30 33 36 39 42 45 48 51 54 57 60 63 66 69 72 75 78 81 84 87 90 93 96 99 102 105 108 111 114 117 120 123 126 129 132 135 138 141 144 147 150 153 156 + + + + + -0.0195101 -0.151054 0 -0.0146353 -0.152166 0 -0.0146353 -0.152166 0.01 -0.0195101 -0.151054 0.01 -0.0195101 -0.151054 0 -0.0146353 -0.152166 0 -0.0025 -1.66356e-16 0 -0.0100777 -0.101174 0 -0.00439707 -0.0507285 0 -0.0195101 0.151054 0 -0.00439707 0.0507285 0 -0.0100777 0.101174 0 -0.0146353 0.152166 0 0.0025 -1.67581e-16 0 0.000588962 0.051102 0 -0.00513348 0.101918 0 -0.00513348 -0.101918 0 0.000588962 -0.051102 0 -0.0146353 -0.152166 0 -0.0146353 -0.152166 0.01 0.0025 -1.67581e-16 0.01 -0.00513348 -0.101918 0.01 0.000588962 -0.051102 0.01 0.0025 -1.67581e-16 0 -0.00513348 -0.101918 0 0.000588962 -0.051102 0 -0.0195101 -0.151054 0.01 -0.0146353 -0.152166 0.01 -0.0025 -1.66356e-16 0.01 -0.0100777 -0.101174 0.01 -0.00439707 -0.0507285 0.01 -0.0195101 0.151054 0.01 -0.00439707 0.0507285 0.01 -0.0100777 0.101174 0.01 -0.0146353 0.152166 0.01 0.0025 -1.67581e-16 0.01 0.000588962 0.051102 0.01 -0.00513348 0.101918 0.01 -0.00513348 -0.101918 0.01 0.000588962 -0.051102 0.01 -0.0195101 -0.151054 0 -0.0195101 -0.151054 0.01 -0.0025 -1.66356e-16 0.01 -0.0100777 -0.101174 0.01 -0.00439707 -0.0507285 0.01 -0.0025 -1.66356e-16 0 -0.0100777 -0.101174 0 -0.00439707 -0.0507285 0 -0.0025 -1.66356e-16 0 -0.0025 -1.66356e-16 0.01 -0.0195101 0.151054 0.01 -0.00439707 0.0507285 0.01 -0.0100777 0.101174 0.01 -0.0195101 0.151054 0 -0.00439707 0.0507285 0 -0.0100777 0.101174 0 -0.0195101 0.151054 0 -0.0146353 0.152166 0 -0.0146353 0.152166 0.01 -0.0195101 0.151054 0.01 0.0025 -1.67581e-16 0 0.0025 -1.67581e-16 0.01 -0.0146353 0.152166 0.01 0.000588962 0.051102 0.01 -0.00513348 0.101918 0.01 -0.0146353 0.152166 0 0.000588962 0.051102 0 -0.00513348 0.101918 0 + + + 1 3 2 1 0 3 16 4 5 16 7 4 17 8 7 17 7 16 13 6 8 13 8 17 10 6 13 14 10 13 15 11 10 15 10 14 12 9 11 12 11 15 21 19 18 21 18 24 21 24 25 22 21 25 20 25 23 20 22 25 38 26 27 38 29 26 39 30 29 39 29 38 28 30 39 35 28 39 32 28 35 36 32 35 37 33 32 37 32 36 34 31 33 34 33 37 43 41 40 43 40 46 44 46 47 44 43 46 42 47 45 42 44 47 51 49 48 51 48 54 52 54 55 52 51 54 50 55 53 50 52 55 56 59 58 57 56 58 63 61 60 63 60 66 64 66 67 64 63 66 62 67 65 62 64 67 + 3 6 9 12 15 18 21 24 27 30 33 36 39 42 45 48 51 54 57 60 63 66 69 72 75 78 81 84 87 90 93 96 99 102 105 108 111 114 117 120 123 126 129 132 135 138 141 144 147 150 153 156 + + + + + -0.0195302 -0.151232 0 -0.0146554 -0.152344 0 -0.0146554 -0.152344 0.01 -0.0195302 -0.151232 0.01 -0.0195302 -0.151232 0 -0.0146554 -0.152344 0 -0.0025 -1.66552e-16 0 -0.0100866 -0.101293 0 -0.00439931 -0.0507883 0 -0.0195302 0.151232 0 -0.00439931 0.0507883 0 -0.0100866 0.101293 0 -0.0146554 0.152344 0 0.0025 -1.67777e-16 0 0.000586728 0.0511617 0 -0.0051424 0.102038 0 -0.0051424 -0.102038 0 0.000586728 -0.0511617 0 -0.0146554 -0.152344 0 -0.0146554 -0.152344 0.01 0.0025 -1.67777e-16 0.01 -0.0051424 -0.102038 0.01 0.000586728 -0.0511617 0.01 0.0025 -1.67777e-16 0 -0.0051424 -0.102038 0 0.000586728 -0.0511617 0 -0.0195302 -0.151232 0.01 -0.0146554 -0.152344 0.01 -0.0025 -1.66552e-16 0.01 -0.0100866 -0.101293 0.01 -0.00439931 -0.0507883 0.01 -0.0195302 0.151232 0.01 -0.00439931 0.0507883 0.01 -0.0100866 0.101293 0.01 -0.0146554 0.152344 0.01 0.0025 -1.67777e-16 0.01 0.000586728 0.0511617 0.01 -0.0051424 0.102038 0.01 -0.0051424 -0.102038 0.01 0.000586728 -0.0511617 0.01 -0.0195302 -0.151232 0 -0.0195302 -0.151232 0.01 -0.0025 -1.66552e-16 0.01 -0.0100866 -0.101293 0.01 -0.00439931 -0.0507883 0.01 -0.0025 -1.66552e-16 0 -0.0100866 -0.101293 0 -0.00439931 -0.0507883 0 -0.0025 -1.66552e-16 0 -0.0025 -1.66552e-16 0.01 -0.0195302 0.151232 0.01 -0.00439931 0.0507883 0.01 -0.0100866 0.101293 0.01 -0.0195302 0.151232 0 -0.00439931 0.0507883 0 -0.0100866 0.101293 0 -0.0195302 0.151232 0 -0.0146554 0.152344 0 -0.0146554 0.152344 0.01 -0.0195302 0.151232 0.01 0.0025 -1.67777e-16 0 0.0025 -1.67777e-16 0.01 -0.0146554 0.152344 0.01 0.000586728 0.0511617 0.01 -0.0051424 0.102038 0.01 -0.0146554 0.152344 0 0.000586728 0.0511617 0 -0.0051424 0.102038 0 + + + 1 3 2 1 0 3 16 4 5 16 7 4 17 8 7 17 7 16 6 8 17 13 6 17 10 6 13 14 10 13 15 11 10 15 10 14 12 9 11 12 11 15 21 19 18 21 18 24 22 24 25 22 21 24 20 25 23 20 22 25 38 26 27 38 29 26 39 30 29 39 29 38 28 30 39 35 28 39 32 28 35 36 32 35 37 33 32 37 32 36 34 31 33 34 33 37 43 41 40 43 40 46 44 46 47 44 43 46 42 47 45 42 44 47 51 49 48 51 48 54 52 54 55 52 51 54 50 55 53 50 52 55 56 59 58 57 56 58 63 61 60 63 60 66 64 66 67 64 63 66 62 67 65 62 64 67 + 3 6 9 12 15 18 21 24 27 30 33 36 39 42 45 48 51 54 57 60 63 66 69 72 75 78 81 84 87 90 93 96 99 102 105 108 111 114 117 120 123 126 129 132 135 138 141 144 147 150 153 156 + + + + + -0.0197305 -0.153011 0 -0.0148557 -0.154123 0 -0.0148557 -0.154123 0.01 -0.0197305 -0.153011 0.01 -0.0197305 -0.153011 0 -0.0148557 -0.154123 0 -0.0025 -1.68511e-16 0 -0.0101759 -0.102485 0 -0.00442165 -0.0513858 0 -0.0197305 0.153011 0 -0.00442165 0.0513858 0 -0.0101759 0.102485 0 -0.0148557 0.154123 0 0.0025 -1.69736e-16 0 0.000564383 0.0517592 0 -0.00523166 0.103229 0 -0.00523166 -0.103229 0 0.000564383 -0.0517592 0 -0.0148557 -0.154123 0 -0.0148557 -0.154123 0.01 0.0025 -1.69736e-16 0.01 -0.00523166 -0.103229 0.01 0.000564383 -0.0517592 0.01 0.0025 -1.69736e-16 0 -0.00523166 -0.103229 0 0.000564383 -0.0517592 0 -0.0197305 -0.153011 0.01 -0.0148557 -0.154123 0.01 -0.0025 -1.68511e-16 0.01 -0.0101759 -0.102485 0.01 -0.00442165 -0.0513858 0.01 -0.0197305 0.153011 0.01 -0.00442165 0.0513858 0.01 -0.0101759 0.102485 0.01 -0.0148557 0.154123 0.01 0.0025 -1.69736e-16 0.01 0.000564383 0.0517592 0.01 -0.00523166 0.103229 0.01 -0.00523166 -0.103229 0.01 0.000564383 -0.0517592 0.01 -0.0197305 -0.153011 0 -0.0197305 -0.153011 0.01 -0.0025 -1.68511e-16 0.01 -0.0101759 -0.102485 0.01 -0.00442165 -0.0513858 0.01 -0.0025 -1.68511e-16 0 -0.0101759 -0.102485 0 -0.00442165 -0.0513858 0 -0.0025 -1.68511e-16 0 -0.0025 -1.68511e-16 0.01 -0.0197305 0.153011 0.01 -0.00442165 0.0513858 0.01 -0.0101759 0.102485 0.01 -0.0197305 0.153011 0 -0.00442165 0.0513858 0 -0.0101759 0.102485 0 -0.0197305 0.153011 0 -0.0148557 0.154123 0 -0.0148557 0.154123 0.01 -0.0197305 0.153011 0.01 0.0025 -1.69736e-16 0 0.0025 -1.69736e-16 0.01 -0.0148557 0.154123 0.01 0.000564383 0.0517592 0.01 -0.00523166 0.103229 0.01 -0.0148557 0.154123 0 0.000564383 0.0517592 0 -0.00523166 0.103229 0 + + + 1 3 2 1 0 3 16 4 5 16 7 4 17 8 7 17 7 16 6 8 17 13 6 17 10 6 13 14 10 13 15 11 10 15 10 14 12 9 11 12 11 15 21 19 18 21 18 24 22 24 25 22 21 24 20 25 23 20 22 25 38 26 27 38 29 26 39 30 29 39 29 38 28 30 39 35 28 39 32 28 35 36 32 35 37 33 32 37 32 36 34 31 33 34 33 37 43 41 40 43 40 46 44 46 47 44 43 46 42 47 45 42 44 47 51 49 48 51 48 54 52 54 55 52 51 54 50 55 53 50 52 55 56 59 58 57 56 58 63 61 60 63 60 66 64 66 67 64 63 66 62 67 65 62 64 67 + 3 6 9 12 15 18 21 24 27 30 33 36 39 42 45 48 51 54 57 60 63 66 69 72 75 78 81 84 87 90 93 96 99 102 105 108 111 114 117 120 123 126 129 132 135 138 141 144 147 150 153 156 + + + + + -0.0197506 -0.153189 0 -0.0148758 -0.154301 0 -0.0148758 -0.154301 0.01 -0.0197506 -0.153189 0.01 -0.0197506 -0.153189 0 -0.0148758 -0.154301 0 -0.0025 -1.68707e-16 0 -0.0101848 -0.102604 0 -0.00442389 -0.0514455 0 -0.0197506 0.153189 0 -0.00442389 0.0514455 0 -0.0101848 0.102604 0 -0.0148758 0.154301 0 0.0025 -1.69932e-16 0 0.000562148 0.051819 0 -0.00524058 0.103349 0 -0.00524058 -0.103349 0 0.000562148 -0.051819 0 -0.0148758 -0.154301 0 -0.0148758 -0.154301 0.01 0.0025 -1.69932e-16 0.01 -0.00524058 -0.103349 0.01 0.000562148 -0.051819 0.01 0.0025 -1.69932e-16 0 -0.00524058 -0.103349 0 0.000562148 -0.051819 0 -0.0197506 -0.153189 0.01 -0.0148758 -0.154301 0.01 -0.0025 -1.68707e-16 0.01 -0.0101848 -0.102604 0.01 -0.00442389 -0.0514455 0.01 -0.0197506 0.153189 0.01 -0.00442389 0.0514455 0.01 -0.0101848 0.102604 0.01 -0.0148758 0.154301 0.01 0.0025 -1.69932e-16 0.01 0.000562148 0.051819 0.01 -0.00524058 0.103349 0.01 -0.00524058 -0.103349 0.01 0.000562148 -0.051819 0.01 -0.0197506 -0.153189 0 -0.0197506 -0.153189 0.01 -0.0025 -1.68707e-16 0.01 -0.0101848 -0.102604 0.01 -0.00442389 -0.0514455 0.01 -0.0025 -1.68707e-16 0 -0.0101848 -0.102604 0 -0.00442389 -0.0514455 0 -0.0025 -1.68707e-16 0 -0.0025 -1.68707e-16 0.01 -0.0197506 0.153189 0.01 -0.00442389 0.0514455 0.01 -0.0101848 0.102604 0.01 -0.0197506 0.153189 0 -0.00442389 0.0514455 0 -0.0101848 0.102604 0 -0.0197506 0.153189 0 -0.0148758 0.154301 0 -0.0148758 0.154301 0.01 -0.0197506 0.153189 0.01 0.0025 -1.69932e-16 0 0.0025 -1.69932e-16 0.01 -0.0148758 0.154301 0.01 0.000562148 0.051819 0.01 -0.00524058 0.103349 0.01 -0.0148758 0.154301 0 0.000562148 0.051819 0 -0.00524058 0.103349 0 + + + 0 3 2 1 0 2 16 4 5 16 7 4 17 8 7 17 7 16 13 6 8 13 8 17 10 6 13 14 10 13 15 11 10 15 10 14 9 11 15 12 9 15 21 19 18 21 18 24 22 24 25 22 21 24 20 25 23 20 22 25 38 26 27 38 29 26 39 30 29 39 29 38 35 28 30 35 30 39 32 28 35 36 32 35 33 32 36 37 33 36 31 33 37 34 31 37 43 41 40 43 40 46 44 46 47 44 43 46 42 47 45 42 44 47 51 49 48 51 48 54 52 54 55 52 51 54 50 55 53 50 52 55 56 59 58 57 56 58 63 61 60 63 60 66 64 66 67 64 63 66 62 67 65 62 64 67 + 3 6 9 12 15 18 21 24 27 30 33 36 39 42 45 48 51 54 57 60 63 66 69 72 75 78 81 84 87 90 93 96 99 102 105 108 111 114 117 120 123 126 129 132 135 138 141 144 147 150 153 156 + + + + + -0.0179624 -0.137309 0 -0.0130876 -0.138421 0 -0.0130876 -0.138421 0.01 -0.0179624 -0.137309 0.01 -0.0179624 -0.137309 0 -0.0130876 -0.138421 0 -0.0025 -1.51219e-16 0 -0.0093882 -0.091968 0 -0.00422446 -0.0461128 0 -0.0179624 0.137309 0 -0.00422446 0.0461128 0 -0.0093882 0.091968 0 -0.0130876 0.138421 0 0.0025 -1.52444e-16 0 0.000761576 0.0464862 0 -0.00444399 0.0927128 0 -0.00444399 -0.0927128 0 0.000761576 -0.0464862 0 -0.0130876 -0.138421 0 -0.0130876 -0.138421 0.01 0.0025 -1.52444e-16 0.01 -0.00444399 -0.0927128 0.01 0.000761576 -0.0464862 0.01 0.0025 -1.52444e-16 0 -0.00444399 -0.0927128 0 0.000761576 -0.0464862 0 -0.0179624 -0.137309 0.01 -0.0130876 -0.138421 0.01 -0.0025 -1.51219e-16 0.01 -0.0093882 -0.091968 0.01 -0.00422446 -0.0461128 0.01 -0.0179624 0.137309 0.01 -0.00422446 0.0461128 0.01 -0.0093882 0.091968 0.01 -0.0130876 0.138421 0.01 0.0025 -1.52444e-16 0.01 0.000761576 0.0464862 0.01 -0.00444399 0.0927128 0.01 -0.00444399 -0.0927128 0.01 0.000761576 -0.0464862 0.01 -0.0179624 -0.137309 0 -0.0179624 -0.137309 0.01 -0.0025 -1.51219e-16 0.01 -0.0093882 -0.091968 0.01 -0.00422446 -0.0461128 0.01 -0.0025 -1.51219e-16 0 -0.0093882 -0.091968 0 -0.00422446 -0.0461128 0 -0.0025 -1.51219e-16 0 -0.0025 -1.51219e-16 0.01 -0.0179624 0.137309 0.01 -0.00422446 0.0461128 0.01 -0.0093882 0.091968 0.01 -0.0179624 0.137309 0 -0.00422446 0.0461128 0 -0.0093882 0.091968 0 -0.0179624 0.137309 0 -0.0130876 0.138421 0 -0.0130876 0.138421 0.01 -0.0179624 0.137309 0.01 0.0025 -1.52444e-16 0 0.0025 -1.52444e-16 0.01 -0.0130876 0.138421 0.01 0.000761576 0.0464862 0.01 -0.00444399 0.0927128 0.01 -0.0130876 0.138421 0 0.000761576 0.0464862 0 -0.00444399 0.0927128 0 + + + 1 3 2 1 0 3 16 4 5 16 7 4 17 8 7 17 7 16 6 8 17 13 6 17 10 6 13 14 10 13 15 11 10 15 10 14 9 11 15 12 9 15 21 19 18 21 18 24 22 24 25 22 21 24 20 25 23 20 22 25 38 26 27 38 29 26 39 30 29 39 29 38 28 30 39 35 28 39 32 28 35 36 32 35 37 33 32 37 32 36 31 33 37 34 31 37 43 41 40 43 40 46 44 46 47 44 43 46 42 47 45 42 44 47 51 49 48 51 48 54 52 54 55 52 51 54 50 55 53 50 52 55 56 59 58 57 56 58 63 61 60 63 60 66 64 66 67 64 63 66 62 67 65 62 64 67 + 3 6 9 12 15 18 21 24 27 30 33 36 39 42 45 48 51 54 57 60 63 66 69 72 75 78 81 84 87 90 93 96 99 102 105 108 111 114 117 120 123 126 129 132 135 138 141 144 147 150 153 156 + + + + + -0.0179824 -0.137487 0 -0.0131076 -0.138599 0 -0.0131076 -0.138599 0.01 -0.0179824 -0.137487 0.01 -0.0179824 -0.137487 0 -0.0131076 -0.138599 0 -0.0025 -1.51415e-16 0 -0.00939713 -0.0920871 0 -0.00422669 -0.0461725 0 -0.0179824 0.137487 0 -0.00422669 0.0461725 0 -0.00939713 0.0920871 0 -0.0131076 0.138599 0 0.0025 -1.5264e-16 0 0.000759341 0.046546 0 -0.00445291 0.0928319 0 -0.00445291 -0.0928319 0 0.000759341 -0.046546 0 -0.0131076 -0.138599 0 -0.0131076 -0.138599 0.01 0.0025 -1.5264e-16 0.01 -0.00445291 -0.0928319 0.01 0.000759341 -0.046546 0.01 0.0025 -1.5264e-16 0 -0.00445291 -0.0928319 0 0.000759341 -0.046546 0 -0.0179824 -0.137487 0.01 -0.0131076 -0.138599 0.01 -0.0025 -1.51415e-16 0.01 -0.00939713 -0.0920871 0.01 -0.00422669 -0.0461725 0.01 -0.0179824 0.137487 0.01 -0.00422669 0.0461725 0.01 -0.00939713 0.0920871 0.01 -0.0131076 0.138599 0.01 0.0025 -1.5264e-16 0.01 0.000759341 0.046546 0.01 -0.00445291 0.0928319 0.01 -0.00445291 -0.0928319 0.01 0.000759341 -0.046546 0.01 -0.0179824 -0.137487 0 -0.0179824 -0.137487 0.01 -0.0025 -1.51415e-16 0.01 -0.00939713 -0.0920871 0.01 -0.00422669 -0.0461725 0.01 -0.0025 -1.51415e-16 0 -0.00939713 -0.0920871 0 -0.00422669 -0.0461725 0 -0.0025 -1.51415e-16 0 -0.0025 -1.51415e-16 0.01 -0.0179824 0.137487 0.01 -0.00422669 0.0461725 0.01 -0.00939713 0.0920871 0.01 -0.0179824 0.137487 0 -0.00422669 0.0461725 0 -0.00939713 0.0920871 0 -0.0179824 0.137487 0 -0.0131076 0.138599 0 -0.0131076 0.138599 0.01 -0.0179824 0.137487 0.01 0.0025 -1.5264e-16 0 0.0025 -1.5264e-16 0.01 -0.0131076 0.138599 0.01 0.000759341 0.046546 0.01 -0.00445291 0.0928319 0.01 -0.0131076 0.138599 0 0.000759341 0.046546 0 -0.00445291 0.0928319 0 + + + 1 3 2 1 0 3 16 4 5 16 7 4 17 8 7 17 7 16 6 8 17 13 6 17 10 6 13 14 10 13 11 10 14 15 11 14 9 11 15 12 9 15 21 19 18 21 18 24 22 24 25 22 21 24 20 25 23 20 22 25 38 26 27 38 29 26 39 30 29 39 29 38 28 30 39 35 28 39 32 28 35 36 32 35 33 32 36 37 33 36 31 33 37 34 31 37 43 41 40 43 40 46 44 46 47 44 43 46 42 47 45 42 44 47 51 49 48 51 48 54 52 54 55 52 51 54 50 55 53 50 52 55 56 59 58 57 56 58 63 61 60 63 60 66 64 66 67 64 63 66 62 67 65 62 64 67 + 3 6 9 12 15 18 21 24 27 30 33 36 39 42 45 48 51 54 57 60 63 66 69 72 75 78 81 84 87 90 93 96 99 102 105 108 111 114 117 120 123 126 129 132 135 138 141 144 147 150 153 156 + + + + + -0.0181828 -0.139266 0 -0.013308 -0.140378 0 -0.013308 -0.140378 0.01 -0.0181828 -0.139266 0.01 -0.0181828 -0.139266 0 -0.013308 -0.140378 0 -0.0025 -1.53375e-16 0 -0.00948638 -0.0932788 0 -0.00424904 -0.04677 0 -0.0181828 0.139266 0 -0.00424904 0.04677 0 -0.00948638 0.0932788 0 -0.013308 0.140378 0 0.0025 -1.54599e-16 0 0.000736996 0.0471435 0 -0.00454217 0.0940236 0 -0.00454217 -0.0940236 0 0.000736996 -0.0471435 0 -0.013308 -0.140378 0 -0.013308 -0.140378 0.01 0.0025 -1.54599e-16 0.01 -0.00454217 -0.0940236 0.01 0.000736996 -0.0471435 0.01 0.0025 -1.54599e-16 0 -0.00454217 -0.0940236 0 0.000736996 -0.0471435 0 -0.0181828 -0.139266 0.01 -0.013308 -0.140378 0.01 -0.0025 -1.53375e-16 0.01 -0.00948638 -0.0932788 0.01 -0.00424904 -0.04677 0.01 -0.0181828 0.139266 0.01 -0.00424904 0.04677 0.01 -0.00948638 0.0932788 0.01 -0.013308 0.140378 0.01 0.0025 -1.54599e-16 0.01 0.000736996 0.0471435 0.01 -0.00454217 0.0940236 0.01 -0.00454217 -0.0940236 0.01 0.000736996 -0.0471435 0.01 -0.0181828 -0.139266 0 -0.0181828 -0.139266 0.01 -0.0025 -1.53375e-16 0.01 -0.00948638 -0.0932788 0.01 -0.00424904 -0.04677 0.01 -0.0025 -1.53375e-16 0 -0.00948638 -0.0932788 0 -0.00424904 -0.04677 0 -0.0025 -1.53375e-16 0 -0.0025 -1.53375e-16 0.01 -0.0181828 0.139266 0.01 -0.00424904 0.04677 0.01 -0.00948638 0.0932788 0.01 -0.0181828 0.139266 0 -0.00424904 0.04677 0 -0.00948638 0.0932788 0 -0.0181828 0.139266 0 -0.013308 0.140378 0 -0.013308 0.140378 0.01 -0.0181828 0.139266 0.01 0.0025 -1.54599e-16 0 0.0025 -1.54599e-16 0.01 -0.013308 0.140378 0.01 0.000736996 0.0471435 0.01 -0.00454217 0.0940236 0.01 -0.013308 0.140378 0 0.000736996 0.0471435 0 -0.00454217 0.0940236 0 + + + 0 3 2 1 0 2 16 4 5 16 7 4 8 7 16 17 8 16 6 8 17 13 6 17 10 6 13 14 10 13 11 10 14 15 11 14 12 9 11 12 11 15 21 19 18 21 18 24 22 24 25 22 21 24 20 25 23 20 22 25 38 26 27 38 29 26 30 29 38 39 30 38 28 30 39 35 28 39 32 28 35 36 32 35 33 32 36 37 33 36 34 31 33 34 33 37 43 41 40 43 40 46 44 46 47 44 43 46 42 47 45 42 44 47 51 49 48 51 48 54 52 54 55 52 51 54 50 55 53 50 52 55 56 59 58 57 56 58 63 61 60 63 60 66 64 66 67 64 63 66 62 67 65 62 64 67 + 3 6 9 12 15 18 21 24 27 30 33 36 39 42 45 48 51 54 57 60 63 66 69 72 75 78 81 84 87 90 93 96 99 102 105 108 111 114 117 120 123 126 129 132 135 138 141 144 147 150 153 156 + + + + + -0.0182028 -0.139444 0 -0.013328 -0.140556 0 -0.013328 -0.140556 0.01 -0.0182028 -0.139444 0.01 -0.0182028 -0.139444 0 -0.013328 -0.140556 0 -0.0025 -1.53571e-16 0 -0.00949531 -0.093398 0 -0.00425127 -0.0468298 0 -0.0182028 0.139444 0 -0.00425127 0.0468298 0 -0.00949531 0.093398 0 -0.013328 0.140556 0 0.0025 -1.54795e-16 0 0.000734762 0.0472032 0 -0.00455109 0.0941428 0 -0.00455109 -0.0941428 0 0.000734762 -0.0472032 0 -0.013328 -0.140556 0 -0.013328 -0.140556 0.01 0.0025 -1.54795e-16 0.01 -0.00455109 -0.0941428 0.01 0.000734762 -0.0472032 0.01 0.0025 -1.54795e-16 0 -0.00455109 -0.0941428 0 0.000734762 -0.0472032 0 -0.0182028 -0.139444 0.01 -0.013328 -0.140556 0.01 -0.0025 -1.53571e-16 0.01 -0.00949531 -0.093398 0.01 -0.00425127 -0.0468298 0.01 -0.0182028 0.139444 0.01 -0.00425127 0.0468298 0.01 -0.00949531 0.093398 0.01 -0.013328 0.140556 0.01 0.0025 -1.54795e-16 0.01 0.000734762 0.0472032 0.01 -0.00455109 0.0941428 0.01 -0.00455109 -0.0941428 0.01 0.000734762 -0.0472032 0.01 -0.0182028 -0.139444 0 -0.0182028 -0.139444 0.01 -0.0025 -1.53571e-16 0.01 -0.00949531 -0.093398 0.01 -0.00425127 -0.0468298 0.01 -0.0025 -1.53571e-16 0 -0.00949531 -0.093398 0 -0.00425127 -0.0468298 0 -0.0025 -1.53571e-16 0 -0.0025 -1.53571e-16 0.01 -0.0182028 0.139444 0.01 -0.00425127 0.0468298 0.01 -0.00949531 0.093398 0.01 -0.0182028 0.139444 0 -0.00425127 0.0468298 0 -0.00949531 0.093398 0 -0.0182028 0.139444 0 -0.013328 0.140556 0 -0.013328 0.140556 0.01 -0.0182028 0.139444 0.01 0.0025 -1.54795e-16 0 0.0025 -1.54795e-16 0.01 -0.013328 0.140556 0.01 0.000734762 0.0472032 0.01 -0.00455109 0.0941428 0.01 -0.013328 0.140556 0 0.000734762 0.0472032 0 -0.00455109 0.0941428 0 + + + 1 3 2 1 0 3 16 4 5 16 7 4 17 8 7 17 7 16 13 6 8 13 8 17 10 6 13 14 10 13 15 11 10 15 10 14 12 9 11 12 11 15 21 19 18 21 18 24 21 24 25 22 21 25 20 25 23 20 22 25 38 26 27 38 29 26 39 30 29 39 29 38 28 30 39 35 28 39 32 28 35 36 32 35 37 33 32 37 32 36 34 31 33 34 33 37 43 41 40 43 40 46 44 46 47 44 43 46 42 47 45 42 44 47 51 49 48 51 48 54 52 54 55 52 51 54 50 55 53 50 52 55 56 59 58 57 56 58 63 61 60 63 60 66 64 66 67 64 63 66 62 67 65 62 64 67 + 3 6 9 12 15 18 21 24 27 30 33 36 39 42 45 48 51 54 57 60 63 66 69 72 75 78 81 84 87 90 93 96 99 102 105 108 111 114 117 120 123 126 129 132 135 138 141 144 147 150 153 156 + + + + + -0.0184057 -0.141246 0 -0.0135309 -0.142358 0 -0.0135309 -0.142358 0.01 -0.0184057 -0.141246 0.01 -0.0184057 -0.141246 0 -0.0135309 -0.142358 0 -0.0025 -1.55555e-16 0 -0.00958568 -0.0946045 0 -0.0042739 -0.0474348 0 -0.0184057 0.141246 0 -0.0042739 0.0474348 0 -0.00958568 0.0946045 0 -0.0135309 0.142358 0 0.0025 -1.56779e-16 0 0.000712138 0.0478082 0 -0.00464146 0.0953493 0 -0.00464146 -0.0953493 0 0.000712138 -0.0478082 0 -0.0135309 -0.142358 0 -0.0135309 -0.142358 0.01 0.0025 -1.56779e-16 0.01 -0.00464146 -0.0953493 0.01 0.000712138 -0.0478082 0.01 0.0025 -1.56779e-16 0 -0.00464146 -0.0953493 0 0.000712138 -0.0478082 0 -0.0184057 -0.141246 0.01 -0.0135309 -0.142358 0.01 -0.0025 -1.55555e-16 0.01 -0.00958568 -0.0946045 0.01 -0.0042739 -0.0474348 0.01 -0.0184057 0.141246 0.01 -0.0042739 0.0474348 0.01 -0.00958568 0.0946045 0.01 -0.0135309 0.142358 0.01 0.0025 -1.56779e-16 0.01 0.000712138 0.0478082 0.01 -0.00464146 0.0953493 0.01 -0.00464146 -0.0953493 0.01 0.000712138 -0.0478082 0.01 -0.0184057 -0.141246 0 -0.0184057 -0.141246 0.01 -0.0025 -1.55555e-16 0.01 -0.00958568 -0.0946045 0.01 -0.0042739 -0.0474348 0.01 -0.0025 -1.55555e-16 0 -0.00958568 -0.0946045 0 -0.0042739 -0.0474348 0 -0.0025 -1.55555e-16 0 -0.0025 -1.55555e-16 0.01 -0.0184057 0.141246 0.01 -0.0042739 0.0474348 0.01 -0.00958568 0.0946045 0.01 -0.0184057 0.141246 0 -0.0042739 0.0474348 0 -0.00958568 0.0946045 0 -0.0184057 0.141246 0 -0.0135309 0.142358 0 -0.0135309 0.142358 0.01 -0.0184057 0.141246 0.01 0.0025 -1.56779e-16 0 0.0025 -1.56779e-16 0.01 -0.0135309 0.142358 0.01 0.000712138 0.0478082 0.01 -0.00464146 0.0953493 0.01 -0.0135309 0.142358 0 0.000712138 0.0478082 0 -0.00464146 0.0953493 0 + + + 1 3 2 1 0 3 16 4 5 16 7 4 17 8 7 17 7 16 13 6 8 13 8 17 10 6 13 14 10 13 15 11 10 15 10 14 12 9 11 12 11 15 21 19 18 21 18 24 22 24 25 22 21 24 20 25 23 20 22 25 38 26 27 38 29 26 39 30 29 39 29 38 35 28 30 35 30 39 32 28 35 36 32 35 37 33 32 37 32 36 34 31 33 34 33 37 43 41 40 43 40 46 44 46 47 44 43 46 42 47 45 42 44 47 51 49 48 51 48 54 52 54 55 52 51 54 50 55 53 50 52 55 56 59 58 57 56 58 63 61 60 63 60 66 64 66 67 64 63 66 62 67 65 62 64 67 + 3 6 9 12 15 18 21 24 27 30 33 36 39 42 45 48 51 54 57 60 63 66 69 72 75 78 81 84 87 90 93 96 99 102 105 108 111 114 117 120 123 126 129 132 135 138 141 144 147 150 153 156 + + + + + -0.0184257 -0.141424 0 -0.0135509 -0.142536 0 -0.0135509 -0.142536 0.01 -0.0184257 -0.141424 0.01 -0.0184257 -0.141424 0 -0.0135509 -0.142536 0 -0.0025 -1.55751e-16 0 -0.0095946 -0.0947237 0 -0.00427613 -0.0474945 0 -0.0184257 0.141424 0 -0.00427613 0.0474945 0 -0.0095946 0.0947237 0 -0.0135509 0.142536 0 0.0025 -1.56975e-16 0 0.000709903 0.047868 0 -0.00465039 0.0954685 0 -0.00465039 -0.0954685 0 0.000709903 -0.047868 0 -0.0135509 -0.142536 0 -0.0135509 -0.142536 0.01 0.0025 -1.56975e-16 0.01 -0.00465039 -0.0954685 0.01 0.000709903 -0.047868 0.01 0.0025 -1.56975e-16 0 -0.00465039 -0.0954685 0 0.000709903 -0.047868 0 -0.0184257 -0.141424 0.01 -0.0135509 -0.142536 0.01 -0.0025 -1.55751e-16 0.01 -0.0095946 -0.0947237 0.01 -0.00427613 -0.0474945 0.01 -0.0184257 0.141424 0.01 -0.00427613 0.0474945 0.01 -0.0095946 0.0947237 0.01 -0.0135509 0.142536 0.01 0.0025 -1.56975e-16 0.01 0.000709903 0.047868 0.01 -0.00465039 0.0954685 0.01 -0.00465039 -0.0954685 0.01 0.000709903 -0.047868 0.01 -0.0184257 -0.141424 0 -0.0184257 -0.141424 0.01 -0.0025 -1.55751e-16 0.01 -0.0095946 -0.0947237 0.01 -0.00427613 -0.0474945 0.01 -0.0025 -1.55751e-16 0 -0.0095946 -0.0947237 0 -0.00427613 -0.0474945 0 -0.0025 -1.55751e-16 0 -0.0025 -1.55751e-16 0.01 -0.0184257 0.141424 0.01 -0.00427613 0.0474945 0.01 -0.0095946 0.0947237 0.01 -0.0184257 0.141424 0 -0.00427613 0.0474945 0 -0.0095946 0.0947237 0 -0.0184257 0.141424 0 -0.0135509 0.142536 0 -0.0135509 0.142536 0.01 -0.0184257 0.141424 0.01 0.0025 -1.56975e-16 0 0.0025 -1.56975e-16 0.01 -0.0135509 0.142536 0.01 0.000709903 0.047868 0.01 -0.00465039 0.0954685 0.01 -0.0135509 0.142536 0 0.000709903 0.047868 0 -0.00465039 0.0954685 0 + + + 1 3 2 1 0 3 7 4 5 16 7 5 17 8 7 17 7 16 6 8 17 13 6 17 10 6 13 14 10 13 15 11 10 15 10 14 9 11 15 12 9 15 21 19 18 21 18 24 22 24 25 22 21 24 20 25 23 20 22 25 29 26 27 38 29 27 39 30 29 39 29 38 28 30 39 35 28 39 32 28 35 36 32 35 37 33 32 37 32 36 31 33 37 34 31 37 43 41 40 43 40 46 44 46 47 44 43 46 42 47 45 42 44 47 51 49 48 51 48 54 52 54 55 52 51 54 50 55 53 50 52 55 56 59 58 57 56 58 63 61 60 63 60 66 64 66 67 64 63 66 62 67 65 62 64 67 + 3 6 9 12 15 18 21 24 27 30 33 36 39 42 45 48 51 54 57 60 63 66 69 72 75 78 81 84 87 90 93 96 99 102 105 108 111 114 117 120 123 126 129 132 135 138 141 144 147 150 153 156 + + + + + -0.0186261 -0.143203 0 -0.0137513 -0.144315 0 -0.0137513 -0.144315 0.01 -0.0186261 -0.143203 0.01 -0.0186261 -0.143203 0 -0.0137513 -0.144315 0 -0.0025 -1.5771e-16 0 -0.00968386 -0.0959154 0 -0.00429848 -0.048092 0 -0.0186261 0.143203 0 -0.00429848 0.048092 0 -0.00968386 0.0959154 0 -0.0137513 0.144315 0 0.0025 -1.58935e-16 0 0.000687559 0.0484655 0 -0.00473964 0.0966602 0 -0.00473964 -0.0966602 0 0.000687559 -0.0484655 0 -0.0137513 -0.144315 0 -0.0137513 -0.144315 0.01 0.0025 -1.58935e-16 0.01 -0.00473964 -0.0966602 0.01 0.000687559 -0.0484655 0.01 0.0025 -1.58935e-16 0 -0.00473964 -0.0966602 0 0.000687559 -0.0484655 0 -0.0186261 -0.143203 0.01 -0.0137513 -0.144315 0.01 -0.0025 -1.5771e-16 0.01 -0.00968386 -0.0959154 0.01 -0.00429848 -0.048092 0.01 -0.0186261 0.143203 0.01 -0.00429848 0.048092 0.01 -0.00968386 0.0959154 0.01 -0.0137513 0.144315 0.01 0.0025 -1.58935e-16 0.01 0.000687559 0.0484655 0.01 -0.00473964 0.0966602 0.01 -0.00473964 -0.0966602 0.01 0.000687559 -0.0484655 0.01 -0.0186261 -0.143203 0 -0.0186261 -0.143203 0.01 -0.0025 -1.5771e-16 0.01 -0.00968386 -0.0959154 0.01 -0.00429848 -0.048092 0.01 -0.0025 -1.5771e-16 0 -0.00968386 -0.0959154 0 -0.00429848 -0.048092 0 -0.0025 -1.5771e-16 0 -0.0025 -1.5771e-16 0.01 -0.0186261 0.143203 0.01 -0.00429848 0.048092 0.01 -0.00968386 0.0959154 0.01 -0.0186261 0.143203 0 -0.00429848 0.048092 0 -0.00968386 0.0959154 0 -0.0186261 0.143203 0 -0.0137513 0.144315 0 -0.0137513 0.144315 0.01 -0.0186261 0.143203 0.01 0.0025 -1.58935e-16 0 0.0025 -1.58935e-16 0.01 -0.0137513 0.144315 0.01 0.000687559 0.0484655 0.01 -0.00473964 0.0966602 0.01 -0.0137513 0.144315 0 0.000687559 0.0484655 0 -0.00473964 0.0966602 0 + + + 1 3 2 1 0 3 16 4 5 16 7 4 17 8 7 17 7 16 6 8 17 13 6 17 10 6 13 14 10 13 11 10 14 15 11 14 9 11 15 12 9 15 21 19 18 21 18 24 22 24 25 22 21 24 20 25 23 20 22 25 38 26 27 38 29 26 39 30 29 39 29 38 28 30 39 35 28 39 32 28 35 36 32 35 33 32 36 37 33 36 31 33 37 34 31 37 43 41 40 43 40 46 44 46 47 44 43 46 42 47 45 42 44 47 51 49 48 51 48 54 52 54 55 52 51 54 50 55 53 50 52 55 56 59 58 57 56 58 63 61 60 63 60 66 64 66 67 64 63 66 62 67 65 62 64 67 + 3 6 9 12 15 18 21 24 27 30 33 36 39 42 45 48 51 54 57 60 63 66 69 72 75 78 81 84 87 90 93 96 99 102 105 108 111 114 117 120 123 126 129 132 135 138 141 144 147 150 153 156 + + + + + -0.0186461 -0.143381 0 -0.0137713 -0.144493 0 -0.0137713 -0.144493 0.01 -0.0186461 -0.143381 0.01 -0.0186461 -0.143381 0 -0.0137713 -0.144493 0 -0.0025 -1.57906e-16 0 -0.00969278 -0.0960346 0 -0.00430071 -0.0481518 0 -0.0186461 0.143381 0 -0.00430071 0.0481518 0 -0.00969278 0.0960346 0 -0.0137713 0.144493 0 0.0025 -1.59131e-16 0 0.000685324 0.0485252 0 -0.00474857 0.0967794 0 -0.00474857 -0.0967794 0 0.000685324 -0.0485252 0 -0.0137713 -0.144493 0 -0.0137713 -0.144493 0.01 0.0025 -1.59131e-16 0.01 -0.00474857 -0.0967794 0.01 0.000685324 -0.0485252 0.01 0.0025 -1.59131e-16 0 -0.00474857 -0.0967794 0 0.000685324 -0.0485252 0 -0.0186461 -0.143381 0.01 -0.0137713 -0.144493 0.01 -0.0025 -1.57906e-16 0.01 -0.00969278 -0.0960346 0.01 -0.00430071 -0.0481518 0.01 -0.0186461 0.143381 0.01 -0.00430071 0.0481518 0.01 -0.00969278 0.0960346 0.01 -0.0137713 0.144493 0.01 0.0025 -1.59131e-16 0.01 0.000685324 0.0485252 0.01 -0.00474857 0.0967794 0.01 -0.00474857 -0.0967794 0.01 0.000685324 -0.0485252 0.01 -0.0186461 -0.143381 0 -0.0186461 -0.143381 0.01 -0.0025 -1.57906e-16 0.01 -0.00969278 -0.0960346 0.01 -0.00430071 -0.0481518 0.01 -0.0025 -1.57906e-16 0 -0.00969278 -0.0960346 0 -0.00430071 -0.0481518 0 -0.0025 -1.57906e-16 0 -0.0025 -1.57906e-16 0.01 -0.0186461 0.143381 0.01 -0.00430071 0.0481518 0.01 -0.00969278 0.0960346 0.01 -0.0186461 0.143381 0 -0.00430071 0.0481518 0 -0.00969278 0.0960346 0 -0.0186461 0.143381 0 -0.0137713 0.144493 0 -0.0137713 0.144493 0.01 -0.0186461 0.143381 0.01 0.0025 -1.59131e-16 0 0.0025 -1.59131e-16 0.01 -0.0137713 0.144493 0.01 0.000685324 0.0485252 0.01 -0.00474857 0.0967794 0.01 -0.0137713 0.144493 0 0.000685324 0.0485252 0 -0.00474857 0.0967794 0 + + + 0 3 2 1 0 2 16 4 5 16 7 4 17 8 7 17 7 16 6 8 17 13 6 17 10 6 13 14 10 13 15 11 10 15 10 14 9 11 15 12 9 15 21 19 18 21 18 24 22 24 25 22 21 24 20 25 23 20 22 25 38 26 27 38 29 26 39 30 29 39 29 38 28 30 39 35 28 39 32 28 35 36 32 35 37 33 32 37 32 36 31 33 37 34 31 37 43 41 40 43 40 46 44 46 47 44 43 46 42 47 45 42 44 47 51 49 48 51 48 54 52 54 55 52 51 54 50 55 53 50 52 55 56 59 58 57 56 58 63 61 60 63 60 66 64 66 67 64 63 66 62 67 65 62 64 67 + 3 6 9 12 15 18 21 24 27 30 33 36 39 42 45 48 51 54 57 60 63 66 69 72 75 78 81 84 87 90 93 96 99 102 105 108 111 114 117 120 123 126 129 132 135 138 141 144 147 150 153 156 + + + + + -0.0144077 -0.136105 0 -0.00948364 -0.136974 0 -0.00948364 -0.136974 0.01 -0.0144077 -0.136105 0.01 -0.0144077 -0.136105 0 -0.00948364 -0.136974 0 -0.0025 -1.91976e-16 0 -0.00779978 -0.0909936 0 -0.00382607 -0.0455739 0 -0.0144077 0.136105 0 -0.00382607 0.0455739 0 -0.00779978 0.0909936 0 -0.00948364 0.136974 0 0.0025 -1.932e-16 0 0.00116548 0.0458646 0 -0.00283358 0.0915741 0 -0.00283358 -0.0915741 0 0.00116548 -0.0458646 0 -0.00948364 -0.136974 0 -0.00948364 -0.136974 0.01 0.0025 -1.932e-16 0.01 -0.00283358 -0.0915741 0.01 0.00116548 -0.0458646 0.01 0.0025 -1.932e-16 0 -0.00283358 -0.0915741 0 0.00116548 -0.0458646 0 -0.0144077 -0.136105 0.01 -0.00948364 -0.136974 0.01 -0.0025 -1.91976e-16 0.01 -0.00779978 -0.0909936 0.01 -0.00382607 -0.0455739 0.01 -0.0144077 0.136105 0.01 -0.00382607 0.0455739 0.01 -0.00779978 0.0909936 0.01 -0.00948364 0.136974 0.01 0.0025 -1.932e-16 0.01 0.00116548 0.0458646 0.01 -0.00283358 0.0915741 0.01 -0.00283358 -0.0915741 0.01 0.00116548 -0.0458646 0.01 -0.0144077 -0.136105 0 -0.0144077 -0.136105 0.01 -0.0025 -1.91976e-16 0.01 -0.00779978 -0.0909936 0.01 -0.00382607 -0.0455739 0.01 -0.0025 -1.91976e-16 0 -0.00779978 -0.0909936 0 -0.00382607 -0.0455739 0 -0.0025 -1.91976e-16 0 -0.0025 -1.91976e-16 0.01 -0.0144077 0.136105 0.01 -0.00382607 0.0455739 0.01 -0.00779978 0.0909936 0.01 -0.0144077 0.136105 0 -0.00382607 0.0455739 0 -0.00779978 0.0909936 0 -0.0144077 0.136105 0 -0.00948364 0.136974 0 -0.00948364 0.136974 0.01 -0.0144077 0.136105 0.01 0.0025 -1.932e-16 0 0.0025 -1.932e-16 0.01 -0.00948364 0.136974 0.01 0.00116548 0.0458646 0.01 -0.00283358 0.0915741 0.01 -0.00948364 0.136974 0 0.00116548 0.0458646 0 -0.00283358 0.0915741 0 + + + 0 3 2 1 0 2 16 4 5 16 7 4 17 8 7 17 7 16 6 8 17 13 6 17 10 6 13 14 10 13 11 10 14 15 11 14 9 11 15 12 9 15 21 19 18 21 18 24 22 24 25 22 21 24 20 25 23 20 22 25 38 26 27 38 29 26 39 30 29 39 29 38 28 30 39 35 28 39 32 28 35 36 32 35 33 32 36 37 33 36 31 33 37 34 31 37 43 41 40 43 40 46 44 46 47 44 43 46 42 47 45 42 44 47 51 49 48 51 48 54 52 54 55 52 51 54 50 55 53 50 52 55 56 59 58 57 56 58 63 61 60 63 60 66 64 66 67 64 63 66 62 67 65 62 64 67 + 3 6 9 12 15 18 21 24 27 30 33 36 39 42 45 48 51 54 57 60 63 66 69 72 75 78 81 84 87 90 93 96 99 102 105 108 111 114 117 120 123 126 129 132 135 138 141 144 147 150 153 156 + + + + + -0.0144092 -0.136123 0 -0.00948516 -0.136991 0 -0.00948516 -0.136991 0.01 -0.0144092 -0.136123 0.01 -0.0144092 -0.136123 0 -0.00948516 -0.136991 0 -0.0025 -1.92e-16 0 -0.00780045 -0.0910052 0 -0.00382623 -0.0455797 0 -0.0144092 0.136123 0 -0.00382623 0.0455797 0 -0.00780045 0.0910052 0 -0.00948516 0.136991 0 0.0025 -1.93225e-16 0 0.00116531 0.0458705 0 -0.00283426 0.0915857 0 -0.00283426 -0.0915857 0 0.00116531 -0.0458705 0 -0.00948516 -0.136991 0 -0.00948516 -0.136991 0.01 0.0025 -1.93225e-16 0.01 -0.00283426 -0.0915857 0.01 0.00116531 -0.0458705 0.01 0.0025 -1.93225e-16 0 -0.00283426 -0.0915857 0 0.00116531 -0.0458705 0 -0.0144092 -0.136123 0.01 -0.00948516 -0.136991 0.01 -0.0025 -1.92e-16 0.01 -0.00780045 -0.0910052 0.01 -0.00382623 -0.0455797 0.01 -0.0144092 0.136123 0.01 -0.00382623 0.0455797 0.01 -0.00780045 0.0910052 0.01 -0.00948516 0.136991 0.01 0.0025 -1.93225e-16 0.01 0.00116531 0.0458705 0.01 -0.00283426 0.0915857 0.01 -0.00283426 -0.0915857 0.01 0.00116531 -0.0458705 0.01 -0.0144092 -0.136123 0 -0.0144092 -0.136123 0.01 -0.0025 -1.92e-16 0.01 -0.00780045 -0.0910052 0.01 -0.00382623 -0.0455797 0.01 -0.0025 -1.92e-16 0 -0.00780045 -0.0910052 0 -0.00382623 -0.0455797 0 -0.0025 -1.92e-16 0 -0.0025 -1.92e-16 0.01 -0.0144092 0.136123 0.01 -0.00382623 0.0455797 0.01 -0.00780045 0.0910052 0.01 -0.0144092 0.136123 0 -0.00382623 0.0455797 0 -0.00780045 0.0910052 0 -0.0144092 0.136123 0 -0.00948516 0.136991 0 -0.00948516 0.136991 0.01 -0.0144092 0.136123 0.01 0.0025 -1.93225e-16 0 0.0025 -1.93225e-16 0.01 -0.00948516 0.136991 0.01 0.00116531 0.0458705 0.01 -0.00283426 0.0915857 0.01 -0.00948516 0.136991 0 0.00116531 0.0458705 0 -0.00283426 0.0915857 0 + + + 1 3 2 1 0 3 7 4 5 16 7 5 17 8 7 17 7 16 6 8 17 13 6 17 10 6 13 14 10 13 11 10 14 15 11 14 12 9 11 12 11 15 21 19 18 21 18 24 22 24 25 22 21 24 20 25 23 20 22 25 29 26 27 38 29 27 39 30 29 39 29 38 28 30 39 35 28 39 32 28 35 36 32 35 33 32 36 37 33 36 34 31 33 34 33 37 43 41 40 43 40 46 44 46 47 44 43 46 42 47 45 42 44 47 51 49 48 51 48 54 52 54 55 52 51 54 50 55 53 50 52 55 56 59 58 57 56 58 63 61 60 63 60 66 64 66 67 64 63 66 62 67 65 62 64 67 + 3 6 9 12 15 18 21 24 27 30 33 36 39 42 45 48 51 54 57 60 63 66 69 72 75 78 81 84 87 90 93 96 99 102 105 108 111 114 117 120 123 126 129 132 135 138 141 144 147 150 153 156 + + + + + -0.0150503 -0.143451 0 -0.0101263 -0.144319 0 -0.0101263 -0.144319 0.01 -0.0150503 -0.143451 0.01 -0.0150503 -0.143451 0 -0.0101263 -0.144319 0 -0.0025 -2.02336e-16 0 -0.00808579 -0.0959044 0 -0.00389763 -0.0480334 0 -0.0150503 0.143451 0 -0.00389763 0.0480334 0 -0.00808579 0.0959044 0 -0.0101263 0.144319 0 0.0025 -2.03561e-16 0 0.00109391 0.0483242 0 -0.0031196 0.0964848 0 -0.0031196 -0.0964848 0 0.00109391 -0.0483242 0 -0.0101263 -0.144319 0 -0.0101263 -0.144319 0.01 0.0025 -2.03561e-16 0.01 -0.0031196 -0.0964848 0.01 0.00109391 -0.0483242 0.01 0.0025 -2.03561e-16 0 -0.0031196 -0.0964848 0 0.00109391 -0.0483242 0 -0.0150503 -0.143451 0.01 -0.0101263 -0.144319 0.01 -0.0025 -2.02336e-16 0.01 -0.00808579 -0.0959044 0.01 -0.00389763 -0.0480334 0.01 -0.0150503 0.143451 0.01 -0.00389763 0.0480334 0.01 -0.00808579 0.0959044 0.01 -0.0101263 0.144319 0.01 0.0025 -2.03561e-16 0.01 0.00109391 0.0483242 0.01 -0.0031196 0.0964848 0.01 -0.0031196 -0.0964848 0.01 0.00109391 -0.0483242 0.01 -0.0150503 -0.143451 0 -0.0150503 -0.143451 0.01 -0.0025 -2.02336e-16 0.01 -0.00808579 -0.0959044 0.01 -0.00389763 -0.0480334 0.01 -0.0025 -2.02336e-16 0 -0.00808579 -0.0959044 0 -0.00389763 -0.0480334 0 -0.0025 -2.02336e-16 0 -0.0025 -2.02336e-16 0.01 -0.0150503 0.143451 0.01 -0.00389763 0.0480334 0.01 -0.00808579 0.0959044 0.01 -0.0150503 0.143451 0 -0.00389763 0.0480334 0 -0.00808579 0.0959044 0 -0.0150503 0.143451 0 -0.0101263 0.144319 0 -0.0101263 0.144319 0.01 -0.0150503 0.143451 0.01 0.0025 -2.03561e-16 0 0.0025 -2.03561e-16 0.01 -0.0101263 0.144319 0.01 0.00109391 0.0483242 0.01 -0.0031196 0.0964848 0.01 -0.0101263 0.144319 0 0.00109391 0.0483242 0 -0.0031196 0.0964848 0 + + + 0 3 2 1 0 2 16 4 5 16 7 4 17 8 7 17 7 16 6 8 17 13 6 17 10 6 13 14 10 13 15 11 10 15 10 14 12 9 11 12 11 15 21 19 18 21 18 24 22 24 25 22 21 24 20 25 23 20 22 25 38 26 27 38 29 26 39 30 29 39 29 38 28 30 39 35 28 39 32 28 35 36 32 35 37 33 32 37 32 36 34 31 33 34 33 37 43 41 40 43 40 46 44 46 47 44 43 46 42 47 45 42 44 47 51 49 48 51 48 54 52 54 55 52 51 54 50 55 53 50 52 55 56 59 58 57 56 58 63 61 60 63 60 66 64 66 67 64 63 66 62 67 65 62 64 67 + 3 6 9 12 15 18 21 24 27 30 33 36 39 42 45 48 51 54 57 60 63 66 69 72 75 78 81 84 87 90 93 96 99 102 105 108 111 114 117 120 123 126 129 132 135 138 141 144 147 150 153 156 + + + + + -0.0150518 -0.143468 0 -0.0101278 -0.144336 0 -0.0101278 -0.144336 0.01 -0.0150518 -0.143468 0.01 -0.0150518 -0.143468 0 -0.0101278 -0.144336 0 -0.0025 -2.02361e-16 0 -0.00808647 -0.095916 0 -0.0038978 -0.0480393 0 -0.0150518 0.143468 0 -0.0038978 0.0480393 0 -0.00808647 0.095916 0 -0.0101278 0.144336 0 0.0025 -2.03585e-16 0 0.00109374 0.04833 0 -0.00312028 0.0964964 0 -0.00312028 -0.0964964 0 0.00109374 -0.04833 0 -0.0101278 -0.144336 0 -0.0101278 -0.144336 0.01 0.0025 -2.03585e-16 0.01 -0.00312028 -0.0964964 0.01 0.00109374 -0.04833 0.01 0.0025 -2.03585e-16 0 -0.00312028 -0.0964964 0 0.00109374 -0.04833 0 -0.0150518 -0.143468 0.01 -0.0101278 -0.144336 0.01 -0.0025 -2.02361e-16 0.01 -0.00808647 -0.095916 0.01 -0.0038978 -0.0480393 0.01 -0.0150518 0.143468 0.01 -0.0038978 0.0480393 0.01 -0.00808647 0.095916 0.01 -0.0101278 0.144336 0.01 0.0025 -2.03585e-16 0.01 0.00109374 0.04833 0.01 -0.00312028 0.0964964 0.01 -0.00312028 -0.0964964 0.01 0.00109374 -0.04833 0.01 -0.0150518 -0.143468 0 -0.0150518 -0.143468 0.01 -0.0025 -2.02361e-16 0.01 -0.00808647 -0.095916 0.01 -0.0038978 -0.0480393 0.01 -0.0025 -2.02361e-16 0 -0.00808647 -0.095916 0 -0.0038978 -0.0480393 0 -0.0025 -2.02361e-16 0 -0.0025 -2.02361e-16 0.01 -0.0150518 0.143468 0.01 -0.0038978 0.0480393 0.01 -0.00808647 0.095916 0.01 -0.0150518 0.143468 0 -0.0038978 0.0480393 0 -0.00808647 0.095916 0 -0.0150518 0.143468 0 -0.0101278 0.144336 0 -0.0101278 0.144336 0.01 -0.0150518 0.143468 0.01 0.0025 -2.03585e-16 0 0.0025 -2.03585e-16 0.01 -0.0101278 0.144336 0.01 0.00109374 0.04833 0.01 -0.00312028 0.0964964 0.01 -0.0101278 0.144336 0 0.00109374 0.04833 0 -0.00312028 0.0964964 0 + + + 0 3 2 1 0 2 16 4 5 16 7 4 17 8 7 17 7 16 6 8 17 13 6 17 10 6 13 14 10 13 15 11 10 15 10 14 12 9 11 12 11 15 21 19 18 21 18 24 22 24 25 22 21 24 20 25 23 20 22 25 38 26 27 38 29 26 39 30 29 39 29 38 28 30 39 35 28 39 32 28 35 36 32 35 37 33 32 37 32 36 34 31 33 34 33 37 43 41 40 43 40 46 44 46 47 44 43 46 42 47 45 42 44 47 51 49 48 51 48 54 52 54 55 52 51 54 50 55 53 50 52 55 56 59 58 57 56 58 63 61 60 63 60 66 64 66 67 64 63 66 62 67 65 62 64 67 + 3 6 9 12 15 18 21 24 27 30 33 36 39 42 45 48 51 54 57 60 63 66 69 72 75 78 81 84 87 90 93 96 99 102 105 108 111 114 117 120 123 126 129 132 135 138 141 144 147 150 153 156 + + + + + -0.0151779 -0.144909 0 -0.0102539 -0.145778 0 -0.0102539 -0.145778 0.01 -0.0151779 -0.144909 0.01 -0.0151779 -0.144909 0 -0.0102539 -0.145778 0 -0.0025 -2.04394e-16 0 -0.00814259 -0.0968795 0 -0.00391184 -0.0485219 0 -0.0151779 0.144909 0 -0.00391184 0.0485219 0 -0.00814259 0.0968795 0 -0.0102539 0.145778 0 0.0025 -2.05618e-16 0 0.0010797 0.0488126 0 -0.0031764 0.09746 0 -0.0031764 -0.09746 0 0.0010797 -0.0488126 0 -0.0102539 -0.145778 0 -0.0102539 -0.145778 0.01 0.0025 -2.05618e-16 0.01 -0.0031764 -0.09746 0.01 0.0010797 -0.0488126 0.01 0.0025 -2.05618e-16 0 -0.0031764 -0.09746 0 0.0010797 -0.0488126 0 -0.0151779 -0.144909 0.01 -0.0102539 -0.145778 0.01 -0.0025 -2.04394e-16 0.01 -0.00814259 -0.0968795 0.01 -0.00391184 -0.0485219 0.01 -0.0151779 0.144909 0.01 -0.00391184 0.0485219 0.01 -0.00814259 0.0968795 0.01 -0.0102539 0.145778 0.01 0.0025 -2.05618e-16 0.01 0.0010797 0.0488126 0.01 -0.0031764 0.09746 0.01 -0.0031764 -0.09746 0.01 0.0010797 -0.0488126 0.01 -0.0151779 -0.144909 0 -0.0151779 -0.144909 0.01 -0.0025 -2.04394e-16 0.01 -0.00814259 -0.0968795 0.01 -0.00391184 -0.0485219 0.01 -0.0025 -2.04394e-16 0 -0.00814259 -0.0968795 0 -0.00391184 -0.0485219 0 -0.0025 -2.04394e-16 0 -0.0025 -2.04394e-16 0.01 -0.0151779 0.144909 0.01 -0.00391184 0.0485219 0.01 -0.00814259 0.0968795 0.01 -0.0151779 0.144909 0 -0.00391184 0.0485219 0 -0.00814259 0.0968795 0 -0.0151779 0.144909 0 -0.0102539 0.145778 0 -0.0102539 0.145778 0.01 -0.0151779 0.144909 0.01 0.0025 -2.05618e-16 0 0.0025 -2.05618e-16 0.01 -0.0102539 0.145778 0.01 0.0010797 0.0488126 0.01 -0.0031764 0.09746 0.01 -0.0102539 0.145778 0 0.0010797 0.0488126 0 -0.0031764 0.09746 0 + + + 0 3 2 1 0 2 16 4 5 16 7 4 17 8 7 17 7 16 6 8 17 13 6 17 10 6 13 14 10 13 15 11 10 15 10 14 12 9 11 12 11 15 21 19 18 21 18 24 22 24 25 22 21 24 20 25 23 20 22 25 38 26 27 38 29 26 39 30 29 39 29 38 28 30 39 35 28 39 32 28 35 36 32 35 37 33 32 37 32 36 34 31 33 34 33 37 43 41 40 43 40 46 44 46 47 44 43 46 42 47 45 42 44 47 51 49 48 51 48 54 52 54 55 52 51 54 50 55 53 50 52 55 56 59 58 57 56 58 63 61 60 63 60 66 64 66 67 64 63 66 62 67 65 62 64 67 + 3 6 9 12 15 18 21 24 27 30 33 36 39 42 45 48 51 54 57 60 63 66 69 72 75 78 81 84 87 90 93 96 99 102 105 108 111 114 117 120 123 126 129 132 135 138 141 144 147 150 153 156 + + + + + -0.015181 -0.144944 0 -0.0102569 -0.145812 0 -0.0102569 -0.145812 0.01 -0.015181 -0.144944 0.01 -0.015181 -0.144944 0 -0.0102569 -0.145812 0 -0.0025 -2.04443e-16 0 -0.00814394 -0.0969028 0 -0.00391218 -0.0485335 0 -0.015181 0.144944 0 -0.00391218 0.0485335 0 -0.00814394 0.0969028 0 -0.0102569 0.145812 0 0.0025 -2.05667e-16 0 0.00107936 0.0488242 0 -0.00317775 0.0974832 0 -0.00317775 -0.0974832 0 0.00107936 -0.0488242 0 -0.0102569 -0.145812 0 -0.0102569 -0.145812 0.01 0.0025 -2.05667e-16 0.01 -0.00317775 -0.0974832 0.01 0.00107936 -0.0488242 0.01 0.0025 -2.05667e-16 0 -0.00317775 -0.0974832 0 0.00107936 -0.0488242 0 -0.015181 -0.144944 0.01 -0.0102569 -0.145812 0.01 -0.0025 -2.04443e-16 0.01 -0.00814394 -0.0969028 0.01 -0.00391218 -0.0485335 0.01 -0.015181 0.144944 0.01 -0.00391218 0.0485335 0.01 -0.00814394 0.0969028 0.01 -0.0102569 0.145812 0.01 0.0025 -2.05667e-16 0.01 0.00107936 0.0488242 0.01 -0.00317775 0.0974832 0.01 -0.00317775 -0.0974832 0.01 0.00107936 -0.0488242 0.01 -0.015181 -0.144944 0 -0.015181 -0.144944 0.01 -0.0025 -2.04443e-16 0.01 -0.00814394 -0.0969028 0.01 -0.00391218 -0.0485335 0.01 -0.0025 -2.04443e-16 0 -0.00814394 -0.0969028 0 -0.00391218 -0.0485335 0 -0.0025 -2.04443e-16 0 -0.0025 -2.04443e-16 0.01 -0.015181 0.144944 0.01 -0.00391218 0.0485335 0.01 -0.00814394 0.0969028 0.01 -0.015181 0.144944 0 -0.00391218 0.0485335 0 -0.00814394 0.0969028 0 -0.015181 0.144944 0 -0.0102569 0.145812 0 -0.0102569 0.145812 0.01 -0.015181 0.144944 0.01 0.0025 -2.05667e-16 0 0.0025 -2.05667e-16 0.01 -0.0102569 0.145812 0.01 0.00107936 0.0488242 0.01 -0.00317775 0.0974832 0.01 -0.0102569 0.145812 0 0.00107936 0.0488242 0 -0.00317775 0.0974832 0 + + + 0 3 2 1 0 2 7 4 5 16 7 5 17 8 7 17 7 16 6 8 17 13 6 17 10 6 13 14 10 13 11 10 14 15 11 14 12 9 11 12 11 15 21 19 18 21 18 24 22 24 25 22 21 24 20 25 23 20 22 25 29 26 27 38 29 27 39 30 29 39 29 38 28 30 39 35 28 39 32 28 35 36 32 35 33 32 36 37 33 36 34 31 33 34 33 37 43 41 40 43 40 46 44 46 47 44 43 46 42 47 45 42 44 47 51 49 48 51 48 54 52 54 55 52 51 54 50 55 53 50 52 55 56 59 58 57 56 58 63 61 60 63 60 66 64 66 67 64 63 66 62 67 65 62 64 67 + 3 6 9 12 15 18 21 24 27 30 33 36 39 42 45 48 51 54 57 60 63 66 69 72 75 78 81 84 87 90 93 96 99 102 105 108 111 114 117 120 123 126 129 132 135 138 141 144 147 150 153 156 + + + + + -0.0153071 -0.146385 0 -0.010383 -0.147254 0 -0.010383 -0.147254 0.01 -0.0153071 -0.146385 0.01 -0.0153071 -0.146385 0 -0.010383 -0.147254 0 -0.0025 -2.06475e-16 0 -0.00820006 -0.0978663 0 -0.00392622 -0.0490161 0 -0.0153071 0.146385 0 -0.00392622 0.0490161 0 -0.00820006 0.0978663 0 -0.010383 0.147254 0 0.0025 -2.077e-16 0 0.00106532 0.0493068 0 -0.00323387 0.0984468 0 -0.00323387 -0.0984468 0 0.00106532 -0.0493068 0 -0.010383 -0.147254 0 -0.010383 -0.147254 0.01 0.0025 -2.077e-16 0.01 -0.00323387 -0.0984468 0.01 0.00106532 -0.0493068 0.01 0.0025 -2.077e-16 0 -0.00323387 -0.0984468 0 0.00106532 -0.0493068 0 -0.0153071 -0.146385 0.01 -0.010383 -0.147254 0.01 -0.0025 -2.06475e-16 0.01 -0.00820006 -0.0978663 0.01 -0.00392622 -0.0490161 0.01 -0.0153071 0.146385 0.01 -0.00392622 0.0490161 0.01 -0.00820006 0.0978663 0.01 -0.010383 0.147254 0.01 0.0025 -2.077e-16 0.01 0.00106532 0.0493068 0.01 -0.00323387 0.0984468 0.01 -0.00323387 -0.0984468 0.01 0.00106532 -0.0493068 0.01 -0.0153071 -0.146385 0 -0.0153071 -0.146385 0.01 -0.0025 -2.06475e-16 0.01 -0.00820006 -0.0978663 0.01 -0.00392622 -0.0490161 0.01 -0.0025 -2.06475e-16 0 -0.00820006 -0.0978663 0 -0.00392622 -0.0490161 0 -0.0025 -2.06475e-16 0 -0.0025 -2.06475e-16 0.01 -0.0153071 0.146385 0.01 -0.00392622 0.0490161 0.01 -0.00820006 0.0978663 0.01 -0.0153071 0.146385 0 -0.00392622 0.0490161 0 -0.00820006 0.0978663 0 -0.0153071 0.146385 0 -0.010383 0.147254 0 -0.010383 0.147254 0.01 -0.0153071 0.146385 0.01 0.0025 -2.077e-16 0 0.0025 -2.077e-16 0.01 -0.010383 0.147254 0.01 0.00106532 0.0493068 0.01 -0.00323387 0.0984468 0.01 -0.010383 0.147254 0 0.00106532 0.0493068 0 -0.00323387 0.0984468 0 + + + 0 3 2 1 0 2 16 4 5 16 7 4 17 8 7 17 7 16 6 8 17 13 6 17 10 6 13 14 10 13 11 10 14 15 11 14 12 9 11 12 11 15 21 19 18 21 18 24 22 24 25 22 21 24 20 25 23 20 22 25 38 26 27 38 29 26 39 30 29 39 29 38 28 30 39 35 28 39 32 28 35 36 32 35 33 32 36 37 33 36 34 31 33 34 33 37 43 41 40 43 40 46 44 46 47 44 43 46 42 47 45 42 44 47 51 49 48 51 48 54 52 54 55 52 51 54 50 55 53 50 52 55 56 59 58 57 56 58 63 61 60 63 60 66 64 66 67 64 63 66 62 67 65 62 64 67 + 3 6 9 12 15 18 21 24 27 30 33 36 39 42 45 48 51 54 57 60 63 66 69 72 75 78 81 84 87 90 93 96 99 102 105 108 111 114 117 120 123 126 129 132 135 138 141 144 147 150 153 156 + + + + + -0.0153086 -0.146403 0 -0.0103845 -0.147271 0 -0.0103845 -0.147271 0.01 -0.0153086 -0.146403 0.01 -0.0153086 -0.146403 0 -0.0103845 -0.147271 0 -0.0025 -2.065e-16 0 -0.00820074 -0.0978779 0 -0.00392639 -0.0490219 0 -0.0153086 0.146403 0 -0.00392639 0.0490219 0 -0.00820074 0.0978779 0 -0.0103845 0.147271 0 0.0025 -2.07725e-16 0 0.00106515 0.0493126 0 -0.00323455 0.0984584 0 -0.00323455 -0.0984584 0 0.00106515 -0.0493126 0 -0.0103845 -0.147271 0 -0.0103845 -0.147271 0.01 0.0025 -2.07725e-16 0.01 -0.00323455 -0.0984584 0.01 0.00106515 -0.0493126 0.01 0.0025 -2.07725e-16 0 -0.00323455 -0.0984584 0 0.00106515 -0.0493126 0 -0.0153086 -0.146403 0.01 -0.0103845 -0.147271 0.01 -0.0025 -2.065e-16 0.01 -0.00820074 -0.0978779 0.01 -0.00392639 -0.0490219 0.01 -0.0153086 0.146403 0.01 -0.00392639 0.0490219 0.01 -0.00820074 0.0978779 0.01 -0.0103845 0.147271 0.01 0.0025 -2.07725e-16 0.01 0.00106515 0.0493126 0.01 -0.00323455 0.0984584 0.01 -0.00323455 -0.0984584 0.01 0.00106515 -0.0493126 0.01 -0.0153086 -0.146403 0 -0.0153086 -0.146403 0.01 -0.0025 -2.065e-16 0.01 -0.00820074 -0.0978779 0.01 -0.00392639 -0.0490219 0.01 -0.0025 -2.065e-16 0 -0.00820074 -0.0978779 0 -0.00392639 -0.0490219 0 -0.0025 -2.065e-16 0 -0.0025 -2.065e-16 0.01 -0.0153086 0.146403 0.01 -0.00392639 0.0490219 0.01 -0.00820074 0.0978779 0.01 -0.0153086 0.146403 0 -0.00392639 0.0490219 0 -0.00820074 0.0978779 0 -0.0153086 0.146403 0 -0.0103845 0.147271 0 -0.0103845 0.147271 0.01 -0.0153086 0.146403 0.01 0.0025 -2.07725e-16 0 0.0025 -2.07725e-16 0.01 -0.0103845 0.147271 0.01 0.00106515 0.0493126 0.01 -0.00323455 0.0984584 0.01 -0.0103845 0.147271 0 0.00106515 0.0493126 0 -0.00323455 0.0984584 0 + + + 0 3 2 1 0 2 7 4 5 16 7 5 17 8 7 17 7 16 6 8 17 13 6 17 10 6 13 14 10 13 15 11 10 15 10 14 12 9 11 12 11 15 21 19 18 21 18 24 22 24 25 22 21 24 20 25 23 20 22 25 29 26 27 38 29 27 39 30 29 39 29 38 28 30 39 35 28 39 32 28 35 36 32 35 37 33 32 37 32 36 34 31 33 34 33 37 43 41 40 43 40 46 44 46 47 44 43 46 42 47 45 42 44 47 51 49 48 51 48 54 52 54 55 52 51 54 50 55 53 50 52 55 56 59 58 57 56 58 63 61 60 63 60 66 64 66 67 64 63 66 62 67 65 62 64 67 + 3 6 9 12 15 18 21 24 27 30 33 36 39 42 45 48 51 54 57 60 63 66 69 72 75 78 81 84 87 90 93 96 99 102 105 108 111 114 117 120 123 126 129 132 135 138 141 144 147 150 153 156 + + + + + -0.0145991 -0.138293 0 -0.00967507 -0.139162 0 -0.00967507 -0.139162 0.01 -0.0145991 -0.138293 0.01 -0.0145991 -0.138293 0 -0.00967507 -0.139162 0 -0.0025 -1.95062e-16 0 -0.00788497 -0.0924564 0 -0.00384738 -0.0463065 0 -0.0145991 0.138293 0 -0.00384738 0.0463065 0 -0.00788497 0.0924564 0 -0.00967507 0.139162 0 0.0025 -1.96286e-16 0 0.00114416 0.0465973 0 -0.00291878 0.0930369 0 -0.00291878 -0.0930369 0 0.00114416 -0.0465973 0 -0.00967507 -0.139162 0 -0.00967507 -0.139162 0.01 0.0025 -1.96286e-16 0.01 -0.00291878 -0.0930369 0.01 0.00114416 -0.0465973 0.01 0.0025 -1.96286e-16 0 -0.00291878 -0.0930369 0 0.00114416 -0.0465973 0 -0.0145991 -0.138293 0.01 -0.00967507 -0.139162 0.01 -0.0025 -1.95062e-16 0.01 -0.00788497 -0.0924564 0.01 -0.00384738 -0.0463065 0.01 -0.0145991 0.138293 0.01 -0.00384738 0.0463065 0.01 -0.00788497 0.0924564 0.01 -0.00967507 0.139162 0.01 0.0025 -1.96286e-16 0.01 0.00114416 0.0465973 0.01 -0.00291878 0.0930369 0.01 -0.00291878 -0.0930369 0.01 0.00114416 -0.0465973 0.01 -0.0145991 -0.138293 0 -0.0145991 -0.138293 0.01 -0.0025 -1.95062e-16 0.01 -0.00788497 -0.0924564 0.01 -0.00384738 -0.0463065 0.01 -0.0025 -1.95062e-16 0 -0.00788497 -0.0924564 0 -0.00384738 -0.0463065 0 -0.0025 -1.95062e-16 0 -0.0025 -1.95062e-16 0.01 -0.0145991 0.138293 0.01 -0.00384738 0.0463065 0.01 -0.00788497 0.0924564 0.01 -0.0145991 0.138293 0 -0.00384738 0.0463065 0 -0.00788497 0.0924564 0 -0.0145991 0.138293 0 -0.00967507 0.139162 0 -0.00967507 0.139162 0.01 -0.0145991 0.138293 0.01 0.0025 -1.96286e-16 0 0.0025 -1.96286e-16 0.01 -0.00967507 0.139162 0.01 0.00114416 0.0465973 0.01 -0.00291878 0.0930369 0.01 -0.00967507 0.139162 0 0.00114416 0.0465973 0 -0.00291878 0.0930369 0 + + + 1 3 2 1 0 3 7 4 5 16 7 5 17 8 7 17 7 16 6 8 17 13 6 17 10 6 13 14 10 13 11 10 14 15 11 14 12 9 11 12 11 15 21 19 18 21 18 24 22 24 25 22 21 24 20 25 23 20 22 25 29 26 27 38 29 27 39 30 29 39 29 38 28 30 39 35 28 39 32 28 35 36 32 35 33 32 36 37 33 36 34 31 33 34 33 37 43 41 40 43 40 46 44 46 47 44 43 46 42 47 45 42 44 47 51 49 48 51 48 54 52 54 55 52 51 54 50 55 53 50 52 55 56 59 58 57 56 58 63 61 60 63 60 66 64 66 67 64 63 66 62 67 65 62 64 67 + 3 6 9 12 15 18 21 24 27 30 33 36 39 42 45 48 51 54 57 60 63 66 69 72 75 78 81 84 87 90 93 96 99 102 105 108 111 114 117 120 123 126 129 132 135 138 141 144 147 150 153 156 + + + + + -0.0154377 -0.147879 0 -0.0105137 -0.148747 0 -0.0105137 -0.148747 0.01 -0.0154377 -0.147879 0.01 -0.0154377 -0.147879 0 -0.0105137 -0.148747 0 -0.0025 -2.08582e-16 0 -0.00825821 -0.0988647 0 -0.00394077 -0.0495161 0 -0.0154377 0.147879 0 -0.00394077 0.0495161 0 -0.00825821 0.0988647 0 -0.0105137 0.148747 0 0.0025 -2.09806e-16 0 0.00105077 0.0498069 0 -0.00329202 0.0994452 0 -0.00329202 -0.0994452 0 0.00105077 -0.0498069 0 -0.0105137 -0.148747 0 -0.0105137 -0.148747 0.01 0.0025 -2.09806e-16 0.01 -0.00329202 -0.0994452 0.01 0.00105077 -0.0498069 0.01 0.0025 -2.09806e-16 0 -0.00329202 -0.0994452 0 0.00105077 -0.0498069 0 -0.0154377 -0.147879 0.01 -0.0105137 -0.148747 0.01 -0.0025 -2.08582e-16 0.01 -0.00825821 -0.0988647 0.01 -0.00394077 -0.0495161 0.01 -0.0154377 0.147879 0.01 -0.00394077 0.0495161 0.01 -0.00825821 0.0988647 0.01 -0.0105137 0.148747 0.01 0.0025 -2.09806e-16 0.01 0.00105077 0.0498069 0.01 -0.00329202 0.0994452 0.01 -0.00329202 -0.0994452 0.01 0.00105077 -0.0498069 0.01 -0.0154377 -0.147879 0 -0.0154377 -0.147879 0.01 -0.0025 -2.08582e-16 0.01 -0.00825821 -0.0988647 0.01 -0.00394077 -0.0495161 0.01 -0.0025 -2.08582e-16 0 -0.00825821 -0.0988647 0 -0.00394077 -0.0495161 0 -0.0025 -2.08582e-16 0 -0.0025 -2.08582e-16 0.01 -0.0154377 0.147879 0.01 -0.00394077 0.0495161 0.01 -0.00825821 0.0988647 0.01 -0.0154377 0.147879 0 -0.00394077 0.0495161 0 -0.00825821 0.0988647 0 -0.0154377 0.147879 0 -0.0105137 0.148747 0 -0.0105137 0.148747 0.01 -0.0154377 0.147879 0.01 0.0025 -2.09806e-16 0 0.0025 -2.09806e-16 0.01 -0.0105137 0.148747 0.01 0.00105077 0.0498069 0.01 -0.00329202 0.0994452 0.01 -0.0105137 0.148747 0 0.00105077 0.0498069 0 -0.00329202 0.0994452 0 + + + 0 3 2 1 0 2 16 4 5 16 7 4 8 7 16 17 8 16 6 8 17 13 6 17 10 6 13 14 10 13 15 11 10 15 10 14 12 9 11 12 11 15 21 19 18 21 18 24 22 24 25 22 21 24 20 25 23 20 22 25 38 26 27 38 29 26 30 29 38 39 30 38 28 30 39 35 28 39 32 28 35 36 32 35 37 33 32 37 32 36 34 31 33 34 33 37 43 41 40 43 40 46 44 46 47 44 43 46 42 47 45 42 44 47 51 49 48 51 48 54 52 54 55 52 51 54 50 55 53 50 52 55 56 59 58 57 56 58 63 61 60 63 60 66 64 66 67 64 63 66 62 67 65 62 64 67 + 3 6 9 12 15 18 21 24 27 30 33 36 39 42 45 48 51 54 57 60 63 66 69 72 75 78 81 84 87 90 93 96 99 102 105 108 111 114 117 120 123 126 129 132 135 138 141 144 147 150 153 156 + + + + + -0.0155638 -0.14932 0 -0.0106398 -0.150188 0 -0.0106398 -0.150188 0.01 -0.0155638 -0.14932 0.01 -0.0155638 -0.14932 0 -0.0106398 -0.150188 0 -0.0025 -2.10615e-16 0 -0.00831434 -0.0998283 0 -0.00395481 -0.0499987 0 -0.0155638 0.14932 0 -0.00395481 0.0499987 0 -0.00831434 0.0998283 0 -0.0106398 0.150188 0 0.0025 -2.11839e-16 0 0.00103673 0.0502895 0 -0.00334814 0.100409 0 -0.00334814 -0.100409 0 0.00103673 -0.0502895 0 -0.0106398 -0.150188 0 -0.0106398 -0.150188 0.01 0.0025 -2.11839e-16 0.01 -0.00334814 -0.100409 0.01 0.00103673 -0.0502895 0.01 0.0025 -2.11839e-16 0 -0.00334814 -0.100409 0 0.00103673 -0.0502895 0 -0.0155638 -0.14932 0.01 -0.0106398 -0.150188 0.01 -0.0025 -2.10615e-16 0.01 -0.00831434 -0.0998283 0.01 -0.00395481 -0.0499987 0.01 -0.0155638 0.14932 0.01 -0.00395481 0.0499987 0.01 -0.00831434 0.0998283 0.01 -0.0106398 0.150188 0.01 0.0025 -2.11839e-16 0.01 0.00103673 0.0502895 0.01 -0.00334814 0.100409 0.01 -0.00334814 -0.100409 0.01 0.00103673 -0.0502895 0.01 -0.0155638 -0.14932 0 -0.0155638 -0.14932 0.01 -0.0025 -2.10615e-16 0.01 -0.00831434 -0.0998283 0.01 -0.00395481 -0.0499987 0.01 -0.0025 -2.10615e-16 0 -0.00831434 -0.0998283 0 -0.00395481 -0.0499987 0 -0.0025 -2.10615e-16 0 -0.0025 -2.10615e-16 0.01 -0.0155638 0.14932 0.01 -0.00395481 0.0499987 0.01 -0.00831434 0.0998283 0.01 -0.0155638 0.14932 0 -0.00395481 0.0499987 0 -0.00831434 0.0998283 0 -0.0155638 0.14932 0 -0.0106398 0.150188 0 -0.0106398 0.150188 0.01 -0.0155638 0.14932 0.01 0.0025 -2.11839e-16 0 0.0025 -2.11839e-16 0.01 -0.0106398 0.150188 0.01 0.00103673 0.0502895 0.01 -0.00334814 0.100409 0.01 -0.0106398 0.150188 0 0.00103673 0.0502895 0 -0.00334814 0.100409 0 + + + 0 3 2 1 0 2 16 4 5 16 7 4 8 7 16 17 8 16 6 8 17 13 6 17 10 6 13 14 10 13 15 11 10 15 10 14 12 9 11 12 11 15 21 19 18 21 18 24 22 24 25 22 21 24 20 25 23 20 22 25 38 26 27 38 29 26 30 29 38 39 30 38 28 30 39 35 28 39 32 28 35 36 32 35 37 33 32 37 32 36 34 31 33 34 33 37 43 41 40 43 40 46 44 46 47 44 43 46 42 47 45 42 44 47 51 49 48 51 48 54 52 54 55 52 51 54 50 55 53 50 52 55 56 59 58 57 56 58 63 61 60 63 60 66 64 66 67 64 63 66 62 67 65 62 64 67 + 3 6 9 12 15 18 21 24 27 30 33 36 39 42 45 48 51 54 57 60 63 66 69 72 75 78 81 84 87 90 93 96 99 102 105 108 111 114 117 120 123 126 129 132 135 138 141 144 147 150 153 156 + + + + + -0.0155653 -0.149337 0 -0.0106413 -0.150206 0 -0.0106413 -0.150206 0.01 -0.0155653 -0.149337 0.01 -0.0155653 -0.149337 0 -0.0106413 -0.150206 0 -0.0025 -2.10639e-16 0 -0.00831501 -0.0998399 0 -0.00395498 -0.0500046 0 -0.0155653 0.149337 0 -0.00395498 0.0500046 0 -0.00831501 0.0998399 0 -0.0106413 0.150206 0 0.0025 -2.11864e-16 0 0.00103656 0.0502953 0 -0.00334882 0.10042 0 -0.00334882 -0.10042 0 0.00103656 -0.0502953 0 -0.0106413 -0.150206 0 -0.0106413 -0.150206 0.01 0.0025 -2.11864e-16 0.01 -0.00334882 -0.10042 0.01 0.00103656 -0.0502953 0.01 0.0025 -2.11864e-16 0 -0.00334882 -0.10042 0 0.00103656 -0.0502953 0 -0.0155653 -0.149337 0.01 -0.0106413 -0.150206 0.01 -0.0025 -2.10639e-16 0.01 -0.00831501 -0.0998399 0.01 -0.00395498 -0.0500046 0.01 -0.0155653 0.149337 0.01 -0.00395498 0.0500046 0.01 -0.00831501 0.0998399 0.01 -0.0106413 0.150206 0.01 0.0025 -2.11864e-16 0.01 0.00103656 0.0502953 0.01 -0.00334882 0.10042 0.01 -0.00334882 -0.10042 0.01 0.00103656 -0.0502953 0.01 -0.0155653 -0.149337 0 -0.0155653 -0.149337 0.01 -0.0025 -2.10639e-16 0.01 -0.00831501 -0.0998399 0.01 -0.00395498 -0.0500046 0.01 -0.0025 -2.10639e-16 0 -0.00831501 -0.0998399 0 -0.00395498 -0.0500046 0 -0.0025 -2.10639e-16 0 -0.0025 -2.10639e-16 0.01 -0.0155653 0.149337 0.01 -0.00395498 0.0500046 0.01 -0.00831501 0.0998399 0.01 -0.0155653 0.149337 0 -0.00395498 0.0500046 0 -0.00831501 0.0998399 0 -0.0155653 0.149337 0 -0.0106413 0.150206 0 -0.0106413 0.150206 0.01 -0.0155653 0.149337 0.01 0.0025 -2.11864e-16 0 0.0025 -2.11864e-16 0.01 -0.0106413 0.150206 0.01 0.00103656 0.0502953 0.01 -0.00334882 0.10042 0.01 -0.0106413 0.150206 0 0.00103656 0.0502953 0 -0.00334882 0.10042 0 + + + 0 3 2 1 0 2 16 4 5 16 7 4 8 7 16 17 8 16 6 8 17 13 6 17 10 6 13 14 10 13 15 11 10 15 10 14 12 9 11 12 11 15 21 19 18 21 18 24 22 24 25 22 21 24 20 25 23 20 22 25 38 26 27 38 29 26 30 29 38 39 30 38 28 30 39 35 28 39 32 28 35 36 32 35 37 33 32 37 32 36 34 31 33 34 33 37 43 41 40 43 40 46 44 46 47 44 43 46 42 47 45 42 44 47 51 49 48 51 48 54 52 54 55 52 51 54 50 55 53 50 52 55 56 59 58 57 56 58 63 61 60 63 60 66 64 66 67 64 63 66 62 67 65 62 64 67 + 3 6 9 12 15 18 21 24 27 30 33 36 39 42 45 48 51 54 57 60 63 66 69 72 75 78 81 84 87 90 93 96 99 102 105 108 111 114 117 120 123 126 129 132 135 138 141 144 147 150 153 156 + + + + + -0.0145353 -0.137564 0 -0.00961126 -0.138432 0 -0.00961126 -0.138432 0.01 -0.0145353 -0.137564 0.01 -0.0145353 -0.137564 0 -0.00961126 -0.138432 0 -0.0025 -1.94033e-16 0 -0.00785657 -0.0919688 0 -0.00384028 -0.0460623 0 -0.0145353 0.137564 0 -0.00384028 0.0460623 0 -0.00785657 0.0919688 0 -0.00961126 0.138432 0 0.0025 -1.95258e-16 0 0.00115126 0.0463531 0 -0.00289038 0.0925493 0 -0.00289038 -0.0925493 0 0.00115126 -0.0463531 0 -0.00961126 -0.138432 0 -0.00961126 -0.138432 0.01 0.0025 -1.95258e-16 0.01 -0.00289038 -0.0925493 0.01 0.00115126 -0.0463531 0.01 0.0025 -1.95258e-16 0 -0.00289038 -0.0925493 0 0.00115126 -0.0463531 0 -0.0145353 -0.137564 0.01 -0.00961126 -0.138432 0.01 -0.0025 -1.94033e-16 0.01 -0.00785657 -0.0919688 0.01 -0.00384028 -0.0460623 0.01 -0.0145353 0.137564 0.01 -0.00384028 0.0460623 0.01 -0.00785657 0.0919688 0.01 -0.00961126 0.138432 0.01 0.0025 -1.95258e-16 0.01 0.00115126 0.0463531 0.01 -0.00289038 0.0925493 0.01 -0.00289038 -0.0925493 0.01 0.00115126 -0.0463531 0.01 -0.0145353 -0.137564 0 -0.0145353 -0.137564 0.01 -0.0025 -1.94033e-16 0.01 -0.00785657 -0.0919688 0.01 -0.00384028 -0.0460623 0.01 -0.0025 -1.94033e-16 0 -0.00785657 -0.0919688 0 -0.00384028 -0.0460623 0 -0.0025 -1.94033e-16 0 -0.0025 -1.94033e-16 0.01 -0.0145353 0.137564 0.01 -0.00384028 0.0460623 0.01 -0.00785657 0.0919688 0.01 -0.0145353 0.137564 0 -0.00384028 0.0460623 0 -0.00785657 0.0919688 0 -0.0145353 0.137564 0 -0.00961126 0.138432 0 -0.00961126 0.138432 0.01 -0.0145353 0.137564 0.01 0.0025 -1.95258e-16 0 0.0025 -1.95258e-16 0.01 -0.00961126 0.138432 0.01 0.00115126 0.0463531 0.01 -0.00289038 0.0925493 0.01 -0.00961126 0.138432 0 0.00115126 0.0463531 0 -0.00289038 0.0925493 0 + + + 1 3 2 1 0 3 16 4 5 16 7 4 8 7 16 17 8 16 6 8 17 13 6 17 10 6 13 14 10 13 11 10 14 15 11 14 9 11 15 12 9 15 21 19 18 21 18 24 22 24 25 22 21 24 20 25 23 20 22 25 38 26 27 38 29 26 30 29 38 39 30 38 28 30 39 35 28 39 32 28 35 36 32 35 33 32 36 37 33 36 31 33 37 34 31 37 43 41 40 43 40 46 44 46 47 44 43 46 42 47 45 42 44 47 51 49 48 51 48 54 52 54 55 52 51 54 50 55 53 50 52 55 56 59 58 57 56 58 63 61 60 63 60 66 64 66 67 64 63 66 62 67 65 62 64 67 + 3 6 9 12 15 18 21 24 27 30 33 36 39 42 45 48 51 54 57 60 63 66 69 72 75 78 81 84 87 90 93 96 99 102 105 108 111 114 117 120 123 126 129 132 135 138 141 144 147 150 153 156 + + + + + -0.0145368 -0.137581 0 -0.00961278 -0.13845 0 -0.00961278 -0.13845 0.01 -0.0145368 -0.137581 0.01 -0.0145368 -0.137581 0 -0.00961278 -0.13845 0 -0.0025 -1.94058e-16 0 -0.00785725 -0.0919804 0 -0.00384045 -0.0460681 0 -0.0145368 0.137581 0 -0.00384045 0.0460681 0 -0.00785725 0.0919804 0 -0.00961278 0.13845 0 0.0025 -1.95282e-16 0 0.00115109 0.0463589 0 -0.00289106 0.0925609 0 -0.00289106 -0.0925609 0 0.00115109 -0.0463589 0 -0.00961278 -0.13845 0 -0.00961278 -0.13845 0.01 0.0025 -1.95282e-16 0.01 -0.00289106 -0.0925609 0.01 0.00115109 -0.0463589 0.01 0.0025 -1.95282e-16 0 -0.00289106 -0.0925609 0 0.00115109 -0.0463589 0 -0.0145368 -0.137581 0.01 -0.00961278 -0.13845 0.01 -0.0025 -1.94058e-16 0.01 -0.00785725 -0.0919804 0.01 -0.00384045 -0.0460681 0.01 -0.0145368 0.137581 0.01 -0.00384045 0.0460681 0.01 -0.00785725 0.0919804 0.01 -0.00961278 0.13845 0.01 0.0025 -1.95282e-16 0.01 0.00115109 0.0463589 0.01 -0.00289106 0.0925609 0.01 -0.00289106 -0.0925609 0.01 0.00115109 -0.0463589 0.01 -0.0145368 -0.137581 0 -0.0145368 -0.137581 0.01 -0.0025 -1.94058e-16 0.01 -0.00785725 -0.0919804 0.01 -0.00384045 -0.0460681 0.01 -0.0025 -1.94058e-16 0 -0.00785725 -0.0919804 0 -0.00384045 -0.0460681 0 -0.0025 -1.94058e-16 0 -0.0025 -1.94058e-16 0.01 -0.0145368 0.137581 0.01 -0.00384045 0.0460681 0.01 -0.00785725 0.0919804 0.01 -0.0145368 0.137581 0 -0.00384045 0.0460681 0 -0.00785725 0.0919804 0 -0.0145368 0.137581 0 -0.00961278 0.13845 0 -0.00961278 0.13845 0.01 -0.0145368 0.137581 0.01 0.0025 -1.95282e-16 0 0.0025 -1.95282e-16 0.01 -0.00961278 0.13845 0.01 0.00115109 0.0463589 0.01 -0.00289106 0.0925609 0.01 -0.00961278 0.13845 0 0.00115109 0.0463589 0 -0.00289106 0.0925609 0 + + + 0 3 2 1 0 2 16 4 5 16 7 4 17 8 7 17 7 16 6 8 17 13 6 17 10 6 13 14 10 13 11 10 14 15 11 14 9 11 15 12 9 15 21 19 18 21 18 24 22 24 25 22 21 24 20 25 23 20 22 25 38 26 27 38 29 26 39 30 29 39 29 38 28 30 39 35 28 39 32 28 35 36 32 35 33 32 36 37 33 36 31 33 37 34 31 37 43 41 40 43 40 46 44 46 47 44 43 46 42 47 45 42 44 47 51 49 48 51 48 54 52 54 55 52 51 54 50 55 53 50 52 55 56 59 58 57 56 58 63 61 60 63 60 66 64 66 67 64 63 66 62 67 65 62 64 67 + 3 6 9 12 15 18 21 24 27 30 33 36 39 42 45 48 51 54 57 60 63 66 69 72 75 78 81 84 87 90 93 96 99 102 105 108 111 114 117 120 123 126 129 132 135 138 141 144 147 150 153 156 + + + + + -0.0146644 -0.13904 0 -0.00974039 -0.139908 0 -0.00974039 -0.139908 0.01 -0.0146644 -0.13904 0.01 -0.0146644 -0.13904 0 -0.00974039 -0.139908 0 -0.0025 -1.96115e-16 0 -0.00791405 -0.0929556 0 -0.00385466 -0.0465566 0 -0.0146644 0.13904 0 -0.00385466 0.0465566 0 -0.00791405 0.0929556 0 -0.00974039 0.139908 0 0.0025 -1.9734e-16 0 0.00113688 0.0468473 0 -0.00294786 0.0935361 0 -0.00294786 -0.0935361 0 0.00113688 -0.0468473 0 -0.00974039 -0.139908 0 -0.00974039 -0.139908 0.01 0.0025 -1.9734e-16 0.01 -0.00294786 -0.0935361 0.01 0.00113688 -0.0468473 0.01 0.0025 -1.9734e-16 0 -0.00294786 -0.0935361 0 0.00113688 -0.0468473 0 -0.0146644 -0.13904 0.01 -0.00974039 -0.139908 0.01 -0.0025 -1.96115e-16 0.01 -0.00791405 -0.0929556 0.01 -0.00385466 -0.0465566 0.01 -0.0146644 0.13904 0.01 -0.00385466 0.0465566 0.01 -0.00791405 0.0929556 0.01 -0.00974039 0.139908 0.01 0.0025 -1.9734e-16 0.01 0.00113688 0.0468473 0.01 -0.00294786 0.0935361 0.01 -0.00294786 -0.0935361 0.01 0.00113688 -0.0468473 0.01 -0.0146644 -0.13904 0 -0.0146644 -0.13904 0.01 -0.0025 -1.96115e-16 0.01 -0.00791405 -0.0929556 0.01 -0.00385466 -0.0465566 0.01 -0.0025 -1.96115e-16 0 -0.00791405 -0.0929556 0 -0.00385466 -0.0465566 0 -0.0025 -1.96115e-16 0 -0.0025 -1.96115e-16 0.01 -0.0146644 0.13904 0.01 -0.00385466 0.0465566 0.01 -0.00791405 0.0929556 0.01 -0.0146644 0.13904 0 -0.00385466 0.0465566 0 -0.00791405 0.0929556 0 -0.0146644 0.13904 0 -0.00974039 0.139908 0 -0.00974039 0.139908 0.01 -0.0146644 0.13904 0.01 0.0025 -1.9734e-16 0 0.0025 -1.9734e-16 0.01 -0.00974039 0.139908 0.01 0.00113688 0.0468473 0.01 -0.00294786 0.0935361 0.01 -0.00974039 0.139908 0 0.00113688 0.0468473 0 -0.00294786 0.0935361 0 + + + 0 3 2 1 0 2 16 4 5 16 7 4 8 7 16 17 8 16 6 8 17 13 6 17 10 6 13 14 10 13 15 11 10 15 10 14 9 11 15 12 9 15 21 19 18 21 18 24 22 24 25 22 21 24 20 25 23 20 22 25 38 26 27 38 29 26 30 29 38 39 30 38 28 30 39 35 28 39 32 28 35 36 32 35 37 33 32 37 32 36 34 31 33 34 33 37 43 41 40 43 40 46 44 46 47 44 43 46 42 47 45 42 44 47 51 49 48 51 48 54 52 54 55 52 51 54 50 55 53 50 52 55 56 59 58 57 56 58 63 61 60 63 60 66 64 66 67 64 63 66 62 67 65 62 64 67 + 3 6 9 12 15 18 21 24 27 30 33 36 39 42 45 48 51 54 57 60 63 66 69 72 75 78 81 84 87 90 93 96 99 102 105 108 111 114 117 120 123 126 129 132 135 138 141 144 147 150 153 156 + + + + + -0.014666 -0.139057 0 -0.00974191 -0.139926 0 -0.00974191 -0.139926 0.01 -0.014666 -0.139057 0.01 -0.014666 -0.139057 0 -0.00974191 -0.139926 0 -0.0025 -1.96139e-16 0 -0.00791472 -0.0929672 0 -0.00385483 -0.0465624 0 -0.014666 0.139057 0 -0.00385483 0.0465624 0 -0.00791472 0.0929672 0 -0.00974191 0.139926 0 0.0025 -1.97364e-16 0 0.00113671 0.0468531 0 -0.00294853 0.0935477 0 -0.00294853 -0.0935477 0 0.00113671 -0.0468531 0 -0.00974191 -0.139926 0 -0.00974191 -0.139926 0.01 0.0025 -1.97364e-16 0.01 -0.00294853 -0.0935477 0.01 0.00113671 -0.0468531 0.01 0.0025 -1.97364e-16 0 -0.00294853 -0.0935477 0 0.00113671 -0.0468531 0 -0.014666 -0.139057 0.01 -0.00974191 -0.139926 0.01 -0.0025 -1.96139e-16 0.01 -0.00791472 -0.0929672 0.01 -0.00385483 -0.0465624 0.01 -0.014666 0.139057 0.01 -0.00385483 0.0465624 0.01 -0.00791472 0.0929672 0.01 -0.00974191 0.139926 0.01 0.0025 -1.97364e-16 0.01 0.00113671 0.0468531 0.01 -0.00294853 0.0935477 0.01 -0.00294853 -0.0935477 0.01 0.00113671 -0.0468531 0.01 -0.014666 -0.139057 0 -0.014666 -0.139057 0.01 -0.0025 -1.96139e-16 0.01 -0.00791472 -0.0929672 0.01 -0.00385483 -0.0465624 0.01 -0.0025 -1.96139e-16 0 -0.00791472 -0.0929672 0 -0.00385483 -0.0465624 0 -0.0025 -1.96139e-16 0 -0.0025 -1.96139e-16 0.01 -0.014666 0.139057 0.01 -0.00385483 0.0465624 0.01 -0.00791472 0.0929672 0.01 -0.014666 0.139057 0 -0.00385483 0.0465624 0 -0.00791472 0.0929672 0 -0.014666 0.139057 0 -0.00974191 0.139926 0 -0.00974191 0.139926 0.01 -0.014666 0.139057 0.01 0.0025 -1.97364e-16 0 0.0025 -1.97364e-16 0.01 -0.00974191 0.139926 0.01 0.00113671 0.0468531 0.01 -0.00294853 0.0935477 0.01 -0.00974191 0.139926 0 0.00113671 0.0468531 0 -0.00294853 0.0935477 0 + + + 0 3 2 1 0 2 7 4 5 16 7 5 8 7 16 17 8 16 6 8 17 13 6 17 10 6 13 14 10 13 11 10 14 15 11 14 9 11 15 12 9 15 21 19 18 21 18 24 22 24 25 22 21 24 20 25 23 20 22 25 29 26 27 38 29 27 30 29 38 39 30 38 28 30 39 35 28 39 32 28 35 36 32 35 33 32 36 37 33 36 31 33 37 34 31 37 43 41 40 43 40 46 44 46 47 44 43 46 42 47 45 42 44 47 51 49 48 51 48 54 52 54 55 52 51 54 50 55 53 50 52 55 56 59 58 57 56 58 63 61 60 63 60 66 64 66 67 64 63 66 62 67 65 62 64 67 + 3 6 9 12 15 18 21 24 27 30 33 36 39 42 45 48 51 54 57 60 63 66 69 72 75 78 81 84 87 90 93 96 99 102 105 108 111 114 117 120 123 126 129 132 135 138 141 144 147 150 153 156 + + + + + -0.014792 -0.140499 0 -0.00986801 -0.141367 0 -0.00986801 -0.141367 0.01 -0.014792 -0.140499 0.01 -0.014792 -0.140499 0 -0.00986801 -0.141367 0 -0.0025 -1.98172e-16 0 -0.00797084 -0.0939308 0 -0.00386887 -0.047045 0 -0.014792 0.140499 0 -0.00386887 0.047045 0 -0.00797084 0.0939308 0 -0.00986801 0.141367 0 0.0025 -1.99397e-16 0 0.00112267 0.0473357 0 -0.00300465 0.0945112 0 -0.00300465 -0.0945112 0 0.00112267 -0.0473357 0 -0.00986801 -0.141367 0 -0.00986801 -0.141367 0.01 0.0025 -1.99397e-16 0.01 -0.00300465 -0.0945112 0.01 0.00112267 -0.0473357 0.01 0.0025 -1.99397e-16 0 -0.00300465 -0.0945112 0 0.00112267 -0.0473357 0 -0.014792 -0.140499 0.01 -0.00986801 -0.141367 0.01 -0.0025 -1.98172e-16 0.01 -0.00797084 -0.0939308 0.01 -0.00386887 -0.047045 0.01 -0.014792 0.140499 0.01 -0.00386887 0.047045 0.01 -0.00797084 0.0939308 0.01 -0.00986801 0.141367 0.01 0.0025 -1.99397e-16 0.01 0.00112267 0.0473357 0.01 -0.00300465 0.0945112 0.01 -0.00300465 -0.0945112 0.01 0.00112267 -0.0473357 0.01 -0.014792 -0.140499 0 -0.014792 -0.140499 0.01 -0.0025 -1.98172e-16 0.01 -0.00797084 -0.0939308 0.01 -0.00386887 -0.047045 0.01 -0.0025 -1.98172e-16 0 -0.00797084 -0.0939308 0 -0.00386887 -0.047045 0 -0.0025 -1.98172e-16 0 -0.0025 -1.98172e-16 0.01 -0.014792 0.140499 0.01 -0.00386887 0.047045 0.01 -0.00797084 0.0939308 0.01 -0.014792 0.140499 0 -0.00386887 0.047045 0 -0.00797084 0.0939308 0 -0.014792 0.140499 0 -0.00986801 0.141367 0 -0.00986801 0.141367 0.01 -0.014792 0.140499 0.01 0.0025 -1.99397e-16 0 0.0025 -1.99397e-16 0.01 -0.00986801 0.141367 0.01 0.00112267 0.0473357 0.01 -0.00300465 0.0945112 0.01 -0.00986801 0.141367 0 0.00112267 0.0473357 0 -0.00300465 0.0945112 0 + + + 0 3 2 1 0 2 16 4 5 16 7 4 17 8 7 17 7 16 6 8 17 13 6 17 10 6 13 14 10 13 11 10 14 15 11 14 9 11 15 12 9 15 21 19 18 21 18 24 22 24 25 22 21 24 20 25 23 20 22 25 38 26 27 38 29 26 39 30 29 39 29 38 28 30 39 35 28 39 32 28 35 36 32 35 33 32 36 37 33 36 31 33 37 34 31 37 43 41 40 43 40 46 44 46 47 44 43 46 42 47 45 42 44 47 51 49 48 51 48 54 52 54 55 52 51 54 50 55 53 50 52 55 56 59 58 57 56 58 63 61 60 63 60 66 64 66 67 64 63 66 62 67 65 62 64 67 + 3 6 9 12 15 18 21 24 27 30 33 36 39 42 45 48 51 54 57 60 63 66 69 72 75 78 81 84 87 90 93 96 99 102 105 108 111 114 117 120 123 126 129 132 135 138 141 144 147 150 153 156 + + + + + -0.0147951 -0.140533 0 -0.00987105 -0.141402 0 -0.00987105 -0.141402 0.01 -0.0147951 -0.140533 0.01 -0.0147951 -0.140533 0 -0.00987105 -0.141402 0 -0.0025 -1.98221e-16 0 -0.0079722 -0.093954 0 -0.00386921 -0.0470566 0 -0.0147951 0.140533 0 -0.00386921 0.0470566 0 -0.0079722 0.093954 0 -0.00987105 0.141402 0 0.0025 -1.99446e-16 0 0.00112233 0.0473473 0 -0.00300601 0.0945345 0 -0.00300601 -0.0945345 0 0.00112233 -0.0473473 0 -0.00987105 -0.141402 0 -0.00987105 -0.141402 0.01 0.0025 -1.99446e-16 0.01 -0.00300601 -0.0945345 0.01 0.00112233 -0.0473473 0.01 0.0025 -1.99446e-16 0 -0.00300601 -0.0945345 0 0.00112233 -0.0473473 0 -0.0147951 -0.140533 0.01 -0.00987105 -0.141402 0.01 -0.0025 -1.98221e-16 0.01 -0.0079722 -0.093954 0.01 -0.00386921 -0.0470566 0.01 -0.0147951 0.140533 0.01 -0.00386921 0.0470566 0.01 -0.0079722 0.093954 0.01 -0.00987105 0.141402 0.01 0.0025 -1.99446e-16 0.01 0.00112233 0.0473473 0.01 -0.00300601 0.0945345 0.01 -0.00300601 -0.0945345 0.01 0.00112233 -0.0473473 0.01 -0.0147951 -0.140533 0 -0.0147951 -0.140533 0.01 -0.0025 -1.98221e-16 0.01 -0.0079722 -0.093954 0.01 -0.00386921 -0.0470566 0.01 -0.0025 -1.98221e-16 0 -0.0079722 -0.093954 0 -0.00386921 -0.0470566 0 -0.0025 -1.98221e-16 0 -0.0025 -1.98221e-16 0.01 -0.0147951 0.140533 0.01 -0.00386921 0.0470566 0.01 -0.0079722 0.093954 0.01 -0.0147951 0.140533 0 -0.00386921 0.0470566 0 -0.0079722 0.093954 0 -0.0147951 0.140533 0 -0.00987105 0.141402 0 -0.00987105 0.141402 0.01 -0.0147951 0.140533 0.01 0.0025 -1.99446e-16 0 0.0025 -1.99446e-16 0.01 -0.00987105 0.141402 0.01 0.00112233 0.0473473 0.01 -0.00300601 0.0945345 0.01 -0.00987105 0.141402 0 0.00112233 0.0473473 0 -0.00300601 0.0945345 0 + + + 0 3 2 1 0 2 16 4 5 16 7 4 8 7 16 17 8 16 6 8 17 13 6 17 10 6 13 14 10 13 11 10 14 15 11 14 9 11 15 12 9 15 21 19 18 21 18 24 22 24 25 22 21 24 20 25 23 20 22 25 38 26 27 38 29 26 30 29 38 39 30 38 28 30 39 35 28 39 32 28 35 36 32 35 33 32 36 37 33 36 31 33 37 34 31 37 43 41 40 43 40 46 44 46 47 44 43 46 42 47 45 42 44 47 51 49 48 51 48 54 52 54 55 52 51 54 50 55 53 50 52 55 56 59 58 57 56 58 63 61 60 63 60 66 64 66 67 64 63 66 62 67 65 62 64 67 + 3 6 9 12 15 18 21 24 27 30 33 36 39 42 45 48 51 54 57 60 63 66 69 72 75 78 81 84 87 90 93 96 99 102 105 108 111 114 117 120 123 126 129 132 135 138 141 144 147 150 153 156 + + + + + -0.0149212 -0.141975 0 -0.00999714 -0.142843 0 -0.00999714 -0.142843 0.01 -0.0149212 -0.141975 0.01 -0.0149212 -0.141975 0 -0.00999714 -0.142843 0 -0.0025 -2.00254e-16 0 -0.00802832 -0.0949176 0 -0.00388325 -0.0475392 0 -0.0149212 0.141975 0 -0.00388325 0.0475392 0 -0.00802832 0.0949176 0 -0.00999714 0.142843 0 0.0025 -2.01479e-16 0 0.00110829 0.0478299 0 -0.00306213 0.095498 0 -0.00306213 -0.095498 0 0.00110829 -0.0478299 0 -0.00999714 -0.142843 0 -0.00999714 -0.142843 0.01 0.0025 -2.01479e-16 0.01 -0.00306213 -0.095498 0.01 0.00110829 -0.0478299 0.01 0.0025 -2.01479e-16 0 -0.00306213 -0.095498 0 0.00110829 -0.0478299 0 -0.0149212 -0.141975 0.01 -0.00999714 -0.142843 0.01 -0.0025 -2.00254e-16 0.01 -0.00802832 -0.0949176 0.01 -0.00388325 -0.0475392 0.01 -0.0149212 0.141975 0.01 -0.00388325 0.0475392 0.01 -0.00802832 0.0949176 0.01 -0.00999714 0.142843 0.01 0.0025 -2.01479e-16 0.01 0.00110829 0.0478299 0.01 -0.00306213 0.095498 0.01 -0.00306213 -0.095498 0.01 0.00110829 -0.0478299 0.01 -0.0149212 -0.141975 0 -0.0149212 -0.141975 0.01 -0.0025 -2.00254e-16 0.01 -0.00802832 -0.0949176 0.01 -0.00388325 -0.0475392 0.01 -0.0025 -2.00254e-16 0 -0.00802832 -0.0949176 0 -0.00388325 -0.0475392 0 -0.0025 -2.00254e-16 0 -0.0025 -2.00254e-16 0.01 -0.0149212 0.141975 0.01 -0.00388325 0.0475392 0.01 -0.00802832 0.0949176 0.01 -0.0149212 0.141975 0 -0.00388325 0.0475392 0 -0.00802832 0.0949176 0 -0.0149212 0.141975 0 -0.00999714 0.142843 0 -0.00999714 0.142843 0.01 -0.0149212 0.141975 0.01 0.0025 -2.01479e-16 0 0.0025 -2.01479e-16 0.01 -0.00999714 0.142843 0.01 0.00110829 0.0478299 0.01 -0.00306213 0.095498 0.01 -0.00999714 0.142843 0 0.00110829 0.0478299 0 -0.00306213 0.095498 0 + + + 0 3 2 1 0 2 16 4 5 16 7 4 17 8 7 17 7 16 6 8 17 13 6 17 10 6 13 14 10 13 15 11 10 15 10 14 12 9 11 12 11 15 21 19 18 21 18 24 22 24 25 22 21 24 20 25 23 20 22 25 38 26 27 38 29 26 39 30 29 39 29 38 28 30 39 35 28 39 32 28 35 36 32 35 37 33 32 37 32 36 34 31 33 34 33 37 43 41 40 43 40 46 44 46 47 44 43 46 42 47 45 42 44 47 51 49 48 51 48 54 52 54 55 52 51 54 50 55 53 50 52 55 56 59 58 57 56 58 63 61 60 63 60 66 64 66 67 64 63 66 62 67 65 62 64 67 + 3 6 9 12 15 18 21 24 27 30 33 36 39 42 45 48 51 54 57 60 63 66 69 72 75 78 81 84 87 90 93 96 99 102 105 108 111 114 117 120 123 126 129 132 135 138 141 144 147 150 153 156 + + + + + -0.0149227 -0.141992 0 -0.00999866 -0.14286 0 -0.00999866 -0.14286 0.01 -0.0149227 -0.141992 0.01 -0.0149227 -0.141992 0 -0.00999866 -0.14286 0 -0.0025 -2.00279e-16 0 -0.00802899 -0.0949292 0 -0.00388342 -0.047545 0 -0.0149227 0.141992 0 -0.00388342 0.047545 0 -0.00802899 0.0949292 0 -0.00999866 0.14286 0 0.0025 -2.01503e-16 0 0.00110812 0.0478358 0 -0.0030628 0.0955096 0 -0.0030628 -0.0955096 0 0.00110812 -0.0478358 0 -0.00999866 -0.14286 0 -0.00999866 -0.14286 0.01 0.0025 -2.01503e-16 0.01 -0.0030628 -0.0955096 0.01 0.00110812 -0.0478358 0.01 0.0025 -2.01503e-16 0 -0.0030628 -0.0955096 0 0.00110812 -0.0478358 0 -0.0149227 -0.141992 0.01 -0.00999866 -0.14286 0.01 -0.0025 -2.00279e-16 0.01 -0.00802899 -0.0949292 0.01 -0.00388342 -0.047545 0.01 -0.0149227 0.141992 0.01 -0.00388342 0.047545 0.01 -0.00802899 0.0949292 0.01 -0.00999866 0.14286 0.01 0.0025 -2.01503e-16 0.01 0.00110812 0.0478358 0.01 -0.0030628 0.0955096 0.01 -0.0030628 -0.0955096 0.01 0.00110812 -0.0478358 0.01 -0.0149227 -0.141992 0 -0.0149227 -0.141992 0.01 -0.0025 -2.00279e-16 0.01 -0.00802899 -0.0949292 0.01 -0.00388342 -0.047545 0.01 -0.0025 -2.00279e-16 0 -0.00802899 -0.0949292 0 -0.00388342 -0.047545 0 -0.0025 -2.00279e-16 0 -0.0025 -2.00279e-16 0.01 -0.0149227 0.141992 0.01 -0.00388342 0.047545 0.01 -0.00802899 0.0949292 0.01 -0.0149227 0.141992 0 -0.00388342 0.047545 0 -0.00802899 0.0949292 0 -0.0149227 0.141992 0 -0.00999866 0.14286 0 -0.00999866 0.14286 0.01 -0.0149227 0.141992 0.01 0.0025 -2.01503e-16 0 0.0025 -2.01503e-16 0.01 -0.00999866 0.14286 0.01 0.00110812 0.0478358 0.01 -0.0030628 0.0955096 0.01 -0.00999866 0.14286 0 0.00110812 0.0478358 0 -0.0030628 0.0955096 0 + + + 0 3 2 1 0 2 16 4 5 16 7 4 17 8 7 17 7 16 6 8 17 13 6 17 10 6 13 14 10 13 15 11 10 15 10 14 12 9 11 12 11 15 21 19 18 21 18 24 22 24 25 22 21 24 20 25 23 20 22 25 38 26 27 38 29 26 39 30 29 39 29 38 28 30 39 35 28 39 32 28 35 36 32 35 37 33 32 37 32 36 34 31 33 34 33 37 43 41 40 43 40 46 44 46 47 44 43 46 42 47 45 42 44 47 51 49 48 51 48 54 52 54 55 52 51 54 50 55 53 50 52 55 56 59 58 57 56 58 63 61 60 63 60 66 64 66 67 64 63 66 62 67 65 62 64 67 + 3 6 9 12 15 18 21 24 27 30 33 36 39 42 45 48 51 54 57 60 63 66 69 72 75 78 81 84 87 90 93 96 99 102 105 108 111 114 117 120 123 126 129 132 135 138 141 144 147 150 153 156 + + + + + -0.0173155 -0.169342 0 -0.0123914 -0.17021 0 -0.0123914 -0.17021 0.01 -0.0173155 -0.169342 0.01 -0.0173155 -0.169342 0 -0.0123914 -0.17021 0 -0.0025 -2.38855e-16 0 -0.00909395 -0.113214 0 -0.00414988 -0.0567028 0 -0.0173155 0.169342 0 -0.00414988 0.0567028 0 -0.00909395 0.113214 0 -0.0123914 0.17021 0 0.0025 -2.4008e-16 0 0.000841657 0.0569936 0 -0.00412776 0.113794 0 -0.00412776 -0.113794 0 0.000841657 -0.0569936 0 -0.0123914 -0.17021 0 -0.0123914 -0.17021 0.01 0.0025 -2.4008e-16 0.01 -0.00412776 -0.113794 0.01 0.000841657 -0.0569936 0.01 0.0025 -2.4008e-16 0 -0.00412776 -0.113794 0 0.000841657 -0.0569936 0 -0.0173155 -0.169342 0.01 -0.0123914 -0.17021 0.01 -0.0025 -2.38855e-16 0.01 -0.00909395 -0.113214 0.01 -0.00414988 -0.0567028 0.01 -0.0173155 0.169342 0.01 -0.00414988 0.0567028 0.01 -0.00909395 0.113214 0.01 -0.0123914 0.17021 0.01 0.0025 -2.4008e-16 0.01 0.000841657 0.0569936 0.01 -0.00412776 0.113794 0.01 -0.00412776 -0.113794 0.01 0.000841657 -0.0569936 0.01 -0.0173155 -0.169342 0 -0.0173155 -0.169342 0.01 -0.0025 -2.38855e-16 0.01 -0.00909395 -0.113214 0.01 -0.00414988 -0.0567028 0.01 -0.0025 -2.38855e-16 0 -0.00909395 -0.113214 0 -0.00414988 -0.0567028 0 -0.0025 -2.38855e-16 0 -0.0025 -2.38855e-16 0.01 -0.0173155 0.169342 0.01 -0.00414988 0.0567028 0.01 -0.00909395 0.113214 0.01 -0.0173155 0.169342 0 -0.00414988 0.0567028 0 -0.00909395 0.113214 0 -0.0173155 0.169342 0 -0.0123914 0.17021 0 -0.0123914 0.17021 0.01 -0.0173155 0.169342 0.01 0.0025 -2.4008e-16 0 0.0025 -2.4008e-16 0.01 -0.0123914 0.17021 0.01 0.000841657 0.0569936 0.01 -0.00412776 0.113794 0.01 -0.0123914 0.17021 0 0.000841657 0.0569936 0 -0.00412776 0.113794 0 + + + 0 3 2 1 0 2 16 4 5 16 7 4 17 8 7 17 7 16 6 8 17 13 6 17 10 6 13 14 10 13 15 11 10 15 10 14 12 9 11 12 11 15 21 19 18 21 18 24 22 24 25 22 21 24 20 25 23 20 22 25 38 26 27 38 29 26 39 30 29 39 29 38 28 30 39 35 28 39 32 28 35 36 32 35 37 33 32 37 32 36 34 31 33 34 33 37 43 41 40 43 40 46 44 46 47 44 43 46 42 47 45 42 44 47 51 49 48 51 48 54 52 54 55 52 51 54 50 55 53 50 52 55 56 59 58 57 56 58 63 61 60 63 60 66 64 66 67 64 63 66 62 67 65 62 64 67 + 3 6 9 12 15 18 21 24 27 30 33 36 39 42 45 48 51 54 57 60 63 66 69 72 75 78 81 84 87 90 93 96 99 102 105 108 111 114 117 120 123 126 129 132 135 138 141 144 147 150 153 156 + + + + + -0.0173094 -0.169272 0 -0.0123854 -0.17014 0 -0.0123854 -0.17014 0.01 -0.0173094 -0.169272 0.01 -0.0173094 -0.169272 0 -0.0123854 -0.17014 0 -0.0025 -2.38757e-16 0 -0.00909125 -0.113167 0 -0.00414921 -0.0566796 0 -0.0173094 0.169272 0 -0.00414921 0.0566796 0 -0.00909125 0.113167 0 -0.0123854 0.17014 0 0.0025 -2.39982e-16 0 0.000842333 0.0569703 0 -0.00412506 0.113748 0 -0.00412506 -0.113748 0 0.000842333 -0.0569703 0 -0.0123854 -0.17014 0 -0.0123854 -0.17014 0.01 0.0025 -2.39982e-16 0.01 -0.00412506 -0.113748 0.01 0.000842333 -0.0569703 0.01 0.0025 -2.39982e-16 0 -0.00412506 -0.113748 0 0.000842333 -0.0569703 0 -0.0173094 -0.169272 0.01 -0.0123854 -0.17014 0.01 -0.0025 -2.38757e-16 0.01 -0.00909125 -0.113167 0.01 -0.00414921 -0.0566796 0.01 -0.0173094 0.169272 0.01 -0.00414921 0.0566796 0.01 -0.00909125 0.113167 0.01 -0.0123854 0.17014 0.01 0.0025 -2.39982e-16 0.01 0.000842333 0.0569703 0.01 -0.00412506 0.113748 0.01 -0.00412506 -0.113748 0.01 0.000842333 -0.0569703 0.01 -0.0173094 -0.169272 0 -0.0173094 -0.169272 0.01 -0.0025 -2.38757e-16 0.01 -0.00909125 -0.113167 0.01 -0.00414921 -0.0566796 0.01 -0.0025 -2.38757e-16 0 -0.00909125 -0.113167 0 -0.00414921 -0.0566796 0 -0.0025 -2.38757e-16 0 -0.0025 -2.38757e-16 0.01 -0.0173094 0.169272 0.01 -0.00414921 0.0566796 0.01 -0.00909125 0.113167 0.01 -0.0173094 0.169272 0 -0.00414921 0.0566796 0 -0.00909125 0.113167 0 -0.0173094 0.169272 0 -0.0123854 0.17014 0 -0.0123854 0.17014 0.01 -0.0173094 0.169272 0.01 0.0025 -2.39982e-16 0 0.0025 -2.39982e-16 0.01 -0.0123854 0.17014 0.01 0.000842333 0.0569703 0.01 -0.00412506 0.113748 0.01 -0.0123854 0.17014 0 0.000842333 0.0569703 0 -0.00412506 0.113748 0 + + + 0 3 2 1 0 2 16 4 5 16 7 4 17 8 7 17 7 16 6 8 17 13 6 17 10 6 13 14 10 13 11 10 14 15 11 14 9 11 15 12 9 15 21 19 18 21 18 24 22 24 25 22 21 24 20 25 23 20 22 25 38 26 27 38 29 26 39 30 29 39 29 38 28 30 39 35 28 39 32 28 35 36 32 35 33 32 36 37 33 36 31 33 37 34 31 37 43 41 40 43 40 46 44 46 47 44 43 46 42 47 45 42 44 47 51 49 48 51 48 54 52 54 55 52 51 54 50 55 53 50 52 55 56 59 58 57 56 58 63 61 60 63 60 66 64 66 67 64 63 66 62 67 65 62 64 67 + 3 6 9 12 15 18 21 24 27 30 33 36 39 42 45 48 51 54 57 60 63 66 69 72 75 78 81 84 87 90 93 96 99 102 105 108 111 114 117 120 123 126 129 132 135 138 141 144 147 150 153 156 + + + + + -0.0179323 -0.176392 0 -0.0130082 -0.17726 0 -0.0130082 -0.17726 0.01 -0.0179323 -0.176392 0.01 -0.0179323 -0.176392 0 -0.0130082 -0.17726 0 -0.0025 -2.48799e-16 0 -0.00936848 -0.117927 0 -0.00421857 -0.0590635 0 -0.0179323 0.176392 0 -0.00421857 0.0590635 0 -0.00936848 0.117927 0 -0.0130082 0.17726 0 0.0025 -2.50024e-16 0 0.000772968 0.0593542 0 -0.00440228 0.118508 0 -0.00440228 -0.118508 0 0.000772968 -0.0593542 0 -0.0130082 -0.17726 0 -0.0130082 -0.17726 0.01 0.0025 -2.50024e-16 0.01 -0.00440228 -0.118508 0.01 0.000772968 -0.0593542 0.01 0.0025 -2.50024e-16 0 -0.00440228 -0.118508 0 0.000772968 -0.0593542 0 -0.0179323 -0.176392 0.01 -0.0130082 -0.17726 0.01 -0.0025 -2.48799e-16 0.01 -0.00936848 -0.117927 0.01 -0.00421857 -0.0590635 0.01 -0.0179323 0.176392 0.01 -0.00421857 0.0590635 0.01 -0.00936848 0.117927 0.01 -0.0130082 0.17726 0.01 0.0025 -2.50024e-16 0.01 0.000772968 0.0593542 0.01 -0.00440228 0.118508 0.01 -0.00440228 -0.118508 0.01 0.000772968 -0.0593542 0.01 -0.0179323 -0.176392 0 -0.0179323 -0.176392 0.01 -0.0025 -2.48799e-16 0.01 -0.00936848 -0.117927 0.01 -0.00421857 -0.0590635 0.01 -0.0025 -2.48799e-16 0 -0.00936848 -0.117927 0 -0.00421857 -0.0590635 0 -0.0025 -2.48799e-16 0 -0.0025 -2.48799e-16 0.01 -0.0179323 0.176392 0.01 -0.00421857 0.0590635 0.01 -0.00936848 0.117927 0.01 -0.0179323 0.176392 0 -0.00421857 0.0590635 0 -0.00936848 0.117927 0 -0.0179323 0.176392 0 -0.0130082 0.17726 0 -0.0130082 0.17726 0.01 -0.0179323 0.176392 0.01 0.0025 -2.50024e-16 0 0.0025 -2.50024e-16 0.01 -0.0130082 0.17726 0.01 0.000772968 0.0593542 0.01 -0.00440228 0.118508 0.01 -0.0130082 0.17726 0 0.000772968 0.0593542 0 -0.00440228 0.118508 0 + + + 0 3 2 1 0 2 16 4 5 16 7 4 17 8 7 17 7 16 6 8 17 13 6 17 10 6 13 14 10 13 11 10 14 15 11 14 12 9 11 12 11 15 21 19 18 21 18 24 22 24 25 22 21 24 20 25 23 20 22 25 38 26 27 38 29 26 39 30 29 39 29 38 28 30 39 35 28 39 32 28 35 36 32 35 33 32 36 37 33 36 34 31 33 34 33 37 43 41 40 43 40 46 44 46 47 44 43 46 42 47 45 42 44 47 51 49 48 51 48 54 52 54 55 52 51 54 50 55 53 50 52 55 56 59 58 57 56 58 63 61 60 63 60 66 64 66 67 64 63 66 62 67 65 62 64 67 + 3 6 9 12 15 18 21 24 27 30 33 36 39 42 45 48 51 54 57 60 63 66 69 72 75 78 81 84 87 90 93 96 99 102 105 108 111 114 117 120 123 126 129 132 135 138 141 144 147 150 153 156 + + + + + -0.0179247 -0.176305 0 -0.0130006 -0.177173 0 -0.0130006 -0.177173 0.01 -0.0179247 -0.176305 0.01 -0.0179247 -0.176305 0 -0.0130006 -0.177173 0 -0.0025 -2.48677e-16 0 -0.0093651 -0.117869 0 -0.00421773 -0.0590344 0 -0.0179247 0.176305 0 -0.00421773 0.0590344 0 -0.0093651 0.117869 0 -0.0130006 0.177173 0 0.0025 -2.49901e-16 0 0.000773814 0.0593252 0 -0.0043989 0.11845 0 -0.0043989 -0.11845 0 0.000773814 -0.0593252 0 -0.0130006 -0.177173 0 -0.0130006 -0.177173 0.01 0.0025 -2.49901e-16 0.01 -0.0043989 -0.11845 0.01 0.000773814 -0.0593252 0.01 0.0025 -2.49901e-16 0 -0.0043989 -0.11845 0 0.000773814 -0.0593252 0 -0.0179247 -0.176305 0.01 -0.0130006 -0.177173 0.01 -0.0025 -2.48677e-16 0.01 -0.0093651 -0.117869 0.01 -0.00421773 -0.0590344 0.01 -0.0179247 0.176305 0.01 -0.00421773 0.0590344 0.01 -0.0093651 0.117869 0.01 -0.0130006 0.177173 0.01 0.0025 -2.49901e-16 0.01 0.000773814 0.0593252 0.01 -0.0043989 0.11845 0.01 -0.0043989 -0.11845 0.01 0.000773814 -0.0593252 0.01 -0.0179247 -0.176305 0 -0.0179247 -0.176305 0.01 -0.0025 -2.48677e-16 0.01 -0.0093651 -0.117869 0.01 -0.00421773 -0.0590344 0.01 -0.0025 -2.48677e-16 0 -0.0093651 -0.117869 0 -0.00421773 -0.0590344 0 -0.0025 -2.48677e-16 0 -0.0025 -2.48677e-16 0.01 -0.0179247 0.176305 0.01 -0.00421773 0.0590344 0.01 -0.0093651 0.117869 0.01 -0.0179247 0.176305 0 -0.00421773 0.0590344 0 -0.0093651 0.117869 0 -0.0179247 0.176305 0 -0.0130006 0.177173 0 -0.0130006 0.177173 0.01 -0.0179247 0.176305 0.01 0.0025 -2.49901e-16 0 0.0025 -2.49901e-16 0.01 -0.0130006 0.177173 0.01 0.000773814 0.0593252 0.01 -0.0043989 0.11845 0.01 -0.0130006 0.177173 0 0.000773814 0.0593252 0 -0.0043989 0.11845 0 + + + 0 3 2 1 0 2 16 4 5 16 7 4 17 8 7 17 7 16 6 8 17 13 6 17 10 6 13 14 10 13 15 11 10 15 10 14 12 9 11 12 11 15 21 19 18 21 18 24 22 24 25 22 21 24 20 25 23 20 22 25 38 26 27 38 29 26 39 30 29 39 29 38 28 30 39 35 28 39 32 28 35 36 32 35 37 33 32 37 32 36 34 31 33 34 33 37 43 41 40 43 40 46 44 46 47 44 43 46 42 47 45 42 44 47 51 49 48 51 48 54 52 54 55 52 51 54 50 55 53 50 52 55 56 59 58 57 56 58 63 61 60 63 60 66 64 66 67 64 63 66 62 67 65 62 64 67 + 3 6 9 12 15 18 21 24 27 30 33 36 39 42 45 48 51 54 57 60 63 66 69 72 75 78 81 84 87 90 93 96 99 102 105 108 111 114 117 120 123 126 129 132 135 138 141 144 147 150 153 156 + + + + + -0.0180553 -0.177798 0 -0.0131313 -0.178667 0 -0.0131313 -0.178667 0.01 -0.0180553 -0.177798 0.01 -0.0180553 -0.177798 0 -0.0131313 -0.178667 0 -0.0025 -2.50783e-16 0 -0.00942325 -0.118868 0 -0.00423228 -0.0595345 0 -0.0180553 0.177798 0 -0.00423228 0.0595345 0 -0.00942325 0.118868 0 -0.0131313 0.178667 0 0.0025 -2.52008e-16 0 0.000759264 0.0598252 0 -0.00445705 0.119448 0 -0.00445705 -0.119448 0 0.000759264 -0.0598252 0 -0.0131313 -0.178667 0 -0.0131313 -0.178667 0.01 0.0025 -2.52008e-16 0.01 -0.00445705 -0.119448 0.01 0.000759264 -0.0598252 0.01 0.0025 -2.52008e-16 0 -0.00445705 -0.119448 0 0.000759264 -0.0598252 0 -0.0180553 -0.177798 0.01 -0.0131313 -0.178667 0.01 -0.0025 -2.50783e-16 0.01 -0.00942325 -0.118868 0.01 -0.00423228 -0.0595345 0.01 -0.0180553 0.177798 0.01 -0.00423228 0.0595345 0.01 -0.00942325 0.118868 0.01 -0.0131313 0.178667 0.01 0.0025 -2.52008e-16 0.01 0.000759264 0.0598252 0.01 -0.00445705 0.119448 0.01 -0.00445705 -0.119448 0.01 0.000759264 -0.0598252 0.01 -0.0180553 -0.177798 0 -0.0180553 -0.177798 0.01 -0.0025 -2.50783e-16 0.01 -0.00942325 -0.118868 0.01 -0.00423228 -0.0595345 0.01 -0.0025 -2.50783e-16 0 -0.00942325 -0.118868 0 -0.00423228 -0.0595345 0 -0.0025 -2.50783e-16 0 -0.0025 -2.50783e-16 0.01 -0.0180553 0.177798 0.01 -0.00423228 0.0595345 0.01 -0.00942325 0.118868 0.01 -0.0180553 0.177798 0 -0.00423228 0.0595345 0 -0.00942325 0.118868 0 -0.0180553 0.177798 0 -0.0131313 0.178667 0 -0.0131313 0.178667 0.01 -0.0180553 0.177798 0.01 0.0025 -2.52008e-16 0 0.0025 -2.52008e-16 0.01 -0.0131313 0.178667 0.01 0.000759264 0.0598252 0.01 -0.00445705 0.119448 0.01 -0.0131313 0.178667 0 0.000759264 0.0598252 0 -0.00445705 0.119448 0 + + + 0 3 2 1 0 2 16 4 5 16 7 4 17 8 7 17 7 16 6 8 17 13 6 17 10 6 13 14 10 13 11 10 14 15 11 14 9 11 15 12 9 15 21 19 18 21 18 24 22 24 25 22 21 24 20 25 23 20 22 25 38 26 27 38 29 26 39 30 29 39 29 38 28 30 39 35 28 39 32 28 35 36 32 35 33 32 36 37 33 36 31 33 37 34 31 37 43 41 40 43 40 46 44 46 47 44 43 46 42 47 45 42 44 47 51 49 48 51 48 54 52 54 55 52 51 54 50 55 53 50 52 55 56 59 58 57 56 58 63 61 60 63 60 66 64 66 67 64 63 66 62 67 65 62 64 67 + 3 6 9 12 15 18 21 24 27 30 33 36 39 42 45 48 51 54 57 60 63 66 69 72 75 78 81 84 87 90 93 96 99 102 105 108 111 114 117 120 123 126 129 132 135 138 141 144 147 150 153 156 + + + + + -0.0180477 -0.177712 0 -0.0131237 -0.17858 0 -0.0131237 -0.17858 0.01 -0.0180477 -0.177712 0.01 -0.0180477 -0.177712 0 -0.0131237 -0.17858 0 -0.0025 -2.50661e-16 0 -0.00941986 -0.118809 0 -0.00423143 -0.0595054 0 -0.0180477 0.177712 0 -0.00423143 0.0595054 0 -0.00941986 0.118809 0 -0.0131237 0.17858 0 0.0025 -2.51885e-16 0 0.00076011 0.0597961 0 -0.00445367 0.11939 0 -0.00445367 -0.11939 0 0.00076011 -0.0597961 0 -0.0131237 -0.17858 0 -0.0131237 -0.17858 0.01 0.0025 -2.51885e-16 0.01 -0.00445367 -0.11939 0.01 0.00076011 -0.0597961 0.01 0.0025 -2.51885e-16 0 -0.00445367 -0.11939 0 0.00076011 -0.0597961 0 -0.0180477 -0.177712 0.01 -0.0131237 -0.17858 0.01 -0.0025 -2.50661e-16 0.01 -0.00941986 -0.118809 0.01 -0.00423143 -0.0595054 0.01 -0.0180477 0.177712 0.01 -0.00423143 0.0595054 0.01 -0.00941986 0.118809 0.01 -0.0131237 0.17858 0.01 0.0025 -2.51885e-16 0.01 0.00076011 0.0597961 0.01 -0.00445367 0.11939 0.01 -0.00445367 -0.11939 0.01 0.00076011 -0.0597961 0.01 -0.0180477 -0.177712 0 -0.0180477 -0.177712 0.01 -0.0025 -2.50661e-16 0.01 -0.00941986 -0.118809 0.01 -0.00423143 -0.0595054 0.01 -0.0025 -2.50661e-16 0 -0.00941986 -0.118809 0 -0.00423143 -0.0595054 0 -0.0025 -2.50661e-16 0 -0.0025 -2.50661e-16 0.01 -0.0180477 0.177712 0.01 -0.00423143 0.0595054 0.01 -0.00941986 0.118809 0.01 -0.0180477 0.177712 0 -0.00423143 0.0595054 0 -0.00941986 0.118809 0 -0.0180477 0.177712 0 -0.0131237 0.17858 0 -0.0131237 0.17858 0.01 -0.0180477 0.177712 0.01 0.0025 -2.51885e-16 0 0.0025 -2.51885e-16 0.01 -0.0131237 0.17858 0.01 0.00076011 0.0597961 0.01 -0.00445367 0.11939 0.01 -0.0131237 0.17858 0 0.00076011 0.0597961 0 -0.00445367 0.11939 0 + + + 0 3 2 1 0 2 16 4 5 16 7 4 8 7 16 17 8 16 6 8 17 13 6 17 10 6 13 14 10 13 15 11 10 15 10 14 12 9 11 12 11 15 21 19 18 21 18 24 22 24 25 22 21 24 20 25 23 20 22 25 38 26 27 38 29 26 30 29 38 39 30 38 28 30 39 35 28 39 32 28 35 36 32 35 37 33 32 37 32 36 34 31 33 34 33 37 43 41 40 43 40 46 44 46 47 44 43 46 42 47 45 42 44 47 51 49 48 51 48 54 52 54 55 52 51 54 50 55 53 50 52 55 56 59 58 57 56 58 63 61 60 63 60 66 64 66 67 64 63 66 62 67 65 62 64 67 + 3 6 9 12 15 18 21 24 27 30 33 36 39 42 45 48 51 54 57 60 63 66 69 72 75 78 81 84 87 90 93 96 99 102 105 108 111 114 117 120 123 126 129 132 135 138 141 144 147 150 153 156 + + + + + -0.0181784 -0.179205 0 -0.0132544 -0.180073 0 -0.0132544 -0.180073 0.01 -0.0181784 -0.179205 0.01 -0.0181784 -0.179205 0 -0.0132544 -0.180073 0 -0.0025 -2.52767e-16 0 -0.00947801 -0.119808 0 -0.00424598 -0.0600055 0 -0.0181784 0.179205 0 -0.00424598 0.0600055 0 -0.00947801 0.119808 0 -0.0132544 0.180073 0 0.0025 -2.53992e-16 0 0.00074556 0.0602962 0 -0.00451182 0.120388 0 -0.00451182 -0.120388 0 0.00074556 -0.0602962 0 -0.0132544 -0.180073 0 -0.0132544 -0.180073 0.01 0.0025 -2.53992e-16 0.01 -0.00451182 -0.120388 0.01 0.00074556 -0.0602962 0.01 0.0025 -2.53992e-16 0 -0.00451182 -0.120388 0 0.00074556 -0.0602962 0 -0.0181784 -0.179205 0.01 -0.0132544 -0.180073 0.01 -0.0025 -2.52767e-16 0.01 -0.00947801 -0.119808 0.01 -0.00424598 -0.0600055 0.01 -0.0181784 0.179205 0.01 -0.00424598 0.0600055 0.01 -0.00947801 0.119808 0.01 -0.0132544 0.180073 0.01 0.0025 -2.53992e-16 0.01 0.00074556 0.0602962 0.01 -0.00451182 0.120388 0.01 -0.00451182 -0.120388 0.01 0.00074556 -0.0602962 0.01 -0.0181784 -0.179205 0 -0.0181784 -0.179205 0.01 -0.0025 -2.52767e-16 0.01 -0.00947801 -0.119808 0.01 -0.00424598 -0.0600055 0.01 -0.0025 -2.52767e-16 0 -0.00947801 -0.119808 0 -0.00424598 -0.0600055 0 -0.0025 -2.52767e-16 0 -0.0025 -2.52767e-16 0.01 -0.0181784 0.179205 0.01 -0.00424598 0.0600055 0.01 -0.00947801 0.119808 0.01 -0.0181784 0.179205 0 -0.00424598 0.0600055 0 -0.00947801 0.119808 0 -0.0181784 0.179205 0 -0.0132544 0.180073 0 -0.0132544 0.180073 0.01 -0.0181784 0.179205 0.01 0.0025 -2.53992e-16 0 0.0025 -2.53992e-16 0.01 -0.0132544 0.180073 0.01 0.00074556 0.0602962 0.01 -0.00451182 0.120388 0.01 -0.0132544 0.180073 0 0.00074556 0.0602962 0 -0.00451182 0.120388 0 + + + 0 3 2 1 0 2 16 4 5 16 7 4 8 7 16 17 8 16 6 8 17 13 6 17 10 6 13 14 10 13 15 11 10 15 10 14 9 11 15 12 9 15 21 19 18 21 18 24 22 24 25 22 21 24 20 25 23 20 22 25 38 26 27 38 29 26 30 29 38 39 30 38 28 30 39 35 28 39 32 28 35 36 32 35 37 33 32 37 32 36 31 33 37 34 31 37 43 41 40 43 40 46 44 46 47 44 43 46 42 47 45 42 44 47 51 49 48 51 48 54 52 54 55 52 51 54 50 55 53 50 52 55 56 59 58 57 56 58 63 61 60 63 60 66 64 66 67 64 63 66 62 67 65 62 64 67 + 3 6 9 12 15 18 21 24 27 30 33 36 39 42 45 48 51 54 57 60 63 66 69 72 75 78 81 84 87 90 93 96 99 102 105 108 111 114 117 120 123 126 129 132 135 138 141 144 147 150 153 156 + + + + + -0.0181708 -0.179118 0 -0.0132468 -0.179986 0 -0.0132468 -0.179986 0.01 -0.0181708 -0.179118 0.01 -0.0181708 -0.179118 0 -0.0132468 -0.179986 0 -0.0025 -2.52645e-16 0 -0.00947463 -0.11975 0 -0.00424513 -0.0599764 0 -0.0181708 0.179118 0 -0.00424513 0.0599764 0 -0.00947463 0.11975 0 -0.0132468 0.179986 0 0.0025 -2.53869e-16 0 0.000746406 0.0602671 0 -0.00450844 0.12033 0 -0.00450844 -0.12033 0 0.000746406 -0.0602671 0 -0.0132468 -0.179986 0 -0.0132468 -0.179986 0.01 0.0025 -2.53869e-16 0.01 -0.00450844 -0.12033 0.01 0.000746406 -0.0602671 0.01 0.0025 -2.53869e-16 0 -0.00450844 -0.12033 0 0.000746406 -0.0602671 0 -0.0181708 -0.179118 0.01 -0.0132468 -0.179986 0.01 -0.0025 -2.52645e-16 0.01 -0.00947463 -0.11975 0.01 -0.00424513 -0.0599764 0.01 -0.0181708 0.179118 0.01 -0.00424513 0.0599764 0.01 -0.00947463 0.11975 0.01 -0.0132468 0.179986 0.01 0.0025 -2.53869e-16 0.01 0.000746406 0.0602671 0.01 -0.00450844 0.12033 0.01 -0.00450844 -0.12033 0.01 0.000746406 -0.0602671 0.01 -0.0181708 -0.179118 0 -0.0181708 -0.179118 0.01 -0.0025 -2.52645e-16 0.01 -0.00947463 -0.11975 0.01 -0.00424513 -0.0599764 0.01 -0.0025 -2.52645e-16 0 -0.00947463 -0.11975 0 -0.00424513 -0.0599764 0 -0.0025 -2.52645e-16 0 -0.0025 -2.52645e-16 0.01 -0.0181708 0.179118 0.01 -0.00424513 0.0599764 0.01 -0.00947463 0.11975 0.01 -0.0181708 0.179118 0 -0.00424513 0.0599764 0 -0.00947463 0.11975 0 -0.0181708 0.179118 0 -0.0132468 0.179986 0 -0.0132468 0.179986 0.01 -0.0181708 0.179118 0.01 0.0025 -2.53869e-16 0 0.0025 -2.53869e-16 0.01 -0.0132468 0.179986 0.01 0.000746406 0.0602671 0.01 -0.00450844 0.12033 0.01 -0.0132468 0.179986 0 0.000746406 0.0602671 0 -0.00450844 0.12033 0 + + + 0 3 2 1 0 2 16 4 5 16 7 4 17 8 7 17 7 16 6 8 17 13 6 17 10 6 13 14 10 13 15 11 10 15 10 14 12 9 11 12 11 15 21 19 18 21 18 24 22 24 25 22 21 24 20 25 23 20 22 25 38 26 27 38 29 26 39 30 29 39 29 38 28 30 39 35 28 39 32 28 35 36 32 35 37 33 32 37 32 36 34 31 33 34 33 37 43 41 40 43 40 46 44 46 47 44 43 46 42 47 45 42 44 47 51 49 48 51 48 54 52 54 55 52 51 54 50 55 53 50 52 55 56 59 58 57 56 58 63 61 60 63 60 66 64 66 67 64 63 66 62 67 65 62 64 67 + 3 6 9 12 15 18 21 24 27 30 33 36 39 42 45 48 51 54 57 60 63 66 69 72 75 78 81 84 87 90 93 96 99 102 105 108 111 114 117 120 123 126 129 132 135 138 141 144 147 150 153 156 + + + + + -0.0183015 -0.180611 0 -0.0133774 -0.18148 0 -0.0133774 -0.18148 0.01 -0.0183015 -0.180611 0.01 -0.0183015 -0.180611 0 -0.0133774 -0.18148 0 -0.0025 -2.54751e-16 0 -0.00953278 -0.120748 0 -0.00425968 -0.0604764 0 -0.0183015 0.180611 0 -0.00425968 0.0604764 0 -0.00953278 0.120748 0 -0.0133774 0.18148 0 0.0025 -2.55976e-16 0 0.000731856 0.0607672 0 -0.00456659 0.121329 0 -0.00456659 -0.121329 0 0.000731856 -0.0607672 0 -0.0133774 -0.18148 0 -0.0133774 -0.18148 0.01 0.0025 -2.55976e-16 0.01 -0.00456659 -0.121329 0.01 0.000731856 -0.0607672 0.01 0.0025 -2.55976e-16 0 -0.00456659 -0.121329 0 0.000731856 -0.0607672 0 -0.0183015 -0.180611 0.01 -0.0133774 -0.18148 0.01 -0.0025 -2.54751e-16 0.01 -0.00953278 -0.120748 0.01 -0.00425968 -0.0604764 0.01 -0.0183015 0.180611 0.01 -0.00425968 0.0604764 0.01 -0.00953278 0.120748 0.01 -0.0133774 0.18148 0.01 0.0025 -2.55976e-16 0.01 0.000731856 0.0607672 0.01 -0.00456659 0.121329 0.01 -0.00456659 -0.121329 0.01 0.000731856 -0.0607672 0.01 -0.0183015 -0.180611 0 -0.0183015 -0.180611 0.01 -0.0025 -2.54751e-16 0.01 -0.00953278 -0.120748 0.01 -0.00425968 -0.0604764 0.01 -0.0025 -2.54751e-16 0 -0.00953278 -0.120748 0 -0.00425968 -0.0604764 0 -0.0025 -2.54751e-16 0 -0.0025 -2.54751e-16 0.01 -0.0183015 0.180611 0.01 -0.00425968 0.0604764 0.01 -0.00953278 0.120748 0.01 -0.0183015 0.180611 0 -0.00425968 0.0604764 0 -0.00953278 0.120748 0 -0.0183015 0.180611 0 -0.0133774 0.18148 0 -0.0133774 0.18148 0.01 -0.0183015 0.180611 0.01 0.0025 -2.55976e-16 0 0.0025 -2.55976e-16 0.01 -0.0133774 0.18148 0.01 0.000731856 0.0607672 0.01 -0.00456659 0.121329 0.01 -0.0133774 0.18148 0 0.000731856 0.0607672 0 -0.00456659 0.121329 0 + + + 0 3 2 1 0 2 7 4 5 16 7 5 17 8 7 17 7 16 6 8 17 13 6 17 10 6 13 14 10 13 15 11 10 15 10 14 12 9 11 12 11 15 21 19 18 21 18 24 22 24 25 22 21 24 20 25 23 20 22 25 29 26 27 38 29 27 39 30 29 39 29 38 28 30 39 35 28 39 32 28 35 36 32 35 37 33 32 37 32 36 34 31 33 34 33 37 43 41 40 43 40 46 44 46 47 44 43 46 42 47 45 42 44 47 51 49 48 51 48 54 52 54 55 52 51 54 50 55 53 50 52 55 56 59 58 57 56 58 63 61 60 63 60 66 64 66 67 64 63 66 62 67 65 62 64 67 + 3 6 9 12 15 18 21 24 27 30 33 36 39 42 45 48 51 54 57 60 63 66 69 72 75 78 81 84 87 90 93 96 99 102 105 108 111 114 117 120 123 126 129 132 135 138 141 144 147 150 153 156 + + + + + -0.0182954 -0.180542 0 -0.0133713 -0.18141 0 -0.0133713 -0.18141 0.01 -0.0182954 -0.180542 0.01 -0.0182954 -0.180542 0 -0.0133713 -0.18141 0 -0.0025 -2.54653e-16 0 -0.00953008 -0.120702 0 -0.00425901 -0.0604532 0 -0.0182954 0.180542 0 -0.00425901 0.0604532 0 -0.00953008 0.120702 0 -0.0133713 0.18141 0 0.0025 -2.55878e-16 0 0.000732533 0.0607439 0 -0.00456389 0.121282 0 -0.00456389 -0.121282 0 0.000732533 -0.0607439 0 -0.0133713 -0.18141 0 -0.0133713 -0.18141 0.01 0.0025 -2.55878e-16 0.01 -0.00456389 -0.121282 0.01 0.000732533 -0.0607439 0.01 0.0025 -2.55878e-16 0 -0.00456389 -0.121282 0 0.000732533 -0.0607439 0 -0.0182954 -0.180542 0.01 -0.0133713 -0.18141 0.01 -0.0025 -2.54653e-16 0.01 -0.00953008 -0.120702 0.01 -0.00425901 -0.0604532 0.01 -0.0182954 0.180542 0.01 -0.00425901 0.0604532 0.01 -0.00953008 0.120702 0.01 -0.0133713 0.18141 0.01 0.0025 -2.55878e-16 0.01 0.000732533 0.0607439 0.01 -0.00456389 0.121282 0.01 -0.00456389 -0.121282 0.01 0.000732533 -0.0607439 0.01 -0.0182954 -0.180542 0 -0.0182954 -0.180542 0.01 -0.0025 -2.54653e-16 0.01 -0.00953008 -0.120702 0.01 -0.00425901 -0.0604532 0.01 -0.0025 -2.54653e-16 0 -0.00953008 -0.120702 0 -0.00425901 -0.0604532 0 -0.0025 -2.54653e-16 0 -0.0025 -2.54653e-16 0.01 -0.0182954 0.180542 0.01 -0.00425901 0.0604532 0.01 -0.00953008 0.120702 0.01 -0.0182954 0.180542 0 -0.00425901 0.0604532 0 -0.00953008 0.120702 0 -0.0182954 0.180542 0 -0.0133713 0.18141 0 -0.0133713 0.18141 0.01 -0.0182954 0.180542 0.01 0.0025 -2.55878e-16 0 0.0025 -2.55878e-16 0.01 -0.0133713 0.18141 0.01 0.000732533 0.0607439 0.01 -0.00456389 0.121282 0.01 -0.0133713 0.18141 0 0.000732533 0.0607439 0 -0.00456389 0.121282 0 + + + 0 3 2 1 0 2 7 4 5 16 7 5 8 7 16 17 8 16 6 8 17 13 6 17 10 6 13 14 10 13 11 10 14 15 11 14 12 9 11 12 11 15 21 19 18 21 18 24 22 24 25 22 21 24 20 25 23 20 22 25 29 26 27 38 29 27 30 29 38 39 30 38 28 30 39 35 28 39 32 28 35 36 32 35 33 32 36 37 33 36 34 31 33 34 33 37 43 41 40 43 40 46 44 46 47 44 43 46 42 47 45 42 44 47 51 49 48 51 48 54 52 54 55 52 51 54 50 55 53 50 52 55 56 59 58 57 56 58 63 61 60 63 60 66 64 66 67 64 63 66 62 67 65 62 64 67 + 3 6 9 12 15 18 21 24 27 30 33 36 39 42 45 48 51 54 57 60 63 66 69 72 75 78 81 84 87 90 93 96 99 102 105 108 111 114 117 120 123 126 129 132 135 138 141 144 147 150 153 156 + + + + + -0.0184245 -0.182018 0 -0.0135005 -0.182886 0 -0.0135005 -0.182886 0.01 -0.0184245 -0.182018 0.01 -0.0184245 -0.182018 0 -0.0135005 -0.182886 0 -0.0025 -2.56735e-16 0 -0.00958755 -0.121689 0 -0.00427339 -0.0609474 0 -0.0184245 0.182018 0 -0.00427339 0.0609474 0 -0.00958755 0.121689 0 -0.0135005 0.182886 0 0.0025 -2.5796e-16 0 0.000718152 0.0612381 0 -0.00462136 0.122269 0 -0.00462136 -0.122269 0 0.000718152 -0.0612381 0 -0.0135005 -0.182886 0 -0.0135005 -0.182886 0.01 0.0025 -2.5796e-16 0.01 -0.00462136 -0.122269 0.01 0.000718152 -0.0612381 0.01 0.0025 -2.5796e-16 0 -0.00462136 -0.122269 0 0.000718152 -0.0612381 0 -0.0184245 -0.182018 0.01 -0.0135005 -0.182886 0.01 -0.0025 -2.56735e-16 0.01 -0.00958755 -0.121689 0.01 -0.00427339 -0.0609474 0.01 -0.0184245 0.182018 0.01 -0.00427339 0.0609474 0.01 -0.00958755 0.121689 0.01 -0.0135005 0.182886 0.01 0.0025 -2.5796e-16 0.01 0.000718152 0.0612381 0.01 -0.00462136 0.122269 0.01 -0.00462136 -0.122269 0.01 0.000718152 -0.0612381 0.01 -0.0184245 -0.182018 0 -0.0184245 -0.182018 0.01 -0.0025 -2.56735e-16 0.01 -0.00958755 -0.121689 0.01 -0.00427339 -0.0609474 0.01 -0.0025 -2.56735e-16 0 -0.00958755 -0.121689 0 -0.00427339 -0.0609474 0 -0.0025 -2.56735e-16 0 -0.0025 -2.56735e-16 0.01 -0.0184245 0.182018 0.01 -0.00427339 0.0609474 0.01 -0.00958755 0.121689 0.01 -0.0184245 0.182018 0 -0.00427339 0.0609474 0 -0.00958755 0.121689 0 -0.0184245 0.182018 0 -0.0135005 0.182886 0 -0.0135005 0.182886 0.01 -0.0184245 0.182018 0.01 0.0025 -2.5796e-16 0 0.0025 -2.5796e-16 0.01 -0.0135005 0.182886 0.01 0.000718152 0.0612381 0.01 -0.00462136 0.122269 0.01 -0.0135005 0.182886 0 0.000718152 0.0612381 0 -0.00462136 0.122269 0 + + + 0 3 2 1 0 2 16 4 5 16 7 4 17 8 7 17 7 16 6 8 17 13 6 17 10 6 13 14 10 13 15 11 10 15 10 14 12 9 11 12 11 15 21 19 18 21 18 24 22 24 25 22 21 24 20 25 23 20 22 25 38 26 27 38 29 26 39 30 29 39 29 38 28 30 39 35 28 39 32 28 35 36 32 35 37 33 32 37 32 36 34 31 33 34 33 37 43 41 40 43 40 46 44 46 47 44 43 46 42 47 45 42 44 47 51 49 48 51 48 54 52 54 55 52 51 54 50 55 53 50 52 55 56 59 58 57 56 58 63 61 60 63 60 66 64 66 67 64 63 66 62 67 65 62 64 67 + 3 6 9 12 15 18 21 24 27 30 33 36 39 42 45 48 51 54 57 60 63 66 69 72 75 78 81 84 87 90 93 96 99 102 105 108 111 114 117 120 123 126 129 132 135 138 141 144 147 150 153 156 + + + + + -0.0184184 -0.181949 0 -0.0134944 -0.182817 0 -0.0134944 -0.182817 0.01 -0.0184184 -0.181949 0.01 -0.0184184 -0.181949 0 -0.0134944 -0.182817 0 -0.0025 -2.56637e-16 0 -0.00958485 -0.121642 0 -0.00427271 -0.0609242 0 -0.0184184 0.181949 0 -0.00427271 0.0609242 0 -0.00958485 0.121642 0 -0.0134944 0.182817 0 0.0025 -2.57862e-16 0 0.000718829 0.0612149 0 -0.00461866 0.122223 0 -0.00461866 -0.122223 0 0.000718829 -0.0612149 0 -0.0134944 -0.182817 0 -0.0134944 -0.182817 0.01 0.0025 -2.57862e-16 0.01 -0.00461866 -0.122223 0.01 0.000718829 -0.0612149 0.01 0.0025 -2.57862e-16 0 -0.00461866 -0.122223 0 0.000718829 -0.0612149 0 -0.0184184 -0.181949 0.01 -0.0134944 -0.182817 0.01 -0.0025 -2.56637e-16 0.01 -0.00958485 -0.121642 0.01 -0.00427271 -0.0609242 0.01 -0.0184184 0.181949 0.01 -0.00427271 0.0609242 0.01 -0.00958485 0.121642 0.01 -0.0134944 0.182817 0.01 0.0025 -2.57862e-16 0.01 0.000718829 0.0612149 0.01 -0.00461866 0.122223 0.01 -0.00461866 -0.122223 0.01 0.000718829 -0.0612149 0.01 -0.0184184 -0.181949 0 -0.0184184 -0.181949 0.01 -0.0025 -2.56637e-16 0.01 -0.00958485 -0.121642 0.01 -0.00427271 -0.0609242 0.01 -0.0025 -2.56637e-16 0 -0.00958485 -0.121642 0 -0.00427271 -0.0609242 0 -0.0025 -2.56637e-16 0 -0.0025 -2.56637e-16 0.01 -0.0184184 0.181949 0.01 -0.00427271 0.0609242 0.01 -0.00958485 0.121642 0.01 -0.0184184 0.181949 0 -0.00427271 0.0609242 0 -0.00958485 0.121642 0 -0.0184184 0.181949 0 -0.0134944 0.182817 0 -0.0134944 0.182817 0.01 -0.0184184 0.181949 0.01 0.0025 -2.57862e-16 0 0.0025 -2.57862e-16 0.01 -0.0134944 0.182817 0.01 0.000718829 0.0612149 0.01 -0.00461866 0.122223 0.01 -0.0134944 0.182817 0 0.000718829 0.0612149 0 -0.00461866 0.122223 0 + + + 0 3 2 1 0 2 16 4 5 16 7 4 17 8 7 17 7 16 6 8 17 13 6 17 10 6 13 14 10 13 15 11 10 15 10 14 12 9 11 12 11 15 21 19 18 21 18 24 22 24 25 22 21 24 20 25 23 20 22 25 38 26 27 38 29 26 39 30 29 39 29 38 28 30 39 35 28 39 32 28 35 36 32 35 37 33 32 37 32 36 34 31 33 34 33 37 43 41 40 43 40 46 44 46 47 44 43 46 42 47 45 42 44 47 51 49 48 51 48 54 52 54 55 52 51 54 50 55 53 50 52 55 56 59 58 57 56 58 63 61 60 63 60 66 64 66 67 64 63 66 62 67 65 62 64 67 + 3 6 9 12 15 18 21 24 27 30 33 36 39 42 45 48 51 54 57 60 63 66 69 72 75 78 81 84 87 90 93 96 99 102 105 108 111 114 117 120 123 126 129 132 135 138 141 144 147 150 153 156 + + + + + -0.0174385 -0.170748 0 -0.0125145 -0.171616 0 -0.0125145 -0.171616 0.01 -0.0174385 -0.170748 0.01 -0.0174385 -0.170748 0 -0.0125145 -0.171616 0 -0.0025 -2.40839e-16 0 -0.00914872 -0.114154 0 -0.00416359 -0.0571738 0 -0.0174385 0.170748 0 -0.00416359 0.0571738 0 -0.00914872 0.114154 0 -0.0125145 0.171616 0 0.0025 -2.42064e-16 0 0.000827953 0.0574645 0 -0.00418253 0.114735 0 -0.00418253 -0.114735 0 0.000827953 -0.0574645 0 -0.0125145 -0.171616 0 -0.0125145 -0.171616 0.01 0.0025 -2.42064e-16 0.01 -0.00418253 -0.114735 0.01 0.000827953 -0.0574645 0.01 0.0025 -2.42064e-16 0 -0.00418253 -0.114735 0 0.000827953 -0.0574645 0 -0.0174385 -0.170748 0.01 -0.0125145 -0.171616 0.01 -0.0025 -2.40839e-16 0.01 -0.00914872 -0.114154 0.01 -0.00416359 -0.0571738 0.01 -0.0174385 0.170748 0.01 -0.00416359 0.0571738 0.01 -0.00914872 0.114154 0.01 -0.0125145 0.171616 0.01 0.0025 -2.42064e-16 0.01 0.000827953 0.0574645 0.01 -0.00418253 0.114735 0.01 -0.00418253 -0.114735 0.01 0.000827953 -0.0574645 0.01 -0.0174385 -0.170748 0 -0.0174385 -0.170748 0.01 -0.0025 -2.40839e-16 0.01 -0.00914872 -0.114154 0.01 -0.00416359 -0.0571738 0.01 -0.0025 -2.40839e-16 0 -0.00914872 -0.114154 0 -0.00416359 -0.0571738 0 -0.0025 -2.40839e-16 0 -0.0025 -2.40839e-16 0.01 -0.0174385 0.170748 0.01 -0.00416359 0.0571738 0.01 -0.00914872 0.114154 0.01 -0.0174385 0.170748 0 -0.00416359 0.0571738 0 -0.00914872 0.114154 0 -0.0174385 0.170748 0 -0.0125145 0.171616 0 -0.0125145 0.171616 0.01 -0.0174385 0.170748 0.01 0.0025 -2.42064e-16 0 0.0025 -2.42064e-16 0.01 -0.0125145 0.171616 0.01 0.000827953 0.0574645 0.01 -0.00418253 0.114735 0.01 -0.0125145 0.171616 0 0.000827953 0.0574645 0 -0.00418253 0.114735 0 + + + 0 3 2 1 0 2 7 4 5 16 7 5 17 8 7 17 7 16 6 8 17 13 6 17 10 6 13 14 10 13 11 10 14 15 11 14 9 11 15 12 9 15 21 19 18 21 18 24 22 24 25 22 21 24 20 25 23 20 22 25 29 26 27 38 29 27 39 30 29 39 29 38 28 30 39 35 28 39 32 28 35 36 32 35 33 32 36 37 33 36 31 33 37 34 31 37 43 41 40 43 40 46 44 46 47 44 43 46 42 47 45 42 44 47 51 49 48 51 48 54 52 54 55 52 51 54 50 55 53 50 52 55 56 59 58 57 56 58 63 61 60 63 60 66 64 66 67 64 63 66 62 67 65 62 64 67 + 3 6 9 12 15 18 21 24 27 30 33 36 39 42 45 48 51 54 57 60 63 66 69 72 75 78 81 84 87 90 93 96 99 102 105 108 111 114 117 120 123 126 129 132 135 138 141 144 147 150 153 156 + + + + + -0.0174325 -0.170679 0 -0.0125084 -0.171547 0 -0.0125084 -0.171547 0.01 -0.0174325 -0.170679 0.01 -0.0174325 -0.170679 0 -0.0125084 -0.171547 0 -0.0025 -2.40741e-16 0 -0.00914602 -0.114108 0 -0.00416291 -0.0571506 0 -0.0174325 0.170679 0 -0.00416291 0.0571506 0 -0.00914602 0.114108 0 -0.0125084 0.171547 0 0.0025 -2.41966e-16 0 0.00082863 0.0574413 0 -0.00417983 0.114688 0 -0.00417983 -0.114688 0 0.00082863 -0.0574413 0 -0.0125084 -0.171547 0 -0.0125084 -0.171547 0.01 0.0025 -2.41966e-16 0.01 -0.00417983 -0.114688 0.01 0.00082863 -0.0574413 0.01 0.0025 -2.41966e-16 0 -0.00417983 -0.114688 0 0.00082863 -0.0574413 0 -0.0174325 -0.170679 0.01 -0.0125084 -0.171547 0.01 -0.0025 -2.40741e-16 0.01 -0.00914602 -0.114108 0.01 -0.00416291 -0.0571506 0.01 -0.0174325 0.170679 0.01 -0.00416291 0.0571506 0.01 -0.00914602 0.114108 0.01 -0.0125084 0.171547 0.01 0.0025 -2.41966e-16 0.01 0.00082863 0.0574413 0.01 -0.00417983 0.114688 0.01 -0.00417983 -0.114688 0.01 0.00082863 -0.0574413 0.01 -0.0174325 -0.170679 0 -0.0174325 -0.170679 0.01 -0.0025 -2.40741e-16 0.01 -0.00914602 -0.114108 0.01 -0.00416291 -0.0571506 0.01 -0.0025 -2.40741e-16 0 -0.00914602 -0.114108 0 -0.00416291 -0.0571506 0 -0.0025 -2.40741e-16 0 -0.0025 -2.40741e-16 0.01 -0.0174325 0.170679 0.01 -0.00416291 0.0571506 0.01 -0.00914602 0.114108 0.01 -0.0174325 0.170679 0 -0.00416291 0.0571506 0 -0.00914602 0.114108 0 -0.0174325 0.170679 0 -0.0125084 0.171547 0 -0.0125084 0.171547 0.01 -0.0174325 0.170679 0.01 0.0025 -2.41966e-16 0 0.0025 -2.41966e-16 0.01 -0.0125084 0.171547 0.01 0.00082863 0.0574413 0.01 -0.00417983 0.114688 0.01 -0.0125084 0.171547 0 0.00082863 0.0574413 0 -0.00417983 0.114688 0 + + + 0 3 2 1 0 2 16 4 5 16 7 4 17 8 7 17 7 16 6 8 17 13 6 17 10 6 13 14 10 13 11 10 14 15 11 14 12 9 11 12 11 15 21 19 18 21 18 24 22 24 25 22 21 24 20 25 23 20 22 25 38 26 27 38 29 26 39 30 29 39 29 38 28 30 39 35 28 39 32 28 35 36 32 35 33 32 36 37 33 36 34 31 33 34 33 37 43 41 40 43 40 46 44 46 47 44 43 46 42 47 45 42 44 47 51 49 48 51 48 54 52 54 55 52 51 54 50 55 53 50 52 55 56 59 58 57 56 58 63 61 60 63 60 66 64 66 67 64 63 66 62 67 65 62 64 67 + 3 6 9 12 15 18 21 24 27 30 33 36 39 42 45 48 51 54 57 60 63 66 69 72 75 78 81 84 87 90 93 96 99 102 105 108 111 114 117 120 123 126 129 132 135 138 141 144 147 150 153 156 + + + + + -0.0175616 -0.172155 0 -0.0126376 -0.173023 0 -0.0126376 -0.173023 0.01 -0.0175616 -0.172155 0.01 -0.0175616 -0.172155 0 -0.0126376 -0.173023 0 -0.0025 -2.42823e-16 0 -0.00920349 -0.115095 0 -0.00417729 -0.0576448 0 -0.0175616 0.172155 0 -0.00417729 0.0576448 0 -0.00920349 0.115095 0 -0.0126376 0.173023 0 0.0025 -2.44048e-16 0 0.000814249 0.0579355 0 -0.0042373 0.115675 0 -0.0042373 -0.115675 0 0.000814249 -0.0579355 0 -0.0126376 -0.173023 0 -0.0126376 -0.173023 0.01 0.0025 -2.44048e-16 0.01 -0.0042373 -0.115675 0.01 0.000814249 -0.0579355 0.01 0.0025 -2.44048e-16 0 -0.0042373 -0.115675 0 0.000814249 -0.0579355 0 -0.0175616 -0.172155 0.01 -0.0126376 -0.173023 0.01 -0.0025 -2.42823e-16 0.01 -0.00920349 -0.115095 0.01 -0.00417729 -0.0576448 0.01 -0.0175616 0.172155 0.01 -0.00417729 0.0576448 0.01 -0.00920349 0.115095 0.01 -0.0126376 0.173023 0.01 0.0025 -2.44048e-16 0.01 0.000814249 0.0579355 0.01 -0.0042373 0.115675 0.01 -0.0042373 -0.115675 0.01 0.000814249 -0.0579355 0.01 -0.0175616 -0.172155 0 -0.0175616 -0.172155 0.01 -0.0025 -2.42823e-16 0.01 -0.00920349 -0.115095 0.01 -0.00417729 -0.0576448 0.01 -0.0025 -2.42823e-16 0 -0.00920349 -0.115095 0 -0.00417729 -0.0576448 0 -0.0025 -2.42823e-16 0 -0.0025 -2.42823e-16 0.01 -0.0175616 0.172155 0.01 -0.00417729 0.0576448 0.01 -0.00920349 0.115095 0.01 -0.0175616 0.172155 0 -0.00417729 0.0576448 0 -0.00920349 0.115095 0 -0.0175616 0.172155 0 -0.0126376 0.173023 0 -0.0126376 0.173023 0.01 -0.0175616 0.172155 0.01 0.0025 -2.44048e-16 0 0.0025 -2.44048e-16 0.01 -0.0126376 0.173023 0.01 0.000814249 0.0579355 0.01 -0.0042373 0.115675 0.01 -0.0126376 0.173023 0 0.000814249 0.0579355 0 -0.0042373 0.115675 0 + + + 0 3 2 1 0 2 16 4 5 16 7 4 17 8 7 17 7 16 6 8 17 13 6 17 10 6 13 14 10 13 11 10 14 15 11 14 12 9 11 12 11 15 21 19 18 21 18 24 22 24 25 22 21 24 20 25 23 20 22 25 38 26 27 38 29 26 39 30 29 39 29 38 28 30 39 35 28 39 32 28 35 36 32 35 33 32 36 37 33 36 31 33 37 34 31 37 43 41 40 43 40 46 44 46 47 44 43 46 42 47 45 42 44 47 51 49 48 51 48 54 52 54 55 52 51 54 50 55 53 50 52 55 56 59 58 57 56 58 63 61 60 63 60 66 64 66 67 64 63 66 62 67 65 62 64 67 + 3 6 9 12 15 18 21 24 27 30 33 36 39 42 45 48 51 54 57 60 63 66 69 72 75 78 81 84 87 90 93 96 99 102 105 108 111 114 117 120 123 126 129 132 135 138 141 144 147 150 153 156 + + + + + -0.0175555 -0.172085 0 -0.0126315 -0.172954 0 -0.0126315 -0.172954 0.01 -0.0175555 -0.172085 0.01 -0.0175555 -0.172085 0 -0.0126315 -0.172954 0 -0.0025 -2.42725e-16 0 -0.00920079 -0.115048 0 -0.00417662 -0.0576215 0 -0.0175555 0.172085 0 -0.00417662 0.0576215 0 -0.00920079 0.115048 0 -0.0126315 0.172954 0 0.0025 -2.4395e-16 0 0.000814926 0.0579122 0 -0.0042346 0.115629 0 -0.0042346 -0.115629 0 0.000814926 -0.0579122 0 -0.0126315 -0.172954 0 -0.0126315 -0.172954 0.01 0.0025 -2.4395e-16 0.01 -0.0042346 -0.115629 0.01 0.000814926 -0.0579122 0.01 0.0025 -2.4395e-16 0 -0.0042346 -0.115629 0 0.000814926 -0.0579122 0 -0.0175555 -0.172085 0.01 -0.0126315 -0.172954 0.01 -0.0025 -2.42725e-16 0.01 -0.00920079 -0.115048 0.01 -0.00417662 -0.0576215 0.01 -0.0175555 0.172085 0.01 -0.00417662 0.0576215 0.01 -0.00920079 0.115048 0.01 -0.0126315 0.172954 0.01 0.0025 -2.4395e-16 0.01 0.000814926 0.0579122 0.01 -0.0042346 0.115629 0.01 -0.0042346 -0.115629 0.01 0.000814926 -0.0579122 0.01 -0.0175555 -0.172085 0 -0.0175555 -0.172085 0.01 -0.0025 -2.42725e-16 0.01 -0.00920079 -0.115048 0.01 -0.00417662 -0.0576215 0.01 -0.0025 -2.42725e-16 0 -0.00920079 -0.115048 0 -0.00417662 -0.0576215 0 -0.0025 -2.42725e-16 0 -0.0025 -2.42725e-16 0.01 -0.0175555 0.172085 0.01 -0.00417662 0.0576215 0.01 -0.00920079 0.115048 0.01 -0.0175555 0.172085 0 -0.00417662 0.0576215 0 -0.00920079 0.115048 0 -0.0175555 0.172085 0 -0.0126315 0.172954 0 -0.0126315 0.172954 0.01 -0.0175555 0.172085 0.01 0.0025 -2.4395e-16 0 0.0025 -2.4395e-16 0.01 -0.0126315 0.172954 0.01 0.000814926 0.0579122 0.01 -0.0042346 0.115629 0.01 -0.0126315 0.172954 0 0.000814926 0.0579122 0 -0.0042346 0.115629 0 + + + 0 3 2 1 0 2 16 4 5 16 7 4 17 8 7 17 7 16 6 8 17 13 6 17 10 6 13 14 10 13 15 11 10 15 10 14 12 9 11 12 11 15 21 19 18 21 18 24 22 24 25 22 21 24 20 25 23 20 22 25 38 26 27 38 29 26 39 30 29 39 29 38 28 30 39 35 28 39 32 28 35 36 32 35 37 33 32 37 32 36 34 31 33 34 33 37 43 41 40 43 40 46 44 46 47 44 43 46 42 47 45 42 44 47 51 49 48 51 48 54 52 54 55 52 51 54 50 55 53 50 52 55 56 59 58 57 56 58 63 61 60 63 60 66 64 66 67 64 63 66 62 67 65 62 64 67 + 3 6 9 12 15 18 21 24 27 30 33 36 39 42 45 48 51 54 57 60 63 66 69 72 75 78 81 84 87 90 93 96 99 102 105 108 111 114 117 120 123 126 129 132 135 138 141 144 147 150 153 156 + + + + + -0.0176862 -0.173579 0 -0.0127621 -0.174447 0 -0.0127621 -0.174447 0.01 -0.0176862 -0.173579 0.01 -0.0176862 -0.173579 0 -0.0127621 -0.174447 0 -0.0025 -2.44831e-16 0 -0.00925894 -0.116046 0 -0.00419116 -0.0581216 0 -0.0176862 0.173579 0 -0.00419116 0.0581216 0 -0.00925894 0.116046 0 -0.0127621 0.174447 0 0.0025 -2.46056e-16 0 0.000800376 0.0584123 0 -0.00429275 0.116627 0 -0.00429275 -0.116627 0 0.000800376 -0.0584123 0 -0.0127621 -0.174447 0 -0.0127621 -0.174447 0.01 0.0025 -2.46056e-16 0.01 -0.00429275 -0.116627 0.01 0.000800376 -0.0584123 0.01 0.0025 -2.46056e-16 0 -0.00429275 -0.116627 0 0.000800376 -0.0584123 0 -0.0176862 -0.173579 0.01 -0.0127621 -0.174447 0.01 -0.0025 -2.44831e-16 0.01 -0.00925894 -0.116046 0.01 -0.00419116 -0.0581216 0.01 -0.0176862 0.173579 0.01 -0.00419116 0.0581216 0.01 -0.00925894 0.116046 0.01 -0.0127621 0.174447 0.01 0.0025 -2.46056e-16 0.01 0.000800376 0.0584123 0.01 -0.00429275 0.116627 0.01 -0.00429275 -0.116627 0.01 0.000800376 -0.0584123 0.01 -0.0176862 -0.173579 0 -0.0176862 -0.173579 0.01 -0.0025 -2.44831e-16 0.01 -0.00925894 -0.116046 0.01 -0.00419116 -0.0581216 0.01 -0.0025 -2.44831e-16 0 -0.00925894 -0.116046 0 -0.00419116 -0.0581216 0 -0.0025 -2.44831e-16 0 -0.0025 -2.44831e-16 0.01 -0.0176862 0.173579 0.01 -0.00419116 0.0581216 0.01 -0.00925894 0.116046 0.01 -0.0176862 0.173579 0 -0.00419116 0.0581216 0 -0.00925894 0.116046 0 -0.0176862 0.173579 0 -0.0127621 0.174447 0 -0.0127621 0.174447 0.01 -0.0176862 0.173579 0.01 0.0025 -2.46056e-16 0 0.0025 -2.46056e-16 0.01 -0.0127621 0.174447 0.01 0.000800376 0.0584123 0.01 -0.00429275 0.116627 0.01 -0.0127621 0.174447 0 0.000800376 0.0584123 0 -0.00429275 0.116627 0 + + + 0 3 2 1 0 2 16 4 5 16 7 4 17 8 7 17 7 16 6 8 17 13 6 17 10 6 13 14 10 13 11 10 14 15 11 14 12 9 11 12 11 15 21 19 18 21 18 24 22 24 25 22 21 24 20 25 23 20 22 25 38 26 27 38 29 26 39 30 29 39 29 38 28 30 39 35 28 39 32 28 35 36 32 35 33 32 36 37 33 36 34 31 33 34 33 37 43 41 40 43 40 46 44 46 47 44 43 46 42 47 45 42 44 47 51 49 48 51 48 54 52 54 55 52 51 54 50 55 53 50 52 55 56 59 58 57 56 58 63 61 60 63 60 66 64 66 67 64 63 66 62 67 65 62 64 67 + 3 6 9 12 15 18 21 24 27 30 33 36 39 42 45 48 51 54 57 60 63 66 69 72 75 78 81 84 87 90 93 96 99 102 105 108 111 114 117 120 123 126 129 132 135 138 141 144 147 150 153 156 + + + + + -0.0176786 -0.173492 0 -0.0127545 -0.17436 0 -0.0127545 -0.17436 0.01 -0.0176786 -0.173492 0.01 -0.0176786 -0.173492 0 -0.0127545 -0.17436 0 -0.0025 -2.44709e-16 0 -0.00925556 -0.115988 0 -0.00419032 -0.0580925 0 -0.0176786 0.173492 0 -0.00419032 0.0580925 0 -0.00925556 0.115988 0 -0.0127545 0.17436 0 0.0025 -2.45934e-16 0 0.000801222 0.0583832 0 -0.00428936 0.116569 0 -0.00428936 -0.116569 0 0.000801222 -0.0583832 0 -0.0127545 -0.17436 0 -0.0127545 -0.17436 0.01 0.0025 -2.45934e-16 0.01 -0.00428936 -0.116569 0.01 0.000801222 -0.0583832 0.01 0.0025 -2.45934e-16 0 -0.00428936 -0.116569 0 0.000801222 -0.0583832 0 -0.0176786 -0.173492 0.01 -0.0127545 -0.17436 0.01 -0.0025 -2.44709e-16 0.01 -0.00925556 -0.115988 0.01 -0.00419032 -0.0580925 0.01 -0.0176786 0.173492 0.01 -0.00419032 0.0580925 0.01 -0.00925556 0.115988 0.01 -0.0127545 0.17436 0.01 0.0025 -2.45934e-16 0.01 0.000801222 0.0583832 0.01 -0.00428936 0.116569 0.01 -0.00428936 -0.116569 0.01 0.000801222 -0.0583832 0.01 -0.0176786 -0.173492 0 -0.0176786 -0.173492 0.01 -0.0025 -2.44709e-16 0.01 -0.00925556 -0.115988 0.01 -0.00419032 -0.0580925 0.01 -0.0025 -2.44709e-16 0 -0.00925556 -0.115988 0 -0.00419032 -0.0580925 0 -0.0025 -2.44709e-16 0 -0.0025 -2.44709e-16 0.01 -0.0176786 0.173492 0.01 -0.00419032 0.0580925 0.01 -0.00925556 0.115988 0.01 -0.0176786 0.173492 0 -0.00419032 0.0580925 0 -0.00925556 0.115988 0 -0.0176786 0.173492 0 -0.0127545 0.17436 0 -0.0127545 0.17436 0.01 -0.0176786 0.173492 0.01 0.0025 -2.45934e-16 0 0.0025 -2.45934e-16 0.01 -0.0127545 0.17436 0.01 0.000801222 0.0583832 0.01 -0.00428936 0.116569 0.01 -0.0127545 0.17436 0 0.000801222 0.0583832 0 -0.00428936 0.116569 0 + + + 0 3 2 1 0 2 7 4 5 16 7 5 17 8 7 17 7 16 6 8 17 13 6 17 10 6 13 14 10 13 11 10 14 15 11 14 12 9 11 12 11 15 21 19 18 21 18 24 22 24 25 22 21 24 20 25 23 20 22 25 29 26 27 38 29 27 39 30 29 39 29 38 28 30 39 35 28 39 32 28 35 36 32 35 37 33 32 37 32 36 34 31 33 34 33 37 43 41 40 43 40 46 44 46 47 44 43 46 42 47 45 42 44 47 51 49 48 51 48 54 52 54 55 52 51 54 50 55 53 50 52 55 56 59 58 57 56 58 63 61 60 63 60 66 64 66 67 64 63 66 62 67 65 62 64 67 + 3 6 9 12 15 18 21 24 27 30 33 36 39 42 45 48 51 54 57 60 63 66 69 72 75 78 81 84 87 90 93 96 99 102 105 108 111 114 117 120 123 126 129 132 135 138 141 144 147 150 153 156 + + + + + -0.0178092 -0.174985 0 -0.0128852 -0.175854 0 -0.0128852 -0.175854 0.01 -0.0178092 -0.174985 0.01 -0.0178092 -0.174985 0 -0.0128852 -0.175854 0 -0.0025 -2.46815e-16 0 -0.00931371 -0.116987 0 -0.00420487 -0.0585925 0 -0.0178092 0.174985 0 -0.00420487 0.0585925 0 -0.00931371 0.116987 0 -0.0128852 0.175854 0 0.0025 -2.4804e-16 0 0.000786672 0.0588833 0 -0.00434752 0.117567 0 -0.00434752 -0.117567 0 0.000786672 -0.0588833 0 -0.0128852 -0.175854 0 -0.0128852 -0.175854 0.01 0.0025 -2.4804e-16 0.01 -0.00434752 -0.117567 0.01 0.000786672 -0.0588833 0.01 0.0025 -2.4804e-16 0 -0.00434752 -0.117567 0 0.000786672 -0.0588833 0 -0.0178092 -0.174985 0.01 -0.0128852 -0.175854 0.01 -0.0025 -2.46815e-16 0.01 -0.00931371 -0.116987 0.01 -0.00420487 -0.0585925 0.01 -0.0178092 0.174985 0.01 -0.00420487 0.0585925 0.01 -0.00931371 0.116987 0.01 -0.0128852 0.175854 0.01 0.0025 -2.4804e-16 0.01 0.000786672 0.0588833 0.01 -0.00434752 0.117567 0.01 -0.00434752 -0.117567 0.01 0.000786672 -0.0588833 0.01 -0.0178092 -0.174985 0 -0.0178092 -0.174985 0.01 -0.0025 -2.46815e-16 0.01 -0.00931371 -0.116987 0.01 -0.00420487 -0.0585925 0.01 -0.0025 -2.46815e-16 0 -0.00931371 -0.116987 0 -0.00420487 -0.0585925 0 -0.0025 -2.46815e-16 0 -0.0025 -2.46815e-16 0.01 -0.0178092 0.174985 0.01 -0.00420487 0.0585925 0.01 -0.00931371 0.116987 0.01 -0.0178092 0.174985 0 -0.00420487 0.0585925 0 -0.00931371 0.116987 0 -0.0178092 0.174985 0 -0.0128852 0.175854 0 -0.0128852 0.175854 0.01 -0.0178092 0.174985 0.01 0.0025 -2.4804e-16 0 0.0025 -2.4804e-16 0.01 -0.0128852 0.175854 0.01 0.000786672 0.0588833 0.01 -0.00434752 0.117567 0.01 -0.0128852 0.175854 0 0.000786672 0.0588833 0 -0.00434752 0.117567 0 + + + 0 3 2 1 0 2 16 4 5 16 7 4 17 8 7 17 7 16 6 8 17 13 6 17 10 6 13 14 10 13 15 11 10 15 10 14 12 9 11 12 11 15 21 19 18 21 18 24 22 24 25 22 21 24 20 25 23 20 22 25 38 26 27 38 29 26 39 30 29 39 29 38 28 30 39 35 28 39 32 28 35 36 32 35 37 33 32 37 32 36 34 31 33 34 33 37 43 41 40 43 40 46 44 46 47 44 43 46 42 47 45 42 44 47 51 49 48 51 48 54 52 54 55 52 51 54 50 55 53 50 52 55 56 59 58 57 56 58 63 61 60 63 60 66 64 66 67 64 63 66 62 67 65 62 64 67 + 3 6 9 12 15 18 21 24 27 30 33 36 39 42 45 48 51 54 57 60 63 66 69 72 75 78 81 84 87 90 93 96 99 102 105 108 111 114 117 120 123 126 129 132 135 138 141 144 147 150 153 156 + + + + + -0.0178016 -0.174898 0 -0.0128776 -0.175767 0 -0.0128776 -0.175767 0.01 -0.0178016 -0.174898 0.01 -0.0178016 -0.174898 0 -0.0128776 -0.175767 0 -0.0025 -2.46693e-16 0 -0.00931033 -0.116929 0 -0.00420402 -0.0585635 0 -0.0178016 0.174898 0 -0.00420402 0.0585635 0 -0.00931033 0.116929 0 -0.0128776 0.175767 0 0.0025 -2.47917e-16 0 0.000787518 0.0588542 0 -0.00434413 0.117509 0 -0.00434413 -0.117509 0 0.000787518 -0.0588542 0 -0.0128776 -0.175767 0 -0.0128776 -0.175767 0.01 0.0025 -2.47917e-16 0.01 -0.00434413 -0.117509 0.01 0.000787518 -0.0588542 0.01 0.0025 -2.47917e-16 0 -0.00434413 -0.117509 0 0.000787518 -0.0588542 0 -0.0178016 -0.174898 0.01 -0.0128776 -0.175767 0.01 -0.0025 -2.46693e-16 0.01 -0.00931033 -0.116929 0.01 -0.00420402 -0.0585635 0.01 -0.0178016 0.174898 0.01 -0.00420402 0.0585635 0.01 -0.00931033 0.116929 0.01 -0.0128776 0.175767 0.01 0.0025 -2.47917e-16 0.01 0.000787518 0.0588542 0.01 -0.00434413 0.117509 0.01 -0.00434413 -0.117509 0.01 0.000787518 -0.0588542 0.01 -0.0178016 -0.174898 0 -0.0178016 -0.174898 0.01 -0.0025 -2.46693e-16 0.01 -0.00931033 -0.116929 0.01 -0.00420402 -0.0585635 0.01 -0.0025 -2.46693e-16 0 -0.00931033 -0.116929 0 -0.00420402 -0.0585635 0 -0.0025 -2.46693e-16 0 -0.0025 -2.46693e-16 0.01 -0.0178016 0.174898 0.01 -0.00420402 0.0585635 0.01 -0.00931033 0.116929 0.01 -0.0178016 0.174898 0 -0.00420402 0.0585635 0 -0.00931033 0.116929 0 -0.0178016 0.174898 0 -0.0128776 0.175767 0 -0.0128776 0.175767 0.01 -0.0178016 0.174898 0.01 0.0025 -2.47917e-16 0 0.0025 -2.47917e-16 0.01 -0.0128776 0.175767 0.01 0.000787518 0.0588542 0.01 -0.00434413 0.117509 0.01 -0.0128776 0.175767 0 0.000787518 0.0588542 0 -0.00434413 0.117509 0 + + + 0 3 2 1 0 2 7 4 5 16 7 5 17 8 7 17 7 16 6 8 17 13 6 17 10 6 13 14 10 13 15 11 10 15 10 14 12 9 11 12 11 15 21 19 18 21 18 24 22 24 25 22 21 24 20 25 23 20 22 25 29 26 27 38 29 27 39 30 29 39 29 38 28 30 39 35 28 39 32 28 35 36 32 35 37 33 32 37 32 36 34 31 33 34 33 37 43 41 40 43 40 46 44 46 47 44 43 46 42 47 45 42 44 47 51 49 48 51 48 54 52 54 55 52 51 54 50 55 53 50 52 55 56 59 58 57 56 58 63 61 60 63 60 66 64 66 67 64 63 66 62 67 65 62 64 67 + 3 6 9 12 15 18 21 24 27 30 33 36 39 42 45 48 51 54 57 60 63 66 69 72 75 78 81 84 87 90 93 96 99 102 105 108 111 114 117 120 123 126 129 132 135 138 141 144 147 150 153 156 + + + + + + + + + + + + + + + + + + + + + + diff --git a/Test/AutoTestData/UsageData/INES_Definition.xml b/Test/AutoTestData/UsageData/INES_Definition.xml new file mode 100644 index 000000000000..0f5c29da5d46 --- /dev/null +++ b/Test/AutoTestData/UsageData/INES_Definition.xml @@ -0,0 +1,113 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Test/AutoTestData/UsageData/INES_example.cal b/Test/AutoTestData/UsageData/INES_example.cal new file mode 100644 index 000000000000..fceed204dfa6 --- /dev/null +++ b/Test/AutoTestData/UsageData/INES_example.cal @@ -0,0 +1,148 @@ +# Calibration file for instrument INES written on 2014-09-09T12:26:56.232783000. +# Format: number UDET offset select group + 0 1 0.0000000 1 1 + 1 2 0.0000000 1 1 + 2 3 0.0000000 1 1 + 3 4 0.0000000 1 1 + 4 5 0.0000000 1 1 + 5 6 0.0000000 1 1 + 6 7 0.0000000 1 1 + 7 8 0.0000000 1 1 + 8 9 0.0000000 1 1 + 9 10 0.0000000 1 1 + 10 11 0.0000000 1 1 + 11 12 0.0000000 1 1 + 12 13 0.0000000 1 1 + 13 14 0.0000000 1 1 + 14 15 0.0000000 1 1 + 15 16 0.0000000 1 1 + 16 17 0.0000000 1 2 + 17 18 0.0000000 1 2 + 18 19 0.0000000 1 2 + 19 20 0.0000000 1 2 + 20 21 0.0000000 1 2 + 21 22 0.0000000 1 2 + 22 23 0.0000000 1 2 + 23 24 0.0000000 1 2 + 24 25 0.0000000 1 2 + 25 26 0.0000000 1 2 + 26 27 0.0000000 1 2 + 27 28 0.0000000 1 2 + 28 29 0.0000000 1 2 + 29 30 0.0000000 1 2 + 30 31 0.0000000 1 2 + 31 32 0.0000000 1 2 + 32 33 0.0000000 1 3 + 33 34 0.0000000 1 3 + 34 35 0.0000000 1 3 + 35 36 0.0000000 1 3 + 36 37 0.0000000 1 3 + 37 38 0.0000000 1 3 + 38 39 0.0000000 1 3 + 39 40 0.0000000 1 3 + 40 41 0.0000000 1 3 + 41 42 0.0000000 1 3 + 42 43 0.0000000 1 3 + 43 44 0.0000000 1 3 + 44 45 0.0000000 1 3 + 45 46 0.0000000 1 3 + 46 47 0.0000000 1 3 + 47 48 0.0000000 1 3 + 48 49 0.0000000 1 4 + 49 50 0.0000000 1 4 + 50 51 0.0000000 1 4 + 51 52 0.0000000 1 4 + 52 53 0.0000000 1 4 + 53 54 0.0000000 1 4 + 54 55 0.0000000 1 4 + 55 56 0.0000000 1 4 + 56 57 0.0000000 1 4 + 57 58 0.0000000 1 4 + 58 59 0.0000000 1 4 + 59 60 0.0000000 1 4 + 60 61 0.0000000 1 4 + 61 62 0.0000000 1 4 + 62 63 0.0000000 1 4 + 63 64 0.0000000 1 4 + 64 65 0.0000000 1 5 + 65 66 0.0000000 1 5 + 66 67 0.0000000 1 5 + 67 68 0.0000000 1 5 + 68 69 0.0000000 1 5 + 69 70 0.0000000 1 5 + 70 71 0.0000000 1 5 + 71 72 0.0000000 1 5 + 72 73 0.0000000 1 5 + 73 74 0.0000000 1 5 + 74 75 0.0000000 1 5 + 75 76 0.0000000 1 5 + 76 77 0.0000000 1 5 + 77 78 0.0000000 1 5 + 78 79 0.0000000 1 5 + 79 80 0.0000000 1 5 + 80 81 0.0000000 1 6 + 81 82 0.0000000 1 6 + 82 83 0.0000000 1 6 + 83 84 0.0000000 1 6 + 84 85 0.0000000 1 6 + 85 86 0.0000000 1 6 + 86 87 0.0000000 1 6 + 87 88 0.0000000 1 6 + 88 89 0.0000000 1 6 + 89 90 0.0000000 1 6 + 90 91 0.0000000 1 6 + 91 92 0.0000000 1 6 + 92 93 0.0000000 1 6 + 93 94 0.0000000 1 6 + 94 95 0.0000000 1 6 + 95 96 0.0000000 1 6 + 96 97 0.0000000 1 7 + 97 98 0.0000000 1 7 + 98 99 0.0000000 1 7 + 99 100 0.0000000 1 7 + 100 101 0.0000000 1 7 + 101 102 0.0000000 1 7 + 102 103 0.0000000 1 7 + 103 104 0.0000000 1 7 + 104 105 0.0000000 1 7 + 105 106 0.0000000 1 7 + 106 107 0.0000000 1 7 + 107 108 0.0000000 1 7 + 108 109 0.0000000 1 7 + 109 110 0.0000000 1 7 + 110 111 0.0000000 1 7 + 111 112 0.0000000 1 7 + 112 113 0.0000000 1 8 + 113 114 0.0000000 1 8 + 114 115 0.0000000 1 8 + 115 116 0.0000000 1 8 + 116 117 0.0000000 1 8 + 117 118 0.0000000 1 8 + 118 119 0.0000000 1 8 + 119 120 0.0000000 1 8 + 120 121 0.0000000 1 8 + 121 122 0.0000000 1 8 + 122 123 0.0000000 1 8 + 123 124 0.0000000 1 8 + 124 125 0.0000000 1 8 + 125 126 0.0000000 1 8 + 126 127 0.0000000 1 8 + 127 128 0.0000000 1 8 + 128 129 0.0000000 1 9 + 129 130 0.0000000 1 9 + 130 131 0.0000000 1 9 + 131 132 0.0000000 1 9 + 132 133 0.0000000 1 9 + 133 134 0.0000000 1 9 + 134 135 0.0000000 1 9 + 135 136 0.0000000 1 9 + 136 137 0.0000000 1 9 + 137 138 0.0000000 1 9 + 138 139 0.0000000 1 9 + 139 140 0.0000000 1 9 + 140 141 0.0000000 1 9 + 141 142 0.0000000 1 9 + 142 143 0.0000000 1 9 + 143 144 0.0000000 1 9 + 144 145 0.0000000 1 0 + 145 147 0.0000000 1 0 diff --git a/Test/AutoTestData/UsageData/NaF_DISF.cdl b/Test/AutoTestData/UsageData/NaF_DISF.cdl new file mode 100644 index 000000000000..a80f2d1247ea --- /dev/null +++ b/Test/AutoTestData/UsageData/NaF_DISF.cdl @@ -0,0 +1,298 @@ +netcdf NaF_DISF { +dimensions: + NQVALUES = 3 ; + NTIMES = 20 ; + NOCTANS = 8 ; + OCTANNAME = 8 ; + NFREQUENCIES = 20 ; +variables: + double q(NQVALUES) ; + q:units = "nm^-1" ; + double time(NTIMES) ; + time:units = "ps" ; + char octan(NOCTANS, OCTANNAME) ; + octan:units = "unitless" ; + int qvectors_statistics(NQVALUES, NOCTANS) ; + double Fqt-Na(NQVALUES, NTIMES) ; + Fqt-Na:units = "unitless" ; + double Fqt-total(NQVALUES, NTIMES) ; + Fqt-total:units = "unitless" ; + double Fqt-F(NQVALUES, NTIMES) ; + Fqt-F:units = "unitless" ; + double frequency(NFREQUENCIES) ; + frequency:units = "THz" ; + double angular_frequency(NFREQUENCIES) ; + angular_frequency:units = "rad ps-1" ; + double time_resolution(NFREQUENCIES) ; + time_resolution:units = "unitless" ; + double frequency_resolution(NFREQUENCIES) ; + frequency_resolution:units = "unitless" ; + double Sqw-Na(NQVALUES, NFREQUENCIES) ; + Sqw-Na:units = "unitless" ; + double Sqw-total(NQVALUES, NFREQUENCIES) ; + Sqw-total:units = "unitless" ; + double Sqw-F(NQVALUES, NFREQUENCIES) ; + Sqw-F:units = "unitless" ; + +// global attributes: + :title = "DynamicIncoherentStructureFactor_serial" ; + :jobinfo = "##########################################################################################\n", + "Job information for DynamicIncoherentStructureFactor_serial analysis.\n", + "##########################################################################################\n", + "\n", + "Job launched on: Mon Oct 20 17:38:50 2014\n", + "\n", + "General informations\n", + "--------------------\n", + "User: sm37\n", + "OS: Linux-2.6.32-358.23.2.el6.x86_64\n", + "Processor: x86_64\n", + "nMOLDYN version: 3.0.8\n", + "Estimate run: no\n", + "\n", + "Parameters\n", + "----------\n", + "subset = all\n", + "timeinfo = 1:2000:100\n", + "trajectory = /home/sm37/Projects/NaF-MD/NVT-300K/NPT-1300K/14ps/nMoldyn/NaF.nc\n", + "qvectorsdirection = no\n", + "pyroserver = monoprocessor\n", + "qshellvalues = 0.0:10.0:1.0\n", + "weights = incoherent\n", + "deuteration = no\n", + "qshellwidth = 1.0\n", + "output = /home/sm37/Projects/NaF-MD/NVT-300K/NPT-1300K/14ps/nMoldyn/NaF_DISF.nc\n", + "qvectorsgenerator = 3D isotropic\n", + "resolution = 0.35\n", + "qvectorspershell = 500\n", + "\n", + "Job status\n", + "----------\n", + "\n", + "Output file written on: Mon Oct 20 17:38:50 2014\n", + "\n", + "" ; +data: + + q = 6, 8, 10 ; + + time = 0, 0.20000000298023224, 0.40000000596046448, 0.60000000894069672, + 0.80000001192092896, 1.0000000149011612, 1.2000000178813934, + 1.4000000208616257, 1.6000000238418579, 1.8000000268220901, + 2.0000000298023224, 2.2000000327825546, 2.4000000357627869, + 2.6000000387430191, 2.8000000417232513, 3.0000000447034836, + 3.2000000476837158, 3.4000000506639481, 3.6000000536441803, + 3.8000000566244125 ; + + octan = + // octan(0, 0-7) + "X+.Y+.Z+", + // octan(1, 0-7) + "X+.Y+.Z-", + // octan(2, 0-7) + "X+.Y-.Z+", + // octan(3, 0-7) + "X+.Y-.Z-", + // octan(4, 0-7) + "X-.Y+.Z+", + // octan(5, 0-7) + "X-.Y+.Z-", + // octan(6, 0-7) + "X-.Y-.Z+", + // octan(7, 0-7) + "X-.Y-.Z-" ; + + qvectors_statistics = + // qvectors_statistics(0, 0-7) + 0, 0, 0, 1, 0, 1, 1, 3, + // qvectors_statistics(1, 0-7) + 0, 1, 1, 2, 1, 2, 2, 3, + // qvectors_statistics(2, 0-7) + 1, 1, 1, 1, 1, 1, 1, 1 ; + + Fqt-Na = + // Fqt-Na(0, 0-19) + 1, 0.92811472380740201, 0.87213949738914276, 0.8212088227095754, + 0.77783275406692887, 0.73874780735937773, 0.70916382866599792, + 0.67897582765926445, 0.65478712865331135, 0.62709585563725945, + 0.59626785490478906, 0.57013455260229651, 0.53121351982526122, + 0.49980069522810933, 0.47496145484366775, 0.43954349090802203, + 0.40648098307815206, 0.38301238199286936, 0.35496595488880472, + 0.34597658430240363, + // Fqt-Na(1, 0-19) + 1, 0.86210383248952782, 0.76313169241099388, 0.67847158077232794, + 0.61283180002178494, 0.55638829370907739, 0.51065066292133254, + 0.46692436461988313, 0.43127395201067137, 0.3969419360975785, + 0.35358958819074782, 0.3129987177785401, 0.26337021545629369, + 0.22880455234767227, 0.20607403447362443, 0.16802996481740126, + 0.14017792225332162, 0.12689685437019746, 0.10351771119519099, + 0.097069411905318481, + // Fqt-Na(2, 0-19) + 1, 0.8014225869948256, 0.66954819425120271, 0.56468949882556729, + 0.49243836152821624, 0.42977017364442821, 0.3778468477360955, + 0.32713622642602125, 0.28800249113594395, 0.25586046573098115, + 0.21389129288802194, 0.16930409260597246, 0.11657178723170304, + 0.085853543298113899, 0.07280155905217181, 0.034439424623498902, + 0.023615475804453209, 0.049772846283147411, 0.039598969122690703, + 0.067676950279804193 ; + + Fqt-total = + // Fqt-total(0, 0-19) + 0.99999999999999956, 0.92811169481436484, 0.87213269337417976, + 0.82120025646685679, 0.7778222617959375, 0.73873188070897589, + 0.70913949648239694, 0.67894501662638862, 0.65474777592314926, + 0.6270496039121346, 0.59622064350233239, 0.57008342990997296, + 0.53115886859825467, 0.49973763830696827, 0.47489214489481052, + 0.43947931817352115, 0.40642335663781431, 0.38295336010359488, + 0.35490898932236203, 0.34591580236687464, + // Fqt-total(1, 0-19) + 0.99999999999999956, 0.8620983996127024, 0.7631210287479927, + 0.67845950463752924, 0.61281769127860797, 0.55636702069777477, + 0.51062333492213152, 0.46689108076948477, 0.43123409355993553, + 0.39689330061213451, 0.35354001976499044, 0.31295032980668858, + 0.26332487386721648, 0.22875417427115974, 0.20601527704114542, + 0.16798222754636538, 0.14013743464240322, 0.12686271473703231, + 0.10350186153380991, 0.097051061116970552, + // Fqt-total(2, 0-19) + 0.99999999999999956, 0.80141534253317759, 0.6695361087653704, + 0.56467737831195997, 0.49242377794911263, 0.4297494183815041, + 0.37782540065028969, 0.32711684687927917, 0.28798277235021519, + 0.25583411551987134, 0.21386535233532089, 0.16928428412736016, + 0.11656510724880031, 0.085838713203058872, 0.072787279831739743, + 0.034439663590170803, 0.023620529521296924, 0.049765967548664865, + 0.039602880937227893, 0.067653590727241988 ; + + Fqt-F = + // Fqt-F(0, 0-19) + 1, 0.92197798390139651, 0.85835456304418301, 0.80385361492385599, + 0.75657541299183562, 0.70648041357393832, 0.65986682458124679, + 0.61655267491441967, 0.5750584971678957, 0.5333898603261582, + 0.50061755331513236, 0.46655997772479996, 0.42049013366379256, + 0.37204737271232396, 0.3345394981465839, 0.30952953052014609, + 0.28972981469429532, 0.26343403405684518, 0.23955371701914724, + 0.22283238264675703, + // Fqt-F(1, 0-19) + 1, 0.85109682401740372, 0.74152711112315306, 0.65400533161634433, + 0.58424748628195844, 0.51328917271447538, 0.45528413641709781, + 0.39949128356306396, 0.35052073064031702, 0.29840644236895664, + 0.25316395738288722, 0.21496468658929466, 0.17150815578147074, + 0.12673856910618003, 0.087031476006217925, 0.07131425348346361, + 0.058150022350094935, 0.05772995742368324, 0.071406297165713423, + 0.059890714629705064, + // Fqt-F(2, 0-19) + 1, 0.78674530766400341, 0.64506299990084637, 0.54013333820298204, + 0.46289203019897457, 0.38772001086688701, 0.33439505179711909, + 0.28787326463944091, 0.24805223116079805, 0.20247493790383261, + 0.16133573299884807, 0.12917211484818697, 0.10303814184071802, + 0.055807770649816436, 0.043871858392440406, 0.034923571101879387, + 0.033854306152642934, 0.035836530190509253, 0.047524305392726764, + 0.02035049668345609 ; + + frequency = 0, 0.12499999813735488, 0.24999999627470976, + 0.37499999441206461, 0.49999999254941951, 0.62499999068677436, + 0.74999998882412922, 0.87499998696148418, 0.99999998509883903, + 1.1249999832361939, 1.2499999813735487, 1.3749999795109036, + 1.4999999776482584, 1.6249999757856135, 1.7499999739229684, + 1.8749999720603232, 1.9999999701976781, 2.1249999683350329, + 2.2499999664723878, 2.3749999646097426 ; + + angular_frequency = 0, 0.78539815169410387, 1.5707963033882077, + 2.3561944550823113, 3.1415926067764155, 3.9269907584705188, + 4.7123889101646226, 5.4977870618587268, 6.283185213552831, + 7.0685833652469343, 7.8539815169410376, 8.6393796686351418, + 9.4247778203292452, 10.21017597202335, 10.995574123717454, + 11.780972275411557, 12.566370427105662, 13.351768578799765, + 14.137166730493869, 14.922564882187972 ; + + time_resolution = 1, 0.99898071091997054, 0.99592907314637102, + 0.99086371166862253, 0.98381545767196288, 0.97482703598580567, + 0.96395263374043882, 0.9512573563244705, 0.93681657828441633, + 0.92071519821891412, 0.90304680796896908, 0.88391278747161739, + 0.86342133751069039, 0.84168646325244623, 0.81882692188773121, + 0.7949651479125952, 0.7702261695670839, 0.74473652972284232, + 0.7186232240740027, 0.69201266885627 ; + + frequency_resolution = 1, 0.0023609648579433649, 3.1071204637868238e-11, + 2.279322120971843e-24, 9.3203530845767308e-43, 2.1244086960943744e-66, + 2.6991239046350686e-95, 1.9115542075339542e-129, 7.5462199679007314e-169, + 1.6605476732214969e-213, 2.0368182704994765e-263, + 1.3926178952762632e-318, 0, 0, 0, 0, 0, 0, 0, 0 ; + + Sqw-Na = + // Sqw-Na(0, 0-19) + 2.1496662863854685, 0.56736244022084847, 0.03436195247730111, + 0.07664651961473154, 0.027288326627623233, 0.029857881587271973, + 0.010242536965606621, 0.014183600016682537, 0.0083390824033198942, + 0.0085924273358376508, 0.0056657016429464847, 0.0087479074310995442, + 0.0024772434365405637, 0.0070691866389435646, 0.0056607554591471959, + 0.0031380572255169433, 0.0036130087775803421, 0.0047763648545595646, + 0.0049674370542060675, 0.0043529106994361945, + // Sqw-Na(1, 0-19) + 1.4546884226997843, 0.6555503906440463, 0.12753236729908099, + 0.097489053916869253, 0.063965245147499794, 0.046991319052596202, + 0.02548787828411608, 0.024049958907575088, 0.021339909040444111, + 0.016016183767904639, 0.010863110814089853, 0.014984052355142675, + 0.0078295146931483383, 0.011635622084610619, 0.010758098909881194, + 0.0064534173502319853, 0.0091594080426023877, 0.0089573375514204866, + 0.0095348711833269303, 0.0081161558354674087, + // Sqw-Na(2, 0-19) + 1.0642025162555124, 0.63825485173433183, 0.20381828253086623, + 0.099745274327009831, 0.10029659779611567, 0.052094655838422217, + 0.044248436895743322, 0.032700511141241104, 0.035351841760559423, + 0.022915846529531898, 0.015275392106540997, 0.022354211099606319, + 0.012645706635670821, 0.014967931589528704, 0.017204946424185113, + 0.0073959067302346243, 0.016751540410214743, 0.01010338350573093, + 0.016797653765451802, 0.0099515987269383731 ; + + Sqw-total = + // Sqw-total(0, 0-19) + 2.1495417836352098, 0.56740456494072888, 0.03438157606863769, + 0.076641923532027062, 0.027290520009762703, 0.02985458298356404, + 0.010242582764617333, 0.014187754744433789, 0.008337917942189875, + 0.008593327037983569, 0.0056675237531856378, 0.0087475891041923961, + 0.0024781966860149356, 0.0070684566481143355, 0.0056602135972618319, + 0.0031391488594492835, 0.0036129368697352584, 0.0047766077378376872, + 0.0049668697514472105, 0.0043536869268518208, + // Sqw-total(1, 0-19) + 1.4545819725587508, 0.65556914929653765, 0.12756296932955544, + 0.097481736072514924, 0.06397049681736397, 0.046985507586340361, + 0.025492710418623381, 0.024051582044986825, 0.021338713242393934, + 0.016017651212123483, 0.010866669182844083, 0.014983261527750962, + 0.0078309643910874725, 0.011636000875880015, 0.010756704808495927, + 0.0064557292384691345, 0.0091577855408014434, 0.0089581131013237707, + 0.0095345507242413797, 0.0081174932430043093, + // Sqw-total(2, 0-19) + 1.0641575373022829, 0.63824495492156841, 0.20383374321859904, + 0.099750804159743217, 0.10029481493086465, 0.052098457605567562, + 0.044248556690989878, 0.032703613444571088, 0.035347224518535073, + 0.022918566798904524, 0.015280686911340486, 0.022353253926211927, + 0.01264654432697895, 0.014970772772899208, 0.017201886209318663, + 0.0073993173867137304, 0.01674955344493307, 0.010105641345352048, + 0.016794520699177681, 0.0099566926975994275 ; + + Sqw-F = + // Sqw-F(0, 0-19) + 1.8974237138019356, 0.65270712288967114, 0.074119348613732247, + 0.067334856035016169, 0.031732118852360852, 0.023174910460220154, + 0.0103353257614374, 0.022601078459439972, 0.0059798841485844854, + 0.010415223887577782, 0.0093572969958326448, 0.0081029771159374341, + 0.0044085268758656425, 0.0055902252156367896, 0.0045629432766639859, + 0.0053497075773264024, 0.0034673234829930479, 0.0052684463770393724, + 0.0038180816624171182, 0.0059255474469886264, + // Sqw-F(1, 0-19) + 1.2390204364867892, 0.69355542067702314, 0.18953208117829706, + 0.082663101222062427, 0.074605128316077282, 0.035217288392177123, + 0.035277782817662307, 0.027338435311001736, 0.018917222185435994, + 0.018989225761792516, 0.018072365926296682, 0.013381836056077685, + 0.010766602724379475, 0.012403053198288171, 0.0079336494971721794, + 0.011137302929199646, 0.0058722193866609408, 0.010528601659054237, + 0.0088856210745125955, 0.010825743511292228, + // Sqw-F(2, 0-19) + 0.97307515681073697, 0.61820390903168854, 0.23514163594722182, + 0.11094871546953894, 0.096684512789551813, 0.059797036092130586, + 0.044491142065885537, 0.038985777701732512, 0.02599730939845632, + 0.028427112290794185, 0.026002666654261902, 0.020414977798369406, + 0.014342869229671033, 0.020724169111133822, 0.011004951090975663, + 0.014305896772264796, 0.012725948740572462, 0.01467776658814412, + 0.010450061479843935, 0.020271983309209745 ; +} diff --git a/Test/AutoTestData/UsageData/tabulatedFunctionExample.nxs b/Test/AutoTestData/UsageData/tabulatedFunctionExample.nxs new file mode 100644 index 000000000000..c1b5d0890514 Binary files /dev/null and b/Test/AutoTestData/UsageData/tabulatedFunctionExample.nxs differ diff --git a/Test/AutoTestData/nom_gr.nxs b/Test/AutoTestData/nom_gr.nxs new file mode 100644 index 000000000000..fddaadeccf5d Binary files /dev/null and b/Test/AutoTestData/nom_gr.nxs differ