diff --git a/Code/Mantid/Build/Jenkins/buildscript b/Code/Mantid/Build/Jenkins/buildscript index 461364befab4..40f6003fab63 100755 --- a/Code/Mantid/Build/Jenkins/buildscript +++ b/Code/Mantid/Build/Jenkins/buildscript @@ -10,6 +10,8 @@ # slave. ############################################################################### SCRIPT_DIR=$(dirname "$0") +# Package by default +BUILDPKG=true ############################################################################### # Print out the versions of things we are using @@ -88,7 +90,6 @@ fi ############################################################################### if [[ ${JOB_NAME} == *clean* ]]; then CLEANBUILD=true - BUILDPKG=true fi if [[ -e $WORKSPACE/build/CMakeCache.txt ]]; then @@ -99,10 +100,6 @@ if [[ -e $WORKSPACE/build/CMakeCache.txt ]]; then fi fi -if [[ ${JOB_NAME} == *pull_requests* ]]; then - BUILDPKG=true -fi - ############################################################################### # Packaging options ############################################################################### diff --git a/Code/Mantid/Build/Jenkins/systemtests.bat b/Code/Mantid/Build/Jenkins/systemtests.bat index 3c2f3e003568..75161531e9db 100755 --- a/Code/Mantid/Build/Jenkins/systemtests.bat +++ b/Code/Mantid/Build/Jenkins/systemtests.bat @@ -1,4 +1,4 @@ -setlocal enbaleextensions enabledelayedexpansion +setlocal enableextensions enabledelayedexpansion ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: :: WINDOWS SCRIPT TO DRIVE THE SYSTEM TESTS OF MANTID :: @@ -46,8 +46,8 @@ if not EXIST %WORKSPACE%\build\CMakeCache.txt ( ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: :: Build step ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: -"%CMAKE_BIN_DIR%\cmake" --build . -- StandardTestData -"%CMAKE_BIN_DIR%\cmake" --build . -- SystemTestData +msbuild /nologo /nr:false /p:Configuration=Release StandardTestData.vcxproj +msbuild /nologo /nr:false /p:Configuration=Release SystemTestData.vcxproj ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: :: Run the tests diff --git a/Code/Mantid/Build/coverity_model.c b/Code/Mantid/Build/coverity_model.c new file mode 100644 index 000000000000..c8db0c45d66b --- /dev/null +++ b/Code/Mantid/Build/coverity_model.c @@ -0,0 +1,18 @@ +/* Coverity Scan model + * + * This is a modeling file for Coverity Scan. Modeling helps to avoid false + * positives. + * + * - A model file can't import any header files. + * - Therefore only some built-in primitives like int, char and void are + * available but not wchar_t, NULL etc. + * - Modeling doesn't need full structs and typedefs. Rudimentary structs + * and similar types are sufficient. + * - An uninitialized local pointer is not an error. It signifies that the + * variable could be either NULL or have some data. + * + * Coverity Scan doesn't pick up modifications automatically. The model file + * must be uploaded by an admin in the analysis settings of + * http://scan.coverity.com/projects/2832 + */ + \ No newline at end of file diff --git a/Code/Mantid/Framework/API/CMakeLists.txt b/Code/Mantid/Framework/API/CMakeLists.txt index c59fd55a43a5..f87f4cede245 100644 --- a/Code/Mantid/Framework/API/CMakeLists.txt +++ b/Code/Mantid/Framework/API/CMakeLists.txt @@ -31,6 +31,7 @@ set ( SRC_FILES src/ExperimentInfo.cpp src/Expression.cpp src/FermiChopperModel.cpp + src/FileBackedExperimentInfo.cpp src/FileFinder.cpp src/FileLoaderRegistry.cpp src/FileProperty.cpp @@ -39,6 +40,7 @@ set ( SRC_FILES src/FunctionDomain1D.cpp src/FunctionDomainMD.cpp src/FunctionFactory.cpp + src/FunctionParameterDecorator.cpp src/FunctionProperty.cpp src/FunctionValues.cpp src/GridDomain.cpp @@ -93,7 +95,7 @@ set ( SRC_FILES src/ParamFunction.cpp src/ParameterReference.cpp src/ParameterTie.cpp - src/PeakFunctionIntegrator.cpp + src/PeakFunctionIntegrator.cpp src/PeakTransform.cpp src/PeakTransformHKL.cpp src/PeakTransformQLab.cpp @@ -171,6 +173,7 @@ set ( INC_FILES inc/MantidAPI/ExperimentInfo.h inc/MantidAPI/Expression.h inc/MantidAPI/FermiChopperModel.h + inc/MantidAPI/FileBackedExperimentInfo.h inc/MantidAPI/FileFinder.h inc/MantidAPI/FileLoaderRegistry.h inc/MantidAPI/FileProperty.h @@ -180,6 +183,7 @@ set ( INC_FILES inc/MantidAPI/FunctionDomain1D.h inc/MantidAPI/FunctionDomainMD.h inc/MantidAPI/FunctionFactory.h + inc/MantidAPI/FunctionParameterDecorator.h inc/MantidAPI/FunctionProperty.h inc/MantidAPI/FunctionValues.h inc/MantidAPI/GridDomain.h @@ -253,7 +257,7 @@ set ( INC_FILES inc/MantidAPI/ParamFunction.h inc/MantidAPI/ParameterReference.h inc/MantidAPI/ParameterTie.h - inc/MantidAPI/PeakFunctionIntegrator.h + inc/MantidAPI/PeakFunctionIntegrator.h inc/MantidAPI/PeakTransform.h inc/MantidAPI/PeakTransformFactory.h inc/MantidAPI/PeakTransformHKL.h @@ -311,12 +315,14 @@ set ( TEST_FILES ExperimentInfoTest.h ExpressionTest.h FermiChopperModelTest.h + FileBackedExperimentInfoTest.h FileFinderTest.h FilePropertyTest.h FrameworkManagerTest.h FuncMinimizerFactoryTest.h FunctionAttributeTest.h FunctionDomainTest.h + FunctionParameterDecoratorTest.h FunctionFactoryTest.h FunctionPropertyTest.h FunctionTest.h @@ -350,7 +356,7 @@ set ( TEST_FILES ParamFunctionAttributeHolderTest.h ParameterReferenceTest.h ParameterTieTest.h - PeakFunctionIntegratorTest.h + PeakFunctionIntegratorTest.h PeakTransformHKLTest.h PeakTransformQLabTest.h PeakTransformQSampleTest.h diff --git a/Code/Mantid/Framework/API/inc/MantidAPI/ExperimentInfo.h b/Code/Mantid/Framework/API/inc/MantidAPI/ExperimentInfo.h index 0c81757b517b..b2012724e47f 100644 --- a/Code/Mantid/Framework/API/inc/MantidAPI/ExperimentInfo.h +++ b/Code/Mantid/Framework/API/inc/MantidAPI/ExperimentInfo.h @@ -34,8 +34,6 @@ class ModeratorModel; * - Run object (sample logs) * - Sample object (sample info) * - * @author Janik Zikovsky - * @date 2011-06-20 */ class MANTID_API_DLL ExperimentInfo { public: @@ -48,94 +46,94 @@ class MANTID_API_DLL ExperimentInfo { /// Copy everything from the given experiment object void copyExperimentInfoFrom(const ExperimentInfo *other); /// Clone us - ExperimentInfo *cloneExperimentInfo() const; + virtual ExperimentInfo *cloneExperimentInfo() const; /// Returns a string description of the object - const std::string toString() const; + virtual const std::string toString() const; /// Instrument accessors void setInstrument(const Geometry::Instrument_const_sptr &instr); /// Returns the parameterized instrument - Geometry::Instrument_const_sptr getInstrument() const; + virtual Geometry::Instrument_const_sptr getInstrument() const; /// Returns the set of parameters modifying the base instrument /// (const-version) - const Geometry::ParameterMap &instrumentParameters() const; + virtual const Geometry::ParameterMap &instrumentParameters() const; /// Returns a modifiable set of instrument parameters - Geometry::ParameterMap &instrumentParameters(); + virtual Geometry::ParameterMap &instrumentParameters(); /// Const version - const Geometry::ParameterMap &constInstrumentParameters() const; + virtual const Geometry::ParameterMap &constInstrumentParameters() const; // Add parameters to the instrument parameter map virtual void populateInstrumentParameters(); /// Replaces current parameter map with copy of given map - void replaceInstrumentParameters(const Geometry::ParameterMap &pmap); + virtual void replaceInstrumentParameters(const Geometry::ParameterMap &pmap); /// exchange contents of current parameter map with contents of other map) - void swapInstrumentParameters(Geometry::ParameterMap &pmap); + virtual void swapInstrumentParameters(Geometry::ParameterMap &pmap); /// Cache a lookup of grouped detIDs to member IDs - void cacheDetectorGroupings(const det2group_map &mapping); + virtual void cacheDetectorGroupings(const det2group_map &mapping); /// Returns the detector IDs that make up the group that this ID is part of - const std::vector &getGroupMembers(const detid_t detID) const; + virtual const std::vector &getGroupMembers(const detid_t detID) const; /// Get a detector or detector group from an ID - Geometry::IDetector_const_sptr getDetectorByID(const detid_t detID) const; + virtual Geometry::IDetector_const_sptr getDetectorByID(const detid_t detID) const; /// Set an object describing the source properties and take ownership - void setModeratorModel(ModeratorModel *source); + virtual void setModeratorModel(ModeratorModel *source); /// Returns a reference to the source properties object - ModeratorModel &moderatorModel() const; + virtual ModeratorModel &moderatorModel() const; /// Set a chopper description specified by index where 0 is closest to the /// source - void setChopperModel(ChopperModel *chopper, const size_t index = 0); + virtual void setChopperModel(ChopperModel *chopper, const size_t index = 0); /// Returns a reference to a chopper description - ChopperModel &chopperModel(const size_t index = 0) const; + virtual ChopperModel &chopperModel(const size_t index = 0) const; /// Sample accessors - const Sample &sample() const; + virtual const Sample &sample() const; /// Writable version of the sample object - Sample &mutableSample(); + virtual Sample &mutableSample(); /// Run details object access - const Run &run() const; + virtual const Run &run() const; /// Writable version of the run object - Run &mutableRun(); + virtual Run &mutableRun(); /// Access a log for this experiment. - Kernel::Property *getLog(const std::string &log) const; + virtual Kernel::Property *getLog(const std::string &log) const; /// Access a single value from a log for this experiment. - double getLogAsSingleValue(const std::string &log) const; + virtual double getLogAsSingleValue(const std::string &log) const; /// Utility method to get the run number - int getRunNumber() const; + virtual int getRunNumber() const; /// Returns the emode for this run - Kernel::DeltaEMode::Type getEMode() const; + virtual Kernel::DeltaEMode::Type getEMode() const; /// Easy access to the efixed value for this run & detector ID - double getEFixed(const detid_t detID) const; + virtual double getEFixed(const detid_t detID) const; /// Easy access to the efixed value for this run & optional detector - double getEFixed(const Geometry::IDetector_const_sptr detector = + virtual double getEFixed(const Geometry::IDetector_const_sptr detector = Geometry::IDetector_const_sptr()) const; /// Set the efixed value for a given detector ID - void setEFixed(const detid_t detID, const double value); + virtual void setEFixed(const detid_t detID, const double value); /// Saves this experiment description to the open NeXus file - void saveExperimentInfoNexus(::NeXus::File *file) const; + virtual void saveExperimentInfoNexus(::NeXus::File *file) const; /// Loads an experiment description from the open NeXus file - void loadExperimentInfoNexus(::NeXus::File *file, std::string ¶meterStr); + virtual void loadExperimentInfoNexus(::NeXus::File *file, std::string ¶meterStr); /// Load the instrument from an open NeXus file. - void loadInstrumentInfoNexus(::NeXus::File *file, std::string ¶meterStr); + virtual void loadInstrumentInfoNexus(::NeXus::File *file, std::string ¶meterStr); /// Load the sample and log info from an open NeXus file. - void loadSampleAndLogInfoNexus(::NeXus::File *file); + virtual void loadSampleAndLogInfoNexus(::NeXus::File *file); /// Populate the parameter map given a string - void readParameterMap(const std::string ¶meterStr); + virtual void readParameterMap(const std::string ¶meterStr); /// Returns the start date for this experiment (or current time if no info /// available) - std::string getWorkspaceStartDate() const; + virtual std::string getWorkspaceStartDate() const; // run/experiment stat time if available, empty otherwise - std::string getAvailableWorkspaceStartDate() const; + virtual std::string getAvailableWorkspaceStartDate() const; // run end time if available, empty otherwise - std::string getAvailableWorkspaceEndDate() const; + virtual std::string getAvailableWorkspaceEndDate() const; /// Utility to retrieve the validity dates for the given IDF static void getValidFromTo(const std::string &IDFfilename, diff --git a/Code/Mantid/Framework/API/inc/MantidAPI/FileBackedExperimentInfo.h b/Code/Mantid/Framework/API/inc/MantidAPI/FileBackedExperimentInfo.h new file mode 100644 index 000000000000..2322fb3e882d --- /dev/null +++ b/Code/Mantid/Framework/API/inc/MantidAPI/FileBackedExperimentInfo.h @@ -0,0 +1,109 @@ +#ifndef MANTID_API_FILEBACKEDEXPERIMENTINFO_H_ +#define MANTID_API_FILEBACKEDEXPERIMENTINFO_H_ +//----------------------------------------------------------------------------- +// Includes +//----------------------------------------------------------------------------- +#include "MantidAPI/DllConfig.h" +#include "MantidAPI/ExperimentInfo.h" + +namespace Mantid { +namespace API { + +/** + Implements a lazy-loading mechanism for the experimental information + stored in a NeXus file. + + Copyright © 2015 ISIS Rutherford Appleton Laboratory, NScD Oak Ridge + National Laboratory & European Spallation Source + + This file is part of Mantid. + + Mantid is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + Mantid is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + + File change history is stored at: + Code Documentation is available at: + */ +class MANTID_API_DLL FileBackedExperimentInfo : public ExperimentInfo { +public: + /// Constructor + FileBackedExperimentInfo(const std::string & filename, const std::string &path); + + ExperimentInfo *cloneExperimentInfo() const; + + const std::string toString() const; + + Geometry::Instrument_const_sptr getInstrument() const; + + const Geometry::ParameterMap &instrumentParameters() const; + + Geometry::ParameterMap &instrumentParameters(); + + const Geometry::ParameterMap &constInstrumentParameters() const; + + void populateInstrumentParameters(); + + void replaceInstrumentParameters(const Geometry::ParameterMap &pmap); + + void swapInstrumentParameters(Geometry::ParameterMap &pmap); + + void cacheDetectorGroupings(const det2group_map &mapping); + + const std::vector &getGroupMembers(const detid_t detID) const; + + Geometry::IDetector_const_sptr getDetectorByID(const detid_t detID) const; + + void setModeratorModel(ModeratorModel *source); + + ModeratorModel &moderatorModel() const; + + void setChopperModel(ChopperModel *chopper, const size_t index = 0); + + ChopperModel &chopperModel(const size_t index = 0) const; + + const Sample &sample() const; + + Sample &mutableSample(); + + const Run &run() const; + + Run &mutableRun(); + + Kernel::Property *getLog(const std::string &log) const; + + double getLogAsSingleValue(const std::string &log) const; + + int getRunNumber() const; + + Kernel::DeltaEMode::Type getEMode() const; + + double getEFixed(const detid_t detID) const; + + double getEFixed(const Geometry::IDetector_const_sptr detector = + Geometry::IDetector_const_sptr()) const; + + void setEFixed(const detid_t detID, const double value); + +private: + void populateIfNotLoaded() const; + void populateFromFile() const; + + mutable bool m_loaded; + std::string m_filename; + std::string m_nxpath; +}; + +} // namespace API +} // namespace Mantid + +#endif /* MANTID_API_FILEBACKEDEXPERIMENTINFO_H_ */ diff --git a/Code/Mantid/Framework/API/inc/MantidAPI/FunctionParameterDecorator.h b/Code/Mantid/Framework/API/inc/MantidAPI/FunctionParameterDecorator.h new file mode 100644 index 000000000000..edbd2d70d720 --- /dev/null +++ b/Code/Mantid/Framework/API/inc/MantidAPI/FunctionParameterDecorator.h @@ -0,0 +1,154 @@ +#ifndef MANTID_API_FUNCTIONPARAMETERDECORATOR_H_ +#define MANTID_API_FUNCTIONPARAMETERDECORATOR_H_ + +#include "MantidAPI/DllConfig.h" +#include "MantidAPI/IFunction.h" + +namespace Mantid { +namespace API { + +/** FunctionParameterDecorator + + FunctionParameterDecorator is an alternative to ParamFunction. Instead of + storing the parameters itself, it stores an "internal function" and exposes + the parameters and attributes of this function. + + A function that implements this interface can use the decorated function + in its implementation of IFunction::function and IFunction::functionDeriv, + for example to modify the values calculated by the function. + + @author Michael Wedel, Paul Scherrer Institut - SINQ + @date 23/02/2015 + + Copyright © 2015 PSI-NXMM + + This file is part of Mantid. + + Mantid is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + Mantid is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + + File change history is stored at: + Code Documentation is available at: +*/ +class MANTID_API_DLL FunctionParameterDecorator : virtual public IFunction { +public: + FunctionParameterDecorator() : IFunction(), m_wrappedFunction() {} + virtual ~FunctionParameterDecorator() {} + + void setDecoratedFunction(const std::string &wrappedFunctionName); + IFunction_sptr getDecoratedFunction() const; + + IFunction_sptr clone() const; + + /// Set i-th parameter of decorated function. + virtual void setParameter(size_t i, const double &value, + bool explicitlySet = true); + /// Set i-th parameter description of decorated function. + virtual void setParameterDescription(size_t i, + const std::string &description); + /// Get i-th parameter of decorated function. + virtual double getParameter(size_t i) const; + /// Set parameter of decorated function by name. + virtual void setParameter(const std::string &name, const double &value, + bool explicitlySet = true); + /// Set description of parameter of decorated function by name. + virtual void setParameterDescription(const std::string &name, + const std::string &description); + /// Get parameter of decorated function by name. + virtual double getParameter(const std::string &name) const; + /// Total number of parameters of decorated function. + virtual size_t nParams() const; + /// Returns the index of parameter of decorated function name. + virtual size_t parameterIndex(const std::string &name) const; + /// Returns the name of parameter i of decorated function. + virtual std::string parameterName(size_t i) const; + /// Returns the description of parameter i of decorated function. + virtual std::string parameterDescription(size_t i) const; + /// Checks if a parameter of decorated function has been set explicitly + virtual bool isExplicitlySet(size_t i) const; + /// Get the fitting error for a parameter of decorated function. + virtual double getError(size_t i) const; + /// Set the fitting error for a parameter of decorated function. + virtual void setError(size_t i, double err); + + /// Check if a declared parameter i of decorated function is active. + virtual bool isFixed(size_t i) const; + /// Removes a declared parameter i of decorated function from the list of + /// active. + virtual void fix(size_t i); + /// Restores a declared parameter i of decorated function to the active + /// status. + virtual void unfix(size_t i); + + /// Return parameter index of decorated function from a parameter reference. + /// Usefull for constraints and ties in composite functions. + virtual size_t getParameterIndex(const ParameterReference &ref) const; + + /// Returns the number of attributes associated with the decorated function. + virtual size_t nAttributes() const; + /// Returns a list of attribute names of decorated function. + virtual std::vector getAttributeNames() const; + /// Return a value of attribute attName of decorated function- + virtual IFunction::Attribute getAttribute(const std::string &attName) const; + /// Set a value to attribute attName of decorated function. + virtual void setAttribute(const std::string &attName, + const IFunction::Attribute &attValue); + /// Check if attribute attName exists in decorated function + virtual bool hasAttribute(const std::string &attName) const; + + /// Tie a parameter of decorated function to other parameters (or a constant). + virtual ParameterTie *tie(const std::string &parName, const std::string &expr, + bool isDefault = false); + /// Apply the ties in decorated function. + virtual void applyTies(); + /// Remove all ties of decorated function. + virtual void clearTies(); + virtual void removeTie(const std::string &parName); + /// Removes i-th parameter's of decorated function tie. + virtual bool removeTie(size_t i); + /// Get the tie of i-th parameter of decorated function. + virtual ParameterTie *getTie(size_t i) const; + + /// Add a constraint to decorated function. + virtual void addConstraint(IConstraint *ic); + /// Get constraint of i-th parameter of decorated function. + virtual IConstraint *getConstraint(size_t i) const; + /// Remove a constraint of decorated function. + virtual void removeConstraint(const std::string &parName); + /// Set parameters of decorated function to satisfy constraints. + void setUpForFit(); + +protected: + /// Does nothing. + void init() {} + + void throwIfNoFunctionSet() const; + + void declareParameter(const std::string &name, double initValue, + const std::string &description); + + virtual void addTie(ParameterTie *tie); + + virtual void beforeDecoratedFunctionSet(const IFunction_sptr &fn); + void setDecoratedFunctionPrivate(const IFunction_sptr &fn); + + IFunction_sptr m_wrappedFunction; +}; + +typedef boost::shared_ptr +FunctionParameterDecorator_sptr; + +} // namespace API +} // namespace Mantid + +#endif /* MANTID_API_FUNCTIONPARAMETERDECORATOR_H_ */ diff --git a/Code/Mantid/Framework/API/inc/MantidAPI/IPeakFunction.h b/Code/Mantid/Framework/API/inc/MantidAPI/IPeakFunction.h index 80e2899f880f..306029e845e1 100644 --- a/Code/Mantid/Framework/API/inc/MantidAPI/IPeakFunction.h +++ b/Code/Mantid/Framework/API/inc/MantidAPI/IPeakFunction.h @@ -70,6 +70,9 @@ class MANTID_API_DLL IPeakFunction : public IFunctionWithLocation { virtual void functionDerivLocal(Jacobian *out, const double *xValues, const size_t nData) = 0; + /// Get name of parameter that is associated to centre. + std::string getCentreParameterName() const; + protected: /// Defines the area around the centre where the peak values are to be /// calculated (in FWHM). diff --git a/Code/Mantid/Framework/API/inc/MantidAPI/NumericAxis.h b/Code/Mantid/Framework/API/inc/MantidAPI/NumericAxis.h index 12c51dc6ac50..47fdb2b72dbc 100644 --- a/Code/Mantid/Framework/API/inc/MantidAPI/NumericAxis.h +++ b/Code/Mantid/Framework/API/inc/MantidAPI/NumericAxis.h @@ -65,6 +65,8 @@ class MANTID_API_DLL NumericAxis : public Axis { virtual void setValue(const std::size_t &index, const double &value); size_t indexOfValue(const double value) const; virtual bool operator==(const Axis &) const; + virtual bool equalWithinTolerance(const Axis &axis2, + const double tolerance) const; std::string label(const std::size_t &index) const; /// Create bin boundaries from the point values virtual std::vector createBinBoundaries() const; diff --git a/Code/Mantid/Framework/API/inc/MantidAPI/RefAxis.h b/Code/Mantid/Framework/API/inc/MantidAPI/RefAxis.h index aeb0787d8171..09307005f23e 100644 --- a/Code/Mantid/Framework/API/inc/MantidAPI/RefAxis.h +++ b/Code/Mantid/Framework/API/inc/MantidAPI/RefAxis.h @@ -54,6 +54,8 @@ class MANTID_API_DLL RefAxis : public NumericAxis { const std::size_t &verticalIndex) const; virtual void setValue(const std::size_t &index, const double &value); virtual bool operator==(const Axis &) const; + virtual bool equalWithinTolerance(const Axis &axis2, + const double tolerance) const; virtual double getMin() const; virtual double getMax() const; diff --git a/Code/Mantid/Framework/API/inc/MantidAPI/SpectrumDetectorMapping.h b/Code/Mantid/Framework/API/inc/MantidAPI/SpectrumDetectorMapping.h index 3696d507d896..8f2ee4c75e44 100644 --- a/Code/Mantid/Framework/API/inc/MantidAPI/SpectrumDetectorMapping.h +++ b/Code/Mantid/Framework/API/inc/MantidAPI/SpectrumDetectorMapping.h @@ -53,7 +53,8 @@ class MANTID_API_DLL SpectrumDetectorMapping { typedef boost::unordered_map> sdmap; public: - explicit SpectrumDetectorMapping(const MatrixWorkspace *const workspace); + explicit SpectrumDetectorMapping(const MatrixWorkspace *const workspace, + bool useSpecNoIndex = true); SpectrumDetectorMapping( const std::vector &spectrumNumbers, const std::vector &detectorIDs, @@ -67,7 +68,10 @@ class MANTID_API_DLL SpectrumDetectorMapping { std::set getSpectrumNumbers() const; const std::set & getDetectorIDsForSpectrumNo(const specid_t spectrumNo) const; + const std::set & + getDetectorIDsForSpectrumIndex(const size_t index) const; const sdmap &getMapping() const; + bool indexIsSpecNumber() const; private: void fillMapFromArray(const specid_t *const spectrumNumbers, @@ -77,6 +81,7 @@ class MANTID_API_DLL SpectrumDetectorMapping { const std::vector &detectorIDs, const std::vector &ignoreDetIDs); + bool m_indexIsSpecNo; /// The mapping of a spectrum number to zero or more detector IDs sdmap m_mapping; }; diff --git a/Code/Mantid/Framework/API/src/FileBackedExperimentInfo.cpp b/Code/Mantid/Framework/API/src/FileBackedExperimentInfo.cpp new file mode 100644 index 000000000000..79bff7b89c77 --- /dev/null +++ b/Code/Mantid/Framework/API/src/FileBackedExperimentInfo.cpp @@ -0,0 +1,315 @@ +//---------------------------------------------------------------------------------------------- +// Includes +//---------------------------------------------------------------------------------------------- +#include "MantidAPI/FileBackedExperimentInfo.h" + +#include + +#include +#include + + +namespace Mantid { +namespace API { + +namespace { + +/// static logger object +Kernel::Logger g_log("FileBackedExperimentInfo"); +} + +/** + * Create an object based on a NeXus file and path + * @param filename The full path to the file + * @param nxpath Path to the location of the experiment information + */ +FileBackedExperimentInfo::FileBackedExperimentInfo(const std::string &filename, + const std::string &nxpath) + : ExperimentInfo(), m_loaded(false), m_filename(filename), m_nxpath(nxpath) {} + +/** + * @return A clone of the object + */ +ExperimentInfo *FileBackedExperimentInfo::cloneExperimentInfo() const { + populateIfNotLoaded(); + return ExperimentInfo::cloneExperimentInfo(); +} + +/// @returns A human-readable description of the object +const std::string FileBackedExperimentInfo::toString() const { + populateIfNotLoaded(); + return ExperimentInfo::toString(); +} + +/// @return A pointer to the parametrized instrument +Geometry::Instrument_const_sptr +FileBackedExperimentInfo::getInstrument() const { + populateIfNotLoaded(); + return ExperimentInfo::getInstrument(); +} + +/** + * @return A reference to a const version of the parameter map + */ +const Geometry::ParameterMap & +FileBackedExperimentInfo::instrumentParameters() const { + populateIfNotLoaded(); + return ExperimentInfo::instrumentParameters(); +} + +/** + * @return A reference to a non-const version of the parameter map + */ +Geometry::ParameterMap &FileBackedExperimentInfo::instrumentParameters() { + populateIfNotLoaded(); + return ExperimentInfo::instrumentParameters(); +} + +/** + * @return A reference to a const version of the parameter map + */ +const Geometry::ParameterMap & +FileBackedExperimentInfo::constInstrumentParameters() const { + populateIfNotLoaded(); + return ExperimentInfo::constInstrumentParameters(); +} + +/** + * Populate object with instrument parameters + */ +void FileBackedExperimentInfo::populateInstrumentParameters() { + populateIfNotLoaded(); + return ExperimentInfo::populateInstrumentParameters(); +} + +/** + * Populate object and then replace parameter map + * @param pmap The new parameter map + */ +void FileBackedExperimentInfo::replaceInstrumentParameters( + const Geometry::ParameterMap &pmap) { + populateIfNotLoaded(); + ExperimentInfo::replaceInstrumentParameters(pmap); +} + +/** + * Populate object and then swap parameter map + * @param pmap The new parameter map + */ +void FileBackedExperimentInfo::swapInstrumentParameters( + Geometry::ParameterMap &pmap) { + populateIfNotLoaded(); + ExperimentInfo::swapInstrumentParameters(pmap); +} + +/** + * Populate the object and cache the groupings + * @param mapping A set of the detector mappings + */ +void +FileBackedExperimentInfo::cacheDetectorGroupings(const det2group_map &mapping) { + populateIfNotLoaded(); + ExperimentInfo::cacheDetectorGroupings(mapping); +} + +/** + * Populate the object and returns the members of the group for a given ID + * @param detID A detector ID to lookup + */ +const std::vector & +FileBackedExperimentInfo::getGroupMembers(const detid_t detID) const { + populateIfNotLoaded(); + return ExperimentInfo::getGroupMembers(detID); +} + +/** + * Populate the object and return a detector by ID + * @param detID A detector ID to lookup + */ +Geometry::IDetector_const_sptr +FileBackedExperimentInfo::getDetectorByID(const detid_t detID) const { + populateIfNotLoaded(); + return ExperimentInfo::getDetectorByID(detID); +} + +/** + * Populate the object and set the moderator model + * @param source A pointer to the model of the moderator + */ +void FileBackedExperimentInfo::setModeratorModel(ModeratorModel *source) { + populateIfNotLoaded(); + ExperimentInfo::setModeratorModel(source); +} + +/** + * @return The object governing the moderator model + */ +ModeratorModel &FileBackedExperimentInfo::moderatorModel() const { + populateIfNotLoaded(); + return ExperimentInfo::moderatorModel(); +} + +/** + * Populate the object & set the model governing the chopper + * @param chopper The model governing the chopper + * @param index The index of the chopper + */ +void FileBackedExperimentInfo::setChopperModel(ChopperModel *chopper, + const size_t index) { + populateIfNotLoaded(); + ExperimentInfo::setChopperModel(chopper, index); +} + +/** + * Populate the object & return the model of the chopper + * @param index The index of the chopper + */ +ChopperModel &FileBackedExperimentInfo::chopperModel(const size_t index) const { + populateIfNotLoaded(); + return ExperimentInfo::chopperModel(index); +} + +/** + * Populate object and return the Sample + * @return A const reference to the Sample + */ +const Sample &FileBackedExperimentInfo::sample() const { + populateIfNotLoaded(); + return ExperimentInfo::sample(); +} + +/** + * Populate object and return a non-const reference to the sample + * @return A non-const reference to the Sample + */ +Sample &FileBackedExperimentInfo::mutableSample() { + populateIfNotLoaded(); + return ExperimentInfo::mutableSample(); +} + +/** + * Populate object and return a const reference to the run + * @return A const reference to the Run + */ +const Run &FileBackedExperimentInfo::run() const { + populateIfNotLoaded(); + return ExperimentInfo::run(); +} + +/** + * Populate object and return a non-const reference to the run + * @return A non-const reference to the Run + */ +Run &FileBackedExperimentInfo::mutableRun() { + populateIfNotLoaded(); + return ExperimentInfo::mutableRun(); +} + +/** + * Return a pointer to a log entry + * @param log A string name of the log + * @return A pointer to the log entry + */ +Kernel::Property * +FileBackedExperimentInfo::getLog(const std::string &log) const { + populateIfNotLoaded(); + return ExperimentInfo::getLog(log); +} + +/** + * Return a pointer to a log entry + * @param log A string name of the log + * @return A pointer to the log entry + */ +double +FileBackedExperimentInfo::getLogAsSingleValue(const std::string &log) const { + populateIfNotLoaded(); + return ExperimentInfo::getLogAsSingleValue(log); +} + +/** + * @return The run number + */ +int FileBackedExperimentInfo::getRunNumber() const { + populateIfNotLoaded(); + return ExperimentInfo::getRunNumber(); +} + +/** + * @return The inelastic energy mode + */ +Kernel::DeltaEMode::Type FileBackedExperimentInfo::getEMode() const { + populateIfNotLoaded(); + return ExperimentInfo::getEMode(); +} + +/** + * @return The efixed for a given detector + * @param detID The ID of the detector + */ +double FileBackedExperimentInfo::getEFixed(const detid_t detID) const { + populateIfNotLoaded(); + return ExperimentInfo::getEFixed(detID); +} + +/** + * Return the efixed value for a given detector + * @param detector The detector object + */ +double FileBackedExperimentInfo::getEFixed( + const Geometry::IDetector_const_sptr detector) const { + populateIfNotLoaded(); + return ExperimentInfo::getEFixed(detector); +} + +/** + * Set the efixed value for a given detector + * @param detID The ID of the detector + * @param value The value of EFixed + */ +void FileBackedExperimentInfo::setEFixed(const detid_t detID, + const double value) { + populateIfNotLoaded(); + ExperimentInfo::setEFixed(detID, value); +} + +//------------------------------------------------------------------------------------------------------ +// Private members +//------------------------------------------------------------------------------------------------------ +/** + * Check if the object has been populated and load the information if + * it has not + */ +void FileBackedExperimentInfo::populateIfNotLoaded() const { + if (m_loaded) + return; + populateFromFile(); +} + +/** + * Populate this object with the data from the file + */ +void FileBackedExperimentInfo::populateFromFile() const { + try { + ::NeXus::File nxFile(m_filename); + nxFile.openPath(m_nxpath); + // The loadExperimentInfo calls things such as mutableSample() + // and if m_loaded is not true then this function is + // will be called recursively. + m_loaded = true; + + std::string parameterStr; + const_cast(this) + ->loadExperimentInfoNexus(&nxFile, parameterStr); + const_cast(this) + ->readParameterMap(parameterStr); + } catch (::NeXus::Exception &exc) { + std::ostringstream os; + os << "Unable to load experiment information from NeXus file: " + << exc.what() << "\n"; + throw std::runtime_error(os.str()); + } +} + +} // namespace API +} // namespace Mantid diff --git a/Code/Mantid/Framework/API/src/FunctionParameterDecorator.cpp b/Code/Mantid/Framework/API/src/FunctionParameterDecorator.cpp new file mode 100644 index 000000000000..aec1d169f14e --- /dev/null +++ b/Code/Mantid/Framework/API/src/FunctionParameterDecorator.cpp @@ -0,0 +1,288 @@ +#include "MantidAPI/FunctionParameterDecorator.h" +#include "MantidAPI/FunctionFactory.h" + +namespace Mantid { +namespace API { + +void FunctionParameterDecorator::setDecoratedFunction( + const std::string &wrappedFunctionName) { + IFunction_sptr fn = + FunctionFactory::Instance().createFunction(wrappedFunctionName); + + beforeDecoratedFunctionSet(fn); + + setDecoratedFunctionPrivate(fn); +} + +IFunction_sptr FunctionParameterDecorator::getDecoratedFunction() const { + return m_wrappedFunction; +} + +IFunction_sptr FunctionParameterDecorator::clone() const { + FunctionParameterDecorator_sptr cloned = + boost::dynamic_pointer_cast( + FunctionFactory::Instance().createFunction(name())); + + if (!cloned) { + throw std::runtime_error( + "Cloned function is not of type FunctionParameterDecorator, aborting."); + } + + IFunction_sptr decoratedFn = getDecoratedFunction(); + + if (decoratedFn) { + cloned->setDecoratedFunctionPrivate(decoratedFn->clone()); + } + + return cloned; +} + +void FunctionParameterDecorator::setParameter(size_t i, const double &value, + bool explicitlySet) { + throwIfNoFunctionSet(); + + m_wrappedFunction->setParameter(i, value, explicitlySet); +} + +void FunctionParameterDecorator::setParameterDescription( + size_t i, const std::string &description) { + throwIfNoFunctionSet(); + + m_wrappedFunction->setParameterDescription(i, description); +} + +double FunctionParameterDecorator::getParameter(size_t i) const { + throwIfNoFunctionSet(); + + return m_wrappedFunction->getParameter(i); +} + +void FunctionParameterDecorator::setParameter(const std::string &name, + const double &value, + bool explicitlySet) { + throwIfNoFunctionSet(); + + m_wrappedFunction->setParameter(name, value, explicitlySet); +} + +void FunctionParameterDecorator::setParameterDescription( + const std::string &name, const std::string &description) { + throwIfNoFunctionSet(); + + m_wrappedFunction->setParameterDescription(name, description); +} + +double FunctionParameterDecorator::getParameter(const std::string &name) const { + throwIfNoFunctionSet(); + + return m_wrappedFunction->getParameter(name); +} + +size_t FunctionParameterDecorator::nParams() const { + if(!m_wrappedFunction) { + return 0; + } + + return m_wrappedFunction->nParams(); +} + +size_t +FunctionParameterDecorator::parameterIndex(const std::string &name) const { + throwIfNoFunctionSet(); + + return m_wrappedFunction->parameterIndex(name); +} + +std::string FunctionParameterDecorator::parameterName(size_t i) const { + throwIfNoFunctionSet(); + + return m_wrappedFunction->parameterName(i); +} + +std::string FunctionParameterDecorator::parameterDescription(size_t i) const { + throwIfNoFunctionSet(); + + return m_wrappedFunction->parameterDescription(i); +} + +bool FunctionParameterDecorator::isExplicitlySet(size_t i) const { + throwIfNoFunctionSet(); + + return m_wrappedFunction->isExplicitlySet(i); +} + +double FunctionParameterDecorator::getError(size_t i) const { + throwIfNoFunctionSet(); + + return m_wrappedFunction->getError(i); +} + +void FunctionParameterDecorator::setError(size_t i, double err) { + throwIfNoFunctionSet(); + + return m_wrappedFunction->setError(i, err); +} + +bool FunctionParameterDecorator::isFixed(size_t i) const { + throwIfNoFunctionSet(); + + return m_wrappedFunction->isFixed(i); +} + +void FunctionParameterDecorator::fix(size_t i) { + throwIfNoFunctionSet(); + + m_wrappedFunction->fix(i); +} + +void FunctionParameterDecorator::unfix(size_t i) { + throwIfNoFunctionSet(); + + m_wrappedFunction->unfix(i); +} + +size_t FunctionParameterDecorator::getParameterIndex( + const ParameterReference &ref) const { + throwIfNoFunctionSet(); + + return m_wrappedFunction->getParameterIndex(ref); +} + +size_t FunctionParameterDecorator::nAttributes() const { + if(!m_wrappedFunction) { + return 0; + } + + return m_wrappedFunction->nAttributes(); +} + +std::vector FunctionParameterDecorator::getAttributeNames() const { + throwIfNoFunctionSet(); + + return m_wrappedFunction->getAttributeNames(); +} + +IFunction::Attribute +FunctionParameterDecorator::getAttribute(const std::string &attName) const { + throwIfNoFunctionSet(); + + return m_wrappedFunction->getAttribute(attName); +} + +void +FunctionParameterDecorator::setAttribute(const std::string &attName, + const IFunction::Attribute &attValue) { + throwIfNoFunctionSet(); + + m_wrappedFunction->setAttribute(attName, attValue); +} + +bool +FunctionParameterDecorator::hasAttribute(const std::string &attName) const { + throwIfNoFunctionSet(); + + return m_wrappedFunction->hasAttribute(attName); +} + +ParameterTie *FunctionParameterDecorator::tie(const std::string &parName, + const std::string &expr, + bool isDefault) { + throwIfNoFunctionSet(); + + return m_wrappedFunction->tie(parName, expr, isDefault); +} + +void FunctionParameterDecorator::applyTies() { + throwIfNoFunctionSet(); + + m_wrappedFunction->applyTies(); +} + +void FunctionParameterDecorator::clearTies() { + throwIfNoFunctionSet(); + + m_wrappedFunction->clearTies(); +} + +void FunctionParameterDecorator::removeTie(const std::string &parName) { + throwIfNoFunctionSet(); + + m_wrappedFunction->removeTie(parName); +} + +bool FunctionParameterDecorator::removeTie(size_t i) { + throwIfNoFunctionSet(); + + return m_wrappedFunction->removeTie(i); +} + +ParameterTie *FunctionParameterDecorator::getTie(size_t i) const { + throwIfNoFunctionSet(); + + return m_wrappedFunction->getTie(i); +} + +void FunctionParameterDecorator::addConstraint(IConstraint *ic) { + throwIfNoFunctionSet(); + + m_wrappedFunction->addConstraint(ic); +} + +IConstraint *FunctionParameterDecorator::getConstraint(size_t i) const { + throwIfNoFunctionSet(); + + return m_wrappedFunction->getConstraint(i); +} + +void FunctionParameterDecorator::removeConstraint(const std::string &parName) { + throwIfNoFunctionSet(); + + m_wrappedFunction->removeConstraint(parName); +} + +void FunctionParameterDecorator::setUpForFit() { + throwIfNoFunctionSet(); + + m_wrappedFunction->setUpForFit(); +} + +/// Throws std::runtime_error when m_wrappedFunction is not set. +void FunctionParameterDecorator::throwIfNoFunctionSet() const { + if (!m_wrappedFunction) { + throw std::runtime_error("No wrapped function set, aborting."); + } +} + +/// Does nothing, function does not have parameters. +void FunctionParameterDecorator::declareParameter( + const std::string &name, double initValue, const std::string &description) { + UNUSED_ARG(name); + UNUSED_ARG(initValue); + UNUSED_ARG(description); +} + +/// Does nothing. +void FunctionParameterDecorator::addTie(ParameterTie *tie) { UNUSED_ARG(tie); } + +/** + * @brief Function that is called before the decorated function is set + * + * This function is called before the decorated function is actually set, with + * the function object in question as a parameter. The base implementation does + * nothing. Re-implementations could for example check whether the function + * has a certain type and throw an exception otherwise. + * + * @param fn :: Function that is going to be decorated. + */ +void FunctionParameterDecorator::beforeDecoratedFunctionSet( + const IFunction_sptr &fn) { + UNUSED_ARG(fn); +} + +void FunctionParameterDecorator::setDecoratedFunctionPrivate( + const IFunction_sptr &fn) { + m_wrappedFunction = fn; +} + +} // namespace API +} // namespace Mantid diff --git a/Code/Mantid/Framework/API/src/IPeakFunction.cpp b/Code/Mantid/Framework/API/src/IPeakFunction.cpp index 07053b760fda..1fa16b418c7a 100644 --- a/Code/Mantid/Framework/API/src/IPeakFunction.cpp +++ b/Code/Mantid/Framework/API/src/IPeakFunction.cpp @@ -2,12 +2,15 @@ // Includes //---------------------------------------------------------------------- #include "MantidAPI/IPeakFunction.h" +#include "MantidAPI/FunctionFactory.h" #include "MantidAPI/Jacobian.h" #include "MantidAPI/PeakFunctionIntegrator.h" +#include "MantidAPI/FunctionParameterDecorator.h" #include "MantidKernel/Exception.h" #include "MantidKernel/ConfigService.h" #include +#include #include namespace Mantid { @@ -41,6 +44,35 @@ class PartialJacobian1 : public Jacobian { double get(size_t iY, size_t iP) { return m_J->get(m_iY0 + iY, iP); } }; +class TempJacobian : public Jacobian { +public: + TempJacobian(size_t y, size_t p) : m_y(y), m_p(p), m_J(y * p) {} + void set(size_t iY, size_t iP, double value) { + m_J[iY * m_p + iP] = value; + } + double get(size_t iY, size_t iP) { + return m_J[iY * m_p + iP]; + } + size_t maxParam(size_t iY) { + double max = -DBL_MAX; + size_t maxIndex = 0; + for(size_t i = 0; i < m_p; ++i) { + double current = get(iY, i); + if(current > max) { + maxIndex = i; + max = current; + } + } + + return maxIndex; + } + +protected: + size_t m_y; + size_t m_p; + std::vector m_J; +}; + /// Default value for the peak radius int IPeakFunction::s_peakRadius = 5; @@ -169,5 +201,25 @@ void IPeakFunction::setIntensity(const double newIntensity) { setHeight(newIntensity / currentIntensity * currentHeight); } +std::string IPeakFunction::getCentreParameterName() const { + FunctionParameterDecorator_sptr fn = + boost::dynamic_pointer_cast( + FunctionFactory::Instance().createFunction("PeakParameterFunction")); + + if (!fn) { + throw std::runtime_error( + "PeakParameterFunction could not be created successfully."); + } + + fn->setDecoratedFunction(this->name()); + + FunctionDomain1DVector domain(std::vector(4, 0.0)); + TempJacobian jacobian(4, fn->nParams()); + + fn->functionDeriv(domain, jacobian); + + return parameterName(jacobian.maxParam(0)); +} + } // namespace API } // namespace Mantid diff --git a/Code/Mantid/Framework/API/src/MatrixWorkspace.cpp b/Code/Mantid/Framework/API/src/MatrixWorkspace.cpp index c326c152d60c..c1bd3dd20807 100644 --- a/Code/Mantid/Framework/API/src/MatrixWorkspace.cpp +++ b/Code/Mantid/Framework/API/src/MatrixWorkspace.cpp @@ -152,8 +152,12 @@ void MatrixWorkspace::updateSpectraUsing(const SpectrumDetectorMapping &map) { for (size_t j = 0; j < getNumberHistograms(); ++j) { auto spec = getSpectrum(j); try { - spec->setDetectorIDs( - map.getDetectorIDsForSpectrumNo(spec->getSpectrumNo())); + if(map.indexIsSpecNumber()) + spec->setDetectorIDs( + map.getDetectorIDsForSpectrumNo(spec->getSpectrumNo())); + else + spec->setDetectorIDs( + map.getDetectorIDsForSpectrumIndex(j)); } catch (std::out_of_range &e) { // Get here if the spectrum number is not in the map. spec->clearDetectorIDs(); diff --git a/Code/Mantid/Framework/API/src/NumericAxis.cpp b/Code/Mantid/Framework/API/src/NumericAxis.cpp index ecdfda7a8443..c165db7295e4 100644 --- a/Code/Mantid/Framework/API/src/NumericAxis.cpp +++ b/Code/Mantid/Framework/API/src/NumericAxis.cpp @@ -6,10 +6,26 @@ #include "MantidKernel/VectorHelper.h" #include +#include #include "MantidKernel/Logger.h" namespace { Mantid::Kernel::Logger g_log("NumericAxis"); + +class EqualWithinTolerance { +public: + EqualWithinTolerance(double tolerance) : m_tolerance(tolerance) {}; + bool operator()(double a, double b) { + if (boost::math::isnan(a) && boost::math::isnan(b)) + return true; + if (boost::math::isinf(a) && boost::math::isinf(b)) + return true; + return std::abs(a - b) <= m_tolerance; + } + +private: + double m_tolerance; +}; } namespace Mantid { @@ -140,6 +156,16 @@ size_t NumericAxis::indexOfValue(const double value) const { * @return true if self and second axis are equal */ bool NumericAxis::operator==(const Axis &axis2) const { + return equalWithinTolerance(axis2, 1e-15); +} + +/** Check if two numeric axis are equivalent to a given tolerance + * @param axis2 :: Reference to the axis to compare to + * @param tolerance :: Tolerance to compare to + * @return true if self and second axis are equal + */ +bool NumericAxis::equalWithinTolerance(const Axis &axis2, + const double tolerance) const { if (length() != axis2.length()) { return false; } @@ -147,7 +173,10 @@ bool NumericAxis::operator==(const Axis &axis2) const { if (!spec2) { return false; } - return std::equal(m_values.begin(), m_values.end(), spec2->m_values.begin()); + // Check each value is within tolerance + EqualWithinTolerance comparison(tolerance); + return std::equal(m_values.begin(), m_values.end(), spec2->m_values.begin(), + comparison); } /** Returns a text label which shows the value at index and identifies the diff --git a/Code/Mantid/Framework/API/src/PropertyNexus.cpp b/Code/Mantid/Framework/API/src/PropertyNexus.cpp index 0290d469289b..22095f975d8c 100644 --- a/Code/Mantid/Framework/API/src/PropertyNexus.cpp +++ b/Code/Mantid/Framework/API/src/PropertyNexus.cpp @@ -186,9 +186,12 @@ Property *loadProperty(::NeXus::File *file, const std::string &group) { break; } - try { - file->getAttr("units", unitsStr); - } catch (::NeXus::Exception &) { + if(file->hasAttr("units")) + { + try { + file->getAttr("units", unitsStr); + } catch (::NeXus::Exception &) { + } } file->closeData(); file->closeGroup(); diff --git a/Code/Mantid/Framework/API/src/RefAxis.cpp b/Code/Mantid/Framework/API/src/RefAxis.cpp index 923d158ecb76..cd68d0027518 100644 --- a/Code/Mantid/Framework/API/src/RefAxis.cpp +++ b/Code/Mantid/Framework/API/src/RefAxis.cpp @@ -90,6 +90,17 @@ bool RefAxis::operator==(const Axis &axis2) const { return true; } +/** Check if two numeric axis are equivalent to a given tolerance + * @param axis2 :: Reference to the axis to compare to + * @param tolerance :: Tolerance to compare to + * @return true if self and second axis are equal + */ +bool RefAxis::equalWithinTolerance(const Axis &axis2, + const double tolerance) const { + UNUSED_ARG(tolerance); + return this->operator==(axis2); +} + double RefAxis::getMin() const { throw std::runtime_error("RefAxis cannot determine minimum value. Use readX " "on the workspace instead"); diff --git a/Code/Mantid/Framework/API/src/SpectrumDetectorMapping.cpp b/Code/Mantid/Framework/API/src/SpectrumDetectorMapping.cpp index a25256ba79bc..e3a58519268c 100644 --- a/Code/Mantid/Framework/API/src/SpectrumDetectorMapping.cpp +++ b/Code/Mantid/Framework/API/src/SpectrumDetectorMapping.cpp @@ -8,7 +8,8 @@ namespace API { * @throws std::invalid_argument if a null workspace pointer is passed in */ SpectrumDetectorMapping::SpectrumDetectorMapping( - const MatrixWorkspace *const workspace) { + const MatrixWorkspace *const workspace, + bool useSpecNoIndex): m_indexIsSpecNo(useSpecNoIndex) { if (!workspace) { throw std::invalid_argument( "SpectrumDetectorMapping: Null workspace pointer passed"); @@ -16,7 +17,14 @@ SpectrumDetectorMapping::SpectrumDetectorMapping( for (size_t i = 0; i < workspace->getNumberHistograms(); ++i) { auto spectrum = workspace->getSpectrum(i); - m_mapping[spectrum->getSpectrumNo()] = spectrum->getDetectorIDs(); + + int index; + if(m_indexIsSpecNo) + index = spectrum->getSpectrumNo(); + else + index = static_cast(i); + + m_mapping[index] = spectrum->getDetectorIDs(); } } @@ -28,7 +36,8 @@ SpectrumDetectorMapping::SpectrumDetectorMapping( SpectrumDetectorMapping::SpectrumDetectorMapping( const std::vector &spectrumNumbers, const std::vector &detectorIDs, - const std::vector &ignoreDetIDs) { + const std::vector &ignoreDetIDs): + m_indexIsSpecNo(true) { if (spectrumNumbers.size() != detectorIDs.size()) { throw std::invalid_argument("SpectrumDetectorMapping: Different length " "spectrum number & detector ID array passed"); @@ -43,7 +52,7 @@ SpectrumDetectorMapping::SpectrumDetectorMapping( */ SpectrumDetectorMapping::SpectrumDetectorMapping( const specid_t *const spectrumNumbers, const detid_t *const detectorIDs, - size_t arrayLengths) { + size_t arrayLengths): m_indexIsSpecNo(true) { if (spectrumNumbers == NULL || detectorIDs == NULL) { throw std::invalid_argument( "SpectrumDetectorMapping: Null array pointer passed"); @@ -93,13 +102,26 @@ std::set SpectrumDetectorMapping::getSpectrumNumbers() const { const std::set &SpectrumDetectorMapping::getDetectorIDsForSpectrumNo( const specid_t spectrumNo) const { + if(!m_indexIsSpecNo) + throw std::runtime_error("Indicies are in spectrum index, not number."); return m_mapping.at(spectrumNo); } +const std::set &SpectrumDetectorMapping::getDetectorIDsForSpectrumIndex( + const size_t spectrumIndex) const { + if(m_indexIsSpecNo) + throw std::runtime_error("Indicies are in spectrum number, not index."); + return m_mapping.at(static_cast(spectrumIndex)); +} + const SpectrumDetectorMapping::sdmap & SpectrumDetectorMapping::getMapping() const { return m_mapping; } +bool SpectrumDetectorMapping::indexIsSpecNumber() const { + return m_indexIsSpecNo; +} + } // namespace API } // namespace Mantid diff --git a/Code/Mantid/Framework/API/test/FileBackedExperimentInfoTest.h b/Code/Mantid/Framework/API/test/FileBackedExperimentInfoTest.h new file mode 100644 index 000000000000..b7ec12deea26 --- /dev/null +++ b/Code/Mantid/Framework/API/test/FileBackedExperimentInfoTest.h @@ -0,0 +1,236 @@ +#ifndef MANTID_API_FILEBACKEDEXPERIMENTINFOTEST_H_ +#define MANTID_API_FILEBACKEDEXPERIMENTINFOTEST_H_ + +#include +#include "ExperimentInfoTest.h" +#include "MantidAPI/FileBackedExperimentInfo.h" +#include "MantidAPI/FileFinder.h" +#include "MantidAPI/Run.h" +#include "MantidAPI/Sample.h" + +#include + +using Mantid::API::FileBackedExperimentInfo; + +class FileBackedExperimentInfoTest : 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 FileBackedExperimentInfoTest *createSuite() { + return new FileBackedExperimentInfoTest(); + } + static void destroySuite(FileBackedExperimentInfoTest *suite) { + delete suite; + } + + FileBackedExperimentInfoTest() { + using Mantid::API::ExperimentInfo; + using Mantid::API::FileFinder; + // Cache in-memory experiment info for comparison + m_filename = FileFinder::Instance().getFullPath("HRP38692a.nxs"); + if (m_filename.empty()) { + throw std::runtime_error("Cannot find test file HRP38692a.nxs"); + } + + m_inMemoryExptInfo = boost::make_shared(); + ::NeXus::File nxFile(m_filename, NXACC_READ); + nxFile.openGroup("mantid_workspace_1", "NXentry"); + std::string paramString; + m_inMemoryExptInfo->loadExperimentInfoNexus(&nxFile, paramString); + m_inMemoryExptInfo->readParameterMap(paramString); + } + + void test_toString_populates_object() { + auto fileBacked = createTestObject(); + TS_ASSERT_EQUALS(fileBacked->toString(), m_inMemoryExptInfo->toString()); + } + + void test_cloneExperimentInfo_populates_object() { + auto fileBacked = createTestObject(); + auto *clonedFileBacked = fileBacked->cloneExperimentInfo(); + + TS_ASSERT_EQUALS(clonedFileBacked->toString(), + m_inMemoryExptInfo->toString()); + delete clonedFileBacked; + } + + void test_getInstrument_populates_object() { + auto fileBacked = createTestObject(); + auto fileBackedInstrument = fileBacked->getInstrument(); + auto inMemoryInstrument = m_inMemoryExptInfo->getInstrument(); + + TS_ASSERT_EQUALS(fileBacked->constInstrumentParameters(), + m_inMemoryExptInfo->constInstrumentParameters()); + } + + void test_instrumentParameters_const_ref_method_populate_object() { + auto fileBacked = createTestObject(); + const auto &pmap = fileBacked->instrumentParameters(); // const + + TS_ASSERT(pmap.size() > 0); + } + + void test_nonconst_ref_instrumentParameters_method_populate_object() { + auto fileBacked = createTestObject(); + auto &pmap = fileBacked->instrumentParameters(); // non-const + + TS_ASSERT(pmap.size() > 0); + } + + void test_constInstrumentParameters_method_populate_object() { + auto fileBacked = createTestObject(); + const auto &pmap = fileBacked->constInstrumentParameters(); + + TS_ASSERT(pmap.size() > 0); + } + + void test_populateInstrumentParameters_method_populate_object() { + auto fileBacked = createTestObject(); + fileBacked->populateInstrumentParameters(); + const auto &pmap = fileBacked->constInstrumentParameters(); + + TS_ASSERT(pmap.size() > 0); + } + + void test_replaceInstrumentParameters_method_populate_object() { + using Mantid::Geometry::ParameterMap; + + auto fileBacked = createTestObject(); + ParameterMap emptyMap; + fileBacked->replaceInstrumentParameters(emptyMap); + + const auto &pmap = fileBacked->constInstrumentParameters(); + TS_ASSERT_EQUALS(0, pmap.size()); + } + + void test_swapInstrumentParameters_method_populate_object() { + using Mantid::Geometry::ParameterMap; + + auto fileBacked = createTestObject(); + ParameterMap emptyMap; + fileBacked->swapInstrumentParameters(emptyMap); + + const auto &pmap = fileBacked->constInstrumentParameters(); + TS_ASSERT_EQUALS(0, pmap.size()); + } + + void test_cacheDetectorGroupings() { + auto fileBacked = createTestObject(); + + std::vector group(2, 1); + group[1] = 2; + Mantid::det2group_map mapping; + mapping.insert(std::make_pair(1, group)); + fileBacked->cacheDetectorGroupings(mapping); + } + + void test_getGroupMembers() { + auto fileBacked = createTestObject(); + + std::vector group(2, 1); + group[1] = 2; + Mantid::det2group_map mapping; + mapping.insert(std::make_pair(1, group)); + fileBacked->cacheDetectorGroupings(mapping); + + TS_ASSERT_EQUALS(group, fileBacked->getGroupMembers(1)); + } + + void test_getDetectorByID() { + auto fileBacked = createTestObject(); + + TS_ASSERT(fileBacked->getDetectorByID(10100)); + } + + void test_ModeratorModelMethods() { + auto fileBacked = createTestObject(); + ModeratorModel *source = new FakeSource; + TS_ASSERT_THROWS_NOTHING(fileBacked->setModeratorModel(source)); + const ModeratorModel &fetched = fileBacked->moderatorModel(); + const ModeratorModel &constInput = + const_cast(*source); + TS_ASSERT_EQUALS(&fetched, &constInput); + } + + void test_chopperModelMethods() { + auto fileBacked = createTestObject(); + + TS_ASSERT_THROWS_NOTHING(fileBacked->setChopperModel(new FakeChopper)); + TS_ASSERT_THROWS_NOTHING(fileBacked->chopperModel(0)); + } + + void test_sample() { + auto fileBacked = createTestObject(); + + TS_ASSERT_EQUALS(m_inMemoryExptInfo->sample().getGeometryFlag(), + fileBacked->sample().getGeometryFlag()); + TS_ASSERT_EQUALS(m_inMemoryExptInfo->sample().getGeometryFlag(), + fileBacked->mutableSample().getGeometryFlag()); + } + + void test_run() { + auto fileBacked = createTestObject(); + + TS_ASSERT_EQUALS(m_inMemoryExptInfo->run().getProtonCharge(), + fileBacked->run().getProtonCharge()) + } + + void test_getLog() { + auto fileBacked = createTestObject(); + + TS_ASSERT_EQUALS(m_inMemoryExptInfo->getLogAsSingleValue("gd_prtn_chrg"), + fileBacked->getLogAsSingleValue("gd_prtn_chrg")); + + auto *inMemoryProp = m_inMemoryExptInfo->getLog("gd_prtn_chrg"); + auto *fileBackedProp = fileBacked->getLog("gd_prtn_chrg"); + TS_ASSERT_EQUALS(inMemoryProp->value(), fileBackedProp->value()); + } + + void test_getRunNumber() { + auto fileBacked = createTestObject(); + + TS_ASSERT_EQUALS(m_inMemoryExptInfo->getRunNumber(), + fileBacked->getRunNumber()); + } + + void test_getEMode() { + auto fileBacked = createTestObject(); + + TS_ASSERT_EQUALS(m_inMemoryExptInfo->getEMode(), fileBacked->getEMode()); + } + + void test_getEFixed() { + auto fileBacked = createTestObject(); + + TS_ASSERT_THROWS(fileBacked->getEFixed(10100), std::runtime_error); + } + + void test_setEFixed() { + auto fileBacked = createTestObject(); + + TS_ASSERT_THROWS_NOTHING(fileBacked->setEFixed(10100, 12.5)); + } + + //------------------------------------------------------------------------------------------------ + // Failure tests + //------------------------------------------------------------------------------------------------ + void test_runtime_error_generated_when_unable_to_load_from_file() { + // Create the file backed experiment info, shouldn't be loaded yet + FileBackedExperimentInfo fileBacked(m_filename, "/not/right/path"); + + TS_ASSERT_THROWS(fileBacked.toString(), std::runtime_error); + } + +private: + Mantid::API::ExperimentInfo_sptr createTestObject() { + // Create the file backed experiment info, shouldn't be loaded yet. + // Manipulate it through the interface + return boost::make_shared(m_filename, + "/mantid_workspace_1"); + } + + Mantid::API::ExperimentInfo_sptr m_inMemoryExptInfo; + std::string m_filename; +}; + +#endif /* MANTID_API_FILEBACKEDEXPERIMENTINFOTEST_H_ */ diff --git a/Code/Mantid/Framework/API/test/FunctionParameterDecoratorTest.h b/Code/Mantid/Framework/API/test/FunctionParameterDecoratorTest.h new file mode 100644 index 000000000000..4cea527b1a51 --- /dev/null +++ b/Code/Mantid/Framework/API/test/FunctionParameterDecoratorTest.h @@ -0,0 +1,368 @@ +#ifndef MANTID_API_WRAPPEDFUNCTIONTEST_H_ +#define MANTID_API_WRAPPEDFUNCTIONTEST_H_ + +#include + +#include "MantidAPI/FunctionParameterDecorator.h" +#include "MantidAPI/ParamFunction.h" +#include "MantidAPI/FunctionFactory.h" +#include "MantidKernel/Exception.h" +#include + +#include +#include + +using namespace Mantid::API; +using namespace Mantid::Kernel; + +using ::testing::_; +using ::testing::Mock; + +class FunctionParameterDecoratorTest; + +class TestableFunctionParameterDecorator : public FunctionParameterDecorator { + friend class FunctionParameterDecoratorTest; + +public: + TestableFunctionParameterDecorator() {} + ~TestableFunctionParameterDecorator() {} + + std::string name() const { return "TestableFunctionParameterDecorator"; } + + void function(const FunctionDomain &domain, FunctionValues &values) const { + throwIfNoFunctionSet(); + + IFunction_sptr fn = getDecoratedFunction(); + fn->function(domain, values); + } + + void functionDeriv(const FunctionDomain &domain, Jacobian &jacobian) { + throwIfNoFunctionSet(); + + IFunction_sptr fn = getDecoratedFunction(); + fn->functionDeriv(domain, jacobian); + } +}; + +DECLARE_FUNCTION(TestableFunctionParameterDecorator); + +class FunctionWithParameters : public ParamFunction { +public: + FunctionWithParameters() : ParamFunction() {} + + std::string name() const { return "FunctionWithParameters"; } + + void init() { + declareParameter("Height"); + declareParameter("PeakCentre"); + declareParameter("Sigma"); + } + + void function(const FunctionDomain &domain, FunctionValues &values) const { + UNUSED_ARG(domain); + UNUSED_ARG(values); + // Does nothing, not required for this test. + } +}; +DECLARE_FUNCTION(FunctionWithParameters); + +class FunctionWithAttributes : public ParamFunction { +public: + FunctionWithAttributes() : ParamFunction() {} + + std::string name() const { return "FunctionWithAttributes"; } + + void init() { + declareParameter("PeakCentre"); + declareParameter("Sigma"); + declareParameter("Height"); + + declareAttribute("Attribute1", IFunction::Attribute(1)); + declareAttribute("Attribute2", IFunction::Attribute("Test")); + } + + void function(const FunctionDomain &domain, FunctionValues &values) const { + UNUSED_ARG(domain); + UNUSED_ARG(values); + // Does nothing, not required for this test. + } +}; + +DECLARE_FUNCTION(FunctionWithAttributes); + +class FunctionParameterDecoratorTest : 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 FunctionParameterDecoratorTest *createSuite() { + return new FunctionParameterDecoratorTest(); + } + static void destroySuite(FunctionParameterDecoratorTest *suite) { + delete suite; + } + + void testSetDecoratedFunction() { + TestableFunctionParameterDecorator fn; + + TS_ASSERT_THROWS_NOTHING(fn.setDecoratedFunction("FunctionWithParameters")); + + IFunction_sptr decorated = fn.getDecoratedFunction(); + TS_ASSERT(decorated); + TS_ASSERT_EQUALS(decorated->name(), "FunctionWithParameters"); + } + + void testSetDecoratedFunctionInvalidName() { + TestableFunctionParameterDecorator fn; + TS_ASSERT_THROWS(fn.setDecoratedFunction("INVALIDFUNCTION"), + Exception::NotFoundError); + TS_ASSERT(!fn.getDecoratedFunction()); + } + + void testThrowIfNoFunctionSet() { + TestableFunctionParameterDecorator fn; + TS_ASSERT_THROWS(fn.throwIfNoFunctionSet(), std::runtime_error); + fn.setDecoratedFunction("FunctionWithParameters"); + TS_ASSERT_THROWS_NOTHING(fn.throwIfNoFunctionSet()); + } + + void testNParams() { + TestableFunctionParameterDecorator invalidFn; + TS_ASSERT_EQUALS(invalidFn.nParams(), 0); + + FunctionParameterDecorator_sptr fn = + getFunctionParameterDecoratorGaussian(); + IFunction_sptr decoratedFunction = fn->getDecoratedFunction(); + + TS_ASSERT_EQUALS(fn->nParams(), decoratedFunction->nParams()); + } + + void testGetSetParameter() { + TestableFunctionParameterDecorator invalidFn; + TS_ASSERT_THROWS(invalidFn.setParameter(0, 2.0), std::runtime_error); + TS_ASSERT_THROWS(invalidFn.getParameter(0), std::runtime_error); + TS_ASSERT_THROWS(invalidFn.setParameter("Height", 2.0), std::runtime_error); + TS_ASSERT_THROWS(invalidFn.getParameter("Height"), std::runtime_error); + + FunctionParameterDecorator_sptr fn = + getFunctionParameterDecoratorGaussian(); + + TS_ASSERT_THROWS_NOTHING(fn->setParameter(0, 2.0)); + + IFunction_sptr decoratedFunction = fn->getDecoratedFunction(); + TS_ASSERT_EQUALS(fn->getParameter(0), decoratedFunction->getParameter(0)); + TS_ASSERT_EQUALS(fn->getParameter(0), 2.0); + TS_ASSERT_THROWS(fn->getParameter(10), std::out_of_range); + + TS_ASSERT_THROWS_NOTHING(fn->setParameter("Height", 4.0)); + TS_ASSERT_EQUALS(fn->getParameter("Height"), + decoratedFunction->getParameter("Height")); + TS_ASSERT_EQUALS(fn->getParameter("Height"), 4.0); + TS_ASSERT_THROWS(fn->getParameter("DoesNotExist"), std::invalid_argument); + } + + void testExplicitelySet() { + TestableFunctionParameterDecorator invalidFn; + TS_ASSERT_THROWS(invalidFn.isExplicitlySet(0), std::runtime_error); + + FunctionParameterDecorator_sptr fn = + getFunctionParameterDecoratorGaussian(); + + TS_ASSERT_THROWS_NOTHING(fn->setParameter(0, 2.0)); + + IFunction_sptr decoratedFunction = fn->getDecoratedFunction(); + + for (size_t i = 0; i < fn->nParams(); ++i) { + TS_ASSERT_EQUALS(fn->isExplicitlySet(i), + decoratedFunction->isExplicitlySet(i)); + } + } + + void testGetSetError() { + TestableFunctionParameterDecorator invalidFn; + TS_ASSERT_THROWS(invalidFn.getError(0), std::runtime_error); + TS_ASSERT_THROWS(invalidFn.setError(0, 2.0), std::runtime_error); + + FunctionParameterDecorator_sptr fn = + getFunctionParameterDecoratorGaussian(); + IFunction_sptr decoratedFunction = fn->getDecoratedFunction(); + + TS_ASSERT_THROWS_NOTHING(fn->setError(0, 3.0)); + TS_ASSERT_EQUALS(fn->getError(0), 3.0); + for (size_t i = 0; i < fn->nParams(); ++i) { + TS_ASSERT_EQUALS(fn->getError(i), decoratedFunction->getError(i)); + } + } + + void testFixUnfixIsFixed() { + TestableFunctionParameterDecorator invalidFn; + TS_ASSERT_THROWS(invalidFn.isFixed(0), std::runtime_error); + TS_ASSERT_THROWS(invalidFn.fix(0), std::runtime_error); + TS_ASSERT_THROWS(invalidFn.unfix(0), std::runtime_error); + + FunctionParameterDecorator_sptr fn = + getFunctionParameterDecoratorGaussian(); + IFunction_sptr decoratedFunction = fn->getDecoratedFunction(); + + for (size_t i = 0; i < fn->nParams(); ++i) { + TS_ASSERT_THROWS_NOTHING(fn->fix(i)); + TS_ASSERT_EQUALS(fn->isFixed(i), decoratedFunction->isFixed(i)); + TS_ASSERT_EQUALS(fn->isFixed(i), true); + TS_ASSERT_THROWS_NOTHING(fn->unfix(i)); + TS_ASSERT_EQUALS(fn->isFixed(i), decoratedFunction->isFixed(i)); + TS_ASSERT_EQUALS(fn->isFixed(i), false); + } + } + + void testAttributes() { + TestableFunctionParameterDecorator invalidFn; + TS_ASSERT_EQUALS(invalidFn.nAttributes(), 0); + + FunctionParameterDecorator_sptr fn = + getFunctionParameterDecoratorGaussian(); + IFunction_sptr decoratedFunction = fn->getDecoratedFunction(); + + TS_ASSERT_EQUALS(fn->nAttributes(), decoratedFunction->nAttributes()); + TS_ASSERT_EQUALS(fn->nAttributes(), 0); + + fn->setDecoratedFunction("FunctionWithAttributes"); + decoratedFunction = fn->getDecoratedFunction(); + TS_ASSERT_EQUALS(fn->nAttributes(), decoratedFunction->nAttributes()); + TS_ASSERT_DIFFERS(fn->nAttributes(), 0); + + std::vector decoratorAttributes = fn->getAttributeNames(); + std::vector wrappedAttributes = + decoratedFunction->getAttributeNames(); + + TS_ASSERT_EQUALS(decoratorAttributes.size(), wrappedAttributes.size()); + + for (size_t i = 0; i < fn->nAttributes(); ++i) { + TS_ASSERT_EQUALS(decoratorAttributes[i], wrappedAttributes[i]); + std::string attribute = decoratorAttributes[i]; + + TS_ASSERT_EQUALS(fn->hasAttribute(attribute), + decoratedFunction->hasAttribute(attribute)); + TS_ASSERT_EQUALS(fn->hasAttribute(attribute), true); + } + + TS_ASSERT_THROWS_NOTHING( + fn->setAttribute(decoratorAttributes[0], IFunction::Attribute(4.0))); + TS_ASSERT_EQUALS( + fn->getAttribute(decoratorAttributes[0]).value(), + decoratedFunction->getAttribute(decoratorAttributes[0]).value()); + } + + void testTies() { + TestableFunctionParameterDecorator invalidFn; + TS_ASSERT_THROWS(invalidFn.tie("Name", "a=b"), std::runtime_error); + TS_ASSERT_THROWS(invalidFn.applyTies(), std::runtime_error); + TS_ASSERT_THROWS(invalidFn.clearTies(), std::runtime_error); + TS_ASSERT_THROWS(invalidFn.removeTie(0), std::runtime_error); + TS_ASSERT_THROWS(invalidFn.getTie(0), std::runtime_error); + + FunctionParameterDecorator_sptr fn = + getFunctionParameterDecoratorGaussian(); + IFunction_sptr decoratedFunction = fn->getDecoratedFunction(); + + ParameterTie *tie = fn->tie("Height", "Height=2.0*Sigma"); + TS_ASSERT(tie); + TS_ASSERT_EQUALS(decoratedFunction->getTie(0), tie); + + TS_ASSERT_THROWS_NOTHING(fn->clearTies()); + TS_ASSERT_THROWS_NOTHING(fn->addTies("Height=4.0*Sigma")); + TS_ASSERT_EQUALS(fn->getTie(0), decoratedFunction->getTie(0)); + TS_ASSERT(fn->getTie(0)); + TS_ASSERT_THROWS_NOTHING(fn->removeTie(0)); + + tie = fn->getTie(0); + TS_ASSERT(!tie); + } + + void testParameterNames() { + FunctionParameterDecorator_sptr fn = + getFunctionParameterDecoratorGaussian(); + + IFunction_sptr decoratedFunction = fn->getDecoratedFunction(); + + std::vector decoratorNames = fn->getParameterNames(); + std::vector wrappedNames = + decoratedFunction->getParameterNames(); + + TS_ASSERT_EQUALS(decoratorNames.size(), wrappedNames.size()); + TS_ASSERT_EQUALS(wrappedNames.size(), 3); + + for (size_t i = 0; i < decoratorNames.size(); ++i) { + TS_ASSERT_EQUALS(decoratorNames[i], wrappedNames[i]); + } + } + + void testSetParameterDescription() { + TestableFunctionParameterDecorator invalidFn; + TS_ASSERT_THROWS(invalidFn.setParameterDescription(0, "None"), + std::runtime_error); + TS_ASSERT_THROWS(invalidFn.parameterDescription(0), std::runtime_error); + + FunctionParameterDecorator_sptr fn = + getFunctionParameterDecoratorGaussian(); + + TS_ASSERT_THROWS_NOTHING(fn->setParameterDescription(0, "None")); + + IFunction_sptr decoratedFunction = fn->getDecoratedFunction(); + TS_ASSERT_EQUALS(fn->parameterDescription(0), + decoratedFunction->parameterDescription(0)); + TS_ASSERT_EQUALS(fn->parameterDescription(0), "None"); + TS_ASSERT_THROWS(fn->parameterDescription(10), std::out_of_range); + + TS_ASSERT_THROWS_NOTHING( + fn->setParameterDescription("Height", "Something")); + TS_ASSERT_THROWS(fn->setParameterDescription("DoesNotExist", "Something"), + std::invalid_argument); + } + + void testBeforeDecoratedFunctionSetIsCalled() { + MockTestableFunctionParameterDecorator fn; + EXPECT_CALL(fn, beforeDecoratedFunctionSet(_)).Times(1); + + fn.setDecoratedFunction("FunctionWithParameters"); + + TS_ASSERT(Mock::VerifyAndClearExpectations(&fn)); + } + + void testClone() { + FunctionParameterDecorator_sptr fn = + getFunctionParameterDecoratorGaussian(); + + fn->setParameter("Height", 3.0); + fn->setParameter("PeakCentre", 0.5); + fn->setParameter("Sigma", 0.3); + + IFunction_sptr cloned = fn->clone(); + + TS_ASSERT(cloned); + + FunctionParameterDecorator_sptr castedClone = + boost::dynamic_pointer_cast(cloned); + TS_ASSERT(castedClone); + TS_ASSERT_EQUALS(cloned->name(), fn->name()); + + TS_ASSERT_EQUALS(cloned->getParameter("Height"), 3.0); + TS_ASSERT_EQUALS(cloned->getParameter("PeakCentre"), 0.5); + TS_ASSERT_EQUALS(cloned->getParameter("Sigma"), 0.3); + } + +private: + FunctionParameterDecorator_sptr getFunctionParameterDecoratorGaussian() { + FunctionParameterDecorator_sptr fn = + boost::make_shared(); + fn->setDecoratedFunction("FunctionWithParameters"); + + return fn; + } + + class MockTestableFunctionParameterDecorator + : public TestableFunctionParameterDecorator { + public: + MOCK_METHOD1(beforeDecoratedFunctionSet, void(const IFunction_sptr &)); + }; +}; + +#endif /* MANTID_API_WRAPPEDFUNCTIONTEST_H_ */ diff --git a/Code/Mantid/Framework/API/test/HistoryViewTest.h b/Code/Mantid/Framework/API/test/HistoryViewTest.h index ff93c52b0a7e..d1fa5f807947 100644 --- a/Code/Mantid/Framework/API/test/HistoryViewTest.h +++ b/Code/Mantid/Framework/API/test/HistoryViewTest.h @@ -13,6 +13,14 @@ using Mantid::Kernel::DateAndTime; class HistoryViewTest : 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 HistoryViewTest *createSuite() { return new HistoryViewTest(); } + static void destroySuite( HistoryViewTest *suite ) { delete suite; } + +private: + // 'Empty' algorithm class for tests class testalg : public Algorithm { diff --git a/Code/Mantid/Framework/API/test/NumericAxisTest.h b/Code/Mantid/Framework/API/test/NumericAxisTest.h index 8bfc02c76131..075fa591c84f 100644 --- a/Code/Mantid/Framework/API/test/NumericAxisTest.h +++ b/Code/Mantid/Framework/API/test/NumericAxisTest.h @@ -34,12 +34,12 @@ class NumericAxisTest : public CxxTest::TestSuite numericAxis = new NumericAxis(5); numericAxis->title() = "A numeric axis"; } - + ~NumericAxisTest() { delete numericAxis; } - + void testConstructor() { TS_ASSERT_EQUALS( numericAxis->title(), "A numeric axis" ); @@ -56,7 +56,7 @@ class NumericAxisTest : public CxxTest::TestSuite axistester.title() = "tester"; axistester.unit() = UnitFactory::Instance().create("Wavelength"); axistester.setValue(0,5.5); - + NumericAxisTester copiedAxis = axistester; TS_ASSERT_EQUALS( copiedAxis.title(), "tester" ); TS_ASSERT_EQUALS( copiedAxis.unit()->unitID(), "Wavelength" ); @@ -64,7 +64,7 @@ class NumericAxisTest : public CxxTest::TestSuite TS_ASSERT_EQUALS( copiedAxis(0), 5.5 ); TS_ASSERT_THROWS( copiedAxis(1), Exception::IndexError ); } - + void testClone() { WorkspaceTester ws; // Fake workspace to pass to clone @@ -72,7 +72,7 @@ class NumericAxisTest : public CxxTest::TestSuite TS_ASSERT_DIFFERS( newNumAxis, numericAxis ); delete newNumAxis; } - + void testCloneDifferentLength() { numericAxis->setValue(0,9.9); @@ -124,7 +124,7 @@ class NumericAxisTest : public CxxTest::TestSuite { TS_ASSERT_THROWS( numericAxis->setValue(-1, 1.1), Exception::IndexError ); TS_ASSERT_THROWS( numericAxis->setValue(5, 1.1), Exception::IndexError ); - + for (int i=0; i<5; ++i) { TS_ASSERT_THROWS_NOTHING( numericAxis->setValue(i, i+0.5) ); @@ -146,7 +146,7 @@ class NumericAxisTest : public CxxTest::TestSuite { axis.setValue(i, static_cast(i)); } - + std::vector boundaries = axis.createBinBoundaries(); const size_t nvalues(boundaries.size()); TS_ASSERT_EQUALS(nvalues, npoints + 1); @@ -172,6 +172,66 @@ class NumericAxisTest : public CxxTest::TestSuite TS_ASSERT_EQUALS(4, axis.indexOfValue(5.4)); } + /** + * Default equality is tested to a tolerance of 1e-15. + */ + void test_equal() + { + double points1[] = {1.0, 2.0, 10e-16, 4.0, 5.0}; + double points2[] = {1.0, 2.0, 20e-16, 4.0, 5.0}; // Just inside the tolerance + double points3[] = {1.0, 2.0, 21e-16, 4.0, 5.0}; // Just outsie the tolerance + const size_t npoints(5); + NumericAxis axis1(std::vector(points1, points1 + npoints)); + NumericAxis axis2(std::vector(points2, points2 + npoints)); + NumericAxis axis3(std::vector(points3, points3 + npoints)); + + TS_ASSERT( axis1 == axis2 ); + TS_ASSERT( !(axis1 == axis3) ); + } + + void test_equalWithinTolerance() + { + double points1[] = {1.0, 2.0, 3.0, 4.0, 5.0}; + double points2[] = {1.0, 2.0, 3.0, 4.0, 5.001}; + const size_t npoints(5); + NumericAxis axis1(std::vector(points1, points1 + npoints)); + NumericAxis axis2(std::vector(points2, points2 + npoints)); + + // Difference (0.001) < tolerance (0.01), should be equal + TS_ASSERT( axis1.equalWithinTolerance(axis2, 0.01) ); + + // Difference (0.001) > tolerance (0.0001), should not be equal + TS_ASSERT( !axis1.equalWithinTolerance(axis2, 0.0001) ); + } + + void test_equalWithinTolerance_Nan() + { + double points1[] = {1.0, 2.0, NAN, 4.0, 5.0}; + double points2[] = {1.0, 2.0, NAN, 4.0, 5.0}; + double points3[] = {1.0, 2.0, 3.0, 4.0, 5.0}; + const size_t npoints(5); + NumericAxis axis1(std::vector(points1, points1 + npoints)); + NumericAxis axis2(std::vector(points2, points2 + npoints)); + NumericAxis axis3(std::vector(points3, points3 + npoints)); + + TS_ASSERT( axis1.equalWithinTolerance(axis2, 0.01) ); + TS_ASSERT( !axis1.equalWithinTolerance(axis3, 0.01) ); + } + + void test_equalWithinTolerance_Inf() + { + double points1[] = {1.0, 2.0, INFINITY, 4.0, 5.0}; + double points2[] = {1.0, 2.0, INFINITY, 4.0, 5.0}; + double points3[] = {1.0, 2.0, 3.0, 4.0, 5.0}; + const size_t npoints(5); + NumericAxis axis1(std::vector(points1, points1 + npoints)); + NumericAxis axis2(std::vector(points2, points2 + npoints)); + NumericAxis axis3(std::vector(points3, points3 + npoints)); + + TS_ASSERT( axis1.equalWithinTolerance(axis2, 0.01) ); + TS_ASSERT( !axis1.equalWithinTolerance(axis3, 0.01) ); + } + //-------------------------------- Failure cases ---------------------------- void test_indexOfValue_Throws_When_Input_Not_In_Axis_Range() diff --git a/Code/Mantid/Framework/API/test/PeakFunctionIntegratorTest.h b/Code/Mantid/Framework/API/test/PeakFunctionIntegratorTest.h index 49c3be3b83e4..f48c7b4d7ad2 100644 --- a/Code/Mantid/Framework/API/test/PeakFunctionIntegratorTest.h +++ b/Code/Mantid/Framework/API/test/PeakFunctionIntegratorTest.h @@ -3,10 +3,9 @@ #include #include "MantidAPI/PeakFunctionIntegrator.h" -#include "MantidAPI/FrameworkManager.h" -#include "MantidAPI/FunctionFactory.h" #include "gsl/gsl_errno.h" +#include using namespace Mantid::API; using namespace Mantid::CurveFitting; @@ -25,18 +24,55 @@ class TestablePeakFunctionIntegrator : public PeakFunctionIntegrator friend class PeakFunctionIntegratorTest; }; -class PeakFunctionIntegratorTest : public CxxTest::TestSuite +class LocalGaussian : public IPeakFunction { -private: - PeakFunctionIntegratorTest() - { - FrameworkManager::Instance(); +public: + LocalGaussian() : IPeakFunction() {} + + std::string name() const { return "LocalGaussian"; } + + double centre() const { return getParameter("Center"); } + void setCentre(const double c) { setParameter("Center", c); } + + double fwhm() const { return getParameter("Sigma") * (2.0 * sqrt(2.0 * log(2.0))); } + void setFwhm(const double w) { setParameter("Sigma", w / (2.0 * sqrt(2.0 * log(2.0)))); } + + double height() const { return getParameter("Height"); } + void setHeight(const double h) { setParameter("Height", h); } + + void init() { + declareParameter("Center"); + declareParameter("Sigma"); + declareParameter("Height"); + } + + void functionLocal(double *out, const double *xValues, const size_t nData) const { + double h = getParameter("Height"); + double s = getParameter("Sigma"); + double c = getParameter("Center"); + + for(size_t i = 0; i < nData; ++i) { + out[i] = h * exp(-0.5 * pow(((xValues[i] - c)/s), 2)); + } } + void functionDerivLocal(Jacobian *out, const double *xValues, const size_t nData) { + UNUSED_ARG(out); + UNUSED_ARG(xValues); + UNUSED_ARG(nData); + + // Do nothing - not required for this test. + } +}; + +class PeakFunctionIntegratorTest : public CxxTest::TestSuite +{ +private: IPeakFunction_sptr getGaussian(double center, double fwhm, double height) { - IPeakFunction_sptr gaussian = boost::dynamic_pointer_cast( - FunctionFactory::Instance().createFunction("Gaussian")); + IPeakFunction_sptr gaussian = boost::make_shared(); + gaussian->initialize(); + gaussian->setCentre(center); gaussian->setFwhm(fwhm); gaussian->setHeight(height); @@ -49,22 +85,6 @@ class PeakFunctionIntegratorTest : public CxxTest::TestSuite return gaussian->height() * gaussian->fwhm() / (2.0 * sqrt(2.0 * log(2.0))) * sqrt(2.0 * M_PI); } - IPeakFunction_sptr getLorentzian(double center, double fwhm, double height) - { - IPeakFunction_sptr lorentzian = boost::dynamic_pointer_cast( - FunctionFactory::Instance().createFunction("Lorentzian")); - lorentzian->setCentre(center); - lorentzian->setFwhm(fwhm); - lorentzian->setHeight(height); - - return lorentzian; - } - - double getLorentzianAnalyticalInfiniteIntegral(IPeakFunction_sptr lorentzian) - { - return lorentzian->getParameter("Amplitude"); - } - public: // This pair of boilerplate methods prevent the suite being created statically // This means the constructor isn't called when running other tests @@ -163,17 +183,6 @@ class PeakFunctionIntegratorTest : public CxxTest::TestSuite TS_ASSERT_DELTA(rThreeSigma.result, 0.997300203936740, integrator.requiredRelativePrecision()); } - void testIntegrateInfinityLorentzian() - { - IPeakFunction_sptr lorentzian = getLorentzian(0.0, 3.0, 8.0); - PeakFunctionIntegrator integrator(1e-8); - - IntegrationResult result = integrator.integrateInfinity(*lorentzian); - TS_ASSERT_EQUALS(result.errorCode, static_cast(GSL_SUCCESS)); - TS_ASSERT_DELTA(result.result, getLorentzianAnalyticalInfiniteIntegral(lorentzian), integrator.requiredRelativePrecision()); - TS_ASSERT_LESS_THAN(result.intervals, 1000); - } - }; #endif // PEAKFUNCTIONINTEGRATORTEST_H diff --git a/Code/Mantid/Framework/API/test/SpectrumDetectorMappingTest.h b/Code/Mantid/Framework/API/test/SpectrumDetectorMappingTest.h index 86c4517e11b1..f6fde2259426 100644 --- a/Code/Mantid/Framework/API/test/SpectrumDetectorMappingTest.h +++ b/Code/Mantid/Framework/API/test/SpectrumDetectorMappingTest.h @@ -153,7 +153,7 @@ class SpectrumDetectorMappingTest : public CxxTest::TestSuite void test_getDetectorIDsForSpectrumNo() { - auto ws = boost::make_shared(); + MatrixWorkspace_sptr ws = boost::make_shared(); SpectrumDetectorMapping map(ws.get()); // The happy path is tested in the methods above. Just test invalid entry here. TS_ASSERT_THROWS( map.getDetectorIDsForSpectrumNo(1), std::out_of_range ); diff --git a/Code/Mantid/Framework/Algorithms/CMakeLists.txt b/Code/Mantid/Framework/Algorithms/CMakeLists.txt index e39b23dc712a..e2bebdb804b0 100644 --- a/Code/Mantid/Framework/Algorithms/CMakeLists.txt +++ b/Code/Mantid/Framework/Algorithms/CMakeLists.txt @@ -52,6 +52,7 @@ set ( SRC_FILES src/ConvertToMatrixWorkspace.cpp src/ConvertToPointData.cpp src/ConvertUnits.cpp + src/CopyDetectorMapping.cpp src/CopyInstrumentParameters.cpp src/CopyLogs.cpp src/CopySample.cpp @@ -90,7 +91,7 @@ set ( SRC_FILES src/EQSANSTofStructure.cpp src/EditInstrumentGeometry.cpp src/ElasticWindow.cpp - src/EstimatePDDetectorResolution.cpp + src/EstimateResolutionDiffraction.cpp src/Exponential.cpp src/ExponentialCorrection.cpp src/ExportTimeSeriesLog.cpp @@ -175,6 +176,7 @@ set ( SRC_FILES src/Q1DWeighted.cpp src/Qhelper.cpp src/Qxy.cpp + src/RRFMuon.cpp src/RadiusSum.cpp src/RayTracerTester.cpp src/ReadGroupsFromFile.cpp @@ -191,7 +193,7 @@ set ( SRC_FILES src/ReflectometryReductionOneAuto.cpp src/ReflectometryWorkflowBase.cpp src/Regroup.cpp - src/RemoveBackground.cpp + src/RemoveBackground.cpp src/RemoveBins.cpp src/RemoveExpDecay.cpp src/RemoveLowResTOF.cpp @@ -204,12 +206,12 @@ set ( SRC_FILES src/ResetNegatives.cpp src/ResizeRectangularDetector.cpp src/RingProfile.cpp - src/RRFMuon.cpp src/SANSDirectBeamScaling.cpp src/SassenaFFT.cpp src/SaveGSASInstrumentFile.cpp src/Scale.cpp src/ScaleX.cpp + src/Segfault.cpp src/SetInstrumentParameter.cpp src/SetUncertainties.cpp src/ShiftLogTime.cpp @@ -237,7 +239,7 @@ set ( SRC_FILES src/SumRowColumn.cpp src/SumSpectra.cpp src/TOFSANSResolution.cpp - src/TOFSANSResolutionByPixel.cpp + src/TOFSANSResolutionByPixel.cpp src/Transpose.cpp src/UnGroupWorkspace.cpp src/UnaryOperation.cpp @@ -306,6 +308,7 @@ set ( INC_FILES inc/MantidAlgorithms/ConvertToMatrixWorkspace.h inc/MantidAlgorithms/ConvertToPointData.h inc/MantidAlgorithms/ConvertUnits.h + inc/MantidAlgorithms/CopyDetectorMapping.h inc/MantidAlgorithms/CopyInstrumentParameters.h inc/MantidAlgorithms/CopyLogs.h inc/MantidAlgorithms/CopySample.h @@ -344,7 +347,7 @@ set ( INC_FILES inc/MantidAlgorithms/EQSANSTofStructure.h inc/MantidAlgorithms/EditInstrumentGeometry.h inc/MantidAlgorithms/ElasticWindow.h - inc/MantidAlgorithms/EstimatePDDetectorResolution.h + inc/MantidAlgorithms/EstimateResolutionDiffraction.h inc/MantidAlgorithms/Exponential.h inc/MantidAlgorithms/ExponentialCorrection.h inc/MantidAlgorithms/ExportTimeSeriesLog.h @@ -430,6 +433,7 @@ set ( INC_FILES inc/MantidAlgorithms/Q1DWeighted.h inc/MantidAlgorithms/Qhelper.h inc/MantidAlgorithms/Qxy.h + inc/MantidAlgorithms/RRFMuon.h inc/MantidAlgorithms/RadiusSum.h inc/MantidAlgorithms/RayTracerTester.h inc/MantidAlgorithms/ReadGroupsFromFile.h @@ -446,7 +450,7 @@ set ( INC_FILES inc/MantidAlgorithms/ReflectometryReductionOneAuto.h inc/MantidAlgorithms/ReflectometryWorkflowBase.h inc/MantidAlgorithms/Regroup.h - inc/MantidAlgorithms/RemoveBackground.h + inc/MantidAlgorithms/RemoveBackground.h inc/MantidAlgorithms/RemoveBins.h inc/MantidAlgorithms/RemoveExpDecay.h inc/MantidAlgorithms/RemoveLowResTOF.h @@ -459,12 +463,12 @@ set ( INC_FILES inc/MantidAlgorithms/ResetNegatives.h inc/MantidAlgorithms/ResizeRectangularDetector.h inc/MantidAlgorithms/RingProfile.h - inc/MantidAlgorithms/RRFMuon.h inc/MantidAlgorithms/SANSDirectBeamScaling.h inc/MantidAlgorithms/SassenaFFT.h inc/MantidAlgorithms/SaveGSASInstrumentFile.h inc/MantidAlgorithms/Scale.h inc/MantidAlgorithms/ScaleX.h + inc/MantidAlgorithms/Segfault.h inc/MantidAlgorithms/SetInstrumentParameter.h inc/MantidAlgorithms/SetUncertainties.h inc/MantidAlgorithms/ShiftLogTime.h @@ -492,7 +496,7 @@ set ( INC_FILES inc/MantidAlgorithms/SumRowColumn.h inc/MantidAlgorithms/SumSpectra.h inc/MantidAlgorithms/TOFSANSResolution.h - inc/MantidAlgorithms/TOFSANSResolutionByPixel.h + inc/MantidAlgorithms/TOFSANSResolutionByPixel.h inc/MantidAlgorithms/Transpose.h inc/MantidAlgorithms/UnGroupWorkspace.h inc/MantidAlgorithms/UnaryOperation.h @@ -571,6 +575,7 @@ set ( TEST_FILES ConvertToMatrixWorkspaceTest.h ConvertToPointDataTest.h ConvertUnitsTest.h + CopyDetectorMappingTest.h CopyInstrumentParametersTest.h CopyLogsTest.h CopySampleTest.h @@ -604,8 +609,8 @@ set ( TEST_FILES DiffractionFocussingTest.h DivideTest.h EditInstrumentGeometryTest.h - ElasticWindowTest.h - EstimatePDDetectorResolutionTest.h + ElasticWindowTest.h + EstimateResolutionDiffractionTest.h ExponentialCorrectionTest.h ExponentialTest.h ExportTimeSeriesLogTest.h @@ -669,7 +674,7 @@ set ( TEST_FILES PDFFourierTransformTest.h PauseTest.h PerformIndexOperationsTest.h - PhaseQuadMuonTest.h + PhaseQuadMuonTest.h PlotAsymmetryByLogValueTest.h PlusTest.h PointByPointVCorrectionTest.h diff --git a/Code/Mantid/Framework/Algorithms/inc/MantidAlgorithms/CopyDetectorMapping.h b/Code/Mantid/Framework/Algorithms/inc/MantidAlgorithms/CopyDetectorMapping.h new file mode 100644 index 000000000000..a9d2827a04bb --- /dev/null +++ b/Code/Mantid/Framework/Algorithms/inc/MantidAlgorithms/CopyDetectorMapping.h @@ -0,0 +1,72 @@ +#ifndef MANTID_ALGORITHMS_COPYDETECTORMAPPING_H_ +#define MANTID_ALGORITHMS_COPYDETECTORMAPPING_H_ + +//---------------------------------------------------------------------- +// Includes +//---------------------------------------------------------------------- +#include "MantidAPI/Algorithm.h" + +namespace Mantid { +namespace Algorithms { + +/** + Algorithm to copy spectra-detector mapping from one matrix workspace + to another. + + @author Dan Nixon + + Copyright © 2010 ISIS Rutherford Appleton Laboratory, NScD Oak Ridge + National Laboratory & European Spallation Source + + This file is part of Mantid. + + Mantid is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + Mantid is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + + File change history is stored at: + Code Documentation is available at: +*/ +class DLLExport CopyDetectorMapping : public API::Algorithm { +public: + /// (Empty) Constructor + CopyDetectorMapping() : API::Algorithm() {} + /// Virtual destructor + virtual ~CopyDetectorMapping() {} + /// Algorithm's name + virtual const std::string name() const { return "CopyDetectorMapping"; } + /// Summary of algorithms purpose + virtual const std::string summary() const { + return "Copies spectra to detector mapping from one Matrix Workspace to another."; + } + + /// Algorithm's version + virtual int version() const { return (1); } + /// Algorithm's category for identification + virtual const std::string category() const { + return "DataHandling"; + } + + /// Input property validation + virtual std::map validateInputs(); + +private: + /// Initialisation code + void init(); + /// Execution code + void exec(); +}; + +} // namespace Algorithms +} // namespace Mantid + +#endif /*MANTID_ALGORITHMS_COPYDETECTORMAPPING_H_*/ diff --git a/Code/Mantid/Framework/Algorithms/inc/MantidAlgorithms/EstimatePDDetectorResolution.h b/Code/Mantid/Framework/Algorithms/inc/MantidAlgorithms/EstimateResolutionDiffraction.h similarity index 73% rename from Code/Mantid/Framework/Algorithms/inc/MantidAlgorithms/EstimatePDDetectorResolution.h rename to Code/Mantid/Framework/Algorithms/inc/MantidAlgorithms/EstimateResolutionDiffraction.h index ca9dd6c09337..8c24786a6d2f 100644 --- a/Code/Mantid/Framework/Algorithms/inc/MantidAlgorithms/EstimatePDDetectorResolution.h +++ b/Code/Mantid/Framework/Algorithms/inc/MantidAlgorithms/EstimateResolutionDiffraction.h @@ -1,5 +1,5 @@ -#ifndef MANTID_ALGORITHMS_ESTIMATEPDDETECTORRESOLUTION_H_ -#define MANTID_ALGORITHMS_ESTIMATEPDDETECTORRESOLUTION_H_ +#ifndef MANTID_ALGORITHMS_ESTIMATERESOLUTIONDIFFRACTION_H_ +#define MANTID_ALGORITHMS_ESTIMATERESOLUTIONDIFFRACTION_H_ #include "MantidKernel/System.h" #include "MantidAPI/Algorithm.h" @@ -8,7 +8,7 @@ namespace Mantid { namespace Algorithms { -/** EstimatePDDetectorResolution : TODO: DESCRIPTION +/** EstimateResolutionDiffraction : TODO: DESCRIPTION Copyright © 2014 ISIS Rutherford Appleton Laboratory, NScD Oak Ridge National Laboratory & European Spallation Source @@ -31,25 +31,25 @@ namespace Algorithms { File change history is stored at: Code Documentation is available at: */ -class DLLExport EstimatePDDetectorResolution : public API::Algorithm { +class DLLExport EstimateResolutionDiffraction : public API::Algorithm { public: - EstimatePDDetectorResolution(); - virtual ~EstimatePDDetectorResolution(); + EstimateResolutionDiffraction(); + virtual ~EstimateResolutionDiffraction(); /// Algorithm's name for identification overriding a virtual method - virtual const std::string name() const { - return "EstimatePDDetectorResolution"; - } + virtual const std::string name() const; + + /// function to return any aliases to the algorithm + virtual const std::string alias() const; + /// Summary of algorithms purpose - virtual const std::string summary() const { - return "Estimate the resolution of each detector for a powder " - "diffractometer. "; - } + virtual const std::string summary() const; /// Algorithm's version for identification overriding a virtual method - virtual int version() const { return 1; } + virtual int version() const; + /// Algorithm's category for identification overriding a virtual method - virtual const std::string category() const { return "Diffraction"; } + virtual const std::string category() const; private: /// Implement abstract Algorithm methods @@ -57,6 +57,9 @@ class DLLExport EstimatePDDetectorResolution : public API::Algorithm { /// Implement abstract Algorithm methods void exec(); + /// Returns the wavelength from either the property or the input workspace + double getWavelength(); + /// Process input properties for algorithm void processAlgProperties(); @@ -90,4 +93,4 @@ class DLLExport EstimatePDDetectorResolution : public API::Algorithm { } // namespace Algorithms } // namespace Mantid -#endif /* MANTID_ALGORITHMS_ESTIMATEPDDETECTORRESOLUTION_H_ */ +#endif /* MANTID_ALGORITHMS_ESTIMATERESOLUTIONDIFFRACTION_H_ */ diff --git a/Code/Mantid/Framework/Algorithms/inc/MantidAlgorithms/PhaseQuadMuon.h b/Code/Mantid/Framework/Algorithms/inc/MantidAlgorithms/PhaseQuadMuon.h index 1cb937441b4d..ddd716bd9206 100644 --- a/Code/Mantid/Framework/Algorithms/inc/MantidAlgorithms/PhaseQuadMuon.h +++ b/Code/Mantid/Framework/Algorithms/inc/MantidAlgorithms/PhaseQuadMuon.h @@ -46,7 +46,7 @@ class DLLExport PhaseQuadMuon : public API::Algorithm { virtual const std::string name() const { return "PhaseQuad"; } /// Summary of algorithm's purpose virtual const std::string summary() const { - return "Calculate Muon squashograms from InputWorkspace and PhaseTable."; + return "Calculate Muon squashograms from InputWorkspace and PhaseTable/PhaseList."; } /// Algorithm's version for identification overriding a virtual method diff --git a/Code/Mantid/Framework/Algorithms/inc/MantidAlgorithms/Segfault.h b/Code/Mantid/Framework/Algorithms/inc/MantidAlgorithms/Segfault.h new file mode 100644 index 000000000000..cf88da31c35e --- /dev/null +++ b/Code/Mantid/Framework/Algorithms/inc/MantidAlgorithms/Segfault.h @@ -0,0 +1,56 @@ +#ifndef MANTID_ALGORITHMS_SEGFAULT_H_ +#define MANTID_ALGORITHMS_SEGFAULT_H_ + +#include "MantidKernel/System.h" +#include "MantidAPI/Algorithm.h" + +namespace Mantid +{ +namespace Algorithms +{ + + /** Segfault : TODO: DESCRIPTION + + Copyright © 2015 ISIS Rutherford Appleton Laboratory, NScD Oak Ridge National Laboratory & European Spallation Source + + This file is part of Mantid. + + Mantid is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + Mantid is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + + File change history is stored at: + Code Documentation is available at: + */ + class DLLExport Segfault : public API::Algorithm + { + public: + Segfault(); + virtual ~Segfault(); + + 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_SEGFAULT_H_ */ \ No newline at end of file diff --git a/Code/Mantid/Framework/Algorithms/src/CheckWorkspacesMatch.cpp b/Code/Mantid/Framework/Algorithms/src/CheckWorkspacesMatch.cpp index 148d7631fe7f..7f7c4cbec7d0 100644 --- a/Code/Mantid/Framework/Algorithms/src/CheckWorkspacesMatch.cpp +++ b/Code/Mantid/Framework/Algorithms/src/CheckWorkspacesMatch.cpp @@ -7,6 +7,7 @@ #include "MantidAPI/IMDHistoWorkspace.h" #include "MantidAPI/WorkspaceGroup.h" #include "MantidAPI/IPeak.h" +#include "MantidAPI/NumericAxis.h" #include "MantidAPI/TableRow.h" #include "MantidDataObjects/EventWorkspace.h" #include "MantidDataObjects/Events.h" @@ -640,7 +641,14 @@ bool CheckWorkspacesMatch::checkAxes(API::MatrixWorkspace_const_sptr ws1, // Use Axis's equality operator to check length and values // Don't check spectra axis as that just takes it values from the ISpectrum // (see checkSpectraMap) - if (!ax1->isSpectra() && !ax1->operator==(*ax2)) { + if (ax1->isNumeric() && ax2->isNumeric()) { + const NumericAxis *na1 = static_cast(ax1); + const double tolerance = getProperty("Tolerance"); + if (!na1->equalWithinTolerance(*ax2, tolerance)) { + result = axis_name + " values mismatch"; + return false; + } + } else if (!ax1->isSpectra() && !ax1->operator==(*ax2)) { result = axis_name + " values mismatch"; return false; } @@ -800,12 +808,14 @@ bool CheckWorkspacesMatch::checkRunProperties(const API::Run &run1, double run1Charge(-1.0); try { run1Charge = run1.getProtonCharge(); - } catch (Exception::NotFoundError &) { + } + catch (Exception::NotFoundError &) { } double run2Charge(-1.0); try { run2Charge = run2.getProtonCharge(); - } catch (Exception::NotFoundError &) { + } + catch (Exception::NotFoundError &) { } if (run1Charge != run2Charge) { diff --git a/Code/Mantid/Framework/Algorithms/src/CopyDetectorMapping.cpp b/Code/Mantid/Framework/Algorithms/src/CopyDetectorMapping.cpp new file mode 100644 index 000000000000..b66eba51a5a0 --- /dev/null +++ b/Code/Mantid/Framework/Algorithms/src/CopyDetectorMapping.cpp @@ -0,0 +1,71 @@ +//---------------------------------------------------------------------- +// Includes +//---------------------------------------------------------------------- +#include "MantidAlgorithms/CopyDetectorMapping.h" +#include "MantidAPI/SpectrumDetectorMapping.h" + +namespace Mantid { +namespace Algorithms { + +DECLARE_ALGORITHM(CopyDetectorMapping) + +using namespace Kernel; +using namespace API; + +void CopyDetectorMapping::init() { + declareProperty(new WorkspaceProperty("WorkspaceToMatch", "", + Direction::Input)); + + declareProperty(new WorkspaceProperty("WorkspaceToRemap", "", + Direction::InOut)); + + declareProperty( + new PropertyWithValue("IndexBySpectrumNumber", false, + Direction::Input), + "Will use mapping indexed by spectrum number rather than the default of" + "spectrum index (recommended when both workspaces have a vertical axis " + "in spectrum number)."); +} + +void CopyDetectorMapping::exec() { + MatrixWorkspace_const_sptr wsToMatch = getProperty("WorkspaceToMatch"); + MatrixWorkspace_sptr wsToRemap = getProperty("WorkspaceToRemap"); + bool indexBySpecNumber = getProperty("IndexBySpectrumNumber"); + + // Copy detector mapping + SpectrumDetectorMapping detMap(wsToMatch.get(), indexBySpecNumber); + wsToRemap->updateSpectraUsing(detMap); + + setProperty("WorkspaceToRemap", wsToRemap); +} + +std::map CopyDetectorMapping::validateInputs() { + std::map issues; + + MatrixWorkspace_sptr wsToMatch = getProperty("WorkspaceToMatch"); + MatrixWorkspace_sptr wsToRemap = getProperty("WorkspaceToRemap"); + + // Check that the workspaces actually are MatrixWorkspaces + bool validWorkspaces = true; + + if (wsToMatch == NULL) { + issues["WorkspaceToMatch"] = "Must be a MatrixWorkspace"; + validWorkspaces = false; + } + + if (wsToRemap == NULL) { + issues["WorkspaceToRemap"] = "Must be a MatrixWorkspace"; + validWorkspaces = false; + } + + // Check histohram counts match (assuming both are MatrixWorkspaces) + if (validWorkspaces && + wsToMatch->getNumberHistograms() != wsToRemap->getNumberHistograms()) + issues["WorkspaceToRemap"] = + "Number of histograms must match WorkspaceToMatch"; + + return issues; +} + +} // namespace Algorithms +} // namespace Mantid diff --git a/Code/Mantid/Framework/Algorithms/src/EstimatePDDetectorResolution.cpp b/Code/Mantid/Framework/Algorithms/src/EstimateResolutionDiffraction.cpp similarity index 64% rename from Code/Mantid/Framework/Algorithms/src/EstimatePDDetectorResolution.cpp rename to Code/Mantid/Framework/Algorithms/src/EstimateResolutionDiffraction.cpp index 6bcaa795c8a0..6dbdfafe0115 100644 --- a/Code/Mantid/Framework/Algorithms/src/EstimatePDDetectorResolution.cpp +++ b/Code/Mantid/Framework/Algorithms/src/EstimateResolutionDiffraction.cpp @@ -1,10 +1,11 @@ //---------------------------------------------------------------------- // Includes //---------------------------------------------------------------------- -#include "MantidAlgorithms/EstimatePDDetectorResolution.h" +#include "MantidAlgorithms/EstimateResolutionDiffraction.h" #include "MantidGeometry/IDetector.h" #include "MantidGeometry/Instrument/Detector.h" #include "MantidAPI/WorkspaceProperty.h" +#include "MantidKernel/BoundedValidator.h" #include "MantidKernel/PhysicalConstants.h" #include "MantidKernel/TimeSeriesProperty.h" #include "MantidKernel/V3D.h" @@ -21,20 +22,49 @@ using namespace std; namespace Mantid { namespace Algorithms { -DECLARE_ALGORITHM(EstimatePDDetectorResolution) +DECLARE_ALGORITHM(EstimateResolutionDiffraction) + +namespace { // hide these constants + /// + const double MICROSEC_TO_SEC=1.0E-6; + /// + const double WAVELENGTH_TO_VELOCITY=1.0E10 * + PhysicalConstants::h / PhysicalConstants::NeutronMass; + /// This is an absurd number for even ultra cold neutrons + const double WAVELENGTH_MAX = 1000.; +} //---------------------------------------------------------------------------------------------- /** Constructor */ -EstimatePDDetectorResolution::EstimatePDDetectorResolution() {} +EstimateResolutionDiffraction::EstimateResolutionDiffraction() {} //---------------------------------------------------------------------------------------------- /** Destructor */ -EstimatePDDetectorResolution::~EstimatePDDetectorResolution() {} +EstimateResolutionDiffraction::~EstimateResolutionDiffraction() {} + +const std::string EstimateResolutionDiffraction::name() const { + return "EstimateResolutionDiffraction"; +} + +const std::string EstimateResolutionDiffraction::alias() const { + return "EstimatePDDetectorResolution"; +} + +const std::string EstimateResolutionDiffraction::summary() const { + return "Estimate the resolution of each detector for a powder " + "diffractometer. "; +} + +int EstimateResolutionDiffraction::version() const { return 1; } + +const std::string EstimateResolutionDiffraction::category() const { + return "Diffraction"; +} //---------------------------------------------------------------------------------------------- -void EstimatePDDetectorResolution::init() { +void EstimateResolutionDiffraction::init() { declareProperty( new WorkspaceProperty("InputWorkspace", "", Direction::Input), @@ -43,17 +73,27 @@ void EstimatePDDetectorResolution::init() { declareProperty(new WorkspaceProperty("OutputWorkspace", "", Direction::Output), "Name of the output workspace containing delta(d)/d of each " - "detector/spectrum. "); + "detector/spectrum."); + auto positiveDeltaTOF = boost::make_shared >(); + positiveDeltaTOF->setLower(0.); + positiveDeltaTOF->setLowerExclusive(true); declareProperty( - "DeltaTOF", EMPTY_DBL(), - "DeltaT as the resolution of TOF with unit microsecond (10^-6m). "); + "DeltaTOF", 0., positiveDeltaTOF, + "DeltaT as the resolution of TOF with unit microsecond (10^-6m)."); + + auto positiveWavelength = boost::make_shared >(); + positiveWavelength->setLower(0.); + positiveWavelength->setLowerExclusive(true); + declareProperty( + "Wavelength", EMPTY_DBL(), positiveWavelength, + "Wavelength setting in Angstroms. This overrides what is in the dataset."); } //---------------------------------------------------------------------------------------------- /** */ -void EstimatePDDetectorResolution::exec() { +void EstimateResolutionDiffraction::exec() { processAlgProperties(); retrieveInstrumentParameters(); @@ -68,66 +108,56 @@ void EstimatePDDetectorResolution::exec() { //---------------------------------------------------------------------------------------------- /** */ -void EstimatePDDetectorResolution::processAlgProperties() { +void EstimateResolutionDiffraction::processAlgProperties() { m_inputWS = getProperty("InputWorkspace"); m_deltaT = getProperty("DeltaTOF"); - if (isEmpty(m_deltaT)) - throw runtime_error("DeltaTOF must be given!"); - m_deltaT *= 1.0E-6; // convert to meter + m_deltaT *= MICROSEC_TO_SEC; // convert to meter } -//---------------------------------------------------------------------------------------------- -/** - */ -void EstimatePDDetectorResolution::retrieveInstrumentParameters() { -#if 0 - // Call SolidAngle to get solid angles for all detectors - Algorithm_sptr calsolidangle = createChildAlgorithm("SolidAngle", -1, -1, true); - calsolidangle->initialize(); - - calsolidangle->setProperty("InputWorkspace", m_inputWS); - - calsolidangle->execute(); - if (!calsolidangle->isExecuted()) - throw runtime_error("Unable to run solid angle. "); - - m_solidangleWS = calsolidangle->getProperty("OutputWorkspace"); - if (!m_solidangleWS) - throw runtime_error("Unable to get solid angle workspace from SolidAngle(). "); - - - size_t numspec = m_solidangleWS->getNumberHistograms(); - for (size_t i = 0; i < numspec; ++i) - g_log.debug() << "[DB]: " << m_solidangleWS->readY(i)[0] << "\n"; -#endif +double EstimateResolutionDiffraction::getWavelength() { + double wavelength = getProperty("Wavelength"); + if (!isEmpty(wavelength)) + { + return wavelength; + } - // Calculate centre neutron velocity Property *cwlproperty = m_inputWS->run().getProperty("LambdaRequest"); if (!cwlproperty) throw runtime_error( "Unable to locate property LambdaRequest as central wavelength. "); + TimeSeriesProperty *cwltimeseries = dynamic_cast *>(cwlproperty); + if (!cwltimeseries) throw runtime_error( "LambdaReqeust is not a TimeSeriesProperty in double. "); - if (cwltimeseries->size() != 1) - throw runtime_error("LambdaRequest should contain 1 and only 1 entry. "); - double centrewavelength = cwltimeseries->nthValue(0); string unit = cwltimeseries->units(); - if (unit.compare("Angstrom") == 0) - centrewavelength *= 1.0E-10; - else - throw runtime_error("Unit is not recognized"); + if (unit.compare("Angstrom") != 0) { + throw runtime_error("Unit is not recognized: "+unit); + } - m_centreVelocity = - PhysicalConstants::h / PhysicalConstants::NeutronMass / centrewavelength; - g_log.notice() << "Centre wavelength = " << centrewavelength - << ", Centre neutron velocity = " << m_centreVelocity << "\n"; + return cwltimeseries->timeAverageValue(); +} - // Calcualte L1 sample to source +//---------------------------------------------------------------------------------------------- +/** + */ +void EstimateResolutionDiffraction::retrieveInstrumentParameters() { + double centrewavelength = getWavelength(); + g_log.notice() << "Centre wavelength = " << centrewavelength << " Angstrom\n"; + if (centrewavelength > WAVELENGTH_MAX) + { + throw runtime_error("unphysical wavelength used"); + } + + // Calculate centre neutron velocity + m_centreVelocity = WAVELENGTH_TO_VELOCITY / centrewavelength; + g_log.notice() << "Centre neutron velocity = " << m_centreVelocity << "\n"; + + // Calculate L1 sample to source Instrument_const_sptr instrument = m_inputWS->getInstrument(); V3D samplepos = instrument->getSample()->getPos(); V3D sourcepos = instrument->getSource()->getPos(); @@ -140,18 +170,20 @@ void EstimatePDDetectorResolution::retrieveInstrumentParameters() { //---------------------------------------------------------------------------------------------- /** */ -void EstimatePDDetectorResolution::createOutputWorkspace() { +void EstimateResolutionDiffraction::createOutputWorkspace() { size_t numspec = m_inputWS->getNumberHistograms(); m_outputWS = boost::dynamic_pointer_cast( WorkspaceFactory::Instance().create("Workspace2D", numspec, 1, 1)); - + // Copy geometry over. + API::WorkspaceFactory::Instance().initializeFromParent(m_inputWS, m_outputWS, + false); return; } //---------------------------------------------------------------------------------------------- /** */ -void EstimatePDDetectorResolution::estimateDetectorResolution() { +void EstimateResolutionDiffraction::estimateDetectorResolution() { Instrument_const_sptr instrument = m_inputWS->getInstrument(); V3D samplepos = instrument->getSample()->getPos(); @@ -193,9 +225,8 @@ void EstimatePDDetectorResolution::estimateDetectorResolution() { double centraltof = (m_L1 + l2) / m_centreVelocity; // Angle - double r, twotheta, phi; - detpos.getSpherical(r, twotheta, phi); - double theta = (twotheta * 0.5) * M_PI / 180.; + double twotheta = m_inputWS->detectorTwoTheta(det); + double theta = 0.5 * twotheta; // double solidangle = m_solidangleWS->readY(i)[0]; double solidangle = det->solidAngle(samplepos); diff --git a/Code/Mantid/Framework/Algorithms/src/Segfault.cpp b/Code/Mantid/Framework/Algorithms/src/Segfault.cpp new file mode 100644 index 000000000000..d470898b56b4 --- /dev/null +++ b/Code/Mantid/Framework/Algorithms/src/Segfault.cpp @@ -0,0 +1,65 @@ +#include "MantidAlgorithms/Segfault.h" + +namespace Mantid { +namespace Algorithms { + +// Register the algorithm into the AlgorithmFactory +DECLARE_ALGORITHM(Segfault) + +//---------------------------------------------------------------------------------------------- +/** Constructor + */ +Segfault::Segfault() {} + +//---------------------------------------------------------------------------------------------- +/** Destructor + */ +Segfault::~Segfault() {} + +//---------------------------------------------------------------------------------------------- + +/// Algorithms name for identification. @see Algorithm::name +const std::string Segfault::name() const { return "Segfault"; } + +/// Algorithm's version for identification. @see Algorithm::version +int Segfault::version() const { return 1; } + +/// Algorithm's category for identification. @see Algorithm::category +const std::string Segfault::category() const { return "Utility\\Development"; } + +/// Algorithm's summary for use in the GUI and help. @see Algorithm::summary +const std::string Segfault::summary() const { + return "WARNING: THIS CRASHES MANTID"; +} + +//---------------------------------------------------------------------------------------------- +/** Initialize the algorithm's properties. + */ +void Segfault::init() { + declareProperty("DryRun", true, + "Just log to the error channel but don't crash mantid"); +} + +//---------------------------------------------------------------------------------------------- +/** Execute the algorithm. + */ +void Segfault::exec() { + bool dryrun = getProperty("DryRun"); + g_log.error("Crashing mantid now"); + + if (!dryrun) { +#if __clang__ +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wc++11-compat-deprecated-writable-strings" +#endif + // writing to read-only memory + char *s = "hello world"; + *s = 'H'; +#if __clang__ +#pragma clang diagnostic pop +#endif + } +} + +} // namespace Algorithms +} // namespace Mantid diff --git a/Code/Mantid/Framework/Algorithms/test/CopyDetectorMappingTest.h b/Code/Mantid/Framework/Algorithms/test/CopyDetectorMappingTest.h new file mode 100644 index 000000000000..f5ce7135d9d5 --- /dev/null +++ b/Code/Mantid/Framework/Algorithms/test/CopyDetectorMappingTest.h @@ -0,0 +1,87 @@ +#ifndef COPYDETECTORMAPPINGTEST_H_ +#define COPYDETECTORMAPPINGTEST_H_ + +#include +#include "MantidAlgorithms/CopyDetectorMapping.h" +#include "MantidTestHelpers/WorkspaceCreationHelper.h" + +using namespace Mantid; +using namespace Mantid::API; +using namespace Mantid::Kernel; + +class CopyDetectorMappingTest : public CxxTest::TestSuite +{ +public: + void testInit() + { + Mantid::Algorithms::CopyDetectorMapping copyMapping; + + TS_ASSERT_THROWS_NOTHING( copyMapping.initialize() ) + TS_ASSERT( copyMapping.isInitialized() ) + } + + void testSimple() + { + Mantid::Algorithms::CopyDetectorMapping copyMapping; + TS_ASSERT_THROWS_NOTHING( copyMapping.initialize() ) + + auto toMatch = WorkspaceCreationHelper::Create2DWorkspace(10, 10); + + // Set the detector map for a spectra in the to match workspace + std::set detIDs; + detIDs.insert(5); + detIDs.insert(9); + detIDs.insert(6); + detIDs.insert(2); + toMatch->getSpectrum(0)->setDetectorIDs(detIDs); + + // Add workspaces to ADS + AnalysisDataService::Instance().add("to_match", toMatch); + AnalysisDataService::Instance().add("to_remap", WorkspaceCreationHelper::Create2DWorkspace(10, 10)); + + // Run algorithm + TS_ASSERT_THROWS_NOTHING( copyMapping.setPropertyValue("WorkspaceToMatch", "to_match") ); + TS_ASSERT_THROWS_NOTHING( copyMapping.setPropertyValue("WorkspaceToRemap", "to_remap") ); + + TS_ASSERT_THROWS_NOTHING( copyMapping.execute() ); + TS_ASSERT( copyMapping.isExecuted() ); + + // Check the detector map in the to remap workspace matches that of the to match workspace + MatrixWorkspace_const_sptr result; + TS_ASSERT_THROWS_NOTHING( result = boost::dynamic_pointer_cast + (AnalysisDataService::Instance().retrieve("to_remap")) ); + std::set resultDetIDs = result->getSpectrum(0)->getDetectorIDs(); + TS_ASSERT( detIDs == resultDetIDs ); + + // Clean up workspace + AnalysisDataService::Instance().remove("to_match"); + AnalysisDataService::Instance().remove("to_remap"); + } + + void testFailWithDifferingSpecSize() + { + Mantid::Algorithms::CopyDetectorMapping copyMapping; + TS_ASSERT_THROWS_NOTHING( copyMapping.initialize() ) + + // Add workspaces to ADS + AnalysisDataService::Instance().add("to_match", WorkspaceCreationHelper::Create2DWorkspace(10, 10)); + AnalysisDataService::Instance().add("to_remap", WorkspaceCreationHelper::Create2DWorkspace(20, 10)); + + // Run algorithm + TS_ASSERT_THROWS_NOTHING( copyMapping.setPropertyValue("WorkspaceToMatch", "to_match") ); + TS_ASSERT_THROWS_NOTHING( copyMapping.setPropertyValue("WorkspaceToRemap", "to_remap") ); + + auto validationIssues = copyMapping.validateInputs(); + TS_ASSERT_DIFFERS( validationIssues.size(), 0 ); + + TS_ASSERT_THROWS_ANYTHING( copyMapping.execute() ); + TS_ASSERT( !copyMapping.isExecuted() ); + + // Clean up workspace + AnalysisDataService::Instance().remove("to_match"); + AnalysisDataService::Instance().remove("to_remap"); + } + +}; + +#endif /*COPYDETECTORMAPPINGTEST_H_*/ diff --git a/Code/Mantid/Framework/Algorithms/test/EstimatePDDetectorResolutionTest.h b/Code/Mantid/Framework/Algorithms/test/EstimateResolutionDiffractionTest.h similarity index 57% rename from Code/Mantid/Framework/Algorithms/test/EstimatePDDetectorResolutionTest.h rename to Code/Mantid/Framework/Algorithms/test/EstimateResolutionDiffractionTest.h index df48447eda4e..c0e0c9a261a0 100644 --- a/Code/Mantid/Framework/Algorithms/test/EstimatePDDetectorResolutionTest.h +++ b/Code/Mantid/Framework/Algorithms/test/EstimateResolutionDiffractionTest.h @@ -1,15 +1,15 @@ -#ifndef MANTID_ALGORITHMS_ESTIMATEPDDETECTORRESOLUTIONTEST_H_ -#define MANTID_ALGORITHMS_ESTIMATEPDDETECTORRESOLUTIONTEST_H_ +#ifndef MANTID_ALGORITHMS_ESTIMATERESOLUTIONDIFFRACTIONTEST_H_ +#define MANTID_ALGORITHMS_ESTIMATERESOLUTIONDIFFRACTIONTEST_H_ #include #include "MantidAPI/MatrixWorkspace.h" -#include "MantidAlgorithms/EstimatePDDetectorResolution.h" +#include "MantidAlgorithms/EstimateResolutionDiffraction.h" #include "MantidDataHandling/LoadEmptyInstrument.h" #include "MantidKernel/DateAndTime.h" #include "MantidKernel/TimeSeriesProperty.h" -using Mantid::Algorithms::EstimatePDDetectorResolution; +using Mantid::Algorithms::EstimateResolutionDiffraction; using Mantid::DataHandling::LoadEmptyInstrument; using namespace Mantid; @@ -17,59 +17,61 @@ using namespace Mantid::API; using namespace Mantid::Kernel; using namespace Mantid::DataHandling; -class EstimatePDDetectorResolutionTest : public CxxTest::TestSuite -{ +class EstimateResolutionDiffractionTest : 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 EstimatePDDetectorResolutionTest *createSuite() { return new EstimatePDDetectorResolutionTest(); } - static void destroySuite( EstimatePDDetectorResolutionTest *suite ) { delete suite; } - + static EstimateResolutionDiffractionTest *createSuite() { + return new EstimateResolutionDiffractionTest(); + } + static void destroySuite(EstimateResolutionDiffractionTest *suite) { + delete suite; + } /** Test init */ - void test_Init() - { - EstimatePDDetectorResolution alg; + void test_Init() { + EstimateResolutionDiffraction alg; TS_ASSERT_THROWS_NOTHING(alg.initialize()); TS_ASSERT(alg.isInitialized()); } /** Test POWGEN */ - void test_EmptyPG3() - { + void test_EmptyPG3() { // Create an empty PG3 workspace MatrixWorkspace_sptr ws = createInstrument(); // Set up and run - EstimatePDDetectorResolution alg; + EstimateResolutionDiffraction alg; alg.initialize(); - TS_ASSERT_THROWS_NOTHING(alg.setPropertyValue("InputWorkspace", ws->name())); - TS_ASSERT_THROWS_NOTHING(alg.setPropertyValue("OutputWorkspace", "PG3_Resolution")); + TS_ASSERT_THROWS_NOTHING( + alg.setPropertyValue("InputWorkspace", ws->name())); + TS_ASSERT_THROWS_NOTHING( + alg.setPropertyValue("OutputWorkspace", "PG3_Resolution")); TS_ASSERT_THROWS_NOTHING(alg.setProperty("DeltaTOF", 40.0)); alg.execute(); TS_ASSERT(alg.isExecuted()); - MatrixWorkspace_sptr outputws = boost::dynamic_pointer_cast( - AnalysisDataService::Instance().retrieve("PG3_Resolution")); + MatrixWorkspace_sptr outputws = + boost::dynamic_pointer_cast( + AnalysisDataService::Instance().retrieve("PG3_Resolution")); TS_ASSERT(outputws); - if (!outputws) return; + if (!outputws) + return; size_t numspec = outputws->getNumberHistograms(); TS_ASSERT_EQUALS(numspec, 25873); for (size_t i = 0; i < numspec; ++i) TS_ASSERT(outputws->readY(i)[0] < 0.03); - } /** Create an instrument */ - API::MatrixWorkspace_sptr createInstrument() - { + API::MatrixWorkspace_sptr createInstrument() { // Create empty workspace LoadEmptyInstrument loader; loader.initialize(); @@ -81,21 +83,19 @@ class EstimatePDDetectorResolutionTest : public CxxTest::TestSuite TS_ASSERT(loader.isExecuted()); // Time series property - TimeSeriesProperty* lambda = new TimeSeriesProperty("LambdaRequest"); + TimeSeriesProperty *lambda = + new TimeSeriesProperty("LambdaRequest"); lambda->setUnits("Angstrom"); DateAndTime time0(0); lambda->addValue(time0, 1.066); // Add log to workspace MatrixWorkspace_sptr ws = boost::dynamic_pointer_cast( - AnalysisDataService::Instance().retrieve("PG3_Sctrach")); + AnalysisDataService::Instance().retrieve("PG3_Sctrach")); ws->mutableRun().addProperty(lambda); return ws; } - - }; - -#endif /* MANTID_ALGORITHMS_ESTIMATEPDDETECTORRESOLUTIONTEST_H_ */ +#endif /* MANTID_ALGORITHMS_ESTIMATERESOLUTIONDIFFRACTIONTEST_H_ */ diff --git a/Code/Mantid/Framework/CurveFitting/CMakeLists.txt b/Code/Mantid/Framework/CurveFitting/CMakeLists.txt index 6d16289ad805..744c07caec24 100644 --- a/Code/Mantid/Framework/CurveFitting/CMakeLists.txt +++ b/Code/Mantid/Framework/CurveFitting/CMakeLists.txt @@ -68,6 +68,7 @@ set ( SRC_FILES src/PRConjugateGradientMinimizer.cpp src/ParDomain.cpp src/PeakParametersNumeric.cpp + src/PeakParameterFunction.cpp src/PlotPeakByLogValue.cpp src/Polynomial.cpp src/ProcessBackground.cpp @@ -181,6 +182,7 @@ set ( INC_FILES inc/MantidCurveFitting/PRConjugateGradientMinimizer.h inc/MantidCurveFitting/ParDomain.h inc/MantidCurveFitting/PeakParametersNumeric.h + inc/MantidCurveFitting/PeakParameterFunction.h inc/MantidCurveFitting/PlotPeakByLogValue.h inc/MantidCurveFitting/Polynomial.h inc/MantidCurveFitting/ProcessBackground.h @@ -259,6 +261,7 @@ set ( TEST_FILES FullprofPolynomialTest.h FunctionDomain1DSpectrumCreatorTest.h FunctionFactoryConstraintTest.h + FunctionParameterDecoratorFitTest.h GSLMatrixTest.h GausDecayTest.h GausOscTest.h @@ -266,6 +269,7 @@ set ( TEST_FILES GaussianTest.h GramCharlierComptonProfileTest.h IkedaCarpenterPVTest.h + IPeakFunctionCentreParameterNameTest.h IPeakFunctionIntensityTest.h LeBailFitTest.h LeBailFunctionTest.h @@ -283,6 +287,7 @@ set ( TEST_FILES NormaliseByPeakAreaTest.h PeakParametersNumericTest.h PRConjugateGradientTest.h + PeakParameterFunctionTest.h PlotPeakByLogValueTest.h PolynomialTest.h ProcessBackgroundTest.h diff --git a/Code/Mantid/Framework/CurveFitting/inc/MantidCurveFitting/PeakParameterFunction.h b/Code/Mantid/Framework/CurveFitting/inc/MantidCurveFitting/PeakParameterFunction.h new file mode 100644 index 000000000000..22621031ef12 --- /dev/null +++ b/Code/Mantid/Framework/CurveFitting/inc/MantidCurveFitting/PeakParameterFunction.h @@ -0,0 +1,68 @@ +#ifndef MANTID_CURVEFITTING_PEAKPARAMETERFUNCTION_H_ +#define MANTID_CURVEFITTING_PEAKPARAMETERFUNCTION_H_ + +#include "MantidCurveFitting/DllConfig.h" +#include "MantidAPI/IFunction1D.h" +#include "MantidAPI/FunctionParameterDecorator.h" +#include "MantidAPI/IPeakFunction.h" + +namespace Mantid { +namespace CurveFitting { + +/** PeakParameterFunction : + + This function implements API::FunctionParameterDecorator to wrap an + IPeakFunction. The function expects a FunctionDomain1D with size exactly 4, + corresponding to the 4 special parameters centre, height, fwhm and intensity. + + They are stored in the output values in that order. Calculating the derivative + of the function yields the partial derivatives of these 4 parameters with + respect to the function's native parameters defined through declareParameter. + + @author Michael Wedel, Paul Scherrer Institut - SINQ + @date 24/02/2015 + + Copyright ©2015 PSI-NXMM + + This file is part of Mantid. + + Mantid is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + Mantid is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + + File change history is stored at: + Code Documentation is available at: +*/ +class MANTID_CURVEFITTING_DLL PeakParameterFunction + : virtual public API::IFunction1D, + virtual public API::FunctionParameterDecorator { +public: + PeakParameterFunction() : FunctionParameterDecorator() {} + virtual ~PeakParameterFunction() {} + + std::string name() const { return "PeakParameterFunction"; } + + void function1D(double *out, const double *xValues, const size_t nData) const; + + void functionDeriv(const API::FunctionDomain &domain, + API::Jacobian &jacobian); + +protected: + void beforeDecoratedFunctionSet(const API::IFunction_sptr &fn); + + API::IPeakFunction_sptr m_peakFunction; +}; + +} // namespace CurveFitting +} // namespace Mantid + +#endif /* MANTID_CURVEFITTING_PEAKPARAMETERFUNCTION_H_ */ diff --git a/Code/Mantid/Framework/CurveFitting/src/PeakParameterFunction.cpp b/Code/Mantid/Framework/CurveFitting/src/PeakParameterFunction.cpp new file mode 100644 index 000000000000..1b9cd589e80e --- /dev/null +++ b/Code/Mantid/Framework/CurveFitting/src/PeakParameterFunction.cpp @@ -0,0 +1,63 @@ +#include "MantidCurveFitting/PeakParameterFunction.h" +#include "MantidAPI/IPeakFunction.h" +#include "MantidAPI/FunctionFactory.h" + +namespace Mantid { +namespace CurveFitting { + +using namespace API; + +DECLARE_FUNCTION(PeakParameterFunction) + +/** + * @brief Calculates centre, height, fwhm and intensity of the wrapped function. + * + * This function expects a domain with size 4, because IPeakFunction has 4 + * special parameters. These parameters are stored as the output values in the + * order centre, height, fwhm, intensity. + * + * The xValues are ignored, it does not matter what the domain contains. + * + * @param out :: Values of IPeakFunction's special parameters. + * @param xValues :: Domain, ignored. + * @param nData :: Domain size, must be 4. + */ +void PeakParameterFunction::function1D(double *out, const double *xValues, + const size_t nData) const { + UNUSED_ARG(xValues); + if (nData != 4) { + throw std::invalid_argument("Can only work with domain of size 4."); + } + + if(!m_peakFunction) { + throw std::runtime_error("IPeakFunction has not been set."); + } + + out[0] = m_peakFunction->centre(); + out[1] = m_peakFunction->height(); + out[2] = m_peakFunction->fwhm(); + out[3] = m_peakFunction->intensity(); +} + +/// Uses numerical derivatives to calculate Jacobian of the function. +void PeakParameterFunction::functionDeriv(const FunctionDomain &domain, + Jacobian &jacobian) { + calNumericalDeriv(domain, jacobian); +} + +/// Make sure the decorated function is IPeakFunction and store it. +void +PeakParameterFunction::beforeDecoratedFunctionSet(const IFunction_sptr &fn) { + boost::shared_ptr peakFunction = + boost::dynamic_pointer_cast(fn); + + if (!peakFunction) { + throw std::invalid_argument( + "Decorated function needs to be an IPeakFunction."); + } + + m_peakFunction = peakFunction; +} + +} // namespace CurveFitting +} // namespace Mantid diff --git a/Code/Mantid/Framework/CurveFitting/test/FunctionParameterDecoratorFitTest.h b/Code/Mantid/Framework/CurveFitting/test/FunctionParameterDecoratorFitTest.h new file mode 100644 index 000000000000..47cc259f3558 --- /dev/null +++ b/Code/Mantid/Framework/CurveFitting/test/FunctionParameterDecoratorFitTest.h @@ -0,0 +1,93 @@ +#ifndef FUNCTIONPARAMETERDECORATORFITTEST_H +#define FUNCTIONPARAMETERDECORATORFITTEST_H + +#include +#include "MantidAPI/FrameworkManager.h" +#include "MantidAPI/FunctionFactory.h" +#include "MantidAPI/AlgorithmManager.h" +#include "MantidTestHelpers/WorkspaceCreationHelper.h" +#include "MantidAPI/FunctionParameterDecorator.h" +#include "MantidDataObjects/Workspace2D.h" + +#include "MantidCurveFitting/Fit.h" + +#include + +using namespace Mantid::API; +using namespace Mantid::DataObjects; +using namespace Mantid::CurveFitting; + +class FunctionParameterDecoratorFitTest; + +/* This class is used to test that Fit works with the decorators. It simply + * forwards calls to function to the decorated function. + */ +class SimpleFunctionParameterDecorator : public FunctionParameterDecorator { + friend class FunctionParameterDecoratorFitTest; + +public: + SimpleFunctionParameterDecorator() {} + ~SimpleFunctionParameterDecorator() {} + + std::string name() const { return "SimpleFunctionParameterDecorator"; } + + void function(const FunctionDomain &domain, FunctionValues &values) const { + throwIfNoFunctionSet(); + + IFunction_sptr fn = getDecoratedFunction(); + fn->function(domain, values); + } + + void functionDeriv(const FunctionDomain &domain, Jacobian &jacobian) { + throwIfNoFunctionSet(); + + IFunction_sptr fn = getDecoratedFunction(); + fn->functionDeriv(domain, jacobian); + } +}; + +DECLARE_FUNCTION(SimpleFunctionParameterDecorator); + +class FunctionParameterDecoratorFitTest : 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 FunctionParameterDecoratorFitTest *createSuite() { + return new FunctionParameterDecoratorFitTest(); + } + static void destroySuite(FunctionParameterDecoratorFitTest *suite) { + delete suite; + } + + FunctionParameterDecoratorFitTest() { FrameworkManager::Instance(); } + + void testFunctionIsRegistered() { + IFunction_sptr fn = FunctionFactory::Instance().createFunction( + "SimpleFunctionParameterDecorator"); + + TS_ASSERT(fn); + } + + void testFit() { + Workspace2D_sptr ws = + WorkspaceCreationHelper::Create1DWorkspaceConstant(20, 1.5, 1.5); + + FunctionParameterDecorator_sptr fn = + boost::make_shared(); + fn->setDecoratedFunction("FlatBackground"); + fn->setParameter("A0", 10.5); + + IAlgorithm_sptr fitAlg = AlgorithmManager::Instance().create("Fit"); + fitAlg->setProperty("Function", boost::static_pointer_cast(fn)); + fitAlg->setProperty("InputWorkspace", ws); + + fitAlg->execute(); + + TS_ASSERT(fitAlg->isExecuted()); + + IFunction_sptr fitFunction = fitAlg->getProperty("Function"); + TS_ASSERT_DELTA(fitFunction->getParameter("A0"), 1.5, 1e-15); + } +}; + +#endif // FUNCTIONPARAMETERDECORATORFITTEST_H diff --git a/Code/Mantid/Framework/CurveFitting/test/GaussianTest.h b/Code/Mantid/Framework/CurveFitting/test/GaussianTest.h index ef010df67c74..40a9a43251b5 100644 --- a/Code/Mantid/Framework/CurveFitting/test/GaussianTest.h +++ b/Code/Mantid/Framework/CurveFitting/test/GaussianTest.h @@ -547,6 +547,15 @@ class GaussianTest : public CxxTest::TestSuite TS_ASSERT_DELTA(fn->intensity(), 20.0, 1e-10); } + void testGetCentreParameterName() + { + boost::shared_ptr fn( new Gaussian() ); + fn->initialize(); + + TS_ASSERT_THROWS_NOTHING(fn->getCentreParameterName()); + TS_ASSERT_EQUALS(fn->getCentreParameterName(), "PeakCentre"); + } + }; diff --git a/Code/Mantid/Framework/CurveFitting/test/IPeakFunctionCentreParameterNameTest.h b/Code/Mantid/Framework/CurveFitting/test/IPeakFunctionCentreParameterNameTest.h new file mode 100644 index 000000000000..13566fffdbec --- /dev/null +++ b/Code/Mantid/Framework/CurveFitting/test/IPeakFunctionCentreParameterNameTest.h @@ -0,0 +1,56 @@ +#ifndef IPEAKFUNCTIONCENTREPARAMETERNAMETEST_H +#define IPEAKFUNCTIONCENTREPARAMETERNAMETEST_H + +#include +#include "MantidAPI/FrameworkManager.h" +#include "MantidAPI/FunctionFactory.h" +#include "MantidAPI/IPeakFunction.h" +#include + +using namespace Mantid::API; + +class IPeakFunctionCentreParameterNameTest : 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 IPeakFunctionCentreParameterNameTest *createSuite() { + return new IPeakFunctionCentreParameterNameTest(); + } + static void destroySuite(IPeakFunctionCentreParameterNameTest *suite) { + delete suite; + } + + IPeakFunctionCentreParameterNameTest() { + FrameworkManager::Instance(); + + m_expectedResults.insert(std::make_pair("Gaussian", "PeakCentre")); + m_expectedResults.insert(std::make_pair("Lorentzian", "PeakCentre")); + m_expectedResults.insert(std::make_pair("IkedaCarpenterPV", "X0")); + m_expectedResults.insert(std::make_pair("Voigt", "LorentzPos")); + m_expectedResults.insert(std::make_pair("BackToBackExponential", "X0")); + } + + /* Test that all functions give the expected result. + */ + void testAllFunctions() { + for (auto it = m_expectedResults.begin(); it != m_expectedResults.end(); + ++it) { + std::string peakFunctionName = it->first; + std::string centreParameterName = it->second; + + IPeakFunction_sptr fn = boost::dynamic_pointer_cast( + FunctionFactory::Instance().createFunction(peakFunctionName)); + + TS_ASSERT(fn); + TSM_ASSERT_EQUALS("IPeakFunction " + peakFunctionName + " gave centre" + "parameter '" + fn->getCentreParameterName() + "', " + "should give '" + centreParameterName + "'.", + fn->getCentreParameterName(), centreParameterName); + } + } + +private: + std::map m_expectedResults; +}; + +#endif // IPEAKFUNCTIONCENTREPARAMETERNAMETEST_H diff --git a/Code/Mantid/Framework/CurveFitting/test/PeakParameterFunctionTest.h b/Code/Mantid/Framework/CurveFitting/test/PeakParameterFunctionTest.h new file mode 100644 index 000000000000..86436da7c3e3 --- /dev/null +++ b/Code/Mantid/Framework/CurveFitting/test/PeakParameterFunctionTest.h @@ -0,0 +1,132 @@ +#ifndef MANTID_CURVEFITTING_PEAKPARAMETERFUNCTIONTEST_H_ +#define MANTID_CURVEFITTING_PEAKPARAMETERFUNCTIONTEST_H_ + +#include + +#include "MantidCurveFitting/PeakParameterFunction.h" +#include "MantidAPI/FrameworkManager.h" +#include "MantidAPI/FunctionDomain1D.h" +#include "MantidAPI/FunctionFactory.h" +#include "MantidAPI/FunctionParameterDecorator.h" +#include "MantidAPI/IPeakFunction.h" + +#include "MantidCurveFitting/Jacobian.h" + +using namespace Mantid::CurveFitting; +using namespace Mantid::API; + +class PeakParameterFunctionTest : 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 + PeakParameterFunctionTest() { FrameworkManager::Instance(); } + + static PeakParameterFunctionTest *createSuite() { + return new PeakParameterFunctionTest(); + } + static void destroySuite(PeakParameterFunctionTest *suite) { delete suite; } + + void testFunction() { + FunctionParameterDecorator_sptr fn = + boost::dynamic_pointer_cast( + FunctionFactory::Instance().createFunction( + "PeakParameterFunction")); + + TS_ASSERT(fn); + + fn->setDecoratedFunction("Gaussian"); + + IPeakFunction_sptr peakFunction = + boost::dynamic_pointer_cast(fn->getDecoratedFunction()); + + FunctionDomain1DVector domain(std::vector(4, 0.0)); + FunctionValues values(domain); + + TS_ASSERT_THROWS_NOTHING(fn->function(domain, values)); + + TS_ASSERT_EQUALS(values[0], peakFunction->centre()); + TS_ASSERT_EQUALS(values[1], peakFunction->height()); + TS_ASSERT_EQUALS(values[2], peakFunction->fwhm()); + TS_ASSERT_EQUALS(values[3], peakFunction->intensity()); + } + + void testFunctionDeriv() { + FunctionParameterDecorator_sptr fn = + boost::dynamic_pointer_cast( + FunctionFactory::Instance().createFunction( + "PeakParameterFunction")); + + TS_ASSERT(fn); + + fn->setDecoratedFunction("Gaussian"); + + FunctionDomain1DVector domain(std::vector(4, 0.0)); + Mantid::CurveFitting::Jacobian jacobian(4, 3); + + TS_ASSERT_THROWS_NOTHING(fn->functionDeriv(domain, jacobian)); + + /* Make sure that (0,1) is larger than (0,0) and (0,2) + * because d(centre)/d(PeakCentre) should be highest. + */ + TS_ASSERT_LESS_THAN(jacobian.get(0, 0), jacobian.get(0, 1)); + TS_ASSERT_LESS_THAN(jacobian.get(0, 2), jacobian.get(0, 1)); + + // Same for d(height)/d(Height) + TS_ASSERT_LESS_THAN(jacobian.get(1, 1), jacobian.get(1, 0)); + TS_ASSERT_LESS_THAN(jacobian.get(1, 2), jacobian.get(1, 0)); + + // Same for d(fwhm)/d(Sigma) + TS_ASSERT_LESS_THAN(jacobian.get(2, 0), jacobian.get(2, 2)); + TS_ASSERT_LESS_THAN(jacobian.get(2, 1), jacobian.get(2, 2)); + } + + void testWrongDomainSize() { + FunctionParameterDecorator_sptr fn = + boost::dynamic_pointer_cast( + FunctionFactory::Instance().createFunction( + "PeakParameterFunction")); + + TS_ASSERT(fn); + + fn->setDecoratedFunction("Gaussian"); + + FunctionDomain1DVector domain(std::vector(3, 0.0)); + FunctionValues values(domain); + Mantid::CurveFitting::Jacobian jacobian(domain.size(), 3); + + TS_ASSERT_THROWS(fn->function(domain, values), std::invalid_argument); + TS_ASSERT_THROWS(fn->functionDeriv(domain, jacobian), + std::invalid_argument); + } + + void testNoFunctionSet() { + FunctionParameterDecorator_sptr fn = + boost::dynamic_pointer_cast( + FunctionFactory::Instance().createFunction( + "PeakParameterFunction")); + + TS_ASSERT(fn); + + FunctionDomain1DVector domain(std::vector(4, 0.0)); + FunctionValues values(domain); + Mantid::CurveFitting::Jacobian jacobian(domain.size(), 3); + + TS_ASSERT_THROWS(fn->function(domain, values), std::runtime_error); + TS_ASSERT_THROWS(fn->functionDeriv(domain, jacobian), std::runtime_error); + } + + void testBeforeDecoratedFunctionSet() { + FunctionParameterDecorator_sptr fn = + boost::dynamic_pointer_cast( + FunctionFactory::Instance().createFunction( + "PeakParameterFunction")); + + TS_ASSERT(fn); + + TS_ASSERT_THROWS_NOTHING(fn->setDecoratedFunction("Gaussian")); + TS_ASSERT_THROWS(fn->setDecoratedFunction("Chebyshev"), + std::invalid_argument); + } +}; + +#endif /* MANTID_CURVEFITTING_PEAKPARAMETERFUNCTIONTEST_H_ */ diff --git a/Code/Mantid/Framework/DataHandling/CMakeLists.txt b/Code/Mantid/Framework/DataHandling/CMakeLists.txt index 33aee4025c4b..1645bc73c319 100644 --- a/Code/Mantid/Framework/DataHandling/CMakeLists.txt +++ b/Code/Mantid/Framework/DataHandling/CMakeLists.txt @@ -92,6 +92,7 @@ set ( SRC_FILES src/LoadSPE.cpp src/LoadSampleDetailsFromRaw.cpp src/LoadSassena.cpp + src/LoadSavuTomoConfig.cpp src/LoadSpec.cpp src/LoadSpice2D.cpp src/LoadSpiceAscii.cpp @@ -140,6 +141,7 @@ set ( SRC_FILES src/SaveReflCustomAscii.cpp src/SaveReflTBL.cpp src/SaveReflThreeColumnAscii.cpp + src/SaveSavuTomoConfig.cpp src/SaveSPE.cpp src/SaveToSNSHistogramNexus.cpp src/SaveVTK.cpp @@ -238,6 +240,7 @@ set ( INC_FILES inc/MantidDataHandling/LoadSPE.h inc/MantidDataHandling/LoadSampleDetailsFromRaw.h inc/MantidDataHandling/LoadSassena.h + inc/MantidDataHandling/LoadSavuTomoConfig.h inc/MantidDataHandling/LoadSpec.h inc/MantidDataHandling/LoadSpice2D.h inc/MantidDataHandling/LoadSpiceAscii.h @@ -286,6 +289,7 @@ set ( INC_FILES inc/MantidDataHandling/SaveReflCustomAscii.h inc/MantidDataHandling/SaveReflTBL.h inc/MantidDataHandling/SaveReflThreeColumnAscii.h + inc/MantidDataHandling/SaveSavuTomoConfig.h inc/MantidDataHandling/SaveSPE.h inc/MantidDataHandling/SaveToSNSHistogramNexus.h inc/MantidDataHandling/SaveVTK.h @@ -380,6 +384,7 @@ set ( TEST_FILES LoadSPETest.h LoadSassenaTest.h LoadSaveAsciiTest.h + LoadSavuTomoConfigTest.h LoadSpice2dTest.h LoadSpiceAsciiTest.h LoadTOFRawNexusTest.h @@ -427,6 +432,7 @@ set ( TEST_FILES SaveReflCustomAsciiTest.h SaveReflTBLTest.h SaveReflThreeColumnAsciiTest.h + SaveSavuTomoConfigTest.h SaveSPETest.h SaveToSNSHistogramNexusTest.h SetSampleMaterialTest.h diff --git a/Code/Mantid/Framework/DataHandling/inc/MantidDataHandling/LoadEventNexus.h b/Code/Mantid/Framework/DataHandling/inc/MantidDataHandling/LoadEventNexus.h index ff849c9f51d5..07c1e9a5df56 100644 --- a/Code/Mantid/Framework/DataHandling/inc/MantidDataHandling/LoadEventNexus.h +++ b/Code/Mantid/Framework/DataHandling/inc/MantidDataHandling/LoadEventNexus.h @@ -247,6 +247,7 @@ class DLLExport LoadEventNexus /// Map detector IDs to event lists. template void makeMapToEventLists(std::vector &vectors); + void createWorkspaceIndexMaps(const bool monitors, const std::vector &bankNames); void loadEvents(API::Progress *const prog, const bool monitors); void createSpectraMapping( const std::string &nxsfile, const bool monitorsOnly, diff --git a/Code/Mantid/Framework/DataHandling/inc/MantidDataHandling/LoadMuonNexus1.h b/Code/Mantid/Framework/DataHandling/inc/MantidDataHandling/LoadMuonNexus1.h index cf08fb1bbd93..e930ad301d5c 100644 --- a/Code/Mantid/Framework/DataHandling/inc/MantidDataHandling/LoadMuonNexus1.h +++ b/Code/Mantid/Framework/DataHandling/inc/MantidDataHandling/LoadMuonNexus1.h @@ -100,7 +100,7 @@ class DLLExport LoadMuonNexus1 : public LoadMuonNexus { void exec(); private: - void loadData(const MantidVecPtr::ptr_type &tcbs, size_t hist, specid_t &i, + void loadData(size_t hist, specid_t &i, specid_t specNo, MuonNexusReader &nxload, const int64_t lengthIn, DataObjects::Workspace2D_sptr localWorkspace); void runLoadMappingTable(DataObjects::Workspace2D_sptr); @@ -112,8 +112,7 @@ class DLLExport LoadMuonNexus1 : public LoadMuonNexus { /// Creates Dead Time Table using all the data between begin and end DataObjects::TableWorkspace_sptr - createDeadTimeTable(std::vector::const_iterator begin, - std::vector::const_iterator end); + createDeadTimeTable(std::vector specToLoad, std::vector deadTimes); /// Loads detector grouping information API::Workspace_sptr loadDetectorGrouping(Mantid::NeXus::NXRoot &root); diff --git a/Code/Mantid/Framework/DataHandling/inc/MantidDataHandling/LoadSavuTomoConfig.h b/Code/Mantid/Framework/DataHandling/inc/MantidDataHandling/LoadSavuTomoConfig.h new file mode 100644 index 000000000000..469369ff4d4d --- /dev/null +++ b/Code/Mantid/Framework/DataHandling/inc/MantidDataHandling/LoadSavuTomoConfig.h @@ -0,0 +1,80 @@ +#ifndef MANTID_DATAHANDLING_LOADSAVUTOMOCONFIG_H_ +#define MANTID_DATAHANDLING_LOADSAVUTOMOCONFIG_H_ + +#include "MantidAPI/Algorithm.h" +#include "MantidAPI/ITableWorkspace.h" + +namespace NeXus { + class File; +} + +namespace Mantid { +namespace DataHandling { + +/** + LoadSavuTomoConfig : Load a tomographic reconstruction parameters + file (as used in the savu tomography reconstructin pipeline) into a + TableWorkspace + + Copyright © 2015 ISIS Rutherford Appleton Laboratory, NScD Oak Ridge + National Laboratory & European Spallation Source + + This file is part of Mantid. + + Mantid is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + Mantid is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + + File change history is stored at: + Code Documentation is available at: +*/ +class DLLExport LoadSavuTomoConfig : public API::Algorithm { +public: + LoadSavuTomoConfig(); + + virtual ~LoadSavuTomoConfig(); + + /// Algorithm's name for identification overriding a virtual method + virtual const std::string name() const { return "LoadSavuTomoConfig"; } + /// Summary of algorithms purpose + virtual const std::string summary() const { + return "Load configuration parameters from a tomographic " + "reconstruction parameter file."; + } + + /// 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\\Tomography"; } + +private: + + /// Implement abstract Algorithm methods + void init(); + /// Implement abstract Algorithm methods + void exec(); + + // do the real loading + Mantid::API::ITableWorkspace_sptr loadFile(std::string& fname, + std::string& wsName); + + // open file safely and carefully checking potential issues + bool checkOpenFile(std::string fname, + boost::shared_ptr &f); +}; + +} // namespace DataHandling +} // namespace Mantid + +#endif /* MANTID_DATAHANDLING_LOADSAVUTOMOCONFIG_H_ */ diff --git a/Code/Mantid/Framework/DataHandling/inc/MantidDataHandling/SaveSavuTomoConfig.h b/Code/Mantid/Framework/DataHandling/inc/MantidDataHandling/SaveSavuTomoConfig.h new file mode 100644 index 000000000000..20de386f2250 --- /dev/null +++ b/Code/Mantid/Framework/DataHandling/inc/MantidDataHandling/SaveSavuTomoConfig.h @@ -0,0 +1,88 @@ +#ifndef MANTID_DATAHANDLING_SAVESAVUTOMOCONFIG_H_ +#define MANTID_DATAHANDLING_SAVESAVUTOMOCONFIG_H_ + +//--------------------------------------------------- +// Includes +//--------------------------------------------------- +#include "MantidAPI/Algorithm.h" +#include "MantidAPI/ITableWorkspace.h" + +namespace Mantid { +namespace DataHandling { + +/** + * Saves a configuration for a tomographic reconstruction into a + * NeXus/HDF5 file. + * + * Operates on table workspaces, with each row representing a plugin + * definition to add. + * + * Columns:4: id/params/name/cite + * + * Copyright © 2014-2015 ISIS Rutherford Appleton Laboratory, + * NScD Oak Ridge National Laboratory & European Spallation Source + * + * This file is part of Mantid. + * + * Mantid is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * Mantid is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + * File change history is stored at: + * Code Documentation is available at: + */ + +class DLLExport SaveSavuTomoConfig : public API::Algorithm { +public: + SaveSavuTomoConfig(); + /// Virtual dtor + virtual ~SaveSavuTomoConfig() {} + + /// Algorithm's name for identification overriding a virtual method + virtual const std::string name() const { return "SaveSavuTomoConfig"; } + + /// Summary of algorithms purpose + virtual const std::string summary() const { + return "Writes a configuration file for a tomographic reconstruction job."; + } + + /// Algorithm's version + virtual int version() const { return (1); } + + /// Algorithm's category for identification + virtual const std::string category() const { + return "DataHandling\\Tomography;"; } + +private: + /// Initialisation code + void init(); + /// Execution code : Single workspace + void exec(); + + /// basic check on a table workspace properties + bool tableLooksGenuine(const API::ITableWorkspace_sptr &tws); + + /// get table workspaces (checking the workspace names given) + std::vector checkTables( + const std::vector &workspaces); + /// write savu tomo config file + void saveFile(const std::string fname, + const std::vector &wss); + + // Number of info entries to read from the input table workspaces + unsigned int m_pluginInfoCount; +}; + +} // namespace DataHandling +} // namespace Mantid + +#endif // MANTID_DATAHANDLING_SAVESAVUTOMOCONFIG_H_ diff --git a/Code/Mantid/Framework/DataHandling/src/DownloadInstrument.cpp b/Code/Mantid/Framework/DataHandling/src/DownloadInstrument.cpp index 2d4788b2b75d..045818331a7e 100644 --- a/Code/Mantid/Framework/DataHandling/src/DownloadInstrument.cpp +++ b/Code/Mantid/Framework/DataHandling/src/DownloadInstrument.cpp @@ -9,7 +9,6 @@ #include #include #include -#include // Visual Studio complains with the inclusion of Poco/FileStream // disabling this warning. #if defined(_WIN32) || defined(_WIN64) @@ -153,7 +152,7 @@ DownloadInstrument::StringToStringMap DownloadInstrument::processRepository() { try { doDownloadFile(gitHubInstrumentRepoUrl, gitHubJson.toString(), headers); } catch (Exception::InternetError &ex) { - if (ex.errorCode() == HTTPResponse::HTTP_NOT_MODIFIED) { + if (ex.errorCode() == InternetHelper::HTTP_NOT_MODIFIED) { // No changes since last time return fileMap; } else { diff --git a/Code/Mantid/Framework/DataHandling/src/ISISDataArchive.cpp b/Code/Mantid/Framework/DataHandling/src/ISISDataArchive.cpp index c9d6a6f8601f..df3faa501c68 100644 --- a/Code/Mantid/Framework/DataHandling/src/ISISDataArchive.cpp +++ b/Code/Mantid/Framework/DataHandling/src/ISISDataArchive.cpp @@ -3,12 +3,9 @@ //---------------------------------------------------------------------- #include "MantidDataHandling/ISISDataArchive.h" #include "MantidAPI/ArchiveSearchFactory.h" +#include "MantidKernel/InternetHelper.h" +#include "MantidKernel/Exception.h" -#include -#include -#include -#include -#include #include #include #include @@ -17,12 +14,6 @@ #include #include -using Poco::Net::HTTPClientSession; -using Poco::Net::HTTPRequest; -using Poco::Net::HTTPResponse; -using Poco::Net::HTTPMessage; -using Poco::URI; - namespace Mantid { namespace DataHandling { namespace { @@ -85,20 +76,11 @@ std::string ISISDataArchive::getPath(const std::string &fName) const { if (fName.empty()) return ""; // Avoid pointless call to service - URI uri(URL_PREFIX + fName); - std::string path(uri.getPathAndQuery()); - - HTTPClientSession session(uri.getHost(), uri.getPort()); - HTTPRequest req(HTTPRequest::HTTP_GET, path, HTTPMessage::HTTP_1_1); - session.sendRequest(req); + Kernel::InternetHelper inetHelper; + std::ostringstream os; + try { + inetHelper.sendRequest(URL_PREFIX + fName,os); - HTTPResponse res; - std::istream &rs = session.receiveResponse(res); - const HTTPResponse::HTTPStatus status = res.getStatus(); - g_log.debug() << "HTTP response=" << res.getStatus() << "\n"; - if (status == HTTPResponse::HTTP_OK) { - std::ostringstream os; - Poco::StreamCopier::copyStream(rs, os); os << Poco::Path::separator() << fName; try { const std::string expectedPath = os.str(); @@ -107,6 +89,12 @@ std::string ISISDataArchive::getPath(const std::string &fName) const { } catch (Poco::Exception &) { } } + catch (Kernel::Exception::InternetError& ie) { + g_log.warning() + << "Could not access archive index " + << ie.what(); + } + return ""; } diff --git a/Code/Mantid/Framework/DataHandling/src/LoadEventNexus.cpp b/Code/Mantid/Framework/DataHandling/src/LoadEventNexus.cpp index dc3afd41e776..3af9cf516d24 100644 --- a/Code/Mantid/Framework/DataHandling/src/LoadEventNexus.cpp +++ b/Code/Mantid/Framework/DataHandling/src/LoadEventNexus.cpp @@ -1351,6 +1351,21 @@ std::size_t numEvents(::NeXus::File &file, bool &hasTotalCounts, return numEvents; } +void LoadEventNexus::createWorkspaceIndexMaps(const bool monitors, + const std::vector &bankNames) { + // Create the required spectra mapping so that the workspace knows what to pad + // to + createSpectraMapping(m_filename, monitors, bankNames); + + // 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); +} + //----------------------------------------------------------------------------- /** * Load events from the file. @@ -1526,6 +1541,9 @@ void LoadEventNexus::loadEvents(API::Progress *const prog, xRef[1] = 1; // Set the binning axis using this. WS->setAllX(axis); + + createWorkspaceIndexMaps(monitors, std::vector()); + return; } @@ -1579,17 +1597,7 @@ void LoadEventNexus::loadEvents(API::Progress *const prog, } } //----------------- 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); + createWorkspaceIndexMaps(monitors, someBanks); // Cache a map for speed. if (!m_haveWeights) { diff --git a/Code/Mantid/Framework/DataHandling/src/LoadMuonNexus.cpp b/Code/Mantid/Framework/DataHandling/src/LoadMuonNexus.cpp index 08d201c0123d..d0caf0fd7e62 100644 --- a/Code/Mantid/Framework/DataHandling/src/LoadMuonNexus.cpp +++ b/Code/Mantid/Framework/DataHandling/src/LoadMuonNexus.cpp @@ -50,14 +50,13 @@ void LoadMuonNexus::init() { "generated for each period"); auto mustBePositive = boost::make_shared>(); - mustBePositive->setLower(0); - declareProperty("SpectrumMin", (int64_t)0, mustBePositive, - "Index number of the first spectrum to read, only used if\n" - "spectrum_max is set and only for single period data\n" - "(default 0)"); + mustBePositive->setLower(1); + declareProperty("SpectrumMin", (int64_t)EMPTY_INT(), mustBePositive, + "Index number of the first spectrum to read\n" + "(default 1)"); declareProperty( "SpectrumMax", (int64_t)EMPTY_INT(), mustBePositive, - "Index of last spectrum to read, only for single period data\n" + "Index of last spectrum to read\n" "(default the last spectrum)"); declareProperty(new ArrayProperty("SpectrumList"), @@ -68,7 +67,9 @@ void LoadMuonNexus::init() { "together based on the groupings in the NeXus file, only\n" "for single period data (default no)"); - declareProperty("EntryNumber", (int64_t)0, mustBePositive, + auto mustBeNonNegative = boost::make_shared>(); + mustBeNonNegative->setLower(0); + declareProperty("EntryNumber", (int64_t)0, mustBeNonNegative, "The particular entry number to read (default: Load all " "workspaces and creates a workspace group)"); diff --git a/Code/Mantid/Framework/DataHandling/src/LoadMuonNexus1.cpp b/Code/Mantid/Framework/DataHandling/src/LoadMuonNexus1.cpp index 9c459971d4f0..660440e839b5 100644 --- a/Code/Mantid/Framework/DataHandling/src/LoadMuonNexus1.cpp +++ b/Code/Mantid/Framework/DataHandling/src/LoadMuonNexus1.cpp @@ -122,14 +122,14 @@ void LoadMuonNexus1::exec() { m_numberOfPeriods = nxload.t_nper; } - // Try to load dead time info - loadDeadTimes(root); - bool autoGroup = getProperty("AutoGroup"); // Grouping info should be returned if user has set the property bool returnGrouping = !getPropertyValue("DetectorGroupingTable").empty(); + // Call private method to validate the optional parameters, if set + checkOptionalProperties(); + Workspace_sptr loadedGrouping; // Try to load detector grouping info, if needed for auto-grouping or user @@ -153,23 +153,23 @@ void LoadMuonNexus1::exec() { boost::shared_ptr instrument; boost::shared_ptr sample; - // Call private method to validate the optional parameters, if set - checkOptionalProperties(); - // Read the number of time channels (i.e. bins) from the Nexus file const int channelsPerSpectrum = nxload.t_ntc1; // Read in the time bin boundaries const int lengthIn = channelsPerSpectrum + 1; - float *timeChannels = new float[lengthIn]; - nxload.getTimeChannels(timeChannels, lengthIn); - // Put the read in array into a vector (inside a shared pointer) - boost::shared_ptr timeChannelsVec( - new MantidVec(timeChannels, timeChannels + lengthIn)); // Calculate the size of a workspace, given its number of periods & spectra to // read int64_t total_specs; if (m_interval || m_list) { + // Remove from list possible duplicate specs + for (auto it=m_spec_list.begin(); it!=m_spec_list.end(); ) { + if ( (*it>=m_spec_min) && (*it<=m_spec_max) ) { + it = m_spec_list.erase(it); + } else { + ++it; + } + } total_specs = m_spec_list.size(); if (m_interval) { total_specs += (m_spec_max - m_spec_min + 1); @@ -178,10 +178,13 @@ void LoadMuonNexus1::exec() { } else { total_specs = m_numberOfSpectra; // for nexus return all spectra - m_spec_min = 0; // changed to 0 for NeXus, was 1 for Raw - m_spec_max = m_numberOfSpectra; // was +1? + m_spec_min = 1; + m_spec_max = m_numberOfSpectra+1; // Add +1 to iterate } + // Try to load dead time info + loadDeadTimes(root); + // Create the 2D workspace for the output DataObjects::Workspace2D_sptr localWorkspace = boost::dynamic_pointer_cast( @@ -232,8 +235,9 @@ void LoadMuonNexus1::exec() { size_t counter = 0; for (int64_t i = m_spec_min; i < m_spec_max; ++i) { // Shift the histogram to read if we're not in the first period - specid_t histToRead = static_cast(i + period * total_specs); - loadData(timeChannelsVec, counter, histToRead, nxload, lengthIn - 1, + specid_t histToRead = static_cast(i-1 + period * nxload.t_nsp1); + specid_t specNo = static_cast(i); + loadData(counter, histToRead, specNo, nxload, lengthIn - 1, localWorkspace); // added -1 for NeXus counter++; progress.report(); @@ -241,8 +245,10 @@ void LoadMuonNexus1::exec() { // Read in the spectra in the optional list parameter, if set if (m_list) { for (size_t i = 0; i < m_spec_list.size(); ++i) { - loadData(timeChannelsVec, counter, m_spec_list[i], nxload, lengthIn - 1, - localWorkspace); + specid_t histToRead = static_cast(m_spec_list[i]-1 + period * nxload.t_nsp1); + specid_t specNo = static_cast(m_spec_list[i]); + loadData(counter, histToRead, specNo, nxload, lengthIn - 1, + localWorkspace); counter++; progress.report(); } @@ -291,8 +297,6 @@ void LoadMuonNexus1::exec() { boost::dynamic_pointer_cast(wsGrpSptr)); } - // Clean up - delete[] timeChannels; } /** @@ -313,23 +317,47 @@ void LoadMuonNexus1::loadDeadTimes(NXRoot &root) { int numDeadTimes = deadTimesData.dim0(); + std::vector specToLoad; std::vector deadTimes; - deadTimes.reserve(numDeadTimes); - for (int i = 0; i < numDeadTimes; i++) - deadTimes.push_back(deadTimesData[i]); + // Set the spectrum list that should be loaded + if ( m_interval || m_list ) { + // Load only selected spectra + for (int64_t i=m_spec_min; i(i)); + } + for (auto it=m_spec_list.begin(); it!=m_spec_list.end(); ++it) { + specToLoad.push_back(*it); + } + } else { + // Load all the spectra + // Start from 1 to N+1 to be consistent with + // the case where spectra are specified + for (int i=1; i(); - for (auto it = deadTimes.begin(); it != deadTimes.end(); - it += m_numberOfSpectra) { - TableWorkspace_sptr table = - createDeadTimeTable(it, it + m_numberOfSpectra); + for (int64_t i=0; i(*it -1 + i*m_numberOfSpectra); + deadTimes.push_back(deadTimesData[index]); + } + + // Load into table + TableWorkspace_sptr table = createDeadTimeTable(specToLoad,deadTimes); tableGroup->addWorkspace(table); } @@ -429,8 +463,8 @@ Workspace_sptr LoadMuonNexus1::loadDetectorGrouping(NXRoot &root) { * @return Dead Time Table create using the data */ TableWorkspace_sptr -LoadMuonNexus1::createDeadTimeTable(std::vector::const_iterator begin, - std::vector::const_iterator end) { +LoadMuonNexus1::createDeadTimeTable(std::vector specToLoad, + std::vector deadTimes) { TableWorkspace_sptr deadTimeTable = boost::dynamic_pointer_cast( WorkspaceFactory::Instance().createTable("TableWorkspace")); @@ -438,11 +472,9 @@ LoadMuonNexus1::createDeadTimeTable(std::vector::const_iterator begin, deadTimeTable->addColumn("int", "spectrum"); deadTimeTable->addColumn("double", "dead-time"); - int s = 1; // Current spectrum - - for (auto it = begin; it != end; it++) { + for (size_t i = 0; iappendRow(); - row << s++ << *it; + row << specToLoad[i] << deadTimes[i]; } return deadTimeTable; @@ -483,7 +515,6 @@ TableWorkspace_sptr LoadMuonNexus1::createDetectorGroupingTable( } /** Load in a single spectrum taken from a NeXus file -* @param tcbs :: The vector containing the time bin boundaries * @param hist :: The workspace index * @param i :: The spectrum number * @param nxload :: A reference to the MuonNeXusReader object @@ -491,8 +522,7 @@ TableWorkspace_sptr LoadMuonNexus1::createDetectorGroupingTable( * @param localWorkspace :: A pointer to the workspace in which the data will be * stored */ -void LoadMuonNexus1::loadData(const MantidVecPtr::ptr_type &tcbs, size_t hist, - specid_t &i, MuonNexusReader &nxload, +void LoadMuonNexus1::loadData(size_t hist, specid_t &i, specid_t specNo, MuonNexusReader &nxload, const int64_t lengthIn, DataObjects::Workspace2D_sptr localWorkspace) { // Read in a spectrum @@ -502,14 +532,27 @@ void LoadMuonNexus1::loadData(const MantidVecPtr::ptr_type &tcbs, size_t hist, MantidVec &Y = localWorkspace->dataY(hist); Y.assign(nxload.counts + i * lengthIn, nxload.counts + i * lengthIn + lengthIn); + // Create and fill another vector for the errors, containing sqrt(count) MantidVec &E = localWorkspace->dataE(hist); typedef double (*uf)(double); uf dblSqrt = std::sqrt; std::transform(Y.begin(), Y.end(), E.begin(), dblSqrt); // Populate the workspace. Loop starts from 1, hence i-1 - localWorkspace->setX(hist, tcbs); - localWorkspace->getSpectrum(hist)->setSpectrumNo(static_cast(hist) + 1); + + // Create and fill another vector for the X axis + float *timeChannels = new float[lengthIn+1](); + nxload.getTimeChannels(timeChannels, static_cast(lengthIn+1)); + // Put the read in array into a vector (inside a shared pointer) + boost::shared_ptr timeChannelsVec( + new MantidVec(timeChannels, timeChannels + lengthIn+1)); + + localWorkspace->setX(hist, timeChannelsVec); + localWorkspace->getSpectrum(hist)->setSpectrumNo(specNo); + + // Clean up + delete[] timeChannels; + } /** Log the run details from the file diff --git a/Code/Mantid/Framework/DataHandling/src/LoadSavuTomoConfig.cpp b/Code/Mantid/Framework/DataHandling/src/LoadSavuTomoConfig.cpp new file mode 100644 index 000000000000..fae3a95e7bdb --- /dev/null +++ b/Code/Mantid/Framework/DataHandling/src/LoadSavuTomoConfig.cpp @@ -0,0 +1,209 @@ +#include "MantidAPI/FileProperty.h" +#include "MantidAPI/ITableWorkspace.h" +#include "MantidAPI/TableRow.h" +#include "MantidAPI/WorkspaceProperty.h" +#include "MantidAPI/WorkspaceFactory.h" +#include "MantidDataHandling/LoadSavuTomoConfig.h" +#include "MantidKernel/PropertyWithValue.h" + +#include + +namespace Mantid { +namespace DataHandling { + +// Register the algorithm into the algorithm factory +DECLARE_ALGORITHM(LoadSavuTomoConfig); + +using namespace Mantid::API; + +LoadSavuTomoConfig::LoadSavuTomoConfig() { +} + +LoadSavuTomoConfig::~LoadSavuTomoConfig() { +} + +/** + * Standard Initialisation method. Declares properties. + */ +void LoadSavuTomoConfig::init() { + // Required input properties + std::vector exts; + exts.push_back(".nxs"); + exts.push_back(".nx5"); + exts.push_back(".xml"); + + declareProperty(new FileProperty("Filename", "", FileProperty::Load, exts), + "The name of the Nexus parameterization file to read, as a full " + "or relative path."); + + declareProperty(new WorkspaceProperty("OutputWorkspace", + "savuTomoConfig", + Kernel::Direction::Output, + PropertyMode::Mandatory), + "The name of the workspace to be created as output of " + "the algorithm, a workspace with this name will be created " + "and stored in the Analysis Data Service."); +} + +/** + * Executes the algorithm: reads in the parameters file and creates + * and fills the output workspace + * + * @throw runtime_error Thrown if execution fails + */ +void LoadSavuTomoConfig::exec() { + progress(0, "Opening file..."); + + // Will throw an approriate exception if there is a problem with the + // properties + std::string fname = getPropertyValue("Filename"); + std::string wsName = getPropertyValue("OutputWorkspace"); + + ITableWorkspace_sptr ws; + try { + // Do the real load. Throws exception if issues found + ws = loadFile(fname, wsName); + if (ws) { + setProperty("OutputWorkspace", ws); + } + } catch(std::exception& e) { + g_log.error() << "Failed to load savu tomography reconstruction " + "parameterization file: " << e.what() << std::endl; + return; + } + + progress(1.0, "Loading finished."); +} + +/** + * Can it be openend in the expected format, and does it seem to have + * sensible contents? + * + * @param fname name of file + * @param f nexus file object, created if file is fine + * + * @return true if everything seems fine, false otherwise + */ +bool LoadSavuTomoConfig::checkOpenFile(std::string fname, + boost::shared_ptr &f) { + try { + f = boost::make_shared(fname); + if (f) + f->getEntries(); + } catch (NeXus::Exception &e) { + g_log.error() << "Failed to open as a NeXus file: '" << fname + << "', error description: " << e.what() << std::endl; + return false; + } + return true; +} + +/** + * Loads a tomography parameterization file into a newly created table + * workspace. The file must have the following syntax: + * + * + * + * + * + * + * + * + * + * + * @param fname name of the parameterization file + * @param wsName name of workspace where to load the file data + * + * @return table workspace with parameters (plugins) found in the + * loaded file + */ +ITableWorkspace_sptr LoadSavuTomoConfig::loadFile(std::string& fname, + std::string& wsName) { + // Throws an exception if there is a problem with file access + //Mantid::NeXus::NXRoot root(fname); + boost::shared_ptr f; + if (!checkOpenFile(fname, f)) { + throw std::runtime_error( + "Failed to recognize this file as a NeXus file, cannot continue."); + } + + ITableWorkspace_sptr ws = + API::WorkspaceFactory::Instance().createTable(); + if (!ws) + throw std::runtime_error("Could not create TableWorkspace for " + "workspace with name '" + wsName + "'"); + + // init workspace + ws->setTitle("Table with tomography parameters from file " + + fname); + ws->addColumn("str", "ID"); + ws->addColumn("str", "Parameters"); + ws->addColumn("str", "Name"); + ws->addColumn("str", "Cite"); + + // a bit of file consistency check, check at least there's a + // 'entry1' + // it could be more strict and demand entries.size()==1 + std::map entries = f->getEntries(); + std::string mainEntryName = "entry"; + auto it = entries.find(mainEntryName); + if (entries.end() == it) { + throw std::runtime_error("Could not find the '" + mainEntryName + "' " + "entry. Even though this file looks like a valid NeXus file, it is " + "not in the correct format for tomography reconstruction " + "parameterization files."); + } + + // go through the input file plugin entries + f->openGroup(mainEntryName, "NXentry"); + f->openGroup("process", "NXprocess"); + size_t pluginsLen = f->getEntries().size(); + for (size_t j=0; jappendRow(); + + std::string entryIdx = boost::lexical_cast(j); + try { + f->openGroup(entryIdx, "NXnote"); + } catch(NeXus::Exception &e) { + // detailed NeXus error message and throw... + g_log.error() << "Failed to load plugin '" << j << "' from" + "NeXus file. Error description: " << e.what() << std::endl; + throw std::runtime_error("Could not load one or more plugin " + "entries from the tomographic reconstruction parameterization " + "file. Please check that the file is correct."); + } + + // TODO: check final 'schema', get these 4 fields from the file + std::string id = ""; + std::string params = ""; + std::string name = ""; + std::string cite = ""; + try { + f->readData("data", params); + f->readData("id", id); + f->readData("name", name); + // cite not available for now + // f->readData("cite", cite); + // This might be extended to an NXcite group that would be included + // not here but inside an "intermediate" NXcollection group. That + // NXcite would have 4 arrays: description, doi, endnote, bibtex. + // But this is what we have so far. + cite = "Not available"; + } catch(NeXus::Exception &e) { + // permissive, just error message but carry on + g_log.warning() << "Failed to read some fields in tomographic " + "reconstruction plugin line. The file seems to be wrong. Error " + "description: " << e.what() << std::endl; + } + + table << id << params << name << cite; + f->closeGroup(); + progress(static_cast(j)/static_cast(pluginsLen)); + } + f->close(); + + return ws; +} + +} // namespace DataHandling +} // namespace Mantid diff --git a/Code/Mantid/Framework/DataHandling/src/SNSDataArchive.cpp b/Code/Mantid/Framework/DataHandling/src/SNSDataArchive.cpp index aec27046ab85..2ecc8bd1680a 100644 --- a/Code/Mantid/Framework/DataHandling/src/SNSDataArchive.cpp +++ b/Code/Mantid/Framework/DataHandling/src/SNSDataArchive.cpp @@ -2,16 +2,12 @@ // Includes //---------------------------------------------------------------------- #include "MantidKernel/Logger.h" +#include "MantidKernel/InternetHelper.h" +#include "MantidKernel/Exception.h" #include "MantidDataHandling/SNSDataArchive.h" #include "MantidAPI/ArchiveSearchFactory.h" #include -#include -#include -#include -#include -#include -#include #include #include #include @@ -23,9 +19,8 @@ #include "Poco/DOM/AutoPtr.h" #include +#include -using Poco::Net::ConnectionRefusedException; -using Poco::URI; namespace Mantid { namespace DataHandling { @@ -62,28 +57,25 @@ SNSDataArchive::getArchivePath(const std::set &filenames, const std::string URL(BASE_URL + filename); g_log.debug() << "URL: " << URL << "\n"; - Poco::URI uri(URL); - std::string path(uri.getPathAndQuery()); - Poco::Net::HTTPClientSession session(uri.getHost(), uri.getPort()); - Poco::Net::HTTPRequest req(Poco::Net::HTTPRequest::HTTP_GET, path, - Poco::Net::HTTPMessage::HTTP_1_1); - session.sendRequest(req); + Kernel::InternetHelper inetHelper; + std::ostringstream rs; + + + int status = inetHelper.sendRequest(URL,rs); - Poco::Net::HTTPResponse res; - std::istream &rs = session.receiveResponse(res); - g_log.debug() << "res.getStatus(): " << res.getStatus() << "\n"; // Create a DOM document from the response. Poco::XML::DOMParser parser; - Poco::XML::InputSource source(rs); + std::istringstream istrsource(rs.str()); + Poco::XML::InputSource source(istrsource); Poco::AutoPtr pDoc = parser.parse(&source); std::vector locations; - // If everything went fine, return the XML document. + // Everything went fine, return the XML document. // Otherwise look for an error message in the XML document. - if (res.getStatus() == Poco::Net::HTTPResponse::HTTP_OK) { + if (status == Kernel::InternetHelper::HTTP_OK) { std::string location; Poco::AutoPtr pList = pDoc->getElementsByTagName("location"); @@ -92,9 +84,6 @@ SNSDataArchive::getArchivePath(const std::set &filenames, g_log.debug() << "location: " << location << "\n"; locations.push_back(location); } - } else { - std::string error(res.getReason()); - throw Poco::ApplicationException("HTTPRequest Error", error); } std::vector::const_iterator ext = exts.begin(); diff --git a/Code/Mantid/Framework/DataHandling/src/SaveSavuTomoConfig.cpp b/Code/Mantid/Framework/DataHandling/src/SaveSavuTomoConfig.cpp new file mode 100644 index 000000000000..a40405806af5 --- /dev/null +++ b/Code/Mantid/Framework/DataHandling/src/SaveSavuTomoConfig.cpp @@ -0,0 +1,200 @@ +#include "MantidAPI/FileProperty.h" +#include "MantidDataHandling/SaveSavuTomoConfig.h" +#include "MantidKernel/ArrayProperty.h" +#include "MantidKernel/MandatoryValidator.h" + +#include +#include + +namespace Mantid { +namespace DataHandling { +// Register the algorithm into the algorithm factory +DECLARE_ALGORITHM(SaveSavuTomoConfig) + +using namespace Kernel; +using namespace API; + +SaveSavuTomoConfig::SaveSavuTomoConfig() : API::Algorithm(), m_pluginInfoCount(4) +{ } + +/** + * Initialise the algorithm + */ +void SaveSavuTomoConfig::init() { + // Get a list of table workspaces which contain the plugin information + declareProperty( + new ArrayProperty("InputWorkspaces", + boost::make_shared>>()), + "The names of the table workspaces containing plugin information."); + + declareProperty(new API::FileProperty("Filename", "", FileProperty::Save, + std::vector(1, ".nxs")), + "The name of the tomographic config file to write, as a full " + "or relative path. This will overwrite existing files."); +} + +/** + * Execute the algorithm + */ +void SaveSavuTomoConfig::exec() { + // Prepare properties for writing to file + std::string fileName = getPropertyValue("Filename"); + + progress(0, "Checking workspace (tables)..."); + + std::vector wss = checkTables(getProperty("InputWorkspaces")); + + try { + saveFile(fileName, wss); + } catch (std::exception &e) { + g_log.error() << "Failed to save savu tomography reconstruction parameterization " + "file, error description: " << e.what() << std::endl; + return; + } + + progress(0, "File saved."); +} + +/** + * Do a basic check that the table seems to be what we need to save a + * savu configuration file. + * + * @param tws Table workspace that should contain plugin/processing + * steps information (a savu configuration) + * + * @return True if the table passed seems to be a savu configuration table + */ +bool SaveSavuTomoConfig::tableLooksGenuine(const ITableWorkspace_sptr &tws) { + // note that more columns might be added in the relatively near future + if (!(tws->columnCount() >= m_pluginInfoCount)) + return false; + + std::vector names = tws->getColumnNames(); + return ( 4 <= names.size() && + "ID" == names[0] && + "Parameters" == names[1] && + "Name" == names[2] && + "Cite" == names[3]); +} + +/** + * Check that the list of workspace names identifies table workspaces + * with (approximately) the expected information (4 columns), and + * return the corresponding (table) workspace objects. + * + * @param workspaces Table workspace names that should contain plugin/processing + * steps information + * + * @return Table workspaces retrieved from the ADS, corresponding to + * the names passed + */ +std::vector SaveSavuTomoConfig::checkTables( + const std::vector &workspaces) { + std::vector wss; + for (auto it = workspaces.begin(); it != workspaces.end(); ++it) { + if (AnalysisDataService::Instance().doesExist(*it)) { + ITableWorkspace_sptr table = + AnalysisDataService::Instance().retrieveWS(*it); + // Check it's valid. Very permissive check for the time being + if (table && tableLooksGenuine(table)) { + wss.push_back(table); + } else { + throw std::runtime_error("Invalid workspace provided: " + + *it + ". This algorithm requires a table " + "workspace with correct savu plugin/ " + "pipeline process information."); + } + } else { + throw std::runtime_error( + "One or more specified table workspaces don't exist. I could not " + "find this one: " + *it); + } + } + return wss; +} + +/** + * Check that the list of workspace names identifies table workspaces + * with (approximately) the expected information (4 columns), and + * return the corresponding (table) workspace objects. + * + * @param fname Destination file name (can be ammended if needed and that + * will be logged) + * @param wss Table workspaces that apparently contain plugin/processing + * steps information + */ +void SaveSavuTomoConfig::saveFile(const std::string fname, + const std::vector &wss) { + // Ensure it has a .nxs extension + std::string fileName = fname; + if (!boost::ends_with(fileName, ".nxs")) { + const std::string ext = ".nxs"; + g_log.notice() << "Adding extension '" << ext << "' to the output " + "file name given (it is a NeXus file). " << std::endl; + fileName = fileName + ".nxs"; + } + + // If file exists, delete it. + Poco::File f(fileName); + if (f.exists()) { + g_log.notice() << "Overwriting existing file: '" << fileName << "'" << + std::endl; + f.remove(); + } else { + g_log.notice() << "Creating file: '" << fileName << ";" << std::endl; + } + + // Create the file handle + NXhandle fileHandle; + NXstatus status = NXopen(fileName.c_str(), NXACC_CREATE5, &fileHandle); + + if (status == NX_ERROR) + throw std::runtime_error("Unable to create file."); + + NeXus::File nxFile(fileHandle); + + std::string topLevelEntry = "entry"; + nxFile.makeGroup(topLevelEntry, "NXentry", true); + + const std::string processingEntry = "processing"; + nxFile.makeGroup(processingEntry, "NXprocess", true); + + // Iterate through all plugin entries (number sub groups 0....n-1) + size_t procCount = 0; + for (size_t i = 0; i < wss.size(); ++i) { + // Concatenate table contents, putting pipeline processing steps in the same sequence + // as they come in the seq of table workspaces + ITableWorkspace_sptr w = wss[i]; + for (size_t ti =0; ti < w->rowCount(); ++ti) { + // Column info order is [ID / Params {as json string} / name {description} / + // citation info] + std::string id = w->cell(ti, 0); + std::string params = w->cell(ti, 1); + std::string name = w->cell(ti, 2); + // Unused for now, until file format is finalized/documented. + // std::string cite = w->cell(ti, 3); + + // but in the file it goes as: data (params), id, name + nxFile.makeGroup(boost::lexical_cast(procCount++), "NXnote", true); + nxFile.writeData("data", params); + nxFile.writeData("id", id); + nxFile.writeData("name", name); + // Ignore citation information for now. Format not fixed yet. + // nxFile.writeData("cite", cite); + nxFile.closeGroup(); // close NXnote + } + } + + nxFile.closeGroup(); // processing NXprocess + + // This seems to be required for certain extensions that can be appended + // to these files. Not fixed for now. + nxFile.makeGroup("intermediate", "NXcollection", false); + + nxFile.closeGroup(); // Top level entry (NXentry) + + nxFile.close(); +} + +} // namespace DataHandling +} // namespace Mantid diff --git a/Code/Mantid/Framework/DataHandling/test/LoadMuonNexus1Test.h b/Code/Mantid/Framework/DataHandling/test/LoadMuonNexus1Test.h index 4e942bf6cc65..88571af5fdcb 100644 --- a/Code/Mantid/Framework/DataHandling/test/LoadMuonNexus1Test.h +++ b/Code/Mantid/Framework/DataHandling/test/LoadMuonNexus1Test.h @@ -273,7 +273,7 @@ class LoadMuonNexus1Test : public CxxTest::TestSuite nxload3.setPropertyValue("Filename", inputFile); nxload3.setPropertyValue("OutputWorkspace", "outWS"); - nxload3.setPropertyValue("SpectrumList", "29,30,31"); + nxload3.setPropertyValue("SpectrumList", "29,30,32"); nxload3.setPropertyValue("SpectrumMin", "5"); nxload3.setPropertyValue("SpectrumMax", "10"); @@ -300,6 +300,83 @@ class LoadMuonNexus1Test : public CxxTest::TestSuite TS_ASSERT_EQUALS( output2D->dataE(8)[479], 12); // Check that the error on that value is correct TS_ASSERT_DELTA( output2D->dataX(8)[479], 7.410, 0.0001); + + } + + void testPartialSpectraLoading () + { + LoadMuonNexus1 alg1; + LoadMuonNexus1 alg2; + + const std::string deadTimeWSName = "LoadMuonNexus1Test_DeadTimes"; + + // Execute alg1 + // It will only load some spectra + TS_ASSERT_THROWS_NOTHING( alg1.initialize() ); + TS_ASSERT( alg1.isInitialized() ); + alg1.setPropertyValue("Filename", inputFile); + alg1.setPropertyValue("OutputWorkspace", "outWS1"); + alg1.setPropertyValue("SpectrumList", "29,31"); + alg1.setPropertyValue("SpectrumMin", "5"); + alg1.setPropertyValue("SpectrumMax", "10"); + alg1.setPropertyValue("DeadTimeTable", deadTimeWSName); + TS_ASSERT_THROWS_NOTHING(alg1.execute()); + TS_ASSERT( alg1.isExecuted() ); + // Get back the saved workspace + MatrixWorkspace_sptr output1 = AnalysisDataService::Instance().retrieveWS("outWS1"); + Workspace2D_sptr out1 = boost::dynamic_pointer_cast(output1); + + // Execute alg2 + // Load all the spectra + TS_ASSERT_THROWS_NOTHING( alg2.initialize() ); + TS_ASSERT( alg2.isInitialized() ); + alg2.setPropertyValue("Filename", inputFile); + alg2.setPropertyValue("OutputWorkspace", "outWS2"); + TS_ASSERT_THROWS_NOTHING(alg2.execute()); + TS_ASSERT( alg2.isExecuted() ); + // Get back the saved workspace + MatrixWorkspace_sptr output2 = AnalysisDataService::Instance().retrieveWS("outWS2"); + Workspace2D_sptr out2 = boost::dynamic_pointer_cast(output2); + + // Check common spectra + // X values should match + TS_ASSERT_EQUALS( out1->readX(0), out2->readX(0) ); + TS_ASSERT_EQUALS( out1->readX(4), out2->readX(5) ); + // Check some Y values + TS_ASSERT_EQUALS( out1->readY(0), out2->readY(4) ); + TS_ASSERT_EQUALS( out1->readY(3), out2->readY(7) ); + TS_ASSERT_EQUALS( out1->readY(5), out2->readY(9) ); + TS_ASSERT_EQUALS( out1->readY(6), out2->readY(28) ); + TS_ASSERT_EQUALS( out1->readY(7), out2->readY(30) ); + // Check some E values + TS_ASSERT_EQUALS( out1->readE(0), out2->readE(4) ); + TS_ASSERT_EQUALS( out1->readE(3), out2->readE(7) ); + TS_ASSERT_EQUALS( out1->readE(5), out2->readE(9) ); + TS_ASSERT_EQUALS( out1->readE(6), out2->readE(28) ); + TS_ASSERT_EQUALS( out1->readE(7), out2->readE(30) ); + + AnalysisDataService::Instance().remove("outWS1"); + AnalysisDataService::Instance().remove("outWS2"); + + // Check dead time table + TableWorkspace_sptr deadTimeTable; + TS_ASSERT_THROWS_NOTHING( deadTimeTable = + AnalysisDataService::Instance().retrieveWS( deadTimeWSName ) ); + TS_ASSERT( deadTimeTable ); + // Check number of rows and columns + TS_ASSERT_EQUALS( deadTimeTable->columnCount(), 2 ); + TS_ASSERT_EQUALS( deadTimeTable->rowCount(), 8 ); + // Check spectrum numbers + TS_ASSERT_EQUALS( deadTimeTable->Int(0,0), 5 ); + TS_ASSERT_EQUALS( deadTimeTable->Int(4,0), 9 ); + TS_ASSERT_EQUALS( deadTimeTable->Int(7,0), 31); + // Check dead time values + TS_ASSERT_DELTA( deadTimeTable->Double(0,1), 0.00161112, 0.00000001 ); + TS_ASSERT_DELTA( deadTimeTable->Double(3,1), 0.00431686, 0.00000001 ); + TS_ASSERT_DELTA( deadTimeTable->Double(6,1), 0.00254914, 0.00000001 ); + AnalysisDataService::Instance().remove(deadTimeWSName); + + } void test_loadingDeadTimes_singlePeriod() diff --git a/Code/Mantid/Framework/DataHandling/test/LoadSavuTomoConfigTest.h b/Code/Mantid/Framework/DataHandling/test/LoadSavuTomoConfigTest.h new file mode 100644 index 000000000000..2f4e3e060990 --- /dev/null +++ b/Code/Mantid/Framework/DataHandling/test/LoadSavuTomoConfigTest.h @@ -0,0 +1,179 @@ +#ifndef LOADSAVUTOMOCONFIGTEST_H_ +#define LOADSAVUTOMOCONFIGTEST_H_ + +#include + +#include "MantidAPI/AlgorithmManager.h" +#include "MantidAPI/AnalysisDataService.h" +#include "MantidAPI/ITableWorkspace.h" +#include "MantidDataHandling/LoadSavuTomoConfig.h" + +using namespace Mantid::API; +using Mantid::DataHandling::LoadSavuTomoConfig; + +class LoadSavuTomoConfigTest : 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 LoadSavuTomoConfigTest *createSuite() { return new LoadSavuTomoConfigTest(); } + static void destroySuite(LoadSavuTomoConfigTest *suite) { delete suite; } + + /// Tests casting, general algorithm properties: name, version, etc. + void test_algorithm() + { + testAlg = + Mantid::API::AlgorithmManager::Instance().create("LoadSavuTomoConfig" /*, 1*/); + TS_ASSERT( testAlg ); + TS_ASSERT_EQUALS( testAlg->name(), "LoadSavuTomoConfig" ); + TS_ASSERT_EQUALS( testAlg->version(), 1 ); + } + + void test_init() + { + if (!testAlg->isInitialized()) + testAlg->initialize(); + + TS_ASSERT_THROWS_NOTHING( testAlg->initialize() ); + TS_ASSERT( testAlg->isInitialized() ); + } + + void test_wrongExec() + { + IAlgorithm_sptr testFail = + Mantid::API::AlgorithmManager::Instance().create("LoadSavuTomoConfig" /*, 1*/); + TS_ASSERT( testFail ); + TS_ASSERT_THROWS_NOTHING( testFail->initialize() ); + // exec without Filename property set -> should throw + TS_ASSERT_THROWS( testFail->execute(), std::runtime_error ); + // try to set empty filename + TS_ASSERT_THROWS( testFail->setPropertyValue("Filename",""), std::invalid_argument ); + TS_ASSERT( !testFail->isExecuted() ); + + // exec with Filename but empty OutputWorkspace -> should throw + IAlgorithm_sptr fail2 = + Mantid::API::AlgorithmManager::Instance().create("LoadSavuTomoConfig" /*, 1*/); + TS_ASSERT_THROWS_NOTHING( fail2->initialize() ); + TS_ASSERT_THROWS_NOTHING( fail2->setPropertyValue("Filename", testFilename) ); + TS_ASSERT_THROWS( fail2->setPropertyValue("OutputWorkspace", ""), std::invalid_argument ); + TS_ASSERT_THROWS( fail2->execute(), std::runtime_error ); + TS_ASSERT( !fail2->isExecuted() ); + + // exec with Filename but no OutputWorkspace -> should not finish + IAlgorithm_sptr fail3 = + Mantid::API::AlgorithmManager::Instance().create("LoadSavuTomoConfig" /*, 1*/); + TS_ASSERT_THROWS_NOTHING( fail3->initialize() ); + TS_ASSERT_THROWS_NOTHING( fail3->setPropertyValue("Filename", testFilename) ); + TS_ASSERT_THROWS_NOTHING( fail3->execute() ); + TS_ASSERT( !fail2->isExecuted() ); + } + + // one file with errors/unrecognized content + void test_wrongContentsFile() + { + // TODO: wait until we have a final spec of the format, then try to fool + // the loader here + } + + // one example file that should load fine + void test_loadOK() + { + // Uses examples from the savu repository: + // https://github.com/DiamondLightSource/Savu/tree/master/test_data + + // TODO: At the moment load just one file to test basic + // functionality. Probably more files should be added here as we + // have more certainty about the format + std::string inWSName = "LoadSavuTomoConfig_test_ws"; + // Load examples from https://github.com/DiamondLightSource/Savu/tree/master/test_data + TS_ASSERT_THROWS_NOTHING( testAlg->setPropertyValue("Filename", testFilename) ); + TS_ASSERT_THROWS_NOTHING( testAlg->setPropertyValue("OutputWorkspace", inWSName) ); + + if (!testAlg->isInitialized()) + testAlg->initialize(); + TS_ASSERT( testAlg->isInitialized() ); + + TS_ASSERT_THROWS_NOTHING( testAlg->execute() ); + TS_ASSERT( testAlg->isExecuted() ); + + AnalysisDataServiceImpl &ads = AnalysisDataService::Instance(); + + TS_ASSERT( ads.doesExist(inWSName) ); + ITableWorkspace_sptr ws; + TS_ASSERT_THROWS_NOTHING(ws = ads.retrieveWS(inWSName) ); + + // general format: 3 columns (data, id, name) + TS_ASSERT_EQUALS( ws->columnCount(), 4) ; + TS_ASSERT_EQUALS( ws->rowCount(), 3 ); + + checkColumns(ws); + +#if (defined __APPLE__ && defined __INTEL_COMPILER) + // This is a horror, an exception needed for osx 10.8 where lib nexus does not behave + // Bug in NeXus strings: the last character is trimmed + // TODO: remove this when osx 10.8 extinguishes (theres a ticket being created for that). + // ID + TS_ASSERT_EQUALS( ws->cell(0, 0), "savu.plugins.timeseries_field_correction" ); + TS_ASSERT_EQUALS( ws->cell(1, 0), "savu.plugins.median_filte" ); + TS_ASSERT_EQUALS( ws->cell(2, 0), "savu.plugins.simple_reco" ); + + // data entry in NeXus file (Params column) + TS_ASSERT_EQUALS( ws->cell(0, 1), "{" ); + TS_ASSERT_EQUALS( ws->cell(1, 1), "{\"kernel_size\": [1, 3, 3]" ); + TS_ASSERT_EQUALS( ws->cell(2, 1), "{\"center_of_rotation\": 86" ); + + // name entry in NeXus file + TS_ASSERT_EQUALS( ws->cell(0, 2), "Timeseries Field Correction" ); + TS_ASSERT_EQUALS( ws->cell(1, 2), "Median Filte" ); + TS_ASSERT_EQUALS( ws->cell(2, 2), "Simple Reconstructio" ); + +#else + // this example has 3 plugins: savu.plugins.timeseries_fields_corrections, savu.median_filter, + // savu.plugins.simple_recon + // ID + TS_ASSERT_EQUALS( ws->cell(0, 0), "savu.plugins.timeseries_field_corrections" ); + TS_ASSERT_EQUALS( ws->cell(1, 0), "savu.plugins.median_filter" ); + TS_ASSERT_EQUALS( ws->cell(2, 0), "savu.plugins.simple_recon" ); + + // data entry in NeXus file (Params column) + TS_ASSERT_EQUALS( ws->cell(0, 1), "{}" ); + TS_ASSERT_EQUALS( ws->cell(1, 1), "{\"kernel_size\": [1, 3, 3]}" ); + TS_ASSERT_EQUALS( ws->cell(2, 1), "{\"center_of_rotation\": 86}" ); + + // name entry in NeXus file + TS_ASSERT_EQUALS( ws->cell(0, 2), "Timeseries Field Corrections" ); + TS_ASSERT_EQUALS( ws->cell(1, 2), "Median Filter" ); + TS_ASSERT_EQUALS( ws->cell(2, 2), "Simple Reconstruction" ); +#endif + + // cite information, not presently available in example files + for (size_t i=0; icell(i, 3), "Not available" ); + } + } + +private: + + void checkColumns(ITableWorkspace_sptr& table) + { + // each row of the workspace should have: ID, Params, Name, Cite + std::vector names = table->getColumnNames(); + TS_ASSERT_EQUALS( names.size(), 4 ); + TS_ASSERT_EQUALS( names[0], "ID" ); + TS_ASSERT_EQUALS( names[1], "Parameters" ); + TS_ASSERT_EQUALS( names[2], "Name" ); + TS_ASSERT_EQUALS( names[3], "Cite" ); + } + + IAlgorithm_sptr testAlg; + static const size_t nRows; + static const size_t nCols; + static const std::string testFilename; + +}; + +const size_t LoadSavuTomoConfigTest::nRows = 3; +const size_t LoadSavuTomoConfigTest::nCols = 4; +const std::string LoadSavuTomoConfigTest::testFilename = "savu_test_data_process03.nxs"; + +#endif /* LOADSAVUTOMOCONFIGTEST_H__*/ diff --git a/Code/Mantid/Framework/DataHandling/test/SaveSavuTomoConfigTest.h b/Code/Mantid/Framework/DataHandling/test/SaveSavuTomoConfigTest.h new file mode 100644 index 000000000000..2347d0aa3b92 --- /dev/null +++ b/Code/Mantid/Framework/DataHandling/test/SaveSavuTomoConfigTest.h @@ -0,0 +1,164 @@ +#ifndef SAVESAVUTOMOCONFIGTEST_H_ +#define SAVESAVUTOMOCONFIGTEST_H_ + +#include + +#include "MantidAPI/AlgorithmManager.h" +#include "MantidAPI/AnalysisDataService.h" +#include "MantidAPI/ITableWorkspace.h" +#include "MantidAPI/TableRow.h" +#include "MantidAPI/WorkspaceFactory.h" +#include "MantidDataHandling/SaveSavuTomoConfig.h" + +#include + +using namespace Mantid::API; +using namespace Mantid::DataHandling; + +class SaveSavuTomoConfigTest : 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 SaveSavuTomoConfigTest *createSuite() { return new SaveSavuTomoConfigTest(); } + static void destroySuite(SaveSavuTomoConfigTest *suite) { delete suite; } + + /// Tests casting, general algorithm properties: name, version, etc. + void test_algorithm() + { + testSave = + Mantid::API::AlgorithmManager::Instance().create("SaveSavuTomoConfig" /*, 1*/); + TS_ASSERT( testSave ); + TS_ASSERT_EQUALS( testSave->name(), "SaveSavuTomoConfig" ); + TS_ASSERT_EQUALS( testSave->version(), 1 ); + } + + void test_init() + { + if (!testSave->isInitialized()) + testSave->initialize(); + + TS_ASSERT_THROWS_NOTHING( testSave->initialize() ); + TS_ASSERT( testSave->isInitialized() ); + } + + /// this is the first test that uses the good workspace (wsName) so it creates it + void test_wrongExec() + { + ITableWorkspace_sptr ws = makeTableWorkspace(wsName); + + IAlgorithm_sptr testFail = + Mantid::API::AlgorithmManager::Instance().create("SaveSavuTomoConfig" /*, 1*/); + TS_ASSERT( testFail ); + TS_ASSERT_THROWS_NOTHING( testFail->initialize() ); + // exec without InputWorkspaces property set -> should throw + TS_ASSERT_THROWS( testFail->execute(), std::runtime_error ); + // try to set empty InputWorkspaces + TS_ASSERT_THROWS( testFail->setPropertyValue("InputWorkspaces",""), std::invalid_argument ); + TS_ASSERT( !testFail->isExecuted() ); + + // exec with InputWorkspaces but empty Filename -> should throw + IAlgorithm_sptr fail2 = + Mantid::API::AlgorithmManager::Instance().create("SaveSavuTomoConfig" /*, 1*/); + TS_ASSERT_THROWS_NOTHING( fail2->initialize() ); + TS_ASSERT_THROWS_NOTHING( fail2->setPropertyValue("InputWorkspaces", wsName) ); + TS_ASSERT_THROWS( fail2->setPropertyValue("Filename", ""), std::invalid_argument ); + TS_ASSERT_THROWS( fail2->execute(), std::runtime_error ); + TS_ASSERT( !fail2->isExecuted() ); + + // exec with InputWorkspaces but no Filename -> should throw + IAlgorithm_sptr fail3 = + Mantid::API::AlgorithmManager::Instance().create("SaveSavuTomoConfig" /*, 1*/); + TS_ASSERT_THROWS_NOTHING( fail3->initialize() ); + TS_ASSERT_THROWS_NOTHING( fail3->setPropertyValue("InputWorkspaces", wsName) ); + TS_ASSERT_THROWS( fail3->execute(), std::runtime_error ); + } + + void test_wrongTableFormat() + { + std::string badWSName = "bad_table"; + ITableWorkspace_sptr ws = makeWrongTableWorkspace(badWSName); + + // using wrong table: should fail + IAlgorithm_sptr fail = + Mantid::API::AlgorithmManager::Instance().create("SaveSavuTomoConfig" /*, 1*/); + TS_ASSERT_THROWS_NOTHING( fail->initialize() ); + TS_ASSERT_THROWS_NOTHING( fail->setPropertyValue("InputWorkspaces", badWSName) ); + TS_ASSERT_THROWS_NOTHING( fail->setPropertyValue("Filename", outFilename) ); + TS_ASSERT_THROWS_NOTHING( fail->execute() ); + TS_ASSERT( !fail->isExecuted() ); + + AnalysisDataService::Instance().remove(badWSName); + } + + /// this is the last test that uses the good workspace (wsName) so it removes it from teh ADS + void test_saveOK() + { + TS_ASSERT( testSave->isInitialized() ); + TS_ASSERT_THROWS_NOTHING( testSave->setPropertyValue("InputWorkspaces", wsName) ); + TS_ASSERT_THROWS_NOTHING( testSave->setPropertyValue("Filename", outFilename) ); + TS_ASSERT_THROWS_NOTHING( testSave->execute() ); + TS_ASSERT( testSave->isExecuted() ); + + // very basic test, to do more than this use the sibling LoadSavuTomo algorithm + TS_ASSERT( Poco::File(outFilename).exists() ); + boost::shared_ptr file; + // can open as NeXus and find one of the entries + TS_ASSERT_THROWS_NOTHING( file = boost::make_shared(outFilename) ); + TS_ASSERT_THROWS_NOTHING( file->openPath("/entry/processing/0") ); + TS_ASSERT_THROWS_NOTHING( file->close() ); + + cleanup(); + } + +private: + /// removes the output file and the input workspace + void cleanup() + { + TS_ASSERT_THROWS_NOTHING( Poco::File(outFilename).remove() ); + TS_ASSERT_THROWS_NOTHING( AnalysisDataService::Instance().remove(wsName) ); + } + + /// helper: specific table format here for savu pipeline configurations + ITableWorkspace_sptr makeTableWorkspace(const std::string &name) + { + ITableWorkspace_sptr ws = WorkspaceFactory::Instance().createTable(); + AnalysisDataService::Instance().addOrReplace(name, ws); + ws->addColumn("str","ID"); + ws->addColumn("str","Parameters"); + ws->addColumn("str","Name"); + ws->addColumn("str","Cite"); + + Mantid::API::TableRow row = ws->appendRow(); + row << "savu.id1" << "{\"param1\": val1}" << "name 1" << "cite 1"; + row = ws->appendRow(); + row << "savu.id2" << "{\"param2\": val2}" << "name 2" << "cite 2"; + + return ws; + } + + // helper to build a bad table: intentionally forgets to add some columns + ITableWorkspace_sptr makeWrongTableWorkspace(const std::string &name) + { + ITableWorkspace_sptr ws = WorkspaceFactory::Instance().createTable(); + AnalysisDataService::Instance().addOrReplace(name, ws); + ws->addColumn("str","ID"); + ws->addColumn("str","Name"); + + Mantid::API::TableRow row = ws->appendRow(); + row << "savu.id1" << "{\"param1\": val1}"; + row = ws->appendRow(); + row << "savu.id2" << "{\"param2\": val2}"; + + return ws; + } + + IAlgorithm_sptr testSave; + static const std::string outFilename; + static const std::string wsName; +}; + +const std::string SaveSavuTomoConfigTest::wsName = "simple_table"; +const std::string SaveSavuTomoConfigTest::outFilename = "savu_tomo_save_test.nxs"; + +#endif /* SAVESAVUTOMOCONFIGTEST_H */ diff --git a/Code/Mantid/Framework/Geometry/CMakeLists.txt b/Code/Mantid/Framework/Geometry/CMakeLists.txt index 730b19c88020..cac42359c3d5 100644 --- a/Code/Mantid/Framework/Geometry/CMakeLists.txt +++ b/Code/Mantid/Framework/Geometry/CMakeLists.txt @@ -1,16 +1,16 @@ set ( SRC_FILES src/ComponentParser.cpp - src/Crystal/BraggScatterer.cpp - src/Crystal/BraggScattererFactory.cpp + src/Crystal/BraggScatterer.cpp + src/Crystal/BraggScattererFactory.cpp src/Crystal/BraggScattererInCrystalStructure.cpp src/Crystal/CenteringGroup.cpp - src/Crystal/CompositeBraggScatterer.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/IsotropicAtomBraggScatterer.cpp src/Crystal/NiggliCell.cpp src/Crystal/OrientedLattice.cpp src/Crystal/PointGroup.cpp @@ -21,6 +21,8 @@ set ( SRC_FILES src/Crystal/ScalarUtils.cpp src/Crystal/SpaceGroup.cpp src/Crystal/SpaceGroupFactory.cpp + src/Crystal/SymmetryElement.cpp + src/Crystal/SymmetryElementFactory.cpp src/Crystal/SymmetryOperation.cpp src/Crystal/SymmetryOperationFactory.cpp src/Crystal/SymmetryOperationSymbolParser.cpp @@ -116,20 +118,20 @@ set ( SRC_UNITY_IGNORE_FILES src/Instrument/CompAssembly.cpp set ( INC_FILES inc/MantidGeometry/ComponentParser.h - inc/MantidGeometry/Crystal/BraggScatterer.h - inc/MantidGeometry/Crystal/BraggScattererFactory.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/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/IsotropicAtomBraggScatterer.h inc/MantidGeometry/Crystal/NiggliCell.h inc/MantidGeometry/Crystal/OrientedLattice.h - inc/MantidGeometry/Crystal/PeakShape.h + inc/MantidGeometry/Crystal/PeakShape.h inc/MantidGeometry/Crystal/PointGroup.h inc/MantidGeometry/Crystal/PointGroupFactory.h inc/MantidGeometry/Crystal/ProductOfCyclicGroups.h @@ -138,6 +140,8 @@ set ( INC_FILES inc/MantidGeometry/Crystal/ScalarUtils.h inc/MantidGeometry/Crystal/SpaceGroup.h inc/MantidGeometry/Crystal/SpaceGroupFactory.h + inc/MantidGeometry/Crystal/SymmetryElement.h + inc/MantidGeometry/Crystal/SymmetryElementFactory.h inc/MantidGeometry/Crystal/SymmetryOperation.h inc/MantidGeometry/Crystal/SymmetryOperationFactory.h inc/MantidGeometry/Crystal/SymmetryOperationSymbolParser.h @@ -229,15 +233,15 @@ set ( TEST_FILES AlgebraTest.h BnIdTest.h BoundingBoxTest.h - BraggScattererFactoryTest.h - BraggScattererInCrystalStructureTest.h - BraggScattererTest.h + BraggScattererFactoryTest.h + BraggScattererInCrystalStructureTest.h + BraggScattererTest.h CenteringGroupTest.h CompAssemblyTest.h ComponentHelperTest.h ComponentParserTest.h ComponentTest.h - CompositeBraggScattererTest.h + CompositeBraggScattererTest.h CompositeImplicitFunctionTest.h ConeTest.h ConventionalCellTest.h @@ -258,7 +262,7 @@ set ( TEST_FILES InstrumentDefinitionParserTest.h InstrumentRayTracerTest.h InstrumentTest.h - IsotropicAtomBraggScattererTest.h + IsotropicAtomBraggScattererTest.h LaszloIntersectionTest.h LineIntersectVisitTest.h LineTest.h @@ -313,6 +317,8 @@ set ( TEST_FILES SphereTest.h SurfaceFactoryTest.h SurfaceTest.h + SymmetryElementFactoryTest.h + SymmetryElementTest.h SymmetryOperationFactoryTest.h SymmetryOperationSymbolParserTest.h SymmetryOperationTest.h diff --git a/Code/Mantid/Framework/Geometry/inc/MantidGeometry/Crystal/SymmetryElement.h b/Code/Mantid/Framework/Geometry/inc/MantidGeometry/Crystal/SymmetryElement.h new file mode 100644 index 000000000000..41a878d6016e --- /dev/null +++ b/Code/Mantid/Framework/Geometry/inc/MantidGeometry/Crystal/SymmetryElement.h @@ -0,0 +1,221 @@ +#ifndef MANTID_GEOMETRY_SYMMETRYELEMENT_H_ +#define MANTID_GEOMETRY_SYMMETRYELEMENT_H_ + +#include "MantidGeometry/DllConfig.h" +#include "MantidKernel/Matrix.h" +#include "MantidGeometry/Crystal/V3R.h" +#include "MantidGeometry/Crystal/SymmetryOperation.h" + +#include +#include + +namespace Mantid { +namespace Geometry { + +/** @class SymmetryElement + + SymmetryElement is an interface for representing symmetry elements that + occur for example in space and point groups. The base class itself can not + be used, it only defines a (very small) interface that currently only + contains the Hermann-Mauguin symbol of the element, as that is the one + common factor for all symmetry elements. There are however classes for + identity, translation, inversion, rotation and mirror. + + However, these classes should not be instantiated directly, they are merely + storing the information on a symmetry element. Instead, they should be + generated through SymmetryElementFactory, which generates the elements + from SymmetryOperation-objects. Please see the documentation of + SymmetryElementFactory for details and examples. + + @author Michael Wedel, Paul Scherrer Institut - SINQ + @date 05/02/2015 + + Copyright © 2015 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 SymmetryElement { +public: + virtual ~SymmetryElement() {} + + virtual boost::shared_ptr clone() const = 0; + + /// Returns the internally stored Hermann-Mauguin symbol. + std::string hmSymbol() const { return m_hmSymbol; } + +protected: + SymmetryElement(const std::string &symbol); + + std::string m_hmSymbol; +}; + +typedef boost::shared_ptr SymmetryElement_sptr; + +/** @class SymmetryElementIdentity + + SymmetryElementIdentity represents the identity. It has no parameters and + always returns the symbol "1". + */ +class MANTID_GEOMETRY_DLL SymmetryElementIdentity : public SymmetryElement { +public: + SymmetryElementIdentity(); + ~SymmetryElementIdentity() {} + + SymmetryElement_sptr clone() const; +}; + +typedef boost::shared_ptr SymmetryElementIdentity_sptr; + +/** @class SymmetryElementInversion + + SymmetryElementInversion represents the inversion. The default inversion + point is (0,0,0), but the constructor takes the inversion point as + a parameter. The symbol stored internally is "-1". + */ +class MANTID_GEOMETRY_DLL SymmetryElementInversion : public SymmetryElement { +public: + SymmetryElementInversion(const V3R &inversionPoint = V3R(0, 0, 0)); + ~SymmetryElementInversion() {} + + SymmetryElement_sptr clone() const; + + /// Returns the internally stored inversion point. + V3R getInversionPoint() const { return m_inversionPoint; } + +protected: + V3R m_inversionPoint; +}; + +typedef boost::shared_ptr +SymmetryElementInversion_sptr; + +/** @class SymmetryElementTranslation + + SymmetryElementTranslation represents translations. The constructor takes + a translation vector as argument, which is then stored. As symbol, "t" is + used, in accordance with the International Tables for Crystallography. + */ +class MANTID_GEOMETRY_DLL SymmetryElementTranslation : public SymmetryElement { +public: + SymmetryElementTranslation(const V3R &translation); + ~SymmetryElementTranslation() {} + + /// Returns the internally stored translation vector. + V3R getTranslation() const { return m_translation; } + + SymmetryElement_sptr clone() const; + +protected: + V3R m_translation; +}; + +typedef boost::shared_ptr +SymmetryElementTranslation_sptr; + +/** @class SymmetryElementWithAxis + + SymmetryElementWithAxis does not represent any symmetry element directly. It + serves as a base class for rotation-axes and mirror-planes, as both are + described by an axis and may have a translation component (screws and + glides). The axis-vector can not be (0,0,0). + */ +class MANTID_GEOMETRY_DLL SymmetryElementWithAxis : public SymmetryElement { +public: + ~SymmetryElementWithAxis() {} + + /// Returns the internally stored axis. + V3R getAxis() const { return m_axis; } + + /// Returns the internally stored translation vector. + V3R getTranslation() const { return m_translation; } + +protected: + SymmetryElementWithAxis(const std::string &symbol, const V3R &axis, + const V3R &translation); + + void setAxis(const V3R &axis); + + V3R m_axis; + V3R m_translation; +}; + +typedef boost::shared_ptr SymmetryElementWithAxis_sptr; + +/** @class SymmetryElementRotation + + SymmetryElementRotation represents rotation-, rotoinversion- and screw-axes. + Besides the axis and translation vectors, which are inherited from + SymmetryElementWithAxis, it also provides a rotation sense. + + When constructed directly, it's possible to leave out translation and + rotation sense, these will be set to default values ((0,0,0) and positive + rotation sense). + + Symbol determination is perfomed by SymmetryElementRotationGenerator, which + uses the SymmetryOperation to derive the Herrman-Mauguin symbol. + */ +class MANTID_GEOMETRY_DLL SymmetryElementRotation + : public SymmetryElementWithAxis { +public: + enum RotationSense { + Positive, + Negative + }; + + SymmetryElementRotation(const std::string &symbol, const V3R &axis, + const V3R &translation = V3R(0, 0, 0), + const RotationSense &rotationSense = Positive); + ~SymmetryElementRotation() {} + + SymmetryElement_sptr clone() const; + + /// Returns the internally stored rotation sense. + RotationSense getRotationSense() const { return m_rotationSense; } + +protected: + RotationSense m_rotationSense; +}; + +typedef boost::shared_ptr SymmetryElementRotation_sptr; + +/** @class SymmetryElementMirror + + SymmetryElementMirror represents mirror and glide-planes. The axis which is + inherited from SymmetryElementWithAxis is perpendicular to the actual + mirror-plane. The translation is (0,0,0) by default. + + Symbol determination is perfomed by SymmetryElementMirrorGenerator, which + uses the SymmetryOperation to derive the Herrman-Mauguin symbol. + */ +class MANTID_GEOMETRY_DLL SymmetryElementMirror + : public SymmetryElementWithAxis { +public: + SymmetryElementMirror(const std::string &symbol, const V3R &axis, + const V3R &translation = V3R(0, 0, 0)); + ~SymmetryElementMirror() {} + + SymmetryElement_sptr clone() const; +}; + +typedef boost::shared_ptr SymmetryElementMirror_sptr; + +} // namespace Geometry +} // namespace Mantid + +#endif /* MANTID_GEOMETRY_SYMMETRYELEMENT_H_ */ diff --git a/Code/Mantid/Framework/Geometry/inc/MantidGeometry/Crystal/SymmetryElementFactory.h b/Code/Mantid/Framework/Geometry/inc/MantidGeometry/Crystal/SymmetryElementFactory.h new file mode 100644 index 000000000000..131b26bae5b6 --- /dev/null +++ b/Code/Mantid/Framework/Geometry/inc/MantidGeometry/Crystal/SymmetryElementFactory.h @@ -0,0 +1,298 @@ +#ifndef MANTID_GEOMETRY_SYMMETRYELEMENTFACTORY_H_ +#define MANTID_GEOMETRY_SYMMETRYELEMENTFACTORY_H_ + +#include "MantidGeometry/DllConfig.h" +#include "MantidKernel/SingletonHolder.h" +#include "MantidGeometry/Crystal/SymmetryElement.h" +#include "MantidGeometry/Crystal/SymmetryOperation.h" +#include "MantidKernel/RegistrationHelper.h" + +#include +#include + +namespace Mantid { +namespace Geometry { + +/** @class AbstractSymmetryElementGenerator + + SymmetryElementFactoryImpl does not generate SymmetryElement objects + directly. Instead, in order to stay as flexible as possible, it stores + instances of AbstractSymmetryElementGenerator. Each subclass of + AbstractSymmetryElementGenerator can be registered once into the factory, + which then uses the canProcess-method to determine whether a certain + generator can be used to derive the SymmetryElement that corresponds to + the SymmetryOperation. + + More about how the symmetry elements are derived from matrix/vector pairs + can be found in the International Tables for Crystallography A, + section 11.2. + */ +class MANTID_GEOMETRY_DLL AbstractSymmetryElementGenerator { +public: + virtual ~AbstractSymmetryElementGenerator() {} + + /// Must generate a valid SymmetryElement from the given operation. + virtual SymmetryElement_sptr + generateElement(const SymmetryOperation &operation) const = 0; + + /// Should return true if the generator can produce a valid SymmetryElement + /// from the provided SymmetryOperation. + virtual bool canProcess(const SymmetryOperation &operation) const = 0; +}; + +typedef boost::shared_ptr +AbstractSymmetryElementGenerator_sptr; + +/** @class SymmetryElementIdentityGenerator + + This implementation of AbstractSymmetryElementGenerator produces only + identity elements. + */ +class MANTID_GEOMETRY_DLL SymmetryElementIdentityGenerator + : public AbstractSymmetryElementGenerator { +public: + SymmetryElementIdentityGenerator() {} + ~SymmetryElementIdentityGenerator() {} + + SymmetryElement_sptr + generateElement(const SymmetryOperation &operation) const; + bool canProcess(const SymmetryOperation &operation) const; +}; + +/** @class SymmetryElementTranslationGenerator + + This implementation of AbstractSymmetryElementGenerator produces only + translation elements. + */ +class MANTID_GEOMETRY_DLL SymmetryElementTranslationGenerator + : public AbstractSymmetryElementGenerator { +public: + SymmetryElementTranslationGenerator() {} + ~SymmetryElementTranslationGenerator() {} + + SymmetryElement_sptr + generateElement(const SymmetryOperation &operation) const; + bool canProcess(const SymmetryOperation &operation) const; +}; + +/** @class SymmetryElementInversionGenerator + + This implementation of AbstractSymmetryElementGenerator produces only + inversion elements. + */ +class MANTID_GEOMETRY_DLL SymmetryElementInversionGenerator + : public AbstractSymmetryElementGenerator { +public: + SymmetryElementInversionGenerator() {} + ~SymmetryElementInversionGenerator() {} + + SymmetryElement_sptr + generateElement(const SymmetryOperation &operation) const; + bool canProcess(const SymmetryOperation &operation) const; +}; + +MANTID_GEOMETRY_DLL gsl_matrix *getGSLMatrix(const Kernel::IntMatrix &matrix); +MANTID_GEOMETRY_DLL gsl_matrix *getGSLIdentityMatrix(size_t rows, size_t cols); + +/** @class SymmetryElementWithAxisGenerator + + SymmetryElementWithAxisGenerator does not create any elements directly, it + serves as a base for SymmetryElementRotationGenerator and + SymmetryAxisMirrorGenerator, which have in common that the axis of the + symmetry element as well as any potential translations must be determined. + + These are implemented according to the algorithms found in the International + Tables for Crystallography A, section 11.2. + + Subclasses must implement the method to determine the Hermann-Mauguin + symbol, as that algorithm is different for example for rotation-axes and + mirror-planes. + */ +class MANTID_GEOMETRY_DLL SymmetryElementWithAxisGenerator + : public AbstractSymmetryElementGenerator { +public: + ~SymmetryElementWithAxisGenerator() {} + +protected: + V3R determineTranslation(const SymmetryOperation &operation) const; + V3R determineAxis(const Kernel::IntMatrix &matrix) const; + + virtual std::string + determineSymbol(const SymmetryOperation &operation) const = 0; +}; + +/** @class SymmetryElementRotationGenerator + + SymmetryElementRotationGenerator inherits from + SymmetryElementWithAxisGenerator, using its methods for determination of + rotation axis and translations in case of screw axes. Furthermore it + determines the rotation sense and of course the Hermann-Mauguin symbol. + */ +class MANTID_GEOMETRY_DLL SymmetryElementRotationGenerator + : public SymmetryElementWithAxisGenerator { +public: + SymmetryElementRotationGenerator() {} + ~SymmetryElementRotationGenerator() {} + + SymmetryElement_sptr + generateElement(const SymmetryOperation &operation) const; + bool canProcess(const SymmetryOperation &operation) const; + +protected: + SymmetryElementRotation::RotationSense + determineRotationSense(const SymmetryOperation &operation, + const V3R &rotationAxis) const; + + std::string determineSymbol(const SymmetryOperation &operation) const; +}; + +/** @class SymmetryElementMirrorGenerator + + SymmetryElementMirrorGenerator also inherits from + SymmetryElementWithAxisGenerator. In addition to that, it determines the + Herrman-Mauguin symbol of the symmetry element. According to the + International Tables for Crystallography there are some unconventional + glide planes which do not have a dedicated symbol. Instead, these are + labeled with the letter "g". + */ +class MANTID_GEOMETRY_DLL SymmetryElementMirrorGenerator + : public SymmetryElementWithAxisGenerator { +public: + SymmetryElementMirrorGenerator() {} + ~SymmetryElementMirrorGenerator() {} + + SymmetryElement_sptr + generateElement(const SymmetryOperation &operation) const; + bool canProcess(const SymmetryOperation &operation) const; + +protected: + std::string determineSymbol(const SymmetryOperation &operation) const; + + static std::map g_glideSymbolMap; +}; + +/** + @class SymmetryElementFactoryImpl + + This factory takes a SymmetryOperation and generates the corresponding + SymmetryElement. It determines what type of element it is (rotation, mirror or + glide plane, ...) and creates the correct object. An example would be this: + + \code + // Mirror plane perpendicular to z-axis + SymmetryOperation mirrorZ("x,y,-z"); + + SymmetryElement_sptr element = + SymmetryElementFactor::Instance().createSymElement(mirrorZ); + + // Prints "m" + std::cout << element->hmSymbol() << std::endl; + + SymmetryElementMirror_sptr mirrorElement = + boost::dynamic_pointer_cast(element); + + // Prints [0,0,1] + std::cout << mirrorElement->getAxis() << std::endl; + \endcode + + Please see also the additional documentation for SymmetryElement. + + The factory itself stores generators that can generate a SymmetryElement from + a provided SymmetryOperation. Each time createSymElement is called, the + factory checks if an operation with that identifier-string has been processed + before. If that's not the case, it tries to find an + AbstractSymmetryElementGenerator that is able to process that operation. The + SymmetryElement that is generated by the generator is not returned directly, + instead it is stored as a prototype object, so that subsequent calls with the + same SymmetryOperation do not have to go through the derivation algorithm + again. Finally a clone of the now available prototype is returned. This way, + symmetry elements are only derived once. + + @author Michael Wedel, Paul Scherrer Institut - SINQ + @date 25/02/2015 + + Copyright © 2015 PSI-NXMM + + This file is part of Mantid. + + Mantid is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + Mantid is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + + File change history is stored at: + Code Documentation is available at: +*/ +class MANTID_GEOMETRY_DLL SymmetryElementFactoryImpl { +public: + virtual ~SymmetryElementFactoryImpl() {} + + SymmetryElement_sptr createSymElement(const SymmetryOperation &operation); + + /// Subscribes the generator of type T with its class name into the factory, + /// throws std::runtime_error if a class with the same name has already been + /// registered. + template + void + subscribeSymmetryElementGenerator(const std::string &generatorClassName) { + AbstractSymmetryElementGenerator_sptr generator = boost::make_shared(); + + if (isSubscribed(generatorClassName)) { + throw std::runtime_error("A generator with name '" + generatorClassName + + "' is already registered."); + } + + subscribe(generator, generatorClassName); + } + +protected: + SymmetryElementFactoryImpl() + : m_generators(), m_generatorNames(), m_prototypes() {} + + bool isSubscribed(const std::string &generatorClassName) const; + void subscribe(const AbstractSymmetryElementGenerator_sptr &generator, + const std::string &generatorClassName); + + SymmetryElement_sptr createFromPrototype(const std::string &identifier) const; + AbstractSymmetryElementGenerator_sptr + getGenerator(const SymmetryOperation &operation) const; + void insertPrototype(const std::string &identifier, + const SymmetryElement_sptr &prototype); + + std::vector m_generators; + std::set m_generatorNames; + std::map m_prototypes; + +private: + friend struct Mantid::Kernel::CreateUsingNew; +}; + +#ifdef _WIN32 +template class MANTID_GEOMETRY_DLL +Mantid::Kernel::SingletonHolder; +#endif + +typedef Mantid::Kernel::SingletonHolder +SymmetryElementFactory; + +} // namespace Geometry +} // namespace Mantid + +#define DECLARE_SYMMETRY_ELEMENT_GENERATOR(classname) \ + namespace { \ + Mantid::Kernel::RegistrationHelper \ + register_symmetry_element_generator_##classname( \ + ((Mantid::Geometry::SymmetryElementFactory::Instance() \ + .subscribeSymmetryElementGenerator(#classname)), \ + 0)); \ + } + +#endif /* MANTID_GEOMETRY_SYMMETRYELEMENTFACTORY_H_ */ diff --git a/Code/Mantid/Framework/Geometry/inc/MantidGeometry/Crystal/SymmetryOperation.h b/Code/Mantid/Framework/Geometry/inc/MantidGeometry/Crystal/SymmetryOperation.h index 7e8bfa04fa29..f0b6524b6170 100644 --- a/Code/Mantid/Framework/Geometry/inc/MantidGeometry/Crystal/SymmetryOperation.h +++ b/Code/Mantid/Framework/Geometry/inc/MantidGeometry/Crystal/SymmetryOperation.h @@ -140,6 +140,8 @@ class MANTID_GEOMETRY_DLL SymmetryOperation { SymmetryOperation operator*(const SymmetryOperation &operand) const; SymmetryOperation inverse() const; + SymmetryOperation operator^(size_t exponent) const; + bool operator!=(const SymmetryOperation &other) const; bool operator==(const SymmetryOperation &other) const; bool operator<(const SymmetryOperation &other) const; diff --git a/Code/Mantid/Framework/Geometry/inc/MantidGeometry/Crystal/V3R.h b/Code/Mantid/Framework/Geometry/inc/MantidGeometry/Crystal/V3R.h index c314d36cc7a8..89cb47ac8073 100644 --- a/Code/Mantid/Framework/Geometry/inc/MantidGeometry/Crystal/V3R.h +++ b/Code/Mantid/Framework/Geometry/inc/MantidGeometry/Crystal/V3R.h @@ -118,6 +118,11 @@ class MANTID_GEOMETRY_DLL V3R { bool operator==(int other) const; bool operator!=(int other) const; + V3R getPositiveVector() const; + + // std::vector operator + operator std::vector() const; + protected: RationalNumber m_x; RationalNumber m_y; diff --git a/Code/Mantid/Framework/Geometry/src/Crystal/SymmetryElement.cpp b/Code/Mantid/Framework/Geometry/src/Crystal/SymmetryElement.cpp new file mode 100644 index 000000000000..ea587436c3e0 --- /dev/null +++ b/Code/Mantid/Framework/Geometry/src/Crystal/SymmetryElement.cpp @@ -0,0 +1,82 @@ +#include "MantidGeometry/Crystal/SymmetryElement.h" +#include "MantidGeometry/Crystal/SymmetryOperationFactory.h" + +#include +#include + +namespace Mantid { +namespace Geometry { + +/// Constructor with symbol argument. +SymmetryElement::SymmetryElement(const std::string &symbol) + : m_hmSymbol(symbol) {} + +SymmetryElementIdentity::SymmetryElementIdentity() : SymmetryElement("1") {} + +/// Returns a clone of the identity element. +SymmetryElement_sptr SymmetryElementIdentity::clone() const { + return boost::make_shared(); +} + +/// Constructor with inversion point, default is (0,0,0). +SymmetryElementInversion::SymmetryElementInversion(const V3R &inversionPoint) + : SymmetryElement("-1"), m_inversionPoint(inversionPoint) {} + +/// Returns a clone of the inversion element. +SymmetryElement_sptr SymmetryElementInversion::clone() const { + return boost::make_shared(m_inversionPoint); +} + +/// Constructor for SymmetryElementWithAxis. +SymmetryElementWithAxis::SymmetryElementWithAxis(const std::string &symbol, + const V3R &axis, + const V3R &translation) + : SymmetryElement(symbol), m_translation(translation) { + setAxis(axis); +} + +/// Sets the axis, throws std::invalid_argument if the axis is (0,0,0). +void SymmetryElementWithAxis::setAxis(const V3R &axis) { + if (axis == V3R(0, 0, 0)) { + throw std::invalid_argument("Axis cannot be (0,0,0)."); + } + + m_axis = axis; +} + +/// Constructor for rotation-,rotoinversion- and screw-axes. +SymmetryElementRotation::SymmetryElementRotation( + const std::string &symbol, const V3R &axis, const V3R &translation, + const SymmetryElementRotation::RotationSense &rotationSense) + : SymmetryElementWithAxis(symbol, axis, translation), + m_rotationSense(rotationSense) {} + +/// Returns a clone of the symmetry element. +SymmetryElement_sptr SymmetryElementRotation::clone() const { + return boost::make_shared( + m_hmSymbol, m_axis, m_translation, m_rotationSense); +} + +/// Constructor for mirror planes. +SymmetryElementMirror::SymmetryElementMirror(const std::string &symbol, + const V3R &axis, + const V3R &translation) + : SymmetryElementWithAxis(symbol, axis, translation) {} + +/// Returns a clone of the mirror plane. +SymmetryElement_sptr SymmetryElementMirror::clone() const { + return boost::make_shared(m_hmSymbol, m_axis, + m_translation); +} + +/// Constructor for translation element, requires translation vector. +SymmetryElementTranslation::SymmetryElementTranslation(const V3R &translation) + : SymmetryElement("t"), m_translation(translation) {} + +/// Returns a clone of the translation. +SymmetryElement_sptr SymmetryElementTranslation::clone() const { + return boost::make_shared(m_translation); +} + +} // namespace Geometry +} // namespace Mantid diff --git a/Code/Mantid/Framework/Geometry/src/Crystal/SymmetryElementFactory.cpp b/Code/Mantid/Framework/Geometry/src/Crystal/SymmetryElementFactory.cpp new file mode 100644 index 000000000000..fcdef2e077fa --- /dev/null +++ b/Code/Mantid/Framework/Geometry/src/Crystal/SymmetryElementFactory.cpp @@ -0,0 +1,426 @@ +#include "MantidGeometry/Crystal/SymmetryElementFactory.h" +#include +#include +#include +#include +#include +#include + +namespace Mantid { +namespace Geometry { + +/// Generates an instance of SymmetryElementIdentity. +SymmetryElement_sptr SymmetryElementIdentityGenerator::generateElement( + const SymmetryOperation &operation) const { + UNUSED_ARG(operation); + + return boost::make_shared(); +} + +/// Checks that the SymmetryOperation has no translation and the matrix is of +/// order 1. +bool SymmetryElementIdentityGenerator::canProcess( + const SymmetryOperation &operation) const { + + return !operation.hasTranslation() && operation.order() == 1; +} + +/// Generates an instance of SymmetryElementTranslation with the vector of the +/// operation as translation vector. +SymmetryElement_sptr SymmetryElementTranslationGenerator::generateElement( + const SymmetryOperation &operation) const { + return boost::make_shared(operation.vector()); +} + +/// Checks that the order of the matrix is 1 and the operation has a +/// translation. +bool SymmetryElementTranslationGenerator::canProcess( + const SymmetryOperation &operation) const { + return operation.order() == 1 && operation.hasTranslation(); +} + +/// Generates an instance of SymmetryElementInversion with the inversion point +/// equal to the vector of the operation divided by two. +SymmetryElement_sptr SymmetryElementInversionGenerator::generateElement( + const SymmetryOperation &operation) const { + + return boost::make_shared(operation.vector() / 2); +} + +/// Checks that the matrix is identity matrix multiplied with -1. +bool SymmetryElementInversionGenerator::canProcess( + const SymmetryOperation &operation) const { + Kernel::IntMatrix inversionMatrix(3, 3, true); + inversionMatrix *= -1; + + return operation.matrix() == inversionMatrix; +} + +/** + * @brief SymmetryElementWithAxisGenerator::determineTranslation + * + * According to ITA, 11.2, the translation component of a symmetry operation + * can be termined with the following algorithm. First, a matrix \f$W\f$ is + * calculated using the symmetry operation \f$S\f$ and its powers up to its + * order \f$k\f$, adding the matrices of the resulting operations: + * + * \f[ + * W = W_1(S^0) + W_2(S^1) + \dots + W_k(S^{k-1}) + * \f] + * + * The translation vector is then calculation from the vector \f$w\f$ of the + * operation: + * + * \f[ + * t = \frac{1}{k}\cdot (W \times w) + * \f] + * + * For operations which do not have translation components, this algorithm + * returns a 0-vector. + * + * @param operation :: Symmetry operation, possibly with translation vector. + * @return Translation vector. + */ +V3R SymmetryElementWithAxisGenerator::determineTranslation( + const SymmetryOperation &operation) const { + Kernel::IntMatrix translationMatrix(3, 3, false); + + for (size_t i = 0; i < operation.order(); ++i) { + translationMatrix += (operation ^ i).matrix(); + } + + return (translationMatrix * operation.vector()) * + RationalNumber(1, static_cast(operation.order())); +} + +/** + * Returns a GSL-matrix for the given IntMatrix + * + * This free function takes an IntMatrix and returns a GSL-matrix with the data. + * It allocates the memory using gsl_matrix_alloc and the caller of the function + * is responsible for freeing the memory again. + * + * @param matrix :: Kernel::IntMatrix. + * @return GSL-matrix containing the same data as the input matrix. + */ +gsl_matrix *getGSLMatrix(const Kernel::IntMatrix &matrix) { + gsl_matrix *gslMatrix = gsl_matrix_alloc(matrix.numRows(), matrix.numCols()); + + for (size_t r = 0; r < matrix.numRows(); ++r) { + for (size_t c = 0; c < matrix.numCols(); ++c) { + gsl_matrix_set(gslMatrix, r, c, static_cast(matrix[r][c])); + } + } + + return gslMatrix; +} + +/** + * Returns a GSL-indentity matrix. + * + * This free function returns a GSL-matrix with the provided dimensions. + * It allocates the memory using gsl_matrix_alloc and the caller of the function + * is responsible for freeing the memory again. + * + * @param rows :: Number of rows in the matrix. + * @param cols :: Number of columns in the matrix. + * @return Identity matrix with dimensions (rows, columns). + */ +gsl_matrix *getGSLIdentityMatrix(size_t rows, size_t cols) { + gsl_matrix *gslMatrix = gsl_matrix_alloc(rows, cols); + + gsl_matrix_set_identity(gslMatrix); + + return gslMatrix; +} + +/** + * Returns the symmetry axis for the given matrix + * + * According to ITA, 11.2 the axis of a symmetry operation can be determined by + * solving the Eigenvalue problem \f$Wu = u\f$ for rotations or \f$Wu = -u\f$ + * for rotoinversions. This is implemented using the general real non-symmetric + * eigen-problem solver provided by the GSL. + * + * @param matrix :: Matrix of a SymmetryOperation + * @return Axis of symmetry element. + */ +V3R SymmetryElementWithAxisGenerator::determineAxis( + const Kernel::IntMatrix &matrix) const { + gsl_matrix *eigenMatrix = getGSLMatrix(matrix); + gsl_matrix *identityMatrix = + getGSLIdentityMatrix(matrix.numRows(), matrix.numCols()); + + gsl_eigen_genv_workspace *eigenWs = gsl_eigen_genv_alloc(matrix.numRows()); + + gsl_vector_complex *alpha = gsl_vector_complex_alloc(3); + gsl_vector *beta = gsl_vector_alloc(3); + gsl_matrix_complex *eigenVectors = gsl_matrix_complex_alloc(3, 3); + + gsl_eigen_genv(eigenMatrix, identityMatrix, alpha, beta, eigenVectors, + eigenWs); + + double determinant = matrix.determinant(); + + std::vector eigenVector(3, 0.0); + + for (size_t i = 0; i < matrix.numCols(); ++i) { + double eigenValue = GSL_REAL(gsl_complex_div_real( + gsl_vector_complex_get(alpha, i), gsl_vector_get(beta, i))); + + if (fabs(eigenValue - determinant) < 1e-9) { + for (size_t j = 0; j < matrix.numRows(); ++j) { + double element = GSL_REAL(gsl_matrix_complex_get(eigenVectors, j, i)); + + eigenVector[j] = element; + } + } + } + + gsl_matrix_free(eigenMatrix); + gsl_matrix_free(identityMatrix); + gsl_eigen_genv_free(eigenWs); + gsl_vector_complex_free(alpha); + gsl_vector_free(beta); + gsl_matrix_complex_free(eigenVectors); + + double min = 1.0; + for (size_t i = 0; i < eigenVector.size(); ++i) { + double absoluteValue = fabs(eigenVector[i]); + if (absoluteValue != 0.0 && + (eigenVector[i] < min && (absoluteValue - fabs(min)) < 1e-9)) { + min = eigenVector[i]; + } + } + + V3R axis; + for (size_t i = 0; i < eigenVector.size(); ++i) { + axis[i] = static_cast(boost::math::round(eigenVector[i] / min)); + } + + return axis; +} + +/// Generates an instance of SymmetryElementRotation with the corresponding +/// symbol, axis, translation vector and rotation sense. +SymmetryElement_sptr SymmetryElementRotationGenerator::generateElement( + const SymmetryOperation &operation) const { + const Kernel::IntMatrix &matrix = operation.matrix(); + + V3R axis = determineAxis(matrix); + V3R translation = determineTranslation(operation); + SymmetryElementRotation::RotationSense rotationSense = + determineRotationSense(operation, axis); + std::string symbol = determineSymbol(operation); + + return boost::make_shared(symbol, axis, translation, + rotationSense); +} + +/// Checks the trace and determinat of the matrix to determine if the matrix +/// belongs to a rotation. +bool SymmetryElementRotationGenerator::canProcess( + const SymmetryOperation &operation) const { + const Kernel::IntMatrix &matrix = operation.matrix(); + int determinant = matrix.determinant(); + int trace = matrix.Trace(); + + return (abs(trace) != 3) && !(trace == 1 && determinant == -1); +} + +/// Determines the rotation sense according to the description in ITA 11.2. +SymmetryElementRotation::RotationSense +SymmetryElementRotationGenerator::determineRotationSense( + const SymmetryOperation &operation, const V3R &rotationAxis) const { + Kernel::V3D pointOnAxis1 = rotationAxis; + Kernel::V3D pointOnAxis2 = rotationAxis * 2; + Kernel::V3D pointOffAxis = rotationAxis + Kernel::V3D(2.1, 5.05, -1.1); + Kernel::V3D generatedPoint = operation * pointOffAxis; + + Kernel::DblMatrix matrix(3, 3, false); + matrix.setColumn(0, pointOnAxis2 - pointOnAxis1); + matrix.setColumn(1, pointOffAxis - pointOnAxis1); + matrix.setColumn(2, generatedPoint - pointOnAxis1); + + double determinant = matrix.determinant() * operation.matrix().determinant(); + + if (determinant < 0) { + return SymmetryElementRotation::Negative; + } else { + return SymmetryElementRotation::Positive; + } +} + +/// Determines the Hermann-Mauguin symbol of the rotation-, rotoinversion- or +/// screw-axis. +std::string SymmetryElementRotationGenerator::determineSymbol( + const SymmetryOperation &operation) const { + const Kernel::IntMatrix &matrix = operation.matrix(); + + int trace = matrix.Trace(); + int determinant = matrix.determinant(); + + if (trace == 0 && determinant == -1) { + return "-3"; + } + + std::string symbol; + + if (determinant < 0) { + symbol += "-"; + } + + symbol += boost::lexical_cast(operation.order()); + + int translation = + static_cast(static_cast(operation.order()) * + Kernel::V3D(determineTranslation(operation)).norm()); + + if (translation != 0) { + symbol += boost::lexical_cast(translation); + } + + return symbol; +} + +std::map SymmetryElementMirrorGenerator::g_glideSymbolMap = + boost::assign::map_list_of(V3R(0, 0, 0), "m")(V3R(1, 0, 0) / 2, + "a")(V3R(0, 1, 0) / 2, "b")( + V3R(0, 0, 1) / 2, "c")(V3R(1, 1, 0) / 2, "n")(V3R(1, 0, 1) / 2, "n")( + V3R(0, 1, 1) / 2, "n")(V3R(1, 1, 1) / 2, "n")(V3R(1, 1, 0) / 4, "d")( + V3R(1, 0, 1) / 4, "d")(V3R(0, 1, 1) / 4, "d")(V3R(1, 1, 1) / 4, "d"); + +/// Generates an instance of SymmetryElementMirror with the corresponding +/// symbol, axis and translation vector. +SymmetryElement_sptr SymmetryElementMirrorGenerator::generateElement( + const SymmetryOperation &operation) const { + const Kernel::IntMatrix &matrix = operation.matrix(); + + V3R axis = determineAxis(matrix); + V3R translation = determineTranslation(operation); + std::string symbol = determineSymbol(operation); + + return boost::make_shared(symbol, axis, translation); +} + +/// Checks that the trace of the matrix is 1 and the determinant is -1. +bool SymmetryElementMirrorGenerator::canProcess( + const SymmetryOperation &operation) const { + const Kernel::IntMatrix &matrix = operation.matrix(); + + return matrix.Trace() == 1 && matrix.determinant() == -1; +} + +/// Determines the symbol from the translation vector using a map. +std::string SymmetryElementMirrorGenerator::determineSymbol( + const SymmetryOperation &operation) const { + V3R rawTranslation = determineTranslation(operation); + + V3R translation; + for (size_t i = 0; i < 3; ++i) { + translation[i] = rawTranslation[i] > RationalNumber(1, 2) + ? rawTranslation[i] - 1 + : rawTranslation[i]; + } + + std::string symbol = g_glideSymbolMap[translation.getPositiveVector()]; + + /* Some space groups have "unconventional glides" for which there is no + * proper symbol, so the general symbol "g" is used for these cases. + * Examples can be found in No. 227 (Fd-3m). + */ + if (symbol == "") { + return "g"; + } + + return symbol; +} + +/** + * Creates a SymmetryElement from a SymmetryOperation + * + * As detailed in the class description, the method checks whether there is + * already a prototype SymmetryElement for the provided SymmetryOperation. If + * not, it tries to find an appropriate generator and uses that to create + * the prototype. Then it returns a clone of the prototype. + * + * @param operation :: SymmetryOperation for which to generate the element. + * @return SymmetryElement for the supplied operation. + */ +SymmetryElement_sptr SymmetryElementFactoryImpl::createSymElement( + const SymmetryOperation &operation) { + std::string operationIdentifier = operation.identifier(); + + SymmetryElement_sptr element = createFromPrototype(operationIdentifier); + + if (element) { + return element; + } + + AbstractSymmetryElementGenerator_sptr generator = getGenerator(operation); + + if (!generator) { + throw std::runtime_error("Could not process symmetry operation '" + + operationIdentifier + "'."); + } + + insertPrototype(operationIdentifier, generator->generateElement(operation)); + + return createFromPrototype(operationIdentifier); +} + +/// Checks whether a generator with that class name is already subscribed. +bool SymmetryElementFactoryImpl::isSubscribed( + const std::string &generatorClassName) const { + return (std::find(m_generatorNames.begin(), m_generatorNames.end(), + generatorClassName) != m_generatorNames.end()); +} + +/// Subscribes a generator and stores its class name for later checks. +void SymmetryElementFactoryImpl::subscribe( + const AbstractSymmetryElementGenerator_sptr &generator, + const std::string &generatorClassName) { + m_generators.push_back(generator); + m_generatorNames.insert(generatorClassName); +} + +/// Creates a SymmetryElement from an internally stored prototype. +SymmetryElement_sptr SymmetryElementFactoryImpl::createFromPrototype( + const std::string &identifier) const { + auto prototypeIterator = m_prototypes.find(identifier); + + if (prototypeIterator != m_prototypes.end()) { + return (prototypeIterator->second)->clone(); + } + + return SymmetryElement_sptr(); +} + +/// Returns a generator that can process the supplied symmetry operation or an +/// invalid pointer if no appropriate generator is found. +AbstractSymmetryElementGenerator_sptr SymmetryElementFactoryImpl::getGenerator( + const SymmetryOperation &operation) const { + for (auto generator = m_generators.begin(); generator != m_generators.end(); + ++generator) { + if ((*generator)->canProcess(operation)) { + return *generator; + } + } + + return AbstractSymmetryElementGenerator_sptr(); +} + +/// Inserts the provided prototype into the factory. +void SymmetryElementFactoryImpl::insertPrototype( + const std::string &identifier, const SymmetryElement_sptr &prototype) { + m_prototypes.insert(std::make_pair(identifier, prototype)); +} + +DECLARE_SYMMETRY_ELEMENT_GENERATOR(SymmetryElementIdentityGenerator); +DECLARE_SYMMETRY_ELEMENT_GENERATOR(SymmetryElementTranslationGenerator); +DECLARE_SYMMETRY_ELEMENT_GENERATOR(SymmetryElementInversionGenerator); +DECLARE_SYMMETRY_ELEMENT_GENERATOR(SymmetryElementRotationGenerator); +DECLARE_SYMMETRY_ELEMENT_GENERATOR(SymmetryElementMirrorGenerator); + +} // 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 1776a9a77d7f..1eacde990c81 100644 --- a/Code/Mantid/Framework/Geometry/src/Crystal/SymmetryOperation.cpp +++ b/Code/Mantid/Framework/Geometry/src/Crystal/SymmetryOperation.cpp @@ -128,6 +128,27 @@ SymmetryOperation SymmetryOperation::inverse() const { return SymmetryOperation(matrix, -(matrix * m_vector)); } +/// Returns the symmetry operation, applied to itself (exponent) times. +SymmetryOperation SymmetryOperation::operator^(size_t exponent) const { + // If the exponent is 1, no calculations are necessary. + if (exponent == 1) { + return SymmetryOperation(*this); + } + + SymmetryOperation op; + + // The same for 0, which means identity in every case. + if (exponent == 0) { + return op; + } + + for (size_t i = 0; i < exponent; ++i) { + op = (*this) * op; + } + + return op; +} + /// 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; diff --git a/Code/Mantid/Framework/Geometry/src/Crystal/V3R.cpp b/Code/Mantid/Framework/Geometry/src/Crystal/V3R.cpp index a24af4113627..a8b40e8df7aa 100644 --- a/Code/Mantid/Framework/Geometry/src/Crystal/V3R.cpp +++ b/Code/Mantid/Framework/Geometry/src/Crystal/V3R.cpp @@ -317,6 +317,21 @@ bool V3R::operator==(int other) const { /// Returns true if any component is different from the integer. bool V3R::operator!=(int other) const { return !(this->operator==(other)); } +/// Returns a V3R with absolute components. +V3R V3R::getPositiveVector() const { + return V3R(boost::abs(m_x), boost::abs(m_y), boost::abs(m_z)); +} + +/// Returns an std::vector with approximations of the components. +V3R::operator std::vector() const { + std::vector vector; + vector.push_back(boost::rational_cast(m_x)); + vector.push_back(boost::rational_cast(m_y)); + vector.push_back(boost::rational_cast(m_z)); + + return vector; +} + /// 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) { diff --git a/Code/Mantid/Framework/Geometry/test/SymmetryElementFactoryTest.h b/Code/Mantid/Framework/Geometry/test/SymmetryElementFactoryTest.h new file mode 100644 index 000000000000..35991f81e705 --- /dev/null +++ b/Code/Mantid/Framework/Geometry/test/SymmetryElementFactoryTest.h @@ -0,0 +1,415 @@ +#ifndef MANTID_GEOMETRY_SYMMETRYELEMENTFACTORYTEST_H_ +#define MANTID_GEOMETRY_SYMMETRYELEMENTFACTORYTEST_H_ + +#include +#include +#include + +#include "MantidGeometry/Crystal/SymmetryElementFactory.h" +#include "MantidGeometry/Crystal/SpaceGroupFactory.h" + +using namespace Mantid::Geometry; +using namespace Mantid::Kernel; + +class SymmetryElementFactoryTest : 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 SymmetryElementFactoryTest *createSuite() { + return new SymmetryElementFactoryTest(); + } + static void destroySuite(SymmetryElementFactoryTest *suite) { delete suite; } + + void testSymmetryElementIdentityGenerator() { + // This generator processes Identity. + SymmetryOperation identity("x,y,z"); + + SymmetryElementIdentityGenerator identityGenerator; + TS_ASSERT(identityGenerator.canProcess(identity)); + TS_ASSERT_THROWS_NOTHING(identityGenerator.generateElement(identity)); + + SymmetryElement_sptr identityElement = + identityGenerator.generateElement(identity); + + TS_ASSERT(identityElement); + TS_ASSERT_EQUALS(identityElement->hmSymbol(), "1"); + + SymmetryElementIdentity_sptr castedElement = + boost::dynamic_pointer_cast(identityElement); + TS_ASSERT(castedElement); + + // But not other operations. + SymmetryOperation inversion("-x,-y,-z"); + TS_ASSERT(!identityGenerator.canProcess(inversion)); + + SymmetryOperation translation("x+1/2,y+1/2,z"); + TS_ASSERT(!identityGenerator.canProcess(translation)); + } + + void testSymmetryElementTranslationGenerator() { + // This generator processes Translations. + SymmetryOperation bodyCentering("x+1/2,y+1/2,z+1/2"); + + SymmetryElementTranslationGenerator translationGenerator; + TS_ASSERT(translationGenerator.canProcess(bodyCentering)); + TS_ASSERT_THROWS_NOTHING( + translationGenerator.generateElement(bodyCentering)); + + SymmetryElement_sptr translationElement = + translationGenerator.generateElement(bodyCentering); + + TS_ASSERT(translationElement); + TS_ASSERT_EQUALS(translationElement->hmSymbol(), "t"); + + SymmetryElementTranslation_sptr castedElement = + boost::dynamic_pointer_cast( + translationElement); + TS_ASSERT(castedElement); + TS_ASSERT_EQUALS(castedElement->getTranslation(), V3R(1, 1, 1) / 2); + + // But not other operations. + SymmetryOperation inversion("-x,-y,-z"); + TS_ASSERT(!translationGenerator.canProcess(inversion)); + + SymmetryOperation identity("x,y,z"); + TS_ASSERT(!translationGenerator.canProcess(identity)); + } + + void testSymmetryElementInversionGenerator() { + // This generator processes Inversion. + SymmetryOperation inversion("-x,-y,-z"); + + SymmetryElementInversionGenerator inversionGenerator; + TS_ASSERT(inversionGenerator.canProcess(inversion)); + TS_ASSERT_THROWS_NOTHING(inversionGenerator.generateElement(inversion)); + + SymmetryElement_sptr inversionElement = + inversionGenerator.generateElement(inversion); + + TS_ASSERT(inversionElement); + TS_ASSERT_EQUALS(inversionElement->hmSymbol(), "-1"); + + // But not other operations. + SymmetryOperation identity("x,y,z"); + TS_ASSERT(!inversionGenerator.canProcess(identity)); + + SymmetryOperation translation("x+1/2,y+1/2,z"); + TS_ASSERT(!inversionGenerator.canProcess(translation)); + + // Inversion can also be at another point + SymmetryOperation shiftedInversion("-x+1/4,-y+1/4,-z+1/4"); + SymmetryElement_sptr shiftedElement = + inversionGenerator.generateElement(shiftedInversion); + + SymmetryElementInversion_sptr castedElement = + boost::dynamic_pointer_cast(shiftedElement); + + TS_ASSERT(castedElement); + TS_ASSERT_EQUALS(castedElement->getInversionPoint(), V3R(1, 1, 1) / 8); + } + + void testGetGSLMatrix() { + IntMatrix mantidMatrix(3, 3, true); + gsl_matrix *matrix = getGSLMatrix(mantidMatrix); + + TS_ASSERT(matrix); + TS_ASSERT_EQUALS(matrix->size1, mantidMatrix.numRows()); + TS_ASSERT_EQUALS(matrix->size2, mantidMatrix.numCols()); + + for (size_t r = 0; r < mantidMatrix.numRows(); ++r) { + for (size_t c = 0; c < mantidMatrix.numCols(); ++c) { + TS_ASSERT_EQUALS(gsl_matrix_get(matrix, r, c), mantidMatrix[r][c]); + } + } + + gsl_matrix_free(matrix); + } + + void testGetGSLIdentityMatrix() { + gsl_matrix *matrix = getGSLIdentityMatrix(3, 3); + + TS_ASSERT_EQUALS(matrix->size1, 3); + TS_ASSERT_EQUALS(matrix->size2, 3); + + gsl_matrix_free(matrix); + } + + void testSymmetryElementWithAxisGeneratorDetermineAxis() { + TestableSymmetryElementWithAxisGenerator generator; + + V3R rotationAxisZ = V3R(0, 0, 1); + SymmetryOperation fourFoldRotoInversionZ("y,-x,-z"); + TS_ASSERT_EQUALS(generator.determineAxis(fourFoldRotoInversionZ.matrix()), + rotationAxisZ); + + SymmetryOperation sixFoldRotationZ("-y,x-y,z"); + TS_ASSERT_EQUALS(generator.determineAxis(sixFoldRotationZ.matrix()), + rotationAxisZ); + + V3R rotationAxisY = V3R(0, 1, 0); + SymmetryOperation glideMirrorCY("x,-y,z+1/2"); + TS_ASSERT_EQUALS(generator.determineAxis(glideMirrorCY.matrix()), + rotationAxisY); + + V3R rotationAxisXYZ = V3R(1, 1, 1); + SymmetryOperation threeFoldRation111("z,x,y"); + TS_ASSERT_EQUALS(generator.determineAxis(threeFoldRation111.matrix()), + rotationAxisXYZ); + + V3R rotationAxisxyZ = V3R(1, -1, -1); + SymmetryOperation threeFoldRationmm1("-z,-x,y"); + TS_ASSERT_EQUALS(generator.determineAxis(threeFoldRationmm1.matrix()), + rotationAxisxyZ); + + V3R rotoInversionAxisxYz = V3R(-1, 1, -1); + SymmetryOperation threeFoldRotoInversionm1mPlus("-z,x,y"); + TS_ASSERT_EQUALS( + generator.determineAxis(threeFoldRotoInversionm1mPlus.matrix()), + rotoInversionAxisxYz); + + V3R rotationAxis2xx0 = V3R(2, 1, 0); + SymmetryOperation twoFoldRotationHex210("x,x-y,-z"); + TS_ASSERT_EQUALS(generator.determineAxis(twoFoldRotationHex210.matrix()), + rotationAxis2xx0); + + V3R rotationAxisx2x0 = V3R(1, 2, 0); + SymmetryOperation twoFoldRotationHex120("y-x,y,-z"); + TS_ASSERT_EQUALS(generator.determineAxis(twoFoldRotationHex120.matrix()), + rotationAxisx2x0); + } + + void testSymmetryElementWithAxisGeneratorDetermineTranslation() { + TestableSymmetryElementWithAxisGenerator generator; + + V3R screwVectorOneHalf = V3R(0, 0, 1) / 2; + SymmetryOperation twoOneScrew("-x,-y,z+1/2"); + TS_ASSERT_EQUALS(generator.determineTranslation(twoOneScrew), + screwVectorOneHalf); + + V3R screwVectorOneThird = V3R(0, 0, 1) / 3; + SymmetryOperation threeOneScrew("-y,x-y,z+1/3"); + TS_ASSERT_EQUALS(generator.determineTranslation(threeOneScrew), + screwVectorOneThird); + + V3R screwVectorTwoThirds = V3R(0, 0, 2) / 3; + SymmetryOperation threeTwoScrew("-y,x-y,z+2/3"); + TS_ASSERT_EQUALS(generator.determineTranslation(threeTwoScrew), + screwVectorTwoThirds); + + V3R glideVectorC = V3R(0, 0, 1) / 2; + SymmetryOperation glidePlaneC("x,-y,z+1/2"); + TS_ASSERT_EQUALS(generator.determineTranslation(glidePlaneC), glideVectorC); + } + + void testSymmetryElementRotationDetermineRotationSense() { + TestableSymmetryElementRotationGenerator generator; + + // Test case 1: 3 [-1 1 -1] (Positive/Negative) in orthogonal system + SymmetryOperation threeFoldRotoInversionm1mPlus("-z,x,y"); + V3R rotationAxism1m = + generator.determineAxis(threeFoldRotoInversionm1mPlus.matrix()); + TS_ASSERT_EQUALS(generator.determineRotationSense( + threeFoldRotoInversionm1mPlus, rotationAxism1m), + SymmetryElementRotation::Positive); + + SymmetryOperation threeFoldRotoInversionm1mMinus("y,z,-x"); + V3R rotationAxism1m2 = + generator.determineAxis(threeFoldRotoInversionm1mPlus.matrix()); + + TS_ASSERT_EQUALS(rotationAxism1m, rotationAxism1m2); + + TS_ASSERT_EQUALS(generator.determineRotationSense( + threeFoldRotoInversionm1mMinus, rotationAxism1m2), + SymmetryElementRotation::Negative); + + // Test case 2: 6 [0 0 1] (Positive/Negative) in hexagonal system + SymmetryOperation sixFoldRotationZPlus("x-y,x,z"); + V3R rotationAxisZ = generator.determineAxis(sixFoldRotationZPlus.matrix()); + TS_ASSERT_EQUALS( + generator.determineRotationSense(sixFoldRotationZPlus, rotationAxisZ), + SymmetryElementRotation::Positive); + + SymmetryOperation sixFoldRotationZMinus("y,y-x,z"); + V3R rotationAxisZ2 = + generator.determineAxis(sixFoldRotationZMinus.matrix()); + + TS_ASSERT_EQUALS(rotationAxisZ, rotationAxisZ2); + + TS_ASSERT_EQUALS( + generator.determineRotationSense(sixFoldRotationZMinus, rotationAxisZ2), + SymmetryElementRotation::Negative); + } + + void testSymmetryElementRotationDetermineSymbol() { + TestableSymmetryElementRotationGenerator generator; + + SymmetryOperation sixFoldRotationZMinus("y,y-x,z"); + TS_ASSERT_EQUALS(generator.determineSymbol(sixFoldRotationZMinus), "6"); + + SymmetryOperation fourThreeScrewAxis("x+3/4,z+1/4,-y+3/4"); + TS_ASSERT_EQUALS(generator.determineSymbol(fourThreeScrewAxis), "43"); + + SymmetryOperation threeFoldRotoInversion("-z+1/4,-x+1/4,-y+1/4"); + TS_ASSERT_EQUALS(generator.determineSymbol(threeFoldRotoInversion), "-3"); + + SymmetryOperation twoOneScrewAxis("-x+1/2,y+1/2,-z"); + TS_ASSERT_EQUALS(generator.determineSymbol(twoOneScrewAxis), "21"); + } + + void testSymmetryElementRotationGenerator() { + // This generator processes Rotations/Rotoinversions. + SymmetryOperation rotation("x+3/4,z+1/4,-y+3/4"); + + SymmetryElementRotationGenerator rotationGenerator; + TS_ASSERT(rotationGenerator.canProcess(rotation)); + TS_ASSERT_THROWS_NOTHING(rotationGenerator.generateElement(rotation)); + + SymmetryElement_sptr rotationElement = + rotationGenerator.generateElement(rotation); + + TS_ASSERT(rotationElement); + TS_ASSERT_EQUALS(rotationElement->hmSymbol(), "43"); + + SymmetryElementRotation_sptr castedElement = + boost::dynamic_pointer_cast(rotationElement); + + TS_ASSERT(castedElement); + TS_ASSERT_EQUALS(castedElement->getRotationSense(), + SymmetryElementRotation::Negative); + TS_ASSERT_EQUALS(castedElement->getAxis(), V3R(1, 0, 0)); + TS_ASSERT_EQUALS(castedElement->getTranslation(), V3R(3, 0, 0) / 4); + + // But not other operations. + SymmetryOperation identity("x,y,z"); + TS_ASSERT(!rotationGenerator.canProcess(identity)); + + SymmetryOperation translation("x+1/2,y+1/2,z"); + TS_ASSERT(!rotationGenerator.canProcess(translation)); + } + + void testSymmetryElementMirrorDetermineSymbol() { + TestableSymmetryElementMirrorGenerator generator; + + SymmetryOperation dGlide("x+1/4,y+3/4,-z+3/4"); + TS_ASSERT_EQUALS(generator.determineSymbol(dGlide), "d"); + + SymmetryOperation gGlide("x+1/2,-z+1/2,-y"); + TS_ASSERT_EQUALS(generator.determineSymbol(gGlide), "g"); + + SymmetryOperation mirror("y,x,z"); + TS_ASSERT_EQUALS(generator.determineSymbol(mirror), "m"); + } + + void testSymmetryElementMirrorGenerator() { + // This generator processes Mirrors/Glides. + SymmetryOperation mirror("x+1/4,y+3/4,-z+3/4"); + + SymmetryElementMirrorGenerator mirrorGenerator; + TS_ASSERT(mirrorGenerator.canProcess(mirror)); + TS_ASSERT_THROWS_NOTHING(mirrorGenerator.generateElement(mirror)); + + SymmetryElement_sptr mirrorElement = + mirrorGenerator.generateElement(mirror); + + TS_ASSERT(mirrorElement); + TS_ASSERT_EQUALS(mirrorElement->hmSymbol(), "d"); + + SymmetryElementMirror_sptr castedElement = + boost::dynamic_pointer_cast(mirrorElement); + + TS_ASSERT(castedElement); + TS_ASSERT_EQUALS(castedElement->getAxis(), V3R(0, 0, 1)); + TS_ASSERT_EQUALS(castedElement->getTranslation(), V3R(1, 3, 0) / 4); + + // But not other operations. + SymmetryOperation identity("x,y,z"); + TS_ASSERT(!mirrorGenerator.canProcess(identity)); + + SymmetryOperation translation("x+1/2,y+1/2,z"); + TS_ASSERT(!mirrorGenerator.canProcess(translation)); + } + + void testSymmetryElementFactoryInstantiation() { + TS_ASSERT_THROWS_NOTHING(SymmetryElementFactory::Instance()); + } + + void testSymmetryElementFactorySubscribe() { + TestableSymmetryElementFactory factory; + TS_ASSERT(!factory.isSubscribed("SymmetryElementMirrorGenerator")); + + TS_ASSERT_THROWS_NOTHING(factory.subscribeSymmetryElementGenerator< + TestableSymmetryElementMirrorGenerator>( + "SymmetryElementMirrorGenerator")); + + TS_ASSERT(factory.isSubscribed("SymmetryElementMirrorGenerator")); + + TS_ASSERT_THROWS(factory.subscribeSymmetryElementGenerator< + TestableSymmetryElementMirrorGenerator>( + "SymmetryElementMirrorGenerator"), + std::runtime_error); + } + + void testSymmetryElementFactoryCreateSymElem() { + SymmetryOperation mirror("x,y,-z"); + + TestableSymmetryElementFactory factory; + factory.subscribeSymmetryElementGenerator< + TestableSymmetryElementMirrorGenerator>( + "SymmetryElementMirrorGenerator"); + + // There is no prototype yet. + TS_ASSERT(!factory.createFromPrototype(mirror.identifier())); + + // But an appropriate generator has been registered. + AbstractSymmetryElementGenerator_sptr generator = + factory.getGenerator(mirror); + TS_ASSERT(generator); + + // It's really the correct one. + boost::shared_ptr castedGenerator = + boost::dynamic_pointer_cast(generator); + TS_ASSERT(castedGenerator); + + // Now we can create the corresponding element + SymmetryElement_sptr mirrorElement = factory.createSymElement(mirror); + + // Make sure it's correct. + TS_ASSERT(mirrorElement); + TS_ASSERT_EQUALS(mirrorElement->hmSymbol(), "m"); + + // At this point we have a prototype stored + SymmetryElement_sptr anotherMirror = + factory.createFromPrototype(mirror.identifier()); + TS_ASSERT(anotherMirror); + + // It should also be a mirror. + TS_ASSERT_EQUALS(anotherMirror->hmSymbol(), "m"); + } + +private: + class TestableSymmetryElementWithAxisGenerator + : public SymmetryElementWithAxisGenerator { + friend class SymmetryElementFactoryTest; + + MOCK_CONST_METHOD1(generateElement, + SymmetryElement_sptr(const SymmetryOperation &)); + MOCK_CONST_METHOD1(canProcess, bool(const SymmetryOperation &)); + MOCK_CONST_METHOD1(determineSymbol, std::string(const SymmetryOperation &)); + }; + + class TestableSymmetryElementRotationGenerator + : public SymmetryElementRotationGenerator { + friend class SymmetryElementFactoryTest; + }; + + class TestableSymmetryElementMirrorGenerator + : public SymmetryElementMirrorGenerator { + friend class SymmetryElementFactoryTest; + }; + + class TestableSymmetryElementFactory : public SymmetryElementFactoryImpl { + friend class SymmetryElementFactoryTest; + }; +}; + +#endif /* MANTID_GEOMETRY_SYMMETRYELEMENTFACTORYTEST_H_ */ diff --git a/Code/Mantid/Framework/Geometry/test/SymmetryElementTest.h b/Code/Mantid/Framework/Geometry/test/SymmetryElementTest.h new file mode 100644 index 000000000000..7c9905105f86 --- /dev/null +++ b/Code/Mantid/Framework/Geometry/test/SymmetryElementTest.h @@ -0,0 +1,179 @@ +#ifndef MANTID_GEOMETRY_SYMMETRYELEMENTTEST_H_ +#define MANTID_GEOMETRY_SYMMETRYELEMENTTEST_H_ + +#include +#include +#include + +#include "MantidGeometry/Crystal/SymmetryElement.h" +#include "MantidGeometry/Crystal/SpaceGroupFactory.h" +#include "MantidGeometry/Crystal/PointGroupFactory.h" + +using namespace Mantid::Geometry; +using namespace Mantid::Kernel; +class SymmetryElementTest : 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 SymmetryElementTest *createSuite() { + return new SymmetryElementTest(); + } + static void destroySuite(SymmetryElementTest *suite) { delete suite; } + + void testConstructionHmSymbol() { + TS_ASSERT_THROWS_NOTHING(MockSymmetryElement element("1")); + MockSymmetryElement element("1"); + + TS_ASSERT_EQUALS(element.hmSymbol(), "1"); + } + + void testSymmetryElementIdentity() { + SymmetryElementIdentity identity; + + TS_ASSERT_EQUALS(identity.hmSymbol(), "1"); + + SymmetryElement_sptr cloned = identity.clone(); + SymmetryElementIdentity_sptr castedClone = + boost::dynamic_pointer_cast(cloned); + + TS_ASSERT(castedClone); + TS_ASSERT_EQUALS(castedClone->hmSymbol(), "1"); + } + + void testSymmetryElementTranslation() { + V3R bodyCenteringVector = V3R(1, 1, 1) / 2; + SymmetryElementTranslation translation(bodyCenteringVector); + TS_ASSERT_EQUALS(translation.hmSymbol(), "t"); + TS_ASSERT_EQUALS(translation.getTranslation(), bodyCenteringVector); + + SymmetryElement_sptr cloned = translation.clone(); + SymmetryElementTranslation_sptr castedClone = + boost::dynamic_pointer_cast(cloned); + + TS_ASSERT(castedClone); + TS_ASSERT_EQUALS(castedClone->hmSymbol(), "t"); + TS_ASSERT_EQUALS(castedClone->getTranslation(), bodyCenteringVector); + } + + void testSymmetryElementInversion() { + V3R oneEighth = V3R(1, 1, 1) / 8; + SymmetryElementInversion inversion(oneEighth); + TS_ASSERT_EQUALS(inversion.hmSymbol(), "-1"); + TS_ASSERT_EQUALS(inversion.getInversionPoint(), oneEighth); + + SymmetryElement_sptr cloned = inversion.clone(); + SymmetryElementInversion_sptr castedClone = + boost::dynamic_pointer_cast(cloned); + + TS_ASSERT(castedClone); + TS_ASSERT_EQUALS(castedClone->hmSymbol(), "-1"); + TS_ASSERT_EQUALS(castedClone->getInversionPoint(), oneEighth); + + SymmetryElementInversion zeroInversion; + TS_ASSERT_EQUALS(zeroInversion.getInversionPoint(), V3R(0, 0, 0)); + } + + void testSymmetryElementWithAxis() { + V3R axis(0, 0, 1); + V3R translation = V3R(0, 0, 1) / 4; + + TS_ASSERT_THROWS(MockSymmetryElementWithAxis invalidElement( + "41", V3R(0, 0, 0), translation), + std::invalid_argument); + + TS_ASSERT_THROWS_NOTHING( + MockSymmetryElementWithAxis axisElement("41", axis, translation)); + + MockSymmetryElementWithAxis axisElement("41", axis, translation); + TS_ASSERT_EQUALS(axisElement.getAxis(), axis); + TS_ASSERT_EQUALS(axisElement.getTranslation(), translation); + } + + void testSymmetryElementRotation() { + std::string symbolPlain("4"); + std::string symbolScrew("41"); + V3R axis(0, 0, 1); + V3R translation = V3R(0, 0, 1) / 4; + SymmetryElementRotation::RotationSense rotationSense( + SymmetryElementRotation::Negative); + + SymmetryElementRotation defaultTranslation(symbolPlain, axis); + TS_ASSERT_EQUALS(defaultTranslation.hmSymbol(), symbolPlain); + TS_ASSERT_EQUALS(defaultTranslation.getAxis(), axis); + TS_ASSERT_EQUALS(defaultTranslation.getTranslation(), V3R(0, 0, 0)); + TS_ASSERT_EQUALS(defaultTranslation.getRotationSense(), + SymmetryElementRotation::Positive); + + SymmetryElementRotation defaultSense(symbolScrew, axis, translation); + TS_ASSERT_EQUALS(defaultSense.hmSymbol(), symbolScrew); + TS_ASSERT_EQUALS(defaultSense.getAxis(), axis); + TS_ASSERT_EQUALS(defaultSense.getTranslation(), translation); + TS_ASSERT_EQUALS(defaultSense.getRotationSense(), + SymmetryElementRotation::Positive); + + SymmetryElementRotation rotationElement(symbolScrew, axis, translation, + rotationSense); + TS_ASSERT_EQUALS(rotationElement.hmSymbol(), symbolScrew); + TS_ASSERT_EQUALS(rotationElement.getAxis(), axis); + TS_ASSERT_EQUALS(rotationElement.getTranslation(), translation); + TS_ASSERT_EQUALS(rotationElement.getRotationSense(), rotationSense); + + SymmetryElement_sptr cloned = rotationElement.clone(); + SymmetryElementRotation_sptr castedClone = + boost::dynamic_pointer_cast(cloned); + TS_ASSERT(castedClone); + + TS_ASSERT_EQUALS(castedClone->hmSymbol(), symbolScrew); + TS_ASSERT_EQUALS(castedClone->getAxis(), axis); + TS_ASSERT_EQUALS(castedClone->getTranslation(), translation); + TS_ASSERT_EQUALS(castedClone->getRotationSense(), rotationSense); + } + + void testSymmetryElementMirror() { + std::string symbolPlain("m"); + std::string symbolGlide("c"); + V3R axis(0, 0, 1); + V3R translation = V3R(0, 0, 1) / 2; + + SymmetryElementMirror defaultTranslation(symbolPlain, axis); + TS_ASSERT_EQUALS(defaultTranslation.hmSymbol(), symbolPlain); + TS_ASSERT_EQUALS(defaultTranslation.getAxis(), axis); + TS_ASSERT_EQUALS(defaultTranslation.getTranslation(), V3R(0, 0, 0)); + + SymmetryElementMirror mirrorElement(symbolGlide, axis, translation); + TS_ASSERT_EQUALS(mirrorElement.hmSymbol(), symbolGlide); + TS_ASSERT_EQUALS(mirrorElement.getAxis(), axis); + TS_ASSERT_EQUALS(mirrorElement.getTranslation(), translation); + + SymmetryElement_sptr cloned = mirrorElement.clone(); + SymmetryElementMirror_sptr castedClone = + boost::dynamic_pointer_cast(cloned); + TS_ASSERT(castedClone); + + TS_ASSERT_EQUALS(castedClone->hmSymbol(), symbolGlide); + TS_ASSERT_EQUALS(castedClone->getAxis(), axis); + TS_ASSERT_EQUALS(castedClone->getTranslation(), translation); + } + +private: + class MockSymmetryElement : public SymmetryElement { + friend class SymmetryElementTest; + + public: + MockSymmetryElement(const std::string &hmSymbol) + : SymmetryElement(hmSymbol) {} + MOCK_CONST_METHOD0(clone, SymmetryElement_sptr()); + }; + + class MockSymmetryElementWithAxis : public SymmetryElementWithAxis { + friend class SymmetryElementTest; + + public: + MockSymmetryElementWithAxis(const std::string &symbol, const V3R &axis, + const V3R &translation) + : SymmetryElementWithAxis(symbol, axis, translation) {} + MOCK_CONST_METHOD0(clone, SymmetryElement_sptr()); + }; +}; + +#endif /* MANTID_GEOMETRY_SYMMETRYELEMENTTEST_H_ */ diff --git a/Code/Mantid/Framework/Geometry/test/SymmetryOperationTest.h b/Code/Mantid/Framework/Geometry/test/SymmetryOperationTest.h index 9a8bacfa36ea..572f8319310a 100644 --- a/Code/Mantid/Framework/Geometry/test/SymmetryOperationTest.h +++ b/Code/Mantid/Framework/Geometry/test/SymmetryOperationTest.h @@ -258,6 +258,23 @@ class SymmetryOperationTest : public CxxTest::TestSuite 2, V3D(m_h, m_h-m_k, -m_l), "x,x-y,-z"); } + void testPower() + { + SymmetryOperation mirror("x,-y,z"); + SymmetryOperation identity; + + TS_ASSERT_EQUALS(mirror^0, identity); + TS_ASSERT_EQUALS(mirror^1, mirror); + TS_ASSERT_EQUALS(mirror^2, identity); + + SymmetryOperation twoFoldZ("-x,-y,z"); + SymmetryOperation fourFoldZ("-y,x,z"); + TS_ASSERT_EQUALS(fourFoldZ^0, identity); + TS_ASSERT_EQUALS(fourFoldZ^1, fourFoldZ); + TS_ASSERT_EQUALS(fourFoldZ^2, twoFoldZ); + TS_ASSERT_EQUALS(fourFoldZ^4, identity); + } + private: V3D applyOrderTimes(const SymmetryOperation &symOp, const V3D &vector) { diff --git a/Code/Mantid/Framework/Geometry/test/V3RTest.h b/Code/Mantid/Framework/Geometry/test/V3RTest.h index 87bb11267ce0..4cf1fd995be0 100644 --- a/Code/Mantid/Framework/Geometry/test/V3RTest.h +++ b/Code/Mantid/Framework/Geometry/test/V3RTest.h @@ -426,6 +426,18 @@ class V3RTest : public CxxTest::TestSuite TS_ASSERT_EQUALS(transformedSmaller.z(), 0); } + void testVectorOperator() + { + V3R test = V3R(1, 2, 3) / 4; + + std::vector approximations(test); + + TS_ASSERT_EQUALS(approximations.size(), 3); + TS_ASSERT_EQUALS(approximations[0], 0.25); + TS_ASSERT_EQUALS(approximations[1], 0.5); + TS_ASSERT_EQUALS(approximations[2], 0.75); + } + }; diff --git a/Code/Mantid/Framework/Kernel/inc/MantidKernel/ConfigService.h b/Code/Mantid/Framework/Kernel/inc/MantidKernel/ConfigService.h index 55229c318c0c..479dafc1847e 100644 --- a/Code/Mantid/Framework/Kernel/inc/MantidKernel/ConfigService.h +++ b/Code/Mantid/Framework/Kernel/inc/MantidKernel/ConfigService.h @@ -247,9 +247,6 @@ class MANTID_KERNEL_DLL ConfigServiceImpl { /// Get the ParaViewPath const std::string getParaViewPath() const; - /// Get the initial view for vates - const std::string getVsiInitialView() const; - private: friend struct Mantid::Kernel::CreateUsingNew; /// Handles distribution of Poco signals. diff --git a/Code/Mantid/Framework/Kernel/inc/MantidKernel/InternetHelper.h b/Code/Mantid/Framework/Kernel/inc/MantidKernel/InternetHelper.h index 88d2df21fa57..dd97898a0807 100644 --- a/Code/Mantid/Framework/Kernel/inc/MantidKernel/InternetHelper.h +++ b/Code/Mantid/Framework/Kernel/inc/MantidKernel/InternetHelper.h @@ -13,13 +13,11 @@ namespace Poco { class URI; namespace Net { -// forward declaration +// forward declarations class HTTPClientSession; -// forward declaration class HTTPResponse; -// forward declaration class HTTPRequest; -// forward declaration +class HostNotFoundException; class HTMLForm; } } @@ -55,6 +53,51 @@ class Logger; */ class MANTID_KERNEL_DLL InternetHelper { public: + enum HTTPStatus + { + HTTP_CONTINUE = 100, + HTTP_SWITCHING_PROTOCOLS = 101, + HTTP_OK = 200, + HTTP_CREATED = 201, + HTTP_ACCEPTED = 202, + HTTP_NONAUTHORITATIVE = 203, + HTTP_NO_CONTENT = 204, + HTTP_RESET_CONTENT = 205, + HTTP_PARTIAL_CONTENT = 206, + HTTP_MULTIPLE_CHOICES = 300, + HTTP_MOVED_PERMANENTLY = 301, + HTTP_FOUND = 302, + HTTP_SEE_OTHER = 303, + HTTP_NOT_MODIFIED = 304, + HTTP_USEPROXY = 305, + // UNUSED: 306 + HTTP_TEMPORARY_REDIRECT = 307, + HTTP_BAD_REQUEST = 400, + HTTP_UNAUTHORIZED = 401, + HTTP_PAYMENT_REQUIRED = 402, + HTTP_FORBIDDEN = 403, + HTTP_NOT_FOUND = 404, + HTTP_METHOD_NOT_ALLOWED = 405, + HTTP_NOT_ACCEPTABLE = 406, + HTTP_PROXY_AUTHENTICATION_REQUIRED = 407, + HTTP_REQUEST_TIMEOUT = 408, + HTTP_CONFLICT = 409, + HTTP_GONE = 410, + HTTP_LENGTH_REQUIRED = 411, + HTTP_PRECONDITION_FAILED = 412, + HTTP_REQUESTENTITYTOOLARGE = 413, + HTTP_REQUESTURITOOLONG = 414, + HTTP_UNSUPPORTEDMEDIATYPE = 415, + HTTP_REQUESTED_RANGE_NOT_SATISFIABLE = 416, + HTTP_EXPECTATION_FAILED = 417, + HTTP_INTERNAL_SERVER_ERROR = 500, + HTTP_NOT_IMPLEMENTED = 501, + HTTP_BAD_GATEWAY = 502, + HTTP_SERVICE_UNAVAILABLE = 503, + HTTP_GATEWAY_TIMEOUT = 504, + HTTP_VERSION_NOT_SUPPORTED = 505 + }; + InternetHelper(); InternetHelper(const Kernel::ProxyInfo &proxy); virtual ~InternetHelper(); @@ -119,6 +162,12 @@ class MANTID_KERNEL_DLL InternetHelper { Poco::URI &uri, std::ostream &responseStream); int processRelocation(const Poco::Net::HTTPResponse &response, std::ostream &responseStream); + bool isRelocated(const int response); + void throwNotConnected(const std::string &url, + const Poco::Net::HostNotFoundException &ex); + + void logDebugRequestSending(const std::string &schemeName, + const std::string &url) const; Kernel::ProxyInfo m_proxyInfo; bool m_isProxySet; diff --git a/Code/Mantid/Framework/Kernel/src/ConfigService.cpp b/Code/Mantid/Framework/Kernel/src/ConfigService.cpp index b8c633056093..61f01093c536 100644 --- a/Code/Mantid/Framework/Kernel/src/ConfigService.cpp +++ b/Code/Mantid/Framework/Kernel/src/ConfigService.cpp @@ -2106,14 +2106,6 @@ const std::string ConfigServiceImpl::getParaViewPath() const { return getString("paraview.path"); } -/** - * Get the user-specified initial view - * @returns A string with the initial view or an empty string - */ -const std::string ConfigServiceImpl::getVsiInitialView() const { - return getString("vsi.initialview"); -} - /// \cond TEMPLATE template DLLExport int ConfigServiceImpl::getValue(const std::string &, double &); diff --git a/Code/Mantid/Framework/Kernel/src/DiskBuffer.cpp b/Code/Mantid/Framework/Kernel/src/DiskBuffer.cpp index eb403135a548..d034504821a3 100644 --- a/Code/Mantid/Framework/Kernel/src/DiskBuffer.cpp +++ b/Code/Mantid/Framework/Kernel/src/DiskBuffer.cpp @@ -9,7 +9,6 @@ using namespace Mantid::Kernel; namespace Mantid { namespace Kernel { -#define DISK_BUFFER_SIZE_TO_REPORT_WRITE 10000 //---------------------------------------------------------------------------------------------- /** Constructor */ @@ -101,8 +100,6 @@ void DiskBuffer::objectDeleted(ISaveable *item) { // indicate to the object that it is not stored in memory any more item->clearBufferState(); m_mutex.unlock(); - // std::cout << "DiskBuffer deleting ID " << item->getId() << "; new size " << - // m_writeBuffer.size() << std::endl; // Mark the amount of space used on disk as free if (item->wasSaved()) @@ -114,9 +111,6 @@ void DiskBuffer::objectDeleted(ISaveable *item) { * stored in the "toWrite" buffer. */ void DiskBuffer::writeOldObjects() { - if (m_writeBufferUsed > DISK_BUFFER_SIZE_TO_REPORT_WRITE) - std::cout << "DiskBuffer:: Writing out " << m_writeBufferUsed - << " events in " << m_nObjectsToWrite << " objects." << std::endl; Poco::ScopedLock _lock(m_mutex); // Holder for any objects that you were NOT able to write. diff --git a/Code/Mantid/Framework/Kernel/src/InternetHelper.cpp b/Code/Mantid/Framework/Kernel/src/InternetHelper.cpp index f881b729f0f9..0d63cf0f4a25 100644 --- a/Code/Mantid/Framework/Kernel/src/InternetHelper.cpp +++ b/Code/Mantid/Framework/Kernel/src/InternetHelper.cpp @@ -45,29 +45,8 @@ using std::string; namespace { // anonymous namespace for some utility functions - /// static Logger object Logger g_log("InternetHelper"); - -/// Throw an exception occurs when the computer -/// is not connected to the internet -void throwNotConnected(const std::string &url, - const HostNotFoundException &ex) { - std::stringstream info; - info << "Failed to download " << url - << " because there is no connection to the host " << ex.message() - << ".\nHint: Check your connection following this link: " << url << " "; - throw Exception::InternetError(info.str() + ex.displayText()); -} - -/// @returns true if the return code is considered a relocation -bool isRelocated(const int response) { - return ((response == HTTPResponse::HTTP_FOUND) || - (response == HTTPResponse::HTTP_MOVED_PERMANENTLY) || - (response == HTTPResponse::HTTP_TEMPORARY_REDIRECT) || - (response == HTTPResponse::HTTP_SEE_OTHER)); -} } //---------------------------------------------------------------------------------------------- @@ -117,6 +96,7 @@ void InternetHelper::createRequest(Poco::URI &uri) { m_request = new HTTPRequest(m_method, uri.getPathAndQuery(), HTTPMessage::HTTP_1_1); + m_response = new HTTPResponse(); if (!m_contentType.empty()) { m_request->setContentType(m_contentType); @@ -132,7 +112,7 @@ void InternetHelper::createRequest(Poco::URI &uri) { m_request->set(itHeaders->first, itHeaders->second); } - if (m_method == "POST") { + if (m_method == "POST") { m_request->setChunkedTransferEncoding(true); } } @@ -150,8 +130,8 @@ int InternetHelper::sendRequestAndProcess(HTTPClientSession &session, g_log.debug() << "Answer from web: " << retStatus << " " << m_response->getReason() << std::endl; - if (retStatus == HTTPResponse::HTTP_OK || - (retStatus == HTTPResponse::HTTP_CREATED && + if (retStatus == HTTP_OK || + (retStatus == HTTP_CREATED && m_method == HTTPRequest::HTTP_POST)) { Poco::StreamCopier::copyStream(rs, responseStream); return retStatus; @@ -193,6 +173,26 @@ int InternetHelper::sendRequest(const std::string &url, return retval; } +/** + * Helper to log (debug level) the request being sent (careful not to + * print blatant passwords, etc.). + * + * @param schemeName Normally "http" or "https" + * @param url url being sent (will be logged) + */ +void InternetHelper::logDebugRequestSending(const std::string &schemeName, + const std::string &url) const { + const std::string insecString = "password="; + if (std::string::npos == url.find(insecString)) { + g_log.debug() << "Sending " << schemeName << " " << m_method << + " request to: " << url << "\n"; + } else { + g_log.debug() << "Sending " << schemeName << " " << m_method << + " request to an url where the query string seems to contain a " + "password! (not shown for security reasons)." << "\n"; + } +} + /** Performs a request using http * @param url the address to the network resource * @param responseStream The stream to fill with the reply on success @@ -200,7 +200,8 @@ int InternetHelper::sendRequest(const std::string &url, int InternetHelper::sendHTTPRequest(const std::string &url, std::ostream &responseStream) { int retStatus = 0; - g_log.debug() << "Sending request to: " << url << "\n"; + + logDebugRequestSending("http", url); Poco::URI uri(url); // Configure Poco HTTP Client Session @@ -229,7 +230,8 @@ int InternetHelper::sendHTTPRequest(const std::string &url, int InternetHelper::sendHTTPSRequest(const std::string &url, std::ostream &responseStream) { int retStatus = 0; - g_log.debug() << "Sending request to: " << url << "\n"; + + logDebugRequestSending("https", url); Poco::URI uri(url); try { @@ -322,24 +324,24 @@ int InternetHelper::processErrorStates(const Poco::Net::HTTPResponse &res, rateLimitRemaining = -1; } - if (retStatus == HTTPResponse::HTTP_OK) { + if (retStatus == HTTP_OK) { throw Exception::InternetError("Response was ok, processing should never " "have entered processErrorStates", retStatus); - } else if (retStatus == HTTPResponse::HTTP_FOUND) { + } else if (retStatus == HTTP_FOUND) { throw Exception::InternetError("Response was HTTP_FOUND, processing should " "never have entered processErrorStates", retStatus); - } else if (retStatus == HTTPResponse::HTTP_MOVED_PERMANENTLY) { + } else if (retStatus == HTTP_MOVED_PERMANENTLY) { throw Exception::InternetError("Response was HTTP_MOVED_PERMANENTLY, " "processing should never have entered " "processErrorStates", retStatus); - } else if (retStatus == HTTPResponse::HTTP_NOT_MODIFIED) { + } else if (retStatus == HTTP_NOT_MODIFIED) { throw Exception::InternetError("Not modified since provided date" + rateLimitReset.toSimpleString(), retStatus); - } else if ((retStatus == HTTPResponse::HTTP_FORBIDDEN) && + } else if ((retStatus == HTTP_FORBIDDEN) && (rateLimitRemaining == 0)) { throw Exception::InternetError( "The Github API rate limit has been reached, try again after " + @@ -349,7 +351,7 @@ int InternetHelper::processErrorStates(const Poco::Net::HTTPResponse &res, std::stringstream info; std::stringstream ss; Poco::StreamCopier::copyStream(rs, ss); - if (retStatus == HTTPResponse::HTTP_NOT_FOUND) + if (retStatus == HTTP_NOT_FOUND) info << "Failed to download " << url << " with the link " << ".\n" << "Hint. Check that link is correct"; @@ -413,6 +415,29 @@ int InternetHelper::downloadFile(const std::string &urlFile, **/ void InternetHelper::setTimeout(int seconds) { m_timeout = seconds; } +/// Checks the HTTP status to decide if this is a relocation +/// @response the HTTP status +/// @returns true if the return code is considered a relocation +bool InternetHelper::isRelocated(const int response) { + return ((response == HTTP_FOUND) || + (response == HTTP_MOVED_PERMANENTLY) || + (response == HTTP_TEMPORARY_REDIRECT) || + (response == HTTP_SEE_OTHER)); +} + +/// Throw an exception occurs when the computer +/// is not connected to the internet +/// @param url The url that was use +/// @param ex The exception generated by Poco +void InternetHelper::throwNotConnected(const std::string &url, + const HostNotFoundException &ex) { + std::stringstream info; + info << "Failed to access " << url + << " because there is no connection to the host " << ex.message() + << ".\nHint: Check your connection following this link: " << url << " "; + throw Exception::InternetError(info.str() + ex.displayText()); +} /** Gets the timeout in seconds * @returns The value in seconds for the timeout diff --git a/Code/Mantid/Framework/MDAlgorithms/src/LoadMD.cpp b/Code/Mantid/Framework/MDAlgorithms/src/LoadMD.cpp index 7855ab4054f3..98e3feea9895 100644 --- a/Code/Mantid/Framework/MDAlgorithms/src/LoadMD.cpp +++ b/Code/Mantid/Framework/MDAlgorithms/src/LoadMD.cpp @@ -179,7 +179,8 @@ void LoadMD::exec() { MDEventFactory::CreateMDWorkspace(m_numDims, eventType); // Now the ExperimentInfo - MDBoxFlatTree::loadExperimentInfos(m_file.get(), ws); + bool lazyLoadExpt = fileBacked; + MDBoxFlatTree::loadExperimentInfos(m_file.get(), m_filename, ws, lazyLoadExpt); // Wrapper to cast to MDEventWorkspace then call the function CALL_MDEVENT_FUNCTION(this->doLoad, ws); @@ -230,7 +231,7 @@ void LoadMD::loadHisto() { MDHistoWorkspace_sptr ws(new MDHistoWorkspace(m_dims)); // Now the ExperimentInfo - MDBoxFlatTree::loadExperimentInfos(m_file.get(), ws); + MDBoxFlatTree::loadExperimentInfos(m_file.get(), m_filename, ws); // Load the WorkspaceHistory "process" ws->history().loadNexus(m_file.get()); diff --git a/Code/Mantid/Framework/MDAlgorithms/src/WeightedMeanMD.cpp b/Code/Mantid/Framework/MDAlgorithms/src/WeightedMeanMD.cpp index 700767b9a3b5..6be27f734faf 100644 --- a/Code/Mantid/Framework/MDAlgorithms/src/WeightedMeanMD.cpp +++ b/Code/Mantid/Framework/MDAlgorithms/src/WeightedMeanMD.cpp @@ -59,10 +59,10 @@ void WeightedMeanMD::execHistoHisto( double e = rhs_err_sq * lhs_err_sq / (rhs_err_sq + lhs_err_sq); signal = s * e; error_sq = e; - } else if ((rhs_err > 0) && (lhs_err <= 0)) { + } else if ((rhs_err > 0) && (lhs_err == 0)) { signal = rhs_s; error_sq = rhs_err * rhs_err; - } else if ((lhs_err <= 0) && (rhs_err > 0)) { + } else if ((lhs_err > 0) && (rhs_err == 0)) { signal = lhs_s; error_sq = lhs_err * lhs_err; } diff --git a/Code/Mantid/Framework/MDEvents/inc/MantidMDEvents/MDBoxFlatTree.h b/Code/Mantid/Framework/MDEvents/inc/MantidMDEvents/MDBoxFlatTree.h index bf9dc6959839..7ce65edab215 100644 --- a/Code/Mantid/Framework/MDEvents/inc/MantidMDEvents/MDBoxFlatTree.h +++ b/Code/Mantid/Framework/MDEvents/inc/MantidMDEvents/MDBoxFlatTree.h @@ -122,7 +122,7 @@ class DLLExport MDBoxFlatTree { /// name of the event type std::string m_eventType; /// shared pointer to multiple experiment info stored within the workspace - boost::shared_ptr m_mEI; + boost::shared_ptr m_mEI; public: static ::NeXus::File *createOrOpenMDWSgroup(const std::string &fileName, @@ -137,7 +137,9 @@ class DLLExport MDBoxFlatTree { // function static void loadExperimentInfos( ::NeXus::File *const file, - boost::shared_ptr ei); + const std::string & filename, + boost::shared_ptr ei, + bool lazy = false); static void saveAffineTransformMatricies(::NeXus::File *const file, API::IMDWorkspace_const_sptr ws); diff --git a/Code/Mantid/Framework/MDEvents/src/MDBoxFlatTree.cpp b/Code/Mantid/Framework/MDEvents/src/MDBoxFlatTree.cpp index 5da592271f6b..04bf88b25efc 100644 --- a/Code/Mantid/Framework/MDEvents/src/MDBoxFlatTree.cpp +++ b/Code/Mantid/Framework/MDEvents/src/MDBoxFlatTree.cpp @@ -3,7 +3,7 @@ #include "MantidMDEvents/MDEvent.h" #include "MantidMDEvents/MDLeanEvent.h" #include "MantidAPI/BoxController.h" -#include "MantidAPI/ExperimentInfo.h" +#include "MantidAPI/FileBackedExperimentInfo.h" #include "MantidMDEvents/MDEventFactory.h" #include @@ -285,7 +285,7 @@ void MDBoxFlatTree::loadBoxStructure(const std::string &fileName, int &nDim, m_mEI = boost::make_shared( Mantid::API::MultipleExperimentInfos()); - loadExperimentInfos(hFile.get(), m_mEI); + loadExperimentInfos(hFile.get(), fileName, m_mEI); } // close workspace group @@ -395,12 +395,15 @@ void MDBoxFlatTree::saveExperimentInfos(::NeXus::File *const file, * * @param file :: the pointer to the properly opened nexus data file where the *experiment info groups can be found. +* @param filename :: the filename of the opened NeXus file. Use for the file-backed case * @param mei :: MDEventWorkspace/MDHisto to load experiment infos to or rather *pointer to the base class of this workspaces (which is an experimentInfo) +* @param lazy :: If true, use the FileBackedExperimentInfo class to only load +* the data from the file when it is requested */ -void MDBoxFlatTree::loadExperimentInfos( - ::NeXus::File *const file, - boost::shared_ptr mei) { +void MDBoxFlatTree::loadExperimentInfos(::NeXus::File *const file, const std::string &filename, + boost::shared_ptr mei, + bool lazy) { // First, find how many experimentX blocks there are std::map entries; file->getEntries(entries); @@ -443,25 +446,31 @@ void MDBoxFlatTree::loadExperimentInfos( // Now go through in order, loading and adding itr = ExperimentBlockNum.begin(); for (; itr != ExperimentBlockNum.end(); itr++) { - std::string groupName = "experiment" + Kernel::Strings::toString(*itr); - - file->openGroup(groupName, "NXgroup"); - API::ExperimentInfo_sptr ei(new API::ExperimentInfo); - std::string parameterStr; - try { - // Get the sample, logs, instrument - ei->loadExperimentInfoNexus(file, parameterStr); - // Now do the parameter map - ei->readParameterMap(parameterStr); + if (lazy) { + auto ei = boost::make_shared( + filename, file->getPath() + "/" + groupName); // And add it to the mutliple experiment info. mei->addExperimentInfo(ei); - } catch (std::exception &e) { - g_log.information("Error loading section '" + groupName + - "' of nxs file."); - g_log.information(e.what()); + } + else { + auto ei = boost::make_shared(); + file->openGroup(groupName, "NXgroup"); + std::string parameterStr; + try { + // Get the sample, logs, instrument + ei->loadExperimentInfoNexus(file, parameterStr); + // Now do the parameter map + ei->readParameterMap(parameterStr); + // And add it to the mutliple experiment info. + mei->addExperimentInfo(ei); + } catch (std::exception &e) { + g_log.information("Error loading section '" + groupName + + "' of nxs file."); + g_log.information(e.what()); + } + file->closeGroup(); } - file->closeGroup(); } } /**Export existing experiment info defined in the box structure to target diff --git a/Code/Mantid/Framework/PythonInterface/mantid/geometry/CMakeLists.txt b/Code/Mantid/Framework/PythonInterface/mantid/geometry/CMakeLists.txt index 1fac4bd18c23..0bbe6d970e7a 100644 --- a/Code/Mantid/Framework/PythonInterface/mantid/geometry/CMakeLists.txt +++ b/Code/Mantid/Framework/PythonInterface/mantid/geometry/CMakeLists.txt @@ -29,6 +29,8 @@ set ( EXPORT_FILES src/Exports/PointGroupFactory.cpp src/Exports/SpaceGroup.cpp src/Exports/SpaceGroupFactory.cpp + src/Exports/SymmetryElement.cpp + src/Exports/SymmetryElementFactory.cpp src/Exports/SymmetryOperation.cpp src/Exports/SymmetryOperationFactory.cpp ) @@ -41,6 +43,7 @@ set ( INC_FILES set ( PY_FILES __init__.py + _aliases.py ) ############################################################################################# diff --git a/Code/Mantid/Framework/PythonInterface/mantid/geometry/__init__.py b/Code/Mantid/Framework/PythonInterface/mantid/geometry/__init__.py index 09c81411e45d..242c424ac561 100644 --- a/Code/Mantid/Framework/PythonInterface/mantid/geometry/__init__.py +++ b/Code/Mantid/Framework/PythonInterface/mantid/geometry/__init__.py @@ -11,3 +11,8 @@ # Load the C++ library ############################################################################### from ._geometry import * + +############################################################################### +# Make aliases accessible in this namespace +############################################################################### +from ._aliases import * \ No newline at end of file diff --git a/Code/Mantid/Framework/PythonInterface/mantid/geometry/_aliases.py b/Code/Mantid/Framework/PythonInterface/mantid/geometry/_aliases.py new file mode 100644 index 000000000000..0a3eebf476a8 --- /dev/null +++ b/Code/Mantid/Framework/PythonInterface/mantid/geometry/_aliases.py @@ -0,0 +1,20 @@ +""" + Defines a set of aliases to make accessing certain objects easier, + like in mantid.api. +""" +from _geometry import (SpaceGroupFactoryImpl, + SymmetryOperationFactoryImpl, + SymmetryElementFactoryImpl, + PointGroupFactoryImpl) + +############################################################################### +# Singleton +############################################################################### + +SpaceGroupFactory = SpaceGroupFactoryImpl.Instance() + +SymmetryOperationFactory = SymmetryOperationFactoryImpl.Instance() + +SymmetryElementFactory = SymmetryElementFactoryImpl.Instance() + +PointGroupFactory = PointGroupFactoryImpl.Instance() \ No newline at end of file diff --git a/Code/Mantid/Framework/PythonInterface/mantid/geometry/src/Exports/SymmetryElement.cpp b/Code/Mantid/Framework/PythonInterface/mantid/geometry/src/Exports/SymmetryElement.cpp new file mode 100644 index 000000000000..eb0ea8480b79 --- /dev/null +++ b/Code/Mantid/Framework/PythonInterface/mantid/geometry/src/Exports/SymmetryElement.cpp @@ -0,0 +1,29 @@ +#include "MantidGeometry/Crystal/SymmetryElement.h" + +#include +#include +#include + +using namespace Mantid::Geometry; +using namespace boost::python; + +namespace { + Mantid::Kernel::V3D getAxis(SymmetryElement & self) + { + try { + SymmetryElementWithAxis &axisElement = dynamic_cast(self); + return Mantid::Kernel::V3D(axisElement.getAxis()); + } catch(std::bad_cast) { + return Mantid::Kernel::V3D(0, 0, 0); + } + } +} + +void export_SymmetryElement() +{ + register_ptr_to_python >(); + scope symmetryElementScope = class_("SymmetryElement", no_init); + class_("SymmetryElement", no_init) + .def("hmSymbol", &SymmetryElement::hmSymbol) + .def("getAxis", &getAxis); +} diff --git a/Code/Mantid/Framework/PythonInterface/mantid/geometry/src/Exports/SymmetryElementFactory.cpp b/Code/Mantid/Framework/PythonInterface/mantid/geometry/src/Exports/SymmetryElementFactory.cpp new file mode 100644 index 000000000000..b91d49193ae6 --- /dev/null +++ b/Code/Mantid/Framework/PythonInterface/mantid/geometry/src/Exports/SymmetryElementFactory.cpp @@ -0,0 +1,16 @@ +#include "MantidGeometry/Crystal/SymmetryElementFactory.h" + +#include + +using namespace Mantid::Geometry; +using namespace boost::python; + +void export_SymmetryElementFactory() +{ + class_("SymmetryElementFactoryImpl", no_init) + .def("createSymElement", &SymmetryElementFactoryImpl::createSymElement) + .def("Instance", &SymmetryElementFactory::Instance, return_value_policy(), + "Returns a reference to the SymmetryElementFactory singleton") + .staticmethod("Instance") + ; +} diff --git a/Code/Mantid/Framework/PythonInterface/mantid/simpleapi.py b/Code/Mantid/Framework/PythonInterface/mantid/simpleapi.py index c85f036ae289..17d7d7463573 100644 --- a/Code/Mantid/Framework/PythonInterface/mantid/simpleapi.py +++ b/Code/Mantid/Framework/PythonInterface/mantid/simpleapi.py @@ -86,7 +86,15 @@ def Load(*args, **kwargs): # Create and execute algm = _create_algorithm_object('Load') _set_logging_option(algm, kwargs) - algm.setProperty('Filename', filename) # Must be set first + try: + algm.setProperty('Filename', filename) # Must be set first + except ValueError as ve: + raise ValueError('Problem when setting Filename. This is the detailed error ' + 'description: ' + str(ve) + '\nIf the file has been found ' + 'but you got this error, you might not have read permissions ' + 'or the file might be corrupted.\nIf the file has not been found, ' + 'you might have forgotten to add its location in the data search ' + 'directories.') # Remove from keywords so it is not set twice try: del kwargs['Filename'] diff --git a/Code/Mantid/Framework/PythonInterface/plugins/algorithms/CalibrateRectangularDetectors.py b/Code/Mantid/Framework/PythonInterface/plugins/algorithms/CalibrateRectangularDetectors.py index fa2074ea6d4a..abc4c6083f10 100644 --- a/Code/Mantid/Framework/PythonInterface/plugins/algorithms/CalibrateRectangularDetectors.py +++ b/Code/Mantid/Framework/PythonInterface/plugins/algorithms/CalibrateRectangularDetectors.py @@ -66,7 +66,7 @@ def PyInit(self): validator.setLower(0) self.declareProperty(IntArrayProperty("Background", values=[0], direction=Direction.Input, validator=validator)) - extensions = [ "_event.nxs", "_runinfo.xml"] + extensions = [ "_event.nxs", "_runinfo.xml", ".nxs.h5"] self.declareProperty("Extension", "_event.nxs", StringListValidator(extensions)) self.declareProperty("CompressOnRead", False, @@ -87,7 +87,9 @@ def PyInit(self): "Maximum absolute value of offsets; default is 1") self.declareProperty("CrossCorrelation", True, "CrossCorrelation if True; minimize using many peaks if False.") - self.declareProperty("PeakPositions", "", + validator = FloatArrayBoundedValidator() + validator.setLower(0.) + self.declareProperty(FloatArrayProperty("PeakPositions", []), "Comma delimited d-space positions of reference peaks. Use 1-3 for Cross Correlation. Unlimited for many peaks option.") self.declareProperty("PeakWindowMax", 0., "Maximum window around a peak to search for it. Optional.") @@ -106,7 +108,7 @@ def PyInit(self): "Type of peak to fit. Used only with CrossCorrelation=False") self.declareProperty("BackgroundType", "Flat", StringListValidator(['Flat', 'Linear', 'Quadratic']), "Used only with CrossCorrelation=False") - self.declareProperty("DetectorsPeaks", "", + self.declareProperty(IntArrayProperty("DetectorsPeaks", []), "Comma delimited numbers of detector banks for each peak if using 2-3 peaks for Cross Correlation. Default is all.") self.declareProperty("PeakHalfWidth", 0.05, "Half width of d-space around peaks for Cross Correlation. Default is 0.05") @@ -134,15 +136,13 @@ def PyInit(self): def validateInputs(self): messages = {} - detectors = self.getProperty("DetectorsPeaks").value.strip() + detectors = self.getProperty("DetectorsPeaks").value if self.getProperty("CrossCorrelation").value: - positions = self.getProperty("PeakPositions").value.strip() - positions = positions.split(',') - if not bool(detectors): + positions = self.getProperty("PeakPositions").value + if len(detectors) <= 1: if len(positions) != 1: messages["PeakPositions"] = "Can only have one cross correlation peak without specifying 'DetectorsPeaks'" else: - detectors = detectors.split(',') if len(detectors) != len(positions): messages["PeakPositions"] = "Must be the same length as 'DetectorsPeaks' (%d != %d)" \ % (len(positions), len(detectors)) @@ -151,7 +151,6 @@ def validateInputs(self): messages["DetectorsPeaks"] = "Up to 3 peaks are supported" elif bool(detectors): messages["DetectorsPeaks"] = "Only allowed for CrossCorrelation=True" - prop = self.getProperty("CrossCorrelationPoints") return messages @@ -216,7 +215,7 @@ def _loadData(self, runnumber, extension, filterWall=None): if runnumber is None or runnumber <= 0: return None - if extension.endswith("_event.nxs"): + if extension.endswith("_event.nxs") or extension.endswith(".nxs.h5"): wksp = self._loadEventNeXusData(runnumber, extension, **filter) else: wksp = self._loadPreNeXusData(runnumber, extension, **filter) @@ -493,9 +492,8 @@ def PyExec(self): self._smoothoffsets = self.getProperty("SmoothSummedOffsets").value self._smoothGroups = self.getProperty("SmoothGroups").value self._peakpos = self.getProperty("PeakPositions").value - positions = self._peakpos.strip().split(',') if self.getProperty("CrossCorrelation").value: - self._peakpos1 = float(positions[0]) + self._peakpos1 = self._peakpos[0] self._peakpos2 = 0 self._peakpos3 = 0 self._lastpixel = 0 @@ -504,15 +502,15 @@ def PyExec(self): peakhalfwidth = self.getProperty("PeakHalfWidth").value self._peakmin = self._peakpos1-peakhalfwidth self._peakmax = self._peakpos1+peakhalfwidth - if len(positions) >= 2: - self._peakpos2 = float(positions[1]) + if len(self._peakpos) >= 2: + self._peakpos2 = self._peakpos[1] self._peakmin2 = self._peakpos2-peakhalfwidth self._peakmax2 = self._peakpos2+peakhalfwidth - if len(positions) >= 3: - self._peakpos3 = float(positions[1]) + if len(self._peakpos) >= 3: + self._peakpos3 = self._peakpos[2] self._peakmin3 = self._peakpos3-peakhalfwidth self._peakmax3 = self._peakpos3+peakhalfwidth - detectors = self.getProperty("DetectorsPeaks").value.strip().split(',') + detectors = self.getProperty("DetectorsPeaks").value if detectors[0]: self._lastpixel = int(detectors[0]) self._lastpixel3 = self._lastpixel @@ -521,7 +519,6 @@ def PyExec(self): self._lastpixel3 = self._lastpixel2 if len(detectors) >= 3: self._lastpixel3 = self._lastpixel2+int(detectors[2]) - pixelbin2 = self._xpixelbin*self._ypixelbin self._ccnumber = self.getProperty("CrossCorrelationPoints").value self._maxoffset = self.getProperty("MaxOffset").value self._diffractionfocus = self.getProperty("DiffractionFocusWorkspace").value diff --git a/Code/Mantid/Framework/PythonInterface/plugins/algorithms/ExportSampleLogsToCSVFile.py b/Code/Mantid/Framework/PythonInterface/plugins/algorithms/ExportSampleLogsToCSVFile.py index 7b606e5828da..b8b09e7549e5 100644 --- a/Code/Mantid/Framework/PythonInterface/plugins/algorithms/ExportSampleLogsToCSVFile.py +++ b/Code/Mantid/Framework/PythonInterface/plugins/algorithms/ExportSampleLogsToCSVFile.py @@ -58,11 +58,14 @@ def PyInit(self): timezones = ["UTC", "America/New_York", "Asia/Shanghai", "Australia/Sydney", "Europe/London", "GMT+0",\ "Europe/Paris", "Europe/Copenhagen"] - self.declareProperty("TimeZone", "America/New_York", StringListValidator(timezones)) + description = "Sample logs recorded in NeXus files (in SNS) are in UTC time. TimeZone " + \ + "can allow the algorithm to output the log with local time." + self.declareProperty("TimeZone", "America/New_York", StringListValidator(timezones), description) # Log time tolerance self.declareProperty("TimeTolerance", 0.01, - "If any 2 log entries with log times within the time tolerance, they will be recorded in one line. Unit is second. ") + "If any 2 log entries with log times within the time tolerance, " + \ + "they will be recorded in one line. Unit is second. ") return diff --git a/Code/Mantid/Framework/PythonInterface/plugins/algorithms/LoadVesuvio.py b/Code/Mantid/Framework/PythonInterface/plugins/algorithms/LoadVesuvio.py index f93c745f456a..8100c0d2728c 100644 --- a/Code/Mantid/Framework/PythonInterface/plugins/algorithms/LoadVesuvio.py +++ b/Code/Mantid/Framework/PythonInterface/plugins/algorithms/LoadVesuvio.py @@ -34,6 +34,58 @@ class LoadVesuvio(PythonAlgorithm): + _ws_index = None + _spectrum_no = None + foil_map = None + _inst_prefix = None + _mon_spectra = None + _mon_index = None + _backward_spectra_list = None + _forward_spectra_list = None + _mon_scale = None + _beta = None + _tof_max = None + _mon_tof_max = None + _back_mon_norm = None + _back_period_sum1 = None + _back_period_sum2 = None + _back_foil_out_norm = None + _forw_mon_norm = None + _forw_period_sum1 = None + _forw_period_sum2 = None + _forw_foil_out_norm = None + _diff_opt = None + _spectra = None + _sumspectra = None + _raw_grp = None + _raw_monitors = None + _nperiods = None + _goodframes = None + pt_times = None + delta_t = None + mon_pt_times = None + delta_tmon = None + summed_ws = None + summed_mon = None + _spectra_type = None + _mon_norm_start = None + _mon_norm_end = None + _period_sum1_start = None + _period_sum1_end = None + _period_sum2_start = None + _period_sum2_end = None + _foil_out_norm_start = None + _foil_out_norm_end = None + sum1 = None + sum2 = None + sum3 = None + foil_thin = None + mon_out = None + mon_thin = None + foil_thick = None + mon_thick = None + foil_out = None + def summary(self): return "Loads raw data produced by the Vesuvio instrument at ISIS." diff --git a/Code/Mantid/Framework/PythonInterface/plugins/algorithms/SNSPowderReduction.py b/Code/Mantid/Framework/PythonInterface/plugins/algorithms/SNSPowderReduction.py index 597b6da5e367..00aecd109507 100644 --- a/Code/Mantid/Framework/PythonInterface/plugins/algorithms/SNSPowderReduction.py +++ b/Code/Mantid/Framework/PythonInterface/plugins/algorithms/SNSPowderReduction.py @@ -64,7 +64,7 @@ def PyInit(self): arrvalidator.setLower(0) self.declareProperty(IntArrayProperty("RunNumber", values=[0], validator=arrvalidator,\ direction=Direction.Input), "Number of sample run or 0 for only Vanadium and/or Background") - extensions = [ "_histo.nxs", "_event.nxs", "_runinfo.xml"] + extensions = [ "_histo.nxs", "_event.nxs", "_runinfo.xml", ".nxs.h5"] self.declareProperty("Extension", "_event.nxs", StringListValidator(extensions)) self.declareProperty("PreserveEvents", True, @@ -498,7 +498,7 @@ def _loadData(self, runnumber, extension, filterWall=None, outname=None, **chunk if outname is not None: name = outname - if extension.endswith("_event.nxs"): + if extension.endswith("_event.nxs") or extension.endswith(".nxs.h5"): chunk["Precount"] = True if filterWall is not None: if filterWall[0] > 0.: diff --git a/Code/Mantid/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/ElasticWindowMultiple.py b/Code/Mantid/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/ElasticWindowMultiple.py index df2869633b8a..b5778fa9c80e 100644 --- a/Code/Mantid/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/ElasticWindowMultiple.py +++ b/Code/Mantid/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/ElasticWindowMultiple.py @@ -34,6 +34,7 @@ class ElasticWindowMultiple(DataProcessorAlgorithm): _range_1_end = None _range_2_start = None _range_2_end = None + _mtd_plot = None def category(self): return 'Workflow\\Inelastic;PythonAlgorithms;Inelastic' diff --git a/Code/Mantid/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/Fury.py b/Code/Mantid/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/Fury.py index eddd34cd12dd..ab8aff547baf 100644 --- a/Code/Mantid/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/Fury.py +++ b/Code/Mantid/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/Fury.py @@ -13,6 +13,7 @@ class Fury(PythonAlgorithm): _resolution = None _e_min = None _e_max = None + _e_width = None _number_points_per_bin = None _parameter_table = None _output_workspace = None @@ -37,7 +38,8 @@ def PyInit(self): self.declareProperty(name='EnergyMax', defaultValue=0.5, doc='Maximum energy for fit. Default=0.5') self.declareProperty(name='NumBins', defaultValue=1, - doc='Decrease total number of spectrum points by this ratio through merging of intensities from neighbouring bins. Default=1') + doc='Decrease total number of spectrum points by this ratio through merging of ' + 'intensities from neighbouring bins. Default=1') self.declareProperty(MatrixWorkspaceProperty('ParameterWorkspace', '',\ direction=Direction.Output, optional=PropertyMode.Optional), diff --git a/Code/Mantid/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/HFIRSANSReduction.py b/Code/Mantid/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/HFIRSANSReduction.py index 3365684c2f7d..901625ad06ca 100644 --- a/Code/Mantid/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/HFIRSANSReduction.py +++ b/Code/Mantid/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/HFIRSANSReduction.py @@ -7,6 +7,8 @@ class HFIRSANSReduction(PythonAlgorithm): + default_output_dir = None + def category(self): return "Workflow\\SANS\\UsesPropertyManager" @@ -18,7 +20,8 @@ def summary(self): def PyInit(self): self.declareProperty('Filename', '', doc='List of input file paths') - self.declareProperty('ReductionProperties', '__sans_reduction_properties', validator=StringMandatoryValidator(), doc='Property manager name for the reduction') + self.declareProperty('ReductionProperties', '__sans_reduction_properties', validator=StringMandatoryValidator(), + doc='Property manager name for the reduction') self.declareProperty('OutputWorkspace', '', doc='Reduced workspace') self.declareProperty('OutputMessage', '', direction=Direction.Output, doc='Output message') diff --git a/Code/Mantid/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/IndirectILLReduction.py b/Code/Mantid/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/IndirectILLReduction.py index 88f8d3073975..25ad18947ba2 100644 --- a/Code/Mantid/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/IndirectILLReduction.py +++ b/Code/Mantid/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/IndirectILLReduction.py @@ -25,38 +25,43 @@ class IndirectILLReduction(DataProcessorAlgorithm): _reflection = None _run_name = None + def category(self): return "Workflow\\MIDAS;Inelastic;PythonAlgorithms" + def summary(self): + return 'Performs an energy transfer reduction for ILL indirect inelastic data.' + + def PyInit(self): - #input options + # Input options self.declareProperty(FileProperty('Run', '', action=FileAction.Load, extensions=["nxs"]), doc='File path of run.') self.declareProperty(name='Analyser', defaultValue='silicon', validator=StringListValidator(['silicon']), - doc='Analyser crystal') + doc='Analyser crystal.') self.declareProperty(name='Reflection', defaultValue='111', validator=StringListValidator(['111']), - doc='Analyser reflection') + doc='Analyser reflection.') self.declareProperty(FileProperty('MapFile', '', action=FileAction.OptionalLoad, extensions=["xml"]), doc='Filename of the map file to use. If left blank the default will be used.') self.declareProperty(name='MirrorMode', defaultValue=False, - doc='Whether to use mirror mode') + doc='Whether to use mirror mode.') - #Output workspace properties + # Output workspace properties self.declareProperty(MatrixWorkspaceProperty("RawWorkspace", "", direction=Direction.Output), doc="Name for the output raw workspace created.") self.declareProperty(MatrixWorkspaceProperty("ReducedWorkspace", "", direction=Direction.Output), - doc="Name for the output reduced workspace created. If mirror mode is used this will be the sum of both" + doc="Name for the output reduced workspace created. If mirror mode is used this will be the sum of both " "the left and right hand workspaces.") self.declareProperty(MatrixWorkspaceProperty("LeftWorkspace", "", @@ -67,13 +72,31 @@ def PyInit(self): optional=PropertyMode.Optional, direction=Direction.Output), doc="Name for the right workspace if mirror mode is used.") - # output options + # Output options self.declareProperty(name='Save', defaultValue=False, - doc='Switch Save result to nxs file Off/On') + doc='Switch Save result to nxs file Off/On.') self.declareProperty(name='Plot', defaultValue=False, doc='Whether to plot the output workspace.') + def validateInputs(self): + issues = dict() + + red_left_workspace = self.getPropertyValue('LeftWorkspace') + red_right_workspace = self.getPropertyValue('RightWorkspace') + use_mirror_mode = self.getProperty('MirrorMode').value + + # Need the right and left workspaces for mirror mode + if use_mirror_mode: + if red_left_workspace == '': + issues['LeftWorkspace'] = 'Mirror Mode requires this workspace to be set' + + if red_right_workspace == '': + issues['RightWorkspace'] = 'Mirror Mode requires this workspace to be set' + + return issues + + def PyExec(self): self.log().information('IndirectILLreduction') @@ -88,13 +111,6 @@ def PyExec(self): self._save = self.getProperty('Save').value self._plot = self.getProperty('Plot').value - if self._use_mirror_mode: - if self._red_left_workspace == '': - raise ValueError("Mirror Mode requires the LeftWorkspace property to be set to a value") - - if self._red_right_workspace == '': - raise ValueError("Mirror Mode requires the RightWorkspace property to be set to a value") - LoadILLIndirect(FileName=run_path, OutputWorkspace=self._raw_workspace) instrument = mtd[self._raw_workspace].getInstrument() diff --git a/Code/Mantid/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/MolDyn.py b/Code/Mantid/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/MolDyn.py index d908602c2285..046ed36d28f7 100644 --- a/Code/Mantid/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/MolDyn.py +++ b/Code/Mantid/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/MolDyn.py @@ -70,6 +70,7 @@ class MolDyn(PythonAlgorithm): _emax = None _res_ws = None _out_ws = None + _mtd_plot = None def category(self): return 'Workflow\\Inelastic;PythonAlgorithms;Inelastic' diff --git a/Code/Mantid/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/SavePlot1D.py b/Code/Mantid/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/SavePlot1D.py index 5e4beec1e3c7..d2fdfd570aa7 100644 --- a/Code/Mantid/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/SavePlot1D.py +++ b/Code/Mantid/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/SavePlot1D.py @@ -3,6 +3,8 @@ class SavePlot1D(mantid.api.PythonAlgorithm): + _wksp = None + def category(self): """ Category """ @@ -22,7 +24,8 @@ def checkGroups(self): def PyInit(self): #declare properties self.declareProperty(mantid.api.WorkspaceProperty("InputWorkspace","",mantid.kernel.Direction.Input),"Workspace to plot") - self.declareProperty(mantid.api.FileProperty('OutputFilename', '', action=mantid.api.FileAction.Save, extensions = ["png"]), doc='Name of the image file to savefile.') + self.declareProperty(mantid.api.FileProperty('OutputFilename', '', action=mantid.api.FileAction.Save, extensions = ["png"]), + doc='Name of the image file to savefile.') self.declareProperty("XLabel","","Label on the X axis. If empty, it will be taken from workspace") self.declareProperty("YLabel","","Label on the Y axis. If empty, it will be taken from workspace") diff --git a/Code/Mantid/Framework/PythonInterface/plugins/functions/Examples/ExamplePeakFunction.py b/Code/Mantid/Framework/PythonInterface/plugins/functions/Examples/ExamplePeakFunction.py index 86aaa24b0b4b..6ab37b8c4523 100644 --- a/Code/Mantid/Framework/PythonInterface/plugins/functions/Examples/ExamplePeakFunction.py +++ b/Code/Mantid/Framework/PythonInterface/plugins/functions/Examples/ExamplePeakFunction.py @@ -14,6 +14,8 @@ class ExamplePeakFunction(IPeakFunction): + _nterms = None + def category(self): """ Optional method to return the category that this @@ -115,7 +117,6 @@ def setActiveParameter(self, index, value): set than that declared """ param_value = value - explicit = False if index == 2: param_value = math.sqrt(math.fabs(1.0/value)) else: 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 cdcd57e2751c..51852e94c51f 100644 --- a/Code/Mantid/Framework/PythonInterface/test/python/mantid/geometry/CMakeLists.txt +++ b/Code/Mantid/Framework/PythonInterface/test/python/mantid/geometry/CMakeLists.txt @@ -14,6 +14,7 @@ set ( TEST_PY_FILES PeakShapeTest.py PointGroupTest.py SpaceGroupTest.py + SymmetryElementTest.py SymmetryOperationTest.py ) diff --git a/Code/Mantid/Framework/PythonInterface/test/python/mantid/geometry/PointGroupTest.py b/Code/Mantid/Framework/PythonInterface/test/python/mantid/geometry/PointGroupTest.py index 358491f5964b..a642f11a54b9 100644 --- a/Code/Mantid/Framework/PythonInterface/test/python/mantid/geometry/PointGroupTest.py +++ b/Code/Mantid/Framework/PythonInterface/test/python/mantid/geometry/PointGroupTest.py @@ -1,16 +1,16 @@ import unittest -from mantid.geometry import PointGroup, PointGroupFactoryImpl +from mantid.geometry import PointGroup, PointGroupFactory from mantid.kernel import V3D class PointGroupTest(unittest.TestCase): def test_creation(self): - self.assertRaises(RuntimeError, PointGroupFactoryImpl.Instance().createPointGroup, "none") + self.assertRaises(RuntimeError, PointGroupFactory.createPointGroup, "none") - PointGroupFactoryImpl.Instance().createPointGroup("m-3m") + PointGroupFactory.createPointGroup("m-3m") def test_getInfo(self): - pg = PointGroupFactoryImpl.Instance().createPointGroup("m-3m") + pg = PointGroupFactory.createPointGroup("m-3m") self.assertEquals(pg.getName(), "m-3m (Cubic)") self.assertEquals(pg.getSymbol(), "m-3m") self.assertEquals(pg.crystalSystem(), PointGroup.CrystalSystem.Cubic) @@ -20,7 +20,7 @@ def test_isEquivalent(self): hkl2 = V3D(-1, -1, -1) hkl3 = V3D(-1, -1, 2) - pg = PointGroupFactoryImpl.Instance().createPointGroup("m-3m") + pg = PointGroupFactory.createPointGroup("m-3m") self.assertTrue(pg.isEquivalent(hkl1, hkl2)) self.assertFalse(pg.isEquivalent(hkl1, hkl3)) @@ -28,7 +28,7 @@ def test_getEquivalents(self): hkl1 = V3D(1, 0, 0) hkl2 = V3D(-1, 0, 0) - pg = PointGroupFactoryImpl.Instance().createPointGroup("-1") + pg = PointGroupFactory.createPointGroup("-1") equivalents = pg.getEquivalents(hkl1) self.assertTrue(hkl1 in equivalents) @@ -40,7 +40,7 @@ def test_getReflectionFamily(self): hkl1 = V3D(0, 0, 1) hkl2 = V3D(-1, 0, 0) - pg = PointGroupFactoryImpl.Instance().createPointGroup("m-3m") + pg = PointGroupFactory.createPointGroup("m-3m") self.assertEquals(pg.getReflectionFamily(hkl1), pg.getReflectionFamily(hkl2)) if __name__ == '__main__': diff --git a/Code/Mantid/Framework/PythonInterface/test/python/mantid/geometry/SpaceGroupTest.py b/Code/Mantid/Framework/PythonInterface/test/python/mantid/geometry/SpaceGroupTest.py index db6e8a16261d..a3a24ed6d47b 100644 --- a/Code/Mantid/Framework/PythonInterface/test/python/mantid/geometry/SpaceGroupTest.py +++ b/Code/Mantid/Framework/PythonInterface/test/python/mantid/geometry/SpaceGroupTest.py @@ -1,15 +1,15 @@ import unittest -from mantid.geometry import SpaceGroup, SpaceGroupFactoryImpl +from mantid.geometry import SpaceGroup, SpaceGroupFactory class SpaceGroupTest(unittest.TestCase): def test_creation(self): - self.assertRaises(ValueError, SpaceGroupFactoryImpl.Instance().createSpaceGroup, "none") + self.assertRaises(ValueError, SpaceGroupFactory.createSpaceGroup, "none") - SpaceGroupFactoryImpl.Instance().createSpaceGroup("I m -3 m") + SpaceGroupFactory.createSpaceGroup("I m -3 m") def test_interface(self): - spaceGroup = SpaceGroupFactoryImpl.Instance().createSpaceGroup("P -1") + spaceGroup = SpaceGroupFactory.createSpaceGroup("P -1") self.assertEquals(spaceGroup.hmSymbol(), "P -1") self.assertEquals(spaceGroup.order(), 2) @@ -20,7 +20,7 @@ def test_interface(self): self.assertTrue("-x,-y,-z" in symOpStrings) def test_equivalentPositions(self): - spaceGroup = SpaceGroupFactoryImpl.Instance().createSpaceGroup("P -1") + spaceGroup = SpaceGroupFactory.createSpaceGroup("P -1") position = [0.34, 0.3, 0.4] equivalentPositions = spaceGroup.getEquivalentPositions(position) diff --git a/Code/Mantid/Framework/PythonInterface/test/python/mantid/geometry/SymmetryElementTest.py b/Code/Mantid/Framework/PythonInterface/test/python/mantid/geometry/SymmetryElementTest.py new file mode 100644 index 000000000000..f5874c853df2 --- /dev/null +++ b/Code/Mantid/Framework/PythonInterface/test/python/mantid/geometry/SymmetryElementTest.py @@ -0,0 +1,30 @@ +import unittest +from mantid.geometry import SymmetryOperation, SymmetryOperationFactory +from mantid.geometry import SymmetryElement, SymmetryElementFactory +from mantid.kernel import V3D + +class SymmetryElementTest(unittest.TestCase): + + def test_creation_axis(self): + symOp = SymmetryOperationFactory.createSymOp("x,y,-z") + symEle = SymmetryElementFactory.createSymElement(symOp) + + self.assertEquals(symEle.hmSymbol(), "m") + self.assertEquals(symEle.getAxis(), V3D(0,0,1)) + + rotation = SymmetryOperationFactory.createSymOp("x,-y,-z") + rotationElement = SymmetryElementFactory.createSymElement(rotation) + + self.assertEquals(rotationElement.hmSymbol(), "2") + self.assertEquals(rotationElement.getAxis(), V3D(1,0,0)) + + def test_creation_no_axis(self): + symOp = SymmetryOperationFactory.createSymOp("-x,-y,-z") + symEle = SymmetryElementFactory.createSymElement(symOp) + + self.assertEquals(symEle.hmSymbol(), "-1") + self.assertEquals(symEle.getAxis(), V3D(0,0,0)) + + +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 index 453b2be7ec45..b2dbbf58bc66 100644 --- a/Code/Mantid/Framework/PythonInterface/test/python/mantid/geometry/SymmetryOperationTest.py +++ b/Code/Mantid/Framework/PythonInterface/test/python/mantid/geometry/SymmetryOperationTest.py @@ -1,21 +1,21 @@ import unittest -from mantid.geometry import SymmetryOperation, SymmetryOperationFactoryImpl +from mantid.geometry import SymmetryOperation, SymmetryOperationFactory from mantid.kernel import V3D class SymmetryOperationTest(unittest.TestCase): def test_creation(self): - self.assertRaises(RuntimeError, SymmetryOperationFactoryImpl.Instance().createSymOp, "none") + self.assertRaises(RuntimeError, SymmetryOperationFactory.createSymOp, "none") - SymmetryOperationFactoryImpl.Instance().createSymOp("x,y,-z") + SymmetryOperationFactory.createSymOp("x,y,-z") def test_getInfo(self): - symOp = SymmetryOperationFactoryImpl.Instance().createSymOp("x, y, -z") + symOp = SymmetryOperationFactory.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") + symOp = SymmetryOperationFactory.createSymOp("x,y,-z") hkl1 = V3D(1, 1, 1) hkl2 = symOp.apply(hkl1) diff --git a/Code/Mantid/Framework/RemoteAlgorithms/CMakeLists.txt b/Code/Mantid/Framework/RemoteAlgorithms/CMakeLists.txt index 340e66fbd199..af01be7b0c7b 100644 --- a/Code/Mantid/Framework/RemoteAlgorithms/CMakeLists.txt +++ b/Code/Mantid/Framework/RemoteAlgorithms/CMakeLists.txt @@ -1,39 +1,45 @@ set( SRC_FILES - src/AbortRemoteJob.cpp - src/Authenticate.cpp - src/DownloadRemoteFile.cpp - src/QueryAllRemoteJobs.cpp - src/QueryRemoteFile.cpp - src/QueryRemoteJob.cpp - src/SimpleJSON.cpp - src/StartRemoteTransaction.cpp - src/StopRemoteTransaction.cpp - src/SubmitRemoteJob.cpp - src/UploadRemoteFile.cpp + src/AbortRemoteJob.cpp + src/Authenticate.cpp + src/DownloadRemoteFile.cpp + src/QueryAllRemoteJobs.cpp + src/QueryRemoteFile.cpp + src/QueryRemoteJob.cpp + src/SimpleJSON.cpp + src/StartRemoteTransaction.cpp + src/StopRemoteTransaction.cpp + src/SubmitRemoteJob.cpp + src/UploadRemoteFile.cpp + src/SCARFTomoReconstruction.cpp ) set( INC_FILES - inc/MantidRemoteAlgorithms/AbortRemoteJob.h - inc/MantidRemoteAlgorithms/Authenticate.h - inc/MantidRemoteAlgorithms/DownloadRemoteFile.h - inc/MantidRemoteAlgorithms/QueryAllRemoteJobs.h - inc/MantidRemoteAlgorithms/QueryRemoteJob.h - inc/MantidRemoteAlgorithms/QueryRemoteFile.h - inc/MantidRemoteAlgorithms/SimpleJSON.h - inc/MantidRemoteAlgorithms/StartRemoteTransaction.h - inc/MantidRemoteAlgorithms/StopRemoteTransaction.h - inc/MantidRemoteAlgorithms/SubmitRemoteJob.h - inc/MantidRemoteAlgorithms/UploadRemoteFile.h + inc/MantidRemoteAlgorithms/AbortRemoteJob.h + inc/MantidRemoteAlgorithms/Authenticate.h + inc/MantidRemoteAlgorithms/DownloadRemoteFile.h + inc/MantidRemoteAlgorithms/QueryAllRemoteJobs.h + inc/MantidRemoteAlgorithms/QueryRemoteJob.h + inc/MantidRemoteAlgorithms/QueryRemoteFile.h + inc/MantidRemoteAlgorithms/SimpleJSON.h + inc/MantidRemoteAlgorithms/StartRemoteTransaction.h + inc/MantidRemoteAlgorithms/StopRemoteTransaction.h + inc/MantidRemoteAlgorithms/SubmitRemoteJob.h + inc/MantidRemoteAlgorithms/UploadRemoteFile.h + inc/MantidRemoteAlgorithms/SCARFTomoReconstruction.h +) + +set ( TEST_FILES + SCARFTomoReconstructionTest.h ) -#set ( TEST_FILES -# -#) #set ( TEST_PY_FILES # #) # No tests yet... +# Not for now, remember later if convenient: Add a precompiled header where they are supported +# enable_precompiled_headers ( inc/MantidRemoteAlgorithms/PrecompiledHeader.h SRC_FILES ) + # Add the target for this directory add_library ( RemoteAlgorithms ${SRC_FILES} ${INC_FILES}) @@ -52,13 +58,10 @@ include_directories ( inc ) target_link_libraries ( RemoteAlgorithms ${MANTIDLIBS} ${GSL_LIBRARIES} ) # Add the unit tests directory -#add_subdirectory ( test ) # No tests yet... +add_subdirectory ( test ) # Note: No tests yet for many remote algorithms... ########################################################################### # Installation settings ########################################################################### install ( TARGETS RemoteAlgorithms ${SYSTEM_PACKAGE_TARGET} DESTINATION ${PLUGINS_DIR} ) - - - diff --git a/Code/Mantid/Framework/RemoteAlgorithms/inc/MantidRemoteAlgorithms/SCARFTomoReconstruction.h b/Code/Mantid/Framework/RemoteAlgorithms/inc/MantidRemoteAlgorithms/SCARFTomoReconstruction.h new file mode 100644 index 000000000000..cf586c0d3fc0 --- /dev/null +++ b/Code/Mantid/Framework/RemoteAlgorithms/inc/MantidRemoteAlgorithms/SCARFTomoReconstruction.h @@ -0,0 +1,167 @@ +#ifndef REMOTE_SCARFTOMORECONSTRUCTION_H_ +#define REMOTE_SCARFTOMORECONSTRUCTION_H_ + +#include "MantidAPI/Algorithm.h" + +namespace Mantid { +namespace RemoteAlgorithms { +/*** + Algorithm to initiate, query about, or cancel a tomographic + reconstruction job on the SCARF computer cluster at RAL. + The algorithm can be used to send different commands to the job + queue, for example: log in, log out, start a reconstruction job, + retrieve information about jobs or to cancel a job. + + If the authentication is successfull, a cookie is received that is + stored internally and re-used for all subsequent interactions with + the compute resource. + + Copyright © 2014-2015 ISIS Rutherford Appleton Laboratory, + NScD Oak Ridge National Laboratory & European Spallation Source + + This file is part of Mantid. + + Mantid is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + Mantid is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + + File change history is stored at: + Code Documentation is available at: + */ + +class DLLExport SCARFTomoReconstruction : public Mantid::API::Algorithm { +public: + /// Constructor + SCARFTomoReconstruction(); + /// Virtual destructor + virtual ~SCARFTomoReconstruction() {} + /// Algorithm's name + virtual const std::string name() const { return "SCARFTomoReconstruction"; } + /// Summary of algorithms purpose + virtual const std::string summary() const { + return "Perform a control action on jobs running on the SCARF computer " + "cluster at RAL, STFC (http://www.scarf.rl.ac.uk/)"; + } + /// Algorithm's version + virtual int version() const { return (1); } + /// Algorithm's category for identification + virtual const std::string category() const { return "Remote"; } + +protected: + /// different methods (HTTP requests) to process reconstruction job commands + virtual void doLogin(const std::string &username, const std::string &password); + virtual void doLogout(const std::string &username); + virtual bool doPing(); + virtual void doSubmit(const std::string &username); + virtual void doQueryStatus(const std::string &username); + virtual void doQueryStatusById(const std::string &username, + const std::string &jobId); + virtual void doCancel(const std::string &username, + const std::string& jobId); + virtual void doUploadFile(const std::string &username, + const std::string &destDir, + const std::string &filename); + virtual void doDownload(const std::string &username, + const std::string &jobId, + const std::string &fname, + const std::string &localDir); + + typedef std::map StringToStringMap; + + /// method that deals with the actual HTTP(S) connection (convenient to + /// mock up all inet messaging) + virtual int doSendRequestGetResponse(const std::string &url, + std::ostream &response, + const StringToStringMap &headers = + StringToStringMap(), + const std::string &method = std::string(), + const std::string &body = ""); + +private: + void init(); + /// Execution code + void exec(); + + // helper for the submit request + std::string buildSubmitBody(const std::string &appName, + const std::string &boundary, + const std::string &inputFiles, + const std::string &inputArgs); + + /// lower level helper to encode parameters + void encodeParam(std::string &body, const std::string &boundary, + const std::string ¶mName, const std::string ¶mVal); + + /// build body as headers + file as an octet string + std::string buildUploadBody(const std::string &boundary, + const std::string &destDir, + const std::string &filename); + + /// fill in output properties with job status and info + void genOutputStatusInfo(const std::string &resp, const std::string &jobID = + std::string()); + + // cookie obtained after logging in + struct Token { + Token(std::string& u, std::string& t): m_url(u), m_token_str(t) {}; + std::string m_url; + std::string m_token_str; + }; + typedef std::pair UsernameToken; + + class Action { + public: + typedef enum {LOGIN=0, LOGOUT, SUBMIT, QUERYSTATUS, QUERYSTATUSBYID, + PING, CANCEL, UPLOAD, DOWNLOAD, UNDEF} Type; + }; + + /// helper to filter the action given by the user + Action::Type getAction(); + + /// helper to fetch and save one file from the compute resource + void getOneJobFile(const std::string &jobId, const std::string &remotePath, + const std::string &localPath, const Token &t); + + /// helper to fetch and save all the files for a remote job + void getAllJobFiles(const std::string &jobId, const std::string &localDir, + const Token &t); + + /// check if output file is writeable, overwritten, etc. + const std::string checkDownloadOutputFile(const std::string &localPath, + const std::string &fname) const; + + /// get a normal file name from a 'PAC Server*...' name + const std::string filterPACFilename(const std::string PACName) const; + + /// extremely simple parser for error messages from LSF PAC + std::string extractPACErrMsg(const std::string &response) const; + + // options passed to the algorithm + Action::Type m_action; + + // when submitting jobs + std::string m_runnablePath; + std::string m_jobOptions; + + // resource name + static const std::string m_SCARFComputeResource; + + // HTTP specifics for SCARF (IBM LSF PAC) + static std::string m_acceptType; + + // store for username-token pairs + static std::map m_tokenStash; +}; + +} // end namespace RemoteAlgorithms +} // end namespace Mantid +#endif /*REMOTE_SCARFTOMORECONSTRUCTION_H_*/ diff --git a/Code/Mantid/Framework/RemoteAlgorithms/src/SCARFTomoReconstruction.cpp b/Code/Mantid/Framework/RemoteAlgorithms/src/SCARFTomoReconstruction.cpp new file mode 100644 index 000000000000..ef3b37f441c8 --- /dev/null +++ b/Code/Mantid/Framework/RemoteAlgorithms/src/SCARFTomoReconstruction.cpp @@ -0,0 +1,1411 @@ +#include + +#include "MantidAPI/FileProperty.h" +#include "MantidAPI/WorkspaceFactory.h" +#include "MantidAPI/WorkspaceProperty.h" +#include "MantidKernel/ArrayProperty.h" +#include "MantidKernel/FacilityInfo.h" +#include "MantidKernel/InternetHelper.h" +#include "MantidKernel/ListValidator.h" +#include "MantidKernel/MandatoryValidator.h" +#include "MantidKernel/MaskedProperty.h" +#include "MantidKernel/NullValidator.h" +#include "MantidKernel/RemoteJobManager.h" +#include "MantidKernel/VisibleWhenProperty.h" +#include "MantidRemoteAlgorithms/SCARFTomoReconstruction.h" + +#include +#include +#include +#include +#include +#include +#include + +namespace Mantid { +namespace RemoteAlgorithms { + +// Register the algorithm into the AlgorithmFactory +DECLARE_ALGORITHM(SCARFTomoReconstruction) + +using namespace Mantid::Kernel; + +std::map + SCARFTomoReconstruction::m_tokenStash; + +std::string SCARFTomoReconstruction::m_acceptType = + "text/plain,application/xml,text/xml"; + +const std::string SCARFTomoReconstruction::m_SCARFComputeResource = "SCARF@STFC"; + +SCARFTomoReconstruction::SCARFTomoReconstruction(): + Mantid::API::Algorithm(), m_action() +{ } + +void SCARFTomoReconstruction::init() { + // list of all actions + std::vector actions; + actions.push_back("LogIn"); + actions.push_back("LogOut"); + actions.push_back("Ping"); + actions.push_back("Upload"); + actions.push_back("SubmitJob"); + actions.push_back("JobStatus"); + actions.push_back("JobStatusByID"); + actions.push_back("Download"); + actions.push_back("CancelJob"); + + auto listValue = boost::make_shared(actions); + auto nullV = boost::make_shared(); + + // Username always visible, it doesn't hurt and it is required to know the + // web service base URL for most LSF commands + auto requireStrValue = boost::make_shared>(); + declareProperty("UserName", "", requireStrValue, + "Name of the user to authenticate as", Direction::Input); + + // Action to perform + declareProperty("Action", "LogIn", listValue, "Choose the operation to perform " + "on the compute resource " + m_SCARFComputeResource, + Direction::Input); + + // - Action: login + declareProperty(new MaskedProperty("Password", "", + Direction::Input), + "The password for the user"); + setPropertySettings("Password", + new VisibleWhenProperty("Action", IS_EQUAL_TO, "LogIn")); + + // - Action: submit + declareProperty(new PropertyWithValue("RunnablePath", + "/work/imat/webservice_test/tomopy/imat_recon_FBP.py", + Direction::Input), + "The path (on the remote compute resource) of a file to run " + "(example: shell or python script)"); + setPropertySettings("RunnablePath", + new VisibleWhenProperty("Action", IS_EQUAL_TO, "SubmitJob")); + + declareProperty(new PropertyWithValue("JobOptions", + "/work/imat/webservice_test/remote_output/test_", + Direction::Input), + "Options for the job command line, application dependent. It " + "can include for example the NXTomo input file when using savu " + "for tomographic reconstruction."); + setPropertySettings("JobOptions", + new VisibleWhenProperty("Action", IS_EQUAL_TO, "SubmitJob")); + + // - Action: upload file + declareProperty(new API::FileProperty("FileToUpload", "", + API::FileProperty::OptionalLoad, "", + Direction::Input), + "Name of the file (local, full path) to upload to the compute " + "resource/server "); + setPropertySettings("FileToUpload", + new VisibleWhenProperty("Action", IS_EQUAL_TO, "Upload")); + + declareProperty(new PropertyWithValue("DestinationDirectory", + "/work/imat", + Direction::Input), + "Path where to upload the file on the compute resource/server"); + setPropertySettings("DestinationDirectory", + new VisibleWhenProperty("Action", IS_EQUAL_TO, "Upload")); + + // - Action: query status and info (of implicitly all jobs) + declareProperty(new ArrayProperty("RemoteJobsID", Direction::Output), + "ID strings for the jobs"); + declareProperty(new ArrayProperty("RemoteJobsNames", Direction::Output), + "Names of the jobs"); + declareProperty(new ArrayProperty("RemoteJobsStatus", Direction::Output), + "Strings describing the current status of the jobs"); + declareProperty(new ArrayProperty("RemoteJobsCommands", Direction::Output), + "Strings with the command line run for the jobs"); + + // - Action: query status and info by ID + declareProperty( + new PropertyWithValue("JobID", 0, Direction::Input), + "The ID of a job currently running or recently run on the " + "compute resource"); + setPropertySettings("JobID", new VisibleWhenProperty("Action", IS_EQUAL_TO, + "JobStatusByID")); + + declareProperty("RemoteJobName", "", nullV, "Name of the remote job", + Direction::Output); + declareProperty("RemoteJobStatus", "", nullV, "Current status of the job " + "(running, exited, etc.)", Direction::Output); + declareProperty("RemoteJobCommand", "", nullV, "Command line run remotely " + "for this job ", Direction::Output); + + // - Action: download file + declareProperty(new PropertyWithValue("RemoteJobFilename", "", + Direction::Input), + "Name of the job file to download - you can give an empty name " + "to download all the files of this job."); + setPropertySettings("RemoteJobFilename", + new VisibleWhenProperty("Action", IS_EQUAL_TO, "Download")); + + declareProperty(new API::FileProperty("LocalDirectory", "", + API::FileProperty::OptionalDirectory, "", + Direction::Input), + "Path to a local directory/folder where to download files from " + "the compute resource/server"); + setPropertySettings("LocalDirectory", + new VisibleWhenProperty("Action", IS_EQUAL_TO, "Download")); + + declareProperty(new PropertyWithValue("DownloadJobID", 0, + Direction::Input), + "ID of the job for which to download files. A job with this ID " + "must be running or have been run on the compute resource."); + setPropertySettings("DownloadJobID", + new VisibleWhenProperty("Action", IS_EQUAL_TO, "Download")); + + // - Action: cancel job by ID + declareProperty( + new PropertyWithValue("CancelJobID", 0, Direction::Input), + "The ID for a currently running job on " + m_SCARFComputeResource); + setPropertySettings("CancelJobID", + new VisibleWhenProperty("Action", IS_EQUAL_TO, + "CancelJob")); +} + +/** + * Execute algorithm: check what action/command has to be run and call + * specific methods. + * + * The implementation of the more specific methods is based on: + * Mantid::Kernel::InternetHelper. + */ +void SCARFTomoReconstruction::exec() { + + m_action = getAction(); + + g_log.information("Running SCARFTomoReconstruction"); + + // only action that doesn't require any credentials + if (Action::PING == m_action) { + doPing(); + return; + } + + // otherwise, check first username and then action-specific parameters + std::string username; + try { + username = getPropertyValue("UserName"); + } catch(std::runtime_error& /*e*/) { + g_log.error() << "To use this algorithm to perform the requested action " + "you need to give a valid username on the compute resource" + + m_SCARFComputeResource << std::endl; + throw; + } + // all actions that require at least a username + if (Action::LOGIN == m_action) { + std::string password; + try { + password = getPropertyValue("Password"); + } catch(std::runtime_error& /*e*/) { + g_log.error() << "To log in using this algorithm you need to give a " + "valid username and password on the compute resource " << + m_SCARFComputeResource << "." << std::endl; + throw; + } + if (password.empty()) { + throw std::runtime_error("You have given an empty password but the " + "current login mechanism on " + + m_SCARFComputeResource + " does not support " + "this. This may change in the future. For the " + "time being you need to provide a password."); + } + doLogin(username, password); + } else if (Action::LOGOUT == m_action) { + doLogout(username); + } else if (Action::SUBMIT == m_action) { + doSubmit(username); + } else if (Action::QUERYSTATUS == m_action) { + doQueryStatus(username); + } else if (Action::QUERYSTATUSBYID == m_action) { + std::string jobId; + try { + jobId = getPropertyValue("JobID"); + } catch(std::runtime_error& /*e*/) { + g_log.error() << "To query the detailed status of a job by its ID you " + "need to give the ID of a job running on " << + m_SCARFComputeResource << "." << std::endl; + throw; + } + doQueryStatusById(username, jobId); + } else if (Action::CANCEL == m_action) { + std::string jobId; + try { + jobId = getPropertyValue("CancelJobID"); + } catch(std::runtime_error& /*e*/) { + g_log.error() << "To cancel a job you need to give the ID of a job " + "running on " << m_SCARFComputeResource << "." << std::endl; + throw; + } + doCancel(username, jobId); + } else if (Action::UPLOAD == m_action) { + std::string filename, destDir; + try { + filename = getPropertyValue("FileToUpload"); + } catch(std::runtime_error& /*e*/) { + g_log.error() << "To upload a file you need to provide an existing " + "local file." << std::endl; + throw; + } + try { + destDir = getPropertyValue("DestinationDirectory"); + } catch(std::runtime_error& /*e*/) { + g_log.error() << "To upload a file you need to provide a destination " + "directory on " << m_SCARFComputeResource << "." << std::endl; + throw; + } + doUploadFile(username, destDir, filename); + } else if (Action::DOWNLOAD == m_action) { + std::string jobId, fname, localDir; + try { + jobId = getPropertyValue("DownloadJobID"); + } catch(std::runtime_error& /*e*/) { + g_log.error() << "To download a file you need to give the ID of a job " + "running on " << m_SCARFComputeResource << "." << std::endl; + throw; + } + try { + fname = getPropertyValue("RemoteJobFilename"); + } catch(std::runtime_error& /*e*/) { + g_log.error() << "To download a file you need to provide the name of a " + "file from the remote job." << std::endl; + throw; + } + try { + localDir = getPropertyValue("LocalDirectory"); + } catch(std::runtime_error& /*e*/) { + g_log.error() << "To download a file you need to provide a destination " + "(local) directory." << std::endl; + throw; + } + doDownload(username, jobId, fname, localDir); + } +} + +/** + * Log into SCARF. If it goes well, it will produce a token that can + * be reused for a while in subsequent queries. Internally it relies + * on the InternetHelper to send an HTTP request and obtain the + * response. + * + * @param username normally an STFC federal ID + * @param password user password + */ +void SCARFTomoReconstruction::doLogin(const std::string &username, + const std::string &password) { + // log into "https://portal.scarf.rl.ac.uk/cgi-bin/token.py"; + + // this should go away and obtained from 'computeResourceInfo' (like + // a very simple InstrumentInfo) or similar. What we need here is + // computeResourceInfo::baseURL() + const std::string SCARFLoginBaseURL = "https://portal.scarf.rl.ac.uk/"; + const std::string SCARFLoginPath = "/cgi-bin/token.py"; + + std::vector res = ConfigService::Instance().getFacility(). + computeResources(); + auto it = std::find(res.begin(), res.end(), m_SCARFComputeResource); + if (res.end() == it) + throw std::runtime_error(std::string("Failed to find a compute resource " + "for " + m_SCARFComputeResource + " (facility: " + + ConfigService::Instance().getFacility().name() + + ").")); + + std::string httpsURL = SCARFLoginBaseURL + SCARFLoginPath + "?username=" + + username + "&password=" + password; + int code; + std::stringstream ss; + try { + code = doSendRequestGetResponse(httpsURL, ss); + } catch (Kernel::Exception::InternetError& ie) { + throw std::runtime_error("Error while sending HTTP request to authenticate " + "(log in): " + std::string(ie.what())); + } + // We would check (Poco::Net::HTTPResponse::HTTP_OK == code) but the SCARF + // login script (token.py) seems to return 200 whatever happens, as far as the + // request is well formed. So this is how to know if authentication succeeded: + const std::string expectedSubstr = "https://portal.scarf.rl.ac.uk"; + std::string resp = ss.str(); + if (InternetHelper::HTTP_OK == code && + resp.find(expectedSubstr) != std::string::npos) { + // it went fine, stash cookie/token which looks like this (2 lines): + // https://portal.scarf.rl.ac.uk:8443/platform/ + // scarf362"2015-02-10T18:50:00Z"Mv2ncX8Z0TpH0lZHxMyXNVCb7ucT6jHNOx... + std::string url, token_str; + std::getline(ss, url); + std::getline(ss, token_str); + // note that the token needs a substring replace and a prefix, like this: + boost::replace_all(token_str, "\"", "#quote#"); + token_str = "platform_token=" + token_str; + // insert in the token stash + UsernameToken tok(username, Token(url, token_str)); + m_tokenStash.insert(tok); // the password is never stored + g_log.notice() << "Got authentication token. You are now logged into " + << m_SCARFComputeResource << std::endl; + } else { + throw std::runtime_error("Login failed. Please check your username and " + "password. Got this response: " + resp); + } +} + +/** + * Log out from SCARF. In practice, it trashes the cookie (if we were + * successfully logged in). + * + * @param username Username to use (should have authenticated before) + */ +void SCARFTomoReconstruction::doLogout(const std::string &username) { + auto it = m_tokenStash.find(username); + if (m_tokenStash.end() == it) { + throw std::runtime_error("Logout failed. You do not seem to be logged in. " + "I do not remember this username. Please check your " + "username."); + } + + // logout query, needs headers = {'Content-Type': 'text/plain', 'Cookie': token, + // 'Accept': 'text/plain,application/xml,text/xml'} + const std::string logoutPath = "webservice/pacclient/logout/"; + const std::string baseURL = it->second.m_url; + const std::string token = it->second.m_token_str; + + std::string httpsURL = baseURL + logoutPath; + StringToStringMap headers; + headers.insert(std::pair("Content-Type", + "text/plain")); + headers.insert(std::pair("Cookie", token)); + headers.insert(std::pair("Accept", m_acceptType)); + int code; + std::stringstream ss; + try { + code = doSendRequestGetResponse(httpsURL, ss, headers); + } catch (Kernel::Exception::InternetError& ie) { + throw std::runtime_error("Error while sending HTTP request to log out: " + + std::string(ie.what())); + } + if (Poco::Net::HTTPResponse::HTTP_OK == code) { + g_log.notice() << "Logged out." << std::endl; + g_log.debug() << "Response from server: " << ss.str() << std::endl; + } else { + throw std::runtime_error("Failed to logout from the web service at: " + + httpsURL + ". Please check your username."); + } + + // successfully logged out, forget the token + m_tokenStash.erase(it); +} + +/** + * Submits a job to SCARF. The different ways jobs could be submitted + * (supported toolkits, LSF PAC submission forms, launcher scripts, + * supported options, etc.) are not well defined at the moment. + * + * @param username Username to use (should have authenticated before) + */ +void SCARFTomoReconstruction::doSubmit(const std::string &username) { + auto it = m_tokenStash.find(username); + if (m_tokenStash.end() == it) { + throw std::runtime_error("Job submission failed. You do not seem to be logged " + "in. I do not remember this username. Please check " + "your username."); + } + + // Not sure at this point if there could be commands without options + // For the time being it's possible. + std::string jobOptions = ""; + try { + jobOptions = getPropertyValue("JobOptions"); + } catch(std::runtime_error& /*e*/) { + g_log.warning() << "You did not specify any options for the job. Maybe you " + "forgot to pass the options?" << std::endl; + m_jobOptions = ""; + } + + std::string runnablePath = ""; + try { + runnablePath = getPropertyValue("RunnablePath"); + } catch(std::runtime_error& /*e*/) { + g_log.error() << "You did not specify a the path to the parameter file " + "which is required to create a new reconstruction job. Please provide " + "a valid tomography reconstruction parameter file" << std::endl; + throw; + } + + progress(0, "Starting job..."); + + // Job submit query, requires specific parameters for LSF submit + // Example params passed to python submit utility: + // $ pacclient.py submit --app TOMOPY_0_0_3 --param "INPUT_FILE= + // /work/imat/webservice_test/tomopy/imat_recon_FBP.py;INPUT_ARGS= + // /work/imat/scripts/test_;JOB_NAME=01_test_job;OUTPUT_FILE=%J.output;ERROR_FILE= + // %J.error" + const std::string appName = "TOMOPY_0_0_3"; + // this gets executed (for example via 'exec' or 'python', depending on the appName + const std::string boundary = "bqJky99mlBWa-ZuqjC53mG6EzbmlxB"; + const std::string &body = buildSubmitBody(appName, boundary, + runnablePath, jobOptions); + + // Job submit, needs these headers: + // headers = {'Content-Type': 'multipart/mixed; boundary='+boundary, + // 'Accept': 'text/xml,application/xml;', 'Cookie': token, + // 'Content-Length': str(len(body))} + // Content-Length is added by InternetHelper/Poco HTTP request + const std::string submitPath = "webservice/pacclient/submitapp"; + const std::string baseURL = it->second.m_url; + const std::string token = it->second.m_token_str; + + std::string httpsURL = baseURL + submitPath; + StringToStringMap headers; + headers.insert(std::pair("Content-Type", + "multipart/mixed; boundary=" + + boundary)); + headers.insert(std::pair("Accept", m_acceptType)); + headers.insert(std::pair("Cookie", token)); + int code; + std::stringstream ss; + try { + code = doSendRequestGetResponse(httpsURL, ss, headers, + Poco::Net::HTTPRequest::HTTP_POST, body); + } catch (Kernel::Exception::InternetError& ie) { + throw std::runtime_error("Error while sending HTTP request to submit a job: " + + std::string(ie.what())); + } + if (Poco::Net::HTTPResponse::HTTP_OK == code) { + std::string resp = ss.str(); + if (std::string::npos != resp.find("")) { + g_log.warning() << "Submitted job but got a a response that seems to contain " + "an error message from " << m_SCARFComputeResource << ": " << + extractPACErrMsg(ss.str()) << std::endl; + } else { + g_log.notice() << "Submitted job successfully." << std::endl; + g_log.debug() << "Response from server: " << resp << std::endl; + } + } else { + throw std::runtime_error("Failed to submit a job through the web service at:" + + httpsURL + ". Please check your username, credentials, " + "and parameters."); + } + + progress(1.0, "Job started on " + m_SCARFComputeResource); +} + +/** + * Query the status of jobs running (if successful will return info on + * jobs running for our user) + * + * @param username Username to use (should have authenticated before) + */ +void SCARFTomoReconstruction::doQueryStatus(const std::string &username) { + auto it = m_tokenStash.find(username); + if (m_tokenStash.end() == it) { + throw std::runtime_error("Job status query failed. You do not seem to be logged " + "in. I do not remember this username. Please check " + "your username."); + } + + progress(0, "Checking the status of jobs..."); + + // Job query status, needs these headers: + // headers = {'Content-Type': 'application/xml', 'Cookie': token, + // 'Accept': ACCEPT_TYPE} + const std::string jobStatusPath = "webservice/pacclient/jobs?"; + const std::string baseURL = it->second.m_url; + const std::string token = it->second.m_token_str; + + std::string httpsURL = baseURL + jobStatusPath; + StringToStringMap headers; + headers.insert(std::pair("Content-Type", + "application/xml")); + headers.insert(std::pair("Accept", m_acceptType)); + headers.insert(std::pair("Cookie", token)); + int code; + std::stringstream ss; + try { + code = doSendRequestGetResponse(httpsURL, ss, headers); + } catch (Kernel::Exception::InternetError& ie) { + throw std::runtime_error("Error while sending HTTP request to query the status " + "of jobs: " + std::string(ie.what())); + } + if (Poco::Net::HTTPResponse::HTTP_OK == code) { + std::string resp = ss.str(); + if (std::string::npos != resp.find("") && + std::string::npos != resp.find("")) { + genOutputStatusInfo(resp); + g_log.notice() << "Queried the status of jobs and stored the " + "information in output properties." << std::endl; + } else { + g_log.warning() << "Queried the status of jobs but got what looks " + "like an error message as response: " << resp << std::endl; + } + g_log.notice() << "Queried job status successfully." << std::endl; + g_log.debug() << "Response from server: " << resp << std::endl; + } else { + throw std::runtime_error("Failed to obtain job status information through the " + "web service at:" + httpsURL + ". Please check your " + "username, credentials, and parameters."); + } + + progress(1.0, "Status of jobs retrived."); +} + +/** + * Query the status of jobs running (if successful will return info on + * jobs running for our user) + * + * @param username Username to use (should have authenticated before) + * @param jobId Identifier of a job as used by the job scheduler (integer number) + */ +void SCARFTomoReconstruction::doQueryStatusById(const std::string &username, + const std::string &jobId) { + auto it = m_tokenStash.find(username); + if (m_tokenStash.end() == it) { + throw std::runtime_error("Job status query failed. You do not seem to be logged " + "in. I do not remember this username. Please check " + "your username."); + } + + progress(0, "Checking the status of job with Id " + jobId); + + // Job query status, needs these headers: + // headers = {'Content-Type': 'application/xml', 'Cookie': token, + // 'Accept': ACCEPT_TYPE} + const std::string jobIdStatusPath = "webservice/pacclient/jobs/"; + const std::string baseURL = it->second.m_url; + const std::string token = it->second.m_token_str; + + std::string httpsURL = baseURL + jobIdStatusPath; + StringToStringMap headers; + headers.insert(std::pair("Content-Type", + "application/xml")); + headers.insert(std::pair("Accept", m_acceptType)); + headers.insert(std::pair("Cookie", token)); + int code; + std::stringstream ss; + try { + code = doSendRequestGetResponse(httpsURL, ss, headers); + } catch (Kernel::Exception::InternetError& ie) { + throw std::runtime_error("Error while sending HTTP request to query the status " + "of a job: " + std::string(ie.what())); + } + if (Poco::Net::HTTPResponse::HTTP_OK == code) { + std::string resp = ss.str(); + if (std::string::npos != resp.find("") && + std::string::npos != resp.find("")) { + genOutputStatusInfo(resp, jobId); + g_log.notice() << "Queried job status (Id " << jobId << ") and stored " + "information into output properties." << std::endl; + g_log.debug() << "Response from server: " << resp << std::endl; + } else { + g_log.warning() << "Queried job status (Id " << jobId << " ) but got what " + "looks like an error message as response: " << resp << std::endl; + } + } else { + throw std::runtime_error("Failed to obtain job (Id:" + jobId +" ) status " + "information through the web service at:" + httpsURL + + ". Please check your username, credentials, and " + "parameters."); + } + + progress(1.0, "Status of job " + jobId + "retrived."); +} + +/** + * Ping the server to see if the web service is active/available. + * + * @return true if the web service responds. + */ +bool SCARFTomoReconstruction::doPing() { + progress(0, "Pinging compute resource " + m_SCARFComputeResource); + + // Job ping, needs these headers: + // headers = {'Content-Type': 'application/xml', 'Accept': ACCEPT_TYPE} + const std::string pingPath = "platform/webservice/pacclient/ping/"; + // This could be retrieved from facilities or similar + // (like SCARFLoginBaseURL above) - TODO: clarify that in Facilities.xml + // the port number is known only after logging in + const std::string baseURL = "https://portal.scarf.rl.ac.uk:8443/"; + + std::string httpsURL = baseURL + pingPath; + StringToStringMap headers; + headers.insert(std::pair("Content-Type", + "application/xml")); + headers.insert(std::pair("Accept", m_acceptType)); + int code; + std::stringstream ss; + try { + code = doSendRequestGetResponse(httpsURL, ss, headers); + } catch (Kernel::Exception::InternetError& ie) { + throw std::runtime_error("Error while sending HTTP request to ping the " + "server " + std::string(ie.what())); + } + bool ok = false; + if (Poco::Net::HTTPResponse::HTTP_OK == code) { + std::string resp = ss.str(); + if (std::string::npos != resp.find("Web Services are ready")) { + g_log.notice() << "Pinged compute resource with apparently good response: " + << resp << std::endl; + ok = true; + } else { + g_log.warning() << "Pinged compute resource but got what looks like an " + "error message: " << resp << std::endl; + } + } else { + throw std::runtime_error("Failed to ping the web service at:" + httpsURL + + ". Please check your parameters, software version, " + "etc."); + } + + progress(1.0, "Ping compute resource " + m_SCARFComputeResource + " done."); + + return ok; +} + +/** + * Cancel a submitted job, identified by its ID in the job queue. + * + * @param username Username to use (should have authenticated before) + * @param jobId Identifier of a job as used by the job scheduler (integer number) + */ +void SCARFTomoReconstruction::doCancel(const std::string &username, + const std::string &jobId) { + auto it = m_tokenStash.find(username); + if (m_tokenStash.end() == it) { + throw std::runtime_error("Job status query failed. You do not seem to be logged " + "in. I do not remember this username. Please check " + "your username."); + } + + progress(0, "Cancelling/killing job " + jobId); + + // Job kill, needs these headers: + // headers = {'Content-Type': 'text/plain', 'Cookie': token, 'Accept': ACCEPT_TYPE} + const std::string killPath = "webservice/pacclient/jobOperation/kill/" + jobId; + const std::string baseURL = it->second.m_url; + const std::string token = it->second.m_token_str; + + std::string httpsURL = baseURL + killPath; + StringToStringMap headers; + headers.insert(std::pair("Content-Type", + "application/xml")); + headers.insert(std::pair("Cookie", token)); + headers.insert(std::pair("Accept", m_acceptType)); + int code; + std::stringstream ss; + try { + code = doSendRequestGetResponse(httpsURL, ss, headers); + } catch (Kernel::Exception::InternetError& ie) { + throw std::runtime_error("Error while sending HTTP request to cancel a job: " + + std::string(ie.what())); + } + if (Poco::Net::HTTPResponse::HTTP_OK == code) { + std::string resp = ss.str(); + if (std::string::npos != resp.find("")) { + g_log.warning() << "Killed job with Id" << jobId << " but got what looks like an " + "error message as response: " << extractPACErrMsg(resp) << std::endl; + } else if (std::string::npos != resp.find("")) { + g_log.notice() << "Killed job with Id" << jobId << "." << std::endl; + g_log.debug() << "Response from server: " << resp << std::endl; + } else { + g_log.warning() << "Killed job with Id" << jobId << " but got what a response " + "that I do not recognize: " << resp << std::endl; + } + } else { + throw std::runtime_error("Failed to kill job (Id: " + jobId +" ) through the web " + "service at:" + httpsURL + ". Please check your " + "existing jobs, username, and parameters."); + } + + progress(1.0, "Killed job with Id " + jobId + "."); +} + +/** + * Upload a file to a directory on the server. + * + * @param username Username to use (should have authenticated before) + * @param destDir Destination directory on the server + * @param filename File name of the local file to upload + */ +void SCARFTomoReconstruction::doUploadFile(const std::string &username, + const std::string &destDir, + const std::string &filename) { + auto it = m_tokenStash.find(username); + if (m_tokenStash.end() == it) { + throw std::runtime_error("File upload failed. You do not seem to be logged " + "in. I do not remember this username. Please check " + "your username."); + } + + progress(0, "Uploading file: " + filename); + + // File upload, needs these headers: + // headers = {'Content-Type': 'multipart/mixed; boundary='+boundary, + // 'Accept': 'text/plain;', 'Cookie': token, + // 'Content-Length': str(len(body))} + // Content-Length is added by InternetHelper/Poco HTTP request + // The 0 at the end of the upload path is 'jobId' 0, if a jobId is given the + // upload goes to a path relative to the job path. + const std::string uploadPath = "webservice/pacclient/upfile/0"; + const std::string boundary = "4k89ogja023oh1-gkdfk903jf9wngmujfs95m"; + const std::string baseURL = it->second.m_url; + const std::string token = it->second.m_token_str; + + InternetHelper session; + std::string httpsURL = baseURL + uploadPath; + StringToStringMap headers; + headers.insert(std::pair("Content-Type", + "multipart/mixed; boundary=" + + boundary)); + headers.insert(std::pair("Accept", m_acceptType)); + headers.insert(std::pair("Cookie", token)); + + const std::string &body = buildUploadBody(boundary, destDir, filename); + int code; + std::stringstream ss; + try { + code = doSendRequestGetResponse(httpsURL, ss, headers, + Poco::Net::HTTPRequest::HTTP_POST, body); + } catch (Kernel::Exception::InternetError& ie) { + throw std::runtime_error("Error while sending HTTP request to upload a file: " + + std::string(ie.what())); + } + if (Poco::Net::HTTPResponse::HTTP_OK == code) { + std::string resp = ss.str(); + g_log.notice() << "Uploaded file, response from server: " << resp << std::endl; + } else { + throw std::runtime_error("Failed to upload file through the web service at:" + + httpsURL + ". Please check your username, credentials, " + "and parameters."); + } + + progress(1.0, "File uploaded to " + m_SCARFComputeResource); +} + +/** + * Download a file or a set of files from a remote job into a local + * directory. Note that this download as supported by LSF at SCARF is + * job-specific: you download a file from a job and not a file in the + * file system in general. When downloading multiple files this action + * requires two steps: one first HTTP request to get the remote + * path(s) for all the job file(s), and a second request or series of + * requests to actually download the file(s). + * + * @param username Username to use (should have authenticated before) + * @param jobId Identifier of a job as used by the job scheduler (integer number) + * @param fname File name (of a job file on the compute resource). If no name is + * given then all the job files are downloaded into localDir + * @param localDir Local directory where to download the file(s) + */ +void SCARFTomoReconstruction::doDownload(const std::string &username, + const std::string &jobId, + const std::string &fname, + const std::string &localDir) { + auto it = m_tokenStash.find(username); + if (m_tokenStash.end() == it) { + throw std::runtime_error("File upload failed. You do not seem to be logged " + "in. I do not remember this username. Please check " + "your username."); + } + + progress(0, "Downloading file: " + fname + " in " + localDir); + + if (fname.empty()) { + // no/empty name implies we want all the files of a remote job + getAllJobFiles(jobId, localDir, it->second); + } else { + // name given, so we directly download this single file + getOneJobFile(jobId, fname, localDir, it->second); + } +} + +/** + * Send the HHTP(S) request required to perform one of the actions. + * + * @param url Full URL, including request string + * @param rss Response body stream + * @param headers HTTP headers given as key-value pairs + * @param method By default GET (Poco::Net::HTTPRequest::HTTP_POST), also accepts + * POST (Poco::Net::HTTPRequest::HTTP_POST) + * @param body HTTP message body + * + * @return HTTP(S) response code + */ +int SCARFTomoReconstruction::doSendRequestGetResponse(const std::string &url, + std::ostream &rss, + const StringToStringMap + &headers, + const std::string &method, + const std::string &body) { + InternetHelper session; + + std::string ContTypeName = "Content-Type"; + auto it = headers.find(ContTypeName); + if (headers.end() != it) { + session.setContentType(it->second); + } + session.headers() = headers; + if (!method.empty()) + session.setMethod(method); + if (!body.empty()) { + session.setBody(body); + // beware, the inet helper will set method=POST if body not empty! + // But here, for example to download, we need a GET with non-empty body + if (Poco::Net::HTTPRequest::HTTP_GET == method) { + session.setMethod(method); + } + } + return session.sendRequest(url, rss); +} + +/** + * Adds one param to a submit request body (first argument). This is + * part of a multipart body content. + * + * @param body Body string being built for an HTTP request + * @param boundary Boundary string between parameters, for request encoding + * @param paramName Name of a parameter, for example INPUT_FILE + * @param paramVal Value of the parameter + */ +void SCARFTomoReconstruction::encodeParam(std::string &body, + const std::string &boundary, + const std::string ¶mName, + const std::string ¶mVal) { + body += "--" + boundary + "\r\n"; + body += "Content-Disposition: form-data; name=\"" + paramName + "\"\r\n"; + body += "Content-Type: application/xml; charset=US-ASCII\r\n"; + body += "Content-Transfer-Encoding: 8bit\r\n"; + body += "\r\n"; + body += "" +paramName+ "" + + paramVal + "\r\n"; +} + +/** + * Tiny helper to generate an integer sequence number for the job + * names. + */ +int seqNo() { + static int s = 1; + return s++; +} + +/** + * Helper method to do the somewhat ugly encoding of parameters for + * submit requests. + * + * @param appName A registered app name/form form SCARF, example: TOMOPY_0_0_3 + * @param boundary Boundary string between parts of the multi-part body + * @param inputFile Input file parameter, this file will be run + * @param inputArgs Arguments to the command (application specific) + * + * @return A string ready to be used as body of a 'job submit' HTTP request + */ +std::string SCARFTomoReconstruction::buildSubmitBody(const std::string &appName, + const std::string &boundary, + const std::string &inputFile, + const std::string &inputArgs) { + // BLOCK: start and encode app name like this: + // --bqJky99mlBWa-ZuqjC53mG6EzbmlxB + // Content-Disposition: form-data; name="AppName" + // Content-ID: + // + // TOMOPY_0_0_3 + std::string body = "--" + boundary + "\r\n"; + body += "Content-Disposition: form-data; name=\"AppName\"\r\n" + "Content-ID: \r\n" + "\r\n" + + appName + "\r\n"; + + // BLOCK: encode params head like this: + // --bqJky99mlBWa-ZuqjC53mG6EzbmlxB + // Content-Disposition: form-data; name="data" + // Content-Type: multipart/mixed; boundary=_Part_1_701508.1145579811786 + // Content-ID: + // + body += "--" + boundary + "\r\n"; + const std::string boundaryInner = "_Part_1_701508.1145579811786"; + body += "Content-Disposition: form-data; name=\"data\"\r\n"; + body += "Content-Type: multipart/mixed; boundary=" + boundaryInner + "\r\n"; + body += "Content-ID: \r\n"; + body += "\r\n"; + + // BLOCKS: encode params like this: + { + // BLOCK: encode INPUT_ARGS like this: + // --_Part_1_701508.1145579811786 + // Content-Disposition: form-data; name="INPUT_ARGS" + // Content-Type: application/xml; charset=US-ASCII + // Content-Transfer-Encoding: 8bit + // INPUT_ARGS + // /work/imat/scripts/test_ + encodeParam(body, boundaryInner, "INPUT_ARGS", inputArgs); + } + { + // BLOCK: encode OUTPUT_FILE like this: + // --_Part_1_701508.1145579811786 + // Content-Disposition: form-data; name="OUTPUT_FILE" + // Content-Type: application/xml; charset=US-ASCII + // Content-Transfer-Encoding: 8bit + // OUTPUT_FILE%J.output + // + encodeParam(body, boundaryInner, "OUTPUT_FILE", "%J.output"); + } + { + // BLOCK: encode ERROR_FILE like this: + // --_Part_1_701508.1145579811786 + // Content-Disposition: form-data; name="ERROR_FILE" + // Content-Type: application/xml; charset=US-ASCII + // Content-Transfer-Encoding: 8bit + // ERROR_FILE%J.error + // + encodeParam(body, boundaryInner, "ERROR_FILE", "%J.error"); + } + { + // BLOCK: encode JOB_NAME like this: + // --_Part_1_701508.1145579811786 + // Content-Disposition: form-data; name="JOB_NAME" + // Content-Type: application/xml; charset=US-ASCII + // Content-Transfer-Encoding: 8bit + // JOB_NAMEfoo + encodeParam(body, boundaryInner, "JOB_NAME", "Mantid_tomography_" + + boost::lexical_cast(seqNo())); + } + { + // BLOCK: encode INPUT_FILE (this is what will be run, + // if appName=TOMOPY_0_0_3) like this: + // --_Part_1_701508.1145579811786 + // Content-Disposition: form-data; name="INPUT_FILE" + // Content-Type: application/xml; charset=US-ASCII + // Content-Transfer-Encoding: 8bit + // INPUT_FILE + // /work/imat/webservice_test/tomopy/imat_recon_FBP.py + // + encodeParam(body, boundaryInner, "INPUT_FILE", inputFile); + } + // BLOCK: params end like this: + // --_Part_1_701508.1145579811786-- + // + body += "--" + boundaryInner + "--\r\n\r\n"; + + // BLOCK: end like this: + body += "--" + boundary + "--\r\n\r\n"; + + return body; +} + +/** + * Helper method to encode the body of file upload requests. + * + * @param boundary Boundary string between parts of the multi-part body + * @param destDir Path where to upload the file on the remote compute resource/server + * @param filename Name (path) of the local file to upload + * + * @return A string ready to be used as body of a 'file upload' HTTP request + */ +std::string SCARFTomoReconstruction::buildUploadBody(const std::string &boundary, + const std::string &destDir, + const std::string &filename) { + // build file name as given in the request body + std::string upName = filename; + std::replace(upName.begin(), upName.end(), '\\', '/'); + // discard up to last / (path) + upName = upName.substr(upName.rfind("/") + 1); + + // BLOCK: start and encode destination directory like this: + // --4k89ogja023oh1-gkdfk903jf9wngmujfs95m + // Content-Disposition: form-data; name="DirName" + // Content-ID: + // + // /work/imat/foo_test + std::string body = "--" + boundary + "\r\n"; + body += "Content-Disposition: form-data; name=\"DirName\"\r\n" + "Content-ID: \r\n" + "\r\n" + + destDir + "\r\n"; + + // BLOCK: encode file like this (could be repeated for multi-file uploads): + // --4k89ogja023oh1-gkdfk903jf9wngmujfs95m + // Content-Disposition: form-data; name="bar.txt"; filename=bar.txt + // Content-Type: application/octet-stream + // Content-ID: + // + body += "--" + boundary + "\r\n"; + body += "Content-Disposition: form-data; name=\"" + upName +"\"\r\n"; + body += "Content-Type: application/octet-stream \r\n"; + body += "Content-Transfer-Encoding: UTF-8\r\n"; + body += "Content-ID: <" + upName + ">\r\n"; + body += "\r\n"; + + // BLOCK: the file + std::ifstream fileStream(filename.c_str(), std::ios_base::binary | + std::ios_base::in); + Poco::StreamCopier::copyToString(fileStream, body); + + // BLOCK: end like this: + body += "--" + boundary + "--" + "\r\n\r\n"; + + return body; +} + +/** + * Fills in a table workspace with job status information from an LSC + * PAC response in ~xml format. Assumes that the workspace passed is + * empty and ready to be filled. This guarantees that a non-null (I) + * table workspace object is returned. + * + * @param resp Body of an HHTP response to a status query + * @param jobIDFilter ID of one job (empty string immplies all jobs) + */ +void SCARFTomoReconstruction::genOutputStatusInfo(const std::string &resp, + const std::string &jobIDFilter) +{ + Poco::XML::DOMParser parser; + Poco::AutoPtr doc; + try { + doc = parser.parseString(resp); + } catch (Poco::Exception &e) { + throw std::runtime_error("Unable to parse response in XML format: " + + e.displayText()); + } catch (std::exception &e) { + throw std::runtime_error("Unable to parse response in XML format: " + + std::string(e.what())); + } + + Poco::XML::Element *pRootElem = doc->documentElement(); + if (!pRootElem || !pRootElem->hasChildNodes()) { + g_log.error("XML response from compute resouce contains no root element."); + throw std::runtime_error("No root element was found in XML response, " + "cannot parse it."); + } + + Poco::AutoPtr jobs = pRootElem->getElementsByTagName("Job"); + if (!jobs) { + g_log.error("XML response from compute resouce contains no root element."); + throw std::runtime_error("No root element was found in XML response, " + "cannot parse it."); + } + + size_t n = jobs->length(); + if (0 == jobs->length()) { + g_log.notice() << "Got information about 0 jobs. You may not have any jobs " + "currently running on the compute resource. The output workspace will not " + "have any rows/information"; + } + + // This is the information that is usually available for running/recently + // run jobs + std::vector jobIds; + std::vector jobNames; + std::vector jobStatus; + std::vector jobCommands; + for (size_t i = 0; i < n; i++) { + Poco::XML::Element *el = static_cast(jobs->item( + static_cast(i))); + if (!el) + throw std::runtime_error("Error while trying to parse job with index " + + boost::lexical_cast(i) + + "could not produce a complete table workspace."); + + Poco::XML::Element *id = el->getChildElement("id"); + if (id) { + const std::string &IdStr = id->innerText().c_str(); + if (!jobIDFilter.empty() && IdStr != jobIDFilter) + continue; + + jobIds.push_back(IdStr); + } + + Poco::XML::Element *name = el->getChildElement("name"); + if (name) { + jobNames.push_back(name->innerText().c_str()); + } else { + jobNames.push_back("Unknown!"); + } + + Poco::XML::Element *status = el->getChildElement("status"); + if (status) { + jobStatus.push_back(status->innerText().c_str()); + } else { + jobStatus.push_back("Unknown!"); + } + + Poco::XML::Element *cmd = el->getChildElement("cmd"); + if (cmd) { + jobCommands.push_back(cmd->innerText().c_str()); + } else { + jobCommands.push_back("Unknown!"); + } + } + + if ( jobIds.size() != jobNames.size() || jobIds.size() != jobStatus.size() || + jobIds.size() != jobCommands.size() ) { + throw std::runtime_error("There was an unexpected error while filling output " + "properties the information retrieved from the remote " + "compute resource. Failed to assign properties."); + } + if (jobIDFilter.empty()) { + // multi-job query + setProperty("RemoteJobsID", jobIds); + setProperty("RemoteJobsNames", jobNames); + setProperty("RemoteJobsStatus", jobStatus); + setProperty("RemoteJobsCommands", jobCommands); + } else { + // Single job query. Here the job ID is an input + if (0 == jobIds.size()) { + setProperty("RemoteJobName", "Unknown!"); + setProperty("RemoteJobStatus", "Unknown!"); + setProperty("RemoteJobCommand", "Unknown!"); + } else { + setProperty("RemoteJobName", jobNames.front()); + setProperty("RemoteJobStatus", jobStatus.front()); + setProperty("RemoteJobCommand", jobCommands.front()); + } + } +} + +/** + * Gets action code in m_action, if input argument is valid. Otherwise + * show error message and get undefined action. + * + * @return A valid action code (including 'undefined' code, if action + * not known). + */ +SCARFTomoReconstruction::Action::Type SCARFTomoReconstruction::getAction() { + std::string par = getPropertyValue("Action"); + Action::Type act = Action::UNDEF; + if (par == "LogIn") { + act = Action::LOGIN; + } else if (par == "LogOut") { + act = Action::LOGOUT; + } else if (par == "SubmitJob") { + act = Action::SUBMIT; + } else if (par == "JobStatus") { + act = Action::QUERYSTATUS; + } else if (par == "JobStatusByID") { + act = Action::QUERYSTATUSBYID; + } else if (par == "Ping") { + act = Action::PING; + } else if (par == "CancelJob") { + act = Action::CANCEL; + } else if (par == "Upload") { + act = Action::UPLOAD; + } else if (par == "Download") { + act = Action::DOWNLOAD; + } else { + g_log.error() << "Unknown action specified: '" << + m_action << "', ignoring it."; + } + return act; +} + +/** + * Helper to check if it's possible to write an output file and give + * informative messages. + * + * @param localPath Destination directory + * @param fname Name of the file being downloaded + * + * @return The full patch checked + */ +const std::string +SCARFTomoReconstruction::checkDownloadOutputFile(const std::string &localPath, + const std::string &fname) + const { + std::string outName = localPath + "/" + fname; + Poco::File f(outName); + if (f.exists()) { + if (f.canWrite()) { + g_log.notice() << "Overwriting output file: " << outName << std::endl; + } else { + g_log.warning() << "It is not possible to write into the output file: " + << outName << ", you may not have the required " + "permissions. Please check." << std::endl; + } + } + return f.path(); +} + +/** + * Turns the esoteric name used in LSF PAC web service into a normal + * filename (as a basename + extention, discarding the path to + * it). For example, this method translates: + * 'PAC Server* /home/isisg/scarf362/../scarf362/ + * Mantid_tomography_1_1423743450375PtlPj/417666.error*FILE*281*true' + * into '417666.error'. + * + * @param PACName A file name specification as returned by PAC LSF + * when downloading multiple files from jobs + * + * @return A filename ready to be used to save the file locally. Empty + * string if fails. + */ +const std::string +SCARFTomoReconstruction::filterPACFilename(const std::string PACName) const { + // discard up to last / (path) + std::string name = PACName.substr(PACName.rfind("/") + 1); + // remove trailing parameters + size_t ast = name.find("*"); + name.replace(ast, std::string::npos, ""); + return name; +} + +/** + * Download a job file once we have obtained the remote path. + * + * @param jobId Identifier of a job as used by the job scheduler (integer number) + * @param remotePath File name (of a job file on the compute resource) + * @param localPath Local path where to download the file (already checked) + * @param t Authentication token/cookie including url+string + */ +void SCARFTomoReconstruction::getOneJobFile(const std::string &jobId, + const std::string &remotePath, + const std::string &localPath, + const Token &t) +{ + // Job download (one) file once we know the remote path, needs these headers: + // headers = {'Content-Type': 'text/plain', 'Cookie': token, 'Accept': ACCEPT_TYPE} + // - and as request body the name of the file + const std::string downloadOnePath = "webservice/pacclient/file/" + jobId; + const std::string baseURL = t.m_url; + const std::string token = t.m_token_str; + + std::string httpsURL = baseURL + downloadOnePath; + + StringToStringMap headers; + headers.insert(std::pair("Content-Type", + "application/xml")); + headers.insert(std::pair("Cookie", token)); + headers.insert(std::pair("Accept", m_acceptType)); + std::string body = remotePath; + int code; + std::stringstream ss; + try { + code = doSendRequestGetResponse(httpsURL, ss, headers, + Poco::Net::HTTPRequest::HTTP_GET, body); + } catch (Kernel::Exception::InternetError& ie) { + throw std::runtime_error("Error while sending HTTP request to download a file: " + + std::string(ie.what())); + } + if (Poco::Net::HTTPResponse::HTTP_OK == code) { + // this is what indicates success/failure: response content empty/not empty + if (ss.rdbuf()->in_avail() > 0) { + // check file is writeable and inform user + // get basename from 'PAC' name + std::string name = filterPACFilename(remotePath); + if (name.empty()) { + g_log.notice() << "Could not download remote file " << remotePath << + " into " << localPath << ", a problem with its name was found" << + std::endl; + } + std::string outName = checkDownloadOutputFile(localPath, name); + std::ofstream file(outName. c_str(), std::ios_base::binary | std::ios_base::out); + Poco::StreamCopier::copyStream(ss, file); + g_log.notice() << "Downloaded remote file " << outName << " into " << + localPath << "." << std::endl; + // do this only if you want to log the file contents! + // g_log.debug() << "Response from server: " << ss.str() << std::endl; + } else { + // log an error but potentially continue with other files + g_log.error() << "Download failed. You may not have the required permissions " + "or the file may not be available on " << m_SCARFComputeResource << ": " << + remotePath << std::endl; + } + } else { + throw std::runtime_error("Failed to download a file for job Id:" + jobId + + " through the web service at:" + httpsURL + ". Please " + "check your existing jobs, username, and parameters."); + } +} + +/** + * Download all files for a remote job. + * + * @param jobId Identifier of a job as used by the job scheduler (integer number) + * @param localDir Local directory where to download the file (already checked) + * @param t Authentication token/cookie including url+string + */ +void SCARFTomoReconstruction::getAllJobFiles(const std::string &jobId, + const std::string &localDir, + const Token &t) +{ + // Job download (multiple) files, needs these headers: + // headers = {'Content-Type': 'text/plain', 'Cookie': token, 'Accept': ACCEPT_TYPE} + const std::string downloadPath = "webservice/pacclient/jobfiles/" + jobId; + const std::string baseURL = t.m_url; + const std::string token = t.m_token_str; + + std::string httpsURL = baseURL + downloadPath; + StringToStringMap headers; + headers.insert(std::pair("Content-Type", + "application/xml")); + headers.insert(std::pair("Cookie", token)); + headers.insert(std::pair("Accept", m_acceptType)); + int code; + std::stringstream ss; + try { + code = doSendRequestGetResponse(httpsURL, ss, headers); + } catch (Kernel::Exception::InternetError& ie) { + throw std::runtime_error("Error while sending HTTP request to download files: " + + std::string(ie.what())); + } + // what you get in this response is one line with text like this: + // 'PAC Server*/home/isisg/scarf362/../scarf362/ + // Mantid_tomography_1_1423743450375PtlPj/417666.error*FILE*281*true;PAC Server*/ + // home/isisg/scarf362/../scarf362/ + // Mantid_tomography_1_1423743450375PtlPj/417666.output*FILE*1145*true;' + // (the number between *FILE* and *true is the size in bytes) + std::vector filePACNames; + if (Poco::Net::HTTPResponse::HTTP_OK == code) { + std::string resp = ss.str(); + // this is what indicates success/failure: presence of '/' or '\' + if (std::string::npos != resp.find('/') || + std::string::npos != resp.find('\\')) { + // you can get multiple files, as remote file names listed separated by ';' + std::string PACname; + while (std::getline(ss, PACname, ';')) { + filePACNames.push_back(PACname); + } + for (size_t i=0; i(filePACNames.size()) + + " file(s) completed in " + localDir); +} + +/** + * Gets the error message from a more or less xml response body. Sometimes these error + * responses may read like this: + * + * Job <417940>: Job has already finished0 + * + * @param response Body of an HHTP response that apparently contains some error message + * + * @return Part of the response that seems to contain the specific error message + */ +std::string SCARFTomoReconstruction::extractPACErrMsg(const std::string &response) const { + // discard up to last errMsg start tag + const std::string openTag = ""; + std::string msg = response.substr(response.rfind(openTag) + openTag.size()); + if (msg.empty()) + return response; + + // remove close tags + size_t tags = msg.rfind(""); + msg.replace(tags, std::string::npos, ""); + + // avoid/translate common entities + boost::replace_all(msg, "<", "<"); + boost::replace_all(msg, ">", ">"); + + return msg; +} + +} // end namespace RemoteAlgorithms +} // end namespace Mantid diff --git a/Code/Mantid/Framework/RemoteAlgorithms/test/CMakeLists.txt b/Code/Mantid/Framework/RemoteAlgorithms/test/CMakeLists.txt new file mode 100644 index 000000000000..9d1894a354c0 --- /dev/null +++ b/Code/Mantid/Framework/RemoteAlgorithms/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 ( RemoteAlgorithmsTest ${TEST_FILES} ) + target_link_libraries ( RemoteAlgorithmsTest RemoteAlgorithms ${GMOCK_LIBRARIES} ) + add_dependencies ( FrameworkTests RemoteAlgorithmsTest ) + # Test data. Not using any for now. Remember to uncomment if data is added for these remote alg. tests + # add_dependencies ( RemoteAlgorithmsTest StandardTestData ) + + # Add to the 'FrameworkTests' group in VS + set_property ( TARGET RemoteAlgorithmsTest PROPERTY FOLDER "UnitTests" ) + +endif () diff --git a/Code/Mantid/Framework/RemoteAlgorithms/test/SCARFTomoReconstructionTest.h b/Code/Mantid/Framework/RemoteAlgorithms/test/SCARFTomoReconstructionTest.h new file mode 100644 index 000000000000..8088f2ccbeef --- /dev/null +++ b/Code/Mantid/Framework/RemoteAlgorithms/test/SCARFTomoReconstructionTest.h @@ -0,0 +1,592 @@ +#ifndef MANTID_REMOTEALGORITHMS_SCARFTOMORECONSTRUCTION_H_ +#define MANTID_REMOTEALGORITHMS_SCARFTOMORECONSTRUCTION_H_ + +#include + +#include "MantidAPI/ITableWorkspace.h" +#include "MantidRemoteAlgorithms/SCARFTomoReconstruction.h" + +using namespace Mantid::RemoteAlgorithms; + +/** + * Very crude mock up for the interaction with the remote compute + * resource (in real life, through the PAC web service of the LSF job + * scheduler on SCARF). This one returns 200 OK and a simple response + * string. + */ +class MockedSCARFTomo: public SCARFTomoReconstruction +{ +protected: + virtual int doSendRequestGetResponse(const std::string &url, + std::ostream &response, + const StringToStringMap &headers = + StringToStringMap(), + const std::string &method = std::string(), + const std::string &body = "") { + UNUSED_ARG(url); + UNUSED_ARG(headers); + UNUSED_ARG(method); + UNUSED_ARG(body); + + response << "response OK - mocked up"; + return 200; + } +}; + +/** + * One more crude mock up for the interaction with the remote compute + * resource. This one returns an error (the connection is fine, but + * the response from the server is an error; example: wrong path, + * server bug, etc.). + */ +class MockedErrorResponse_SCARFTomo: public SCARFTomoReconstruction +{ +protected: + virtual int doSendRequestGetResponse(const std::string &url, + std::ostream &response, + const StringToStringMap &headers = + StringToStringMap(), + const std::string &method = std::string(), + const std::string &body = "") { + UNUSED_ARG(url); + UNUSED_ARG(response); + UNUSED_ARG(headers); + UNUSED_ARG(method); + UNUSED_ARG(body); + + response << "Error response - mocked up"; + return 404; + } +}; + +/** + * One more crude mock up for the interaction with the remote compute + * resource. This one raises an exception as if the (underlying) + * InternetHelper had found a connection issue. + */ +class MockedConnectionError_SCARFTomo: public SCARFTomoReconstruction +{ +protected: + virtual int doSendRequestGetResponse(const std::string &url, + std::ostream &response, + const StringToStringMap &headers = + StringToStringMap(), + const std::string &method = std::string(), + const std::string &body = "") { + UNUSED_ARG(url); + UNUSED_ARG(response); + UNUSED_ARG(headers); + UNUSED_ARG(method); + UNUSED_ARG(body); + + // throw as if there was a connection error + throw Mantid::Kernel::Exception::InternetError("Mocked up exception - connection error"); + } +}; + +/** + * One more crude mock up for the interaction with the remote compute + * resource. This one returns an OK code and a string that reads like + * what we expect when doing a successful login request. + */ +class MockedGoodLoginResponse_SCARFTomo: public SCARFTomoReconstruction +{ +protected: + virtual int doSendRequestGetResponse(const std::string &url, + std::ostream &response, + const StringToStringMap &headers = + StringToStringMap(), + const std::string &method = std::string(), + const std::string &body = "") { + UNUSED_ARG(url); + UNUSED_ARG(response); + UNUSED_ARG(headers); + UNUSED_ARG(method); + UNUSED_ARG(body); + + response << "https://portal.scarf.rl.ac.uk - response OK and login successful - mocked up"; + return 200; + } +}; + +/** + * One more crude mock up for the interaction with the remote compute + * resource. This one returns an OK code and a string that reads like + * a response with basic job status information. + */ +class MockedGoodJobStatus_SCARFTomo: public SCARFTomoReconstruction +{ +public: + MockedGoodJobStatus_SCARFTomo(const std::string &id): SCARFTomoReconstruction(), + jobID(id) + {}; + +protected: + virtual int doSendRequestGetResponse(const std::string &url, + std::ostream &response, + const StringToStringMap &headers = + StringToStringMap(), + const std::string &method = std::string(), + const std::string &body = "") { + UNUSED_ARG(url); + UNUSED_ARG(response); + UNUSED_ARG(headers); + UNUSED_ARG(method); + UNUSED_ARG(body); + + response << "" + "python /work/imat/webservice_test/test.py.py " + "/work/imat/webservice_test/test_out/-" + "" << jobID << "Mantid_tomography_1Running" + ""; + return 200; + } +private: + std::string jobID; +}; + +class SCARFTomoReconstructionTest: 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 SCARFTomoReconstructionTest *createSuite() { return new SCARFTomoReconstructionTest(); } + static void destroySuite(SCARFTomoReconstructionTest *suite) { delete suite; } + + void test_castAlgorithm() + { + // can create + boost::shared_ptr a; + TS_ASSERT(a = boost::make_shared()); + // can cast to inherited interfaces and base classes + + MockedSCARFTomo alg; + TS_ASSERT( dynamic_cast(&alg) ); + TS_ASSERT( dynamic_cast(&alg) ); + TS_ASSERT( dynamic_cast(&alg) ); + TS_ASSERT( dynamic_cast(&alg) ); + TS_ASSERT( dynamic_cast(&alg) ); + } + + void test_initAlgorithm() + { + MockedSCARFTomo tomo; + TS_ASSERT_THROWS_NOTHING( tomo.initialize() ); + } + + void test_propertiesMissing() + { + MockedSCARFTomo alg1; + TS_ASSERT_THROWS_NOTHING( alg1.initialize() ); + // password missing + TS_ASSERT_THROWS_NOTHING( alg1.setPropertyValue("UserName", "anything") ); + TS_ASSERT_THROWS_NOTHING( alg1.setPropertyValue("Action","LogIn") ); + + TS_ASSERT_THROWS_NOTHING( alg1.execute() ); + TS_ASSERT( !alg1.isExecuted() ); + + MockedSCARFTomo alg2; + TS_ASSERT_THROWS_NOTHING( alg2.initialize() ); + // username missing + TS_ASSERT_THROWS_NOTHING( alg2.setPropertyValue("Password", "whatever") ); + TS_ASSERT_THROWS_NOTHING( alg2.setPropertyValue("Action","LogIn") ); + + TS_ASSERT_THROWS( alg2.execute(), std::runtime_error ); + TS_ASSERT( !alg2.isExecuted() ); + + MockedSCARFTomo alg3; + TS_ASSERT_THROWS_NOTHING( alg3.initialize() ); + // mispellings... + // these try to set inexistent propeties => runtime_error + TS_ASSERT_THROWS( alg3.setPropertyValue("sername", "anything"), std::runtime_error ); + TS_ASSERT_THROWS( alg3.setPropertyValue("Passw", "anything"), std::runtime_error ); + // these try to set wrong values for valid properties => invalid_argument + TS_ASSERT_THROWS( alg3.setPropertyValue("Action","Loggin"), std::invalid_argument ); + TS_ASSERT_THROWS( alg3.setProperty("Action", "unknown_opt"), std::invalid_argument ); + TS_ASSERT_THROWS( alg3.setPropertyValue("JobID","strings_not_allowed"), std::invalid_argument ); + } + + void test_actionWithoutUsernameBeforeLogin() + { + MockedSCARFTomo alg; + TS_ASSERT_THROWS_NOTHING( alg.initialize() ); + + // Forget the username and you should get an exception + // alg.setProperty("UserName", "foo_user")); + TS_ASSERT_THROWS_NOTHING( alg.setProperty("Action", "JobStatus") ); + + TS_ASSERT_THROWS( alg.execute(), std::runtime_error ); + TS_ASSERT( !alg.isExecuted() ); + + MockedSCARFTomo tomo; + TS_ASSERT_THROWS_NOTHING( tomo.initialize() ); + TS_ASSERT_THROWS_NOTHING( tomo.setProperty("Action", "SubmitJob") ); + + TS_ASSERT_THROWS( tomo.execute(), std::runtime_error ); + TS_ASSERT( !tomo.isExecuted() ); + } + + void test_actionWithoutLogin() + { + MockedSCARFTomo alg; + + // Even if you provide all required params, you should get an exception + // if not logged in + TS_ASSERT_THROWS_NOTHING( alg.initialize() ); + TS_ASSERT_THROWS_NOTHING( alg.setProperty("Action", "JobStatus") ); + + TS_ASSERT_THROWS(alg.execute(), std::runtime_error ); + TS_ASSERT( !alg.isExecuted() ); + + MockedSCARFTomo tomo; + TS_ASSERT_THROWS_NOTHING( tomo.initialize() ); + TS_ASSERT_THROWS_NOTHING( tomo.setProperty("UserName", "anyone") ); + TS_ASSERT_THROWS_NOTHING( tomo.setProperty("Action", "SubmitJob") ); + TS_ASSERT_THROWS_NOTHING( tomo.setProperty("RunnablePath", "/foo/bar.sh") ); + TS_ASSERT_THROWS_NOTHING( tomo.setProperty("JobOptions", "--test --baz") ); + + TS_ASSERT_THROWS_NOTHING( tomo.execute() ); + TS_ASSERT( !tomo.isExecuted() ); + } + + /// Login is required before running the other actions (except ping) + // The good username is: foo_user + void test_login() + { + goodUsername = "foo_user"; + goodPassword = "foo_password"; + + // severe (connection) error + MockedConnectionError_SCARFTomo err; + TS_ASSERT_THROWS_NOTHING( err.initialize() ); + TS_ASSERT_THROWS_NOTHING( err.setProperty("UserName", goodUsername) ); + TS_ASSERT_THROWS_NOTHING( err.setProperty("Password", goodPassword) ); + TS_ASSERT_THROWS_NOTHING( err.setProperty("Action", "LogIn") ); + + TS_ASSERT_THROWS_NOTHING( err.execute() ); + TS_ASSERT( !err.isExecuted() ); + + // standard mocked response: looks like an unsuccessful login attempt + MockedSCARFTomo tomo; + TS_ASSERT_THROWS_NOTHING( tomo.initialize() ); + TS_ASSERT_THROWS_NOTHING( tomo.setProperty("UserName", goodUsername) ); + TS_ASSERT_THROWS_NOTHING( tomo.setProperty("Password", goodPassword) ); + TS_ASSERT_THROWS_NOTHING( tomo.setProperty("Action", "LogIn") ); + + TS_ASSERT_THROWS_NOTHING( tomo.execute() ); + TS_ASSERT( !tomo.isExecuted() ); + + // successful login attempt + MockedGoodLoginResponse_SCARFTomo login; + TS_ASSERT_THROWS_NOTHING( login.initialize() ); + TS_ASSERT_THROWS_NOTHING( login.setProperty("UserName", goodUsername) ); + TS_ASSERT_THROWS_NOTHING( login.setProperty("Password", goodPassword) ); + TS_ASSERT_THROWS_NOTHING( login.setProperty("Action", "LogIn") ); + + TS_ASSERT_THROWS_NOTHING( login.execute() ); + TS_ASSERT( login.isExecuted() ); + } + + void test_actionWithoutUsernameAfterLogin() + { + MockedSCARFTomo alg; + TS_ASSERT_THROWS_NOTHING( alg.initialize() ); + + TS_ASSERT_THROWS_NOTHING( alg.setProperty("Action", "JobStatus") ); + + TS_ASSERT_THROWS( alg.execute(), std::runtime_error ); + TS_ASSERT( !alg.isExecuted() ); + + MockedSCARFTomo tomo; + TS_ASSERT_THROWS_NOTHING( tomo.initialize() ); + // Forget this and you should get an exception + // tomo.setProperty("UserName", 3)); + TS_ASSERT_THROWS_NOTHING( tomo.setProperty("Action", "SubmitJob") ); + + TS_ASSERT_THROWS( tomo.execute(), std::runtime_error ); + TS_ASSERT( !tomo.isExecuted() ); + } + + void test_actionWrongUsername() + { + // Once you log out all actions should produce an exception + MockedSCARFTomo tomo; + TS_ASSERT_THROWS_NOTHING( tomo.initialize() ); + TS_ASSERT_THROWS_NOTHING( tomo.setProperty("UserName", "fail_" + goodUsername) ); + TS_ASSERT_THROWS_NOTHING( tomo.setProperty("Action", "JobStatus") ); + TS_ASSERT_THROWS_NOTHING( tomo.setProperty("RunnablePath", "/foo/bar.sh") ); + TS_ASSERT_THROWS_NOTHING( tomo.setProperty("JobOptions", "--test --baz") ); + + TS_ASSERT_THROWS_NOTHING( tomo.execute() ); + TS_ASSERT( !tomo.isExecuted() ); + } + + void test_wrongExec() + { + MockedSCARFTomo alg; + TS_ASSERT_THROWS_NOTHING( alg.initialize() ); + TS_ASSERT_THROWS( alg.setProperty("RandomName", 32), std::runtime_error ); + + TS_ASSERT_THROWS( alg.execute(), std::runtime_error ); + TS_ASSERT( !alg.isExecuted() ); + } + + void test_ping() + { + MockedSCARFTomo alg; + TS_ASSERT_THROWS_NOTHING( alg.initialize() ); + TS_ASSERT_THROWS_NOTHING( alg.setPropertyValue("Action", "Ping") ); + TS_ASSERT_THROWS_NOTHING( alg.setPropertyValue("Username", goodUsername) ); + + TS_ASSERT_THROWS_NOTHING( alg.execute() ); + TS_ASSERT( alg.isExecuted() ); + } + + void test_submit() + { + MockedSCARFTomo alg; + TS_ASSERT_THROWS_NOTHING( alg.initialize() ); + TS_ASSERT_THROWS_NOTHING( alg.setProperty("UserName", goodUsername) ); + TS_ASSERT_THROWS_NOTHING( alg.setProperty("Action", "SubmitJob") ); + TS_ASSERT_THROWS_NOTHING( alg.setProperty("RunnablePath", "/foo/bar.sh") ); + TS_ASSERT_THROWS_NOTHING( alg.setProperty("JobOptions", "--test --baz") ); + + TS_ASSERT_THROWS_NOTHING( alg.execute() ); + TS_ASSERT( alg.isExecuted() ); + + // second submit in a row + MockedSCARFTomo tomo; + TS_ASSERT_THROWS_NOTHING( tomo.initialize() ); + TS_ASSERT_THROWS_NOTHING( tomo.setProperty("UserName", goodUsername) ); + TS_ASSERT_THROWS_NOTHING( tomo.setProperty("Action", "SubmitJob") ); + TS_ASSERT_THROWS_NOTHING( tomo.setProperty("RunnablePath", "/foo/bar.sh") ); + TS_ASSERT_THROWS_NOTHING( tomo.setProperty("JobOptions", "--random --baz") ); + + TS_ASSERT_THROWS_NOTHING( tomo.execute() ); + TS_ASSERT( tomo.isExecuted() ); + } + + void test_queryStatus() + { + // this one is the basic mock up which doesn't provide the response content that we need + MockedSCARFTomo err; + TS_ASSERT_THROWS_NOTHING( err.initialize() ); + TS_ASSERT_THROWS_NOTHING( err.setProperty("UserName", goodUsername) ); + TS_ASSERT_THROWS_NOTHING( err.setProperty("Action", "JobStatus") ); + + TS_ASSERT_THROWS_NOTHING( err.execute() ); + TS_ASSERT( err.isExecuted()) ; + + std::vector vec; + TS_ASSERT_THROWS_NOTHING(vec = err.getProperty("RemoteJobsID")); + TS_ASSERT_EQUALS( vec.size(), 0 ); + TS_ASSERT_THROWS_NOTHING(vec = err.getProperty("RemoteJobsNames")); + TS_ASSERT_EQUALS( vec.size(), 0 ); + TS_ASSERT_THROWS_NOTHING(vec = err.getProperty("RemoteJobsStatus")); + TS_ASSERT_EQUALS( vec.size(), 0 ); + TS_ASSERT_THROWS_NOTHING(vec = err.getProperty("RemoteJobsCommands")); + TS_ASSERT_EQUALS( vec.size(), 0 ); + + // this one gives a basic/sufficient response with job status information + MockedGoodJobStatus_SCARFTomo alg("wrong id"); + TS_ASSERT_THROWS_NOTHING( alg.initialize() ); + TS_ASSERT_THROWS_NOTHING( alg.setProperty("UserName", goodUsername) ); + TS_ASSERT_THROWS_NOTHING( alg.setProperty("Action", "JobStatus") ); + + TS_ASSERT_THROWS_NOTHING( alg.execute() ); + TS_ASSERT( alg.isExecuted()) ; + + // the mock produces info on one job + TS_ASSERT_THROWS_NOTHING(vec = alg.getProperty("RemoteJobsID")); + TS_ASSERT_EQUALS( vec.size(), 1 ); + TS_ASSERT( vec.size()>0 && !vec.front().empty() ); + TS_ASSERT_THROWS_NOTHING(vec = alg.getProperty("RemoteJobsNames")); + TS_ASSERT_EQUALS( vec.size(), 1 ); + TS_ASSERT( vec.size()>0 && !vec.front().empty() ); + TS_ASSERT_THROWS_NOTHING(vec = alg.getProperty("RemoteJobsStatus")); + TS_ASSERT_EQUALS( vec.size(), 1 ); + TS_ASSERT( vec.size()>0 && !vec.front().empty() ); + TS_ASSERT_THROWS_NOTHING(vec = alg.getProperty("RemoteJobsCommands")); + TS_ASSERT_EQUALS( vec.size(), 1 ); + TS_ASSERT( vec.size()>0 && !vec.front().empty() ); + } + + void test_queryStatusByID() + { + // this one is the basic mockup: doesn't provide the response content that we need + MockedSCARFTomo err; + TS_ASSERT_THROWS_NOTHING( err.initialize() ); + TS_ASSERT_THROWS_NOTHING( err.setProperty("UserName", goodUsername) ); + TS_ASSERT_THROWS_NOTHING( err.setProperty("Action", "JobStatusByID") ); + TS_ASSERT_THROWS_NOTHING( err.setProperty("JobID", 123456789) ); + + TS_ASSERT_THROWS_NOTHING( err.execute() ); + TS_ASSERT( err.isExecuted()) ; + + std::string tmp; + TS_ASSERT_THROWS_NOTHING( tmp = err.getPropertyValue("RemoteJobName") ); + TS_ASSERT( tmp.empty() ); + TS_ASSERT_THROWS_NOTHING( tmp = err.getPropertyValue("RemoteJobStatus") ); + TS_ASSERT( tmp.empty() ); + TS_ASSERT_THROWS_NOTHING( tmp = err.getPropertyValue("RemoteJobsCommands") ); + TS_ASSERT( tmp.empty() ); + + // this one gives a basic/sufficient response with job status information + std::string jobID = "444449"; + MockedGoodJobStatus_SCARFTomo alg(jobID); + TS_ASSERT_THROWS_NOTHING( alg.initialize() ); + TS_ASSERT_THROWS_NOTHING( alg.setProperty("UserName", goodUsername) ); + TS_ASSERT_THROWS_NOTHING( alg.setProperty("Action", "JobStatusByID") ); + TS_ASSERT_THROWS_NOTHING( alg.setProperty("JobID", jobID) ); + + TS_ASSERT_THROWS_NOTHING( alg.execute() ); + TS_ASSERT( alg.isExecuted()) ; + + // It could also check that it gets the names, etc. that the mock-up produces + TS_ASSERT_THROWS_NOTHING( tmp = alg.getPropertyValue("RemoteJobName") ); + TS_ASSERT( !tmp.empty() ); + TS_ASSERT_THROWS_NOTHING( tmp = alg.getPropertyValue("RemoteJobStatus") ); + TS_ASSERT( !tmp.empty() ); + TS_ASSERT_THROWS_NOTHING( tmp = alg.getPropertyValue("RemoteJobCommand") ); + TS_ASSERT( !tmp.empty() ); + } + + void test_cancel() + { + MockedSCARFTomo alg; + TS_ASSERT_THROWS_NOTHING( alg.initialize() ); + TS_ASSERT_THROWS_NOTHING( alg.setProperty("UserName", goodUsername) ); + TS_ASSERT_THROWS_NOTHING( alg.setProperty("Action", "CancelJob") ); + TS_ASSERT_THROWS_NOTHING( alg.setProperty("CancelJobID", 123456789) ); + + TS_ASSERT_THROWS_NOTHING( alg.execute() ); + TS_ASSERT( alg.isExecuted()) ; + } + + void test_upload() + { + MockedSCARFTomo alg; + TS_ASSERT_THROWS_NOTHING( alg.initialize() ); + TS_ASSERT_THROWS_NOTHING( alg.setProperty("Username", goodUsername) ); + TS_ASSERT_THROWS_NOTHING( alg.setProperty("Action", "Upload") ); + TS_ASSERT_THROWS_NOTHING( alg.setProperty("FileToUpload", "random_file") ); + TS_ASSERT_THROWS_NOTHING( alg.setProperty("DestinationDirectory", "random_path/") ); + + TS_ASSERT_THROWS_NOTHING( alg.execute() ); + TS_ASSERT( alg.isExecuted()) ; + } + + void test_download() + { + MockedSCARFTomo alg; + TS_ASSERT_THROWS_NOTHING( alg.initialize() ); + + // Download with empty filename (get all files) + TS_ASSERT_THROWS_NOTHING( alg.setProperty("UserName", goodUsername) ); + TS_ASSERT_THROWS_NOTHING( alg.setProperty("Action", "Download") ); + TS_ASSERT_THROWS_NOTHING( alg.setProperty("DownloadJobID", 12345) ); + TS_ASSERT_THROWS_NOTHING( alg.setProperty("RemoteJobFilename", "") ); + TS_ASSERT_THROWS_NOTHING( alg.setProperty("LocalDirectory", "/tmp/foo") ); + TS_ASSERT_THROWS_NOTHING( alg.execute() ); + TS_ASSERT( alg.isExecuted() ); + + MockedSCARFTomo alg2; + TS_ASSERT_THROWS_NOTHING( alg2.initialize() ); + + // Download a single file (giving its name) + TS_ASSERT_THROWS_NOTHING( alg2.setProperty("UserName", goodUsername) ); + TS_ASSERT_THROWS_NOTHING( alg2.setProperty("Action", "Download") ); + TS_ASSERT_THROWS_NOTHING( alg2.setProperty("DownloadJobID", 12345) ); + TS_ASSERT_THROWS_NOTHING( alg2.setProperty("RemoteJobFilename", "inexistent_test_name.nxs.foo") ); + TS_ASSERT_THROWS_NOTHING( alg2.setProperty("LocalDirectory", "/tmp/foo") ); + TS_ASSERT_THROWS_NOTHING( alg2.execute() ); + TS_ASSERT( !alg2.isExecuted() ); + } + + void test_errorResponseFromServer() + { + MockedErrorResponse_SCARFTomo err; + TS_ASSERT_THROWS_NOTHING( err.initialize() ); + TS_ASSERT_THROWS_NOTHING( err.setPropertyValue("Username", goodUsername) ); + TS_ASSERT_THROWS_NOTHING( err.setPropertyValue("Action","JobStatus") ); + + TS_ASSERT_THROWS_NOTHING( err.execute() ); + TS_ASSERT( !err.isExecuted() ); + } + + // logout must run after all the (positive) tests + void test_logout() + { + MockedSCARFTomo alg; + TS_ASSERT_THROWS_NOTHING( alg.initialize() ); + TS_ASSERT_THROWS_NOTHING( alg.setProperty("UserName", goodUsername)); + TS_ASSERT_THROWS_NOTHING( alg.setProperty("Action", "LogOut") ); + + TS_ASSERT_THROWS_NOTHING( alg.execute() ); + TS_ASSERT( alg.isExecuted() ); + } + + void test_actionAfterLogout() + { + MockedSCARFTomo alg; + // Once you log out all actions should produce an exception, regardless of the username given + TS_ASSERT_THROWS_NOTHING( alg.initialize() ); + TS_ASSERT_THROWS_NOTHING( alg.setProperty("UserName", "fail_" + goodUsername) ); + TS_ASSERT_THROWS_NOTHING( alg.setProperty("Action", "JobStatus") ); + TS_ASSERT_THROWS_NOTHING( alg.setProperty("RunnablePath", "/foo/bar.sh") ); + TS_ASSERT_THROWS_NOTHING( alg.setProperty("JobOptions", "--test --baz") ); + + TS_ASSERT_THROWS_NOTHING(alg.execute() ); + TS_ASSERT( !alg.isExecuted() ); + + MockedSCARFTomo alg2; + TS_ASSERT_THROWS_NOTHING( alg2.initialize() ); + TS_ASSERT_THROWS_NOTHING( alg2.setProperty("UserName", goodUsername) ); + TS_ASSERT_THROWS_NOTHING( alg2.setProperty("Action", "JobStatus") ); + TS_ASSERT_THROWS_NOTHING( alg2.setProperty("RunnablePath", "/foo/bar.sh") ); + TS_ASSERT_THROWS_NOTHING( alg2.setProperty("JobOptions", "--test --baz") ); + + TS_ASSERT_THROWS_NOTHING(alg2.execute() ); + TS_ASSERT( !alg2.isExecuted() ); + } + + void test_failConnect() + { + MockedConnectionError_SCARFTomo fail; + TS_ASSERT_THROWS_NOTHING( fail.initialize() ); + TS_ASSERT_THROWS_NOTHING( fail.setPropertyValue("Action", "Ping") ); + + TS_ASSERT_THROWS( fail.execute(), std::runtime_error ); + TS_ASSERT( !fail.isExecuted() ); + + MockedConnectionError_SCARFTomo fail2; + TS_ASSERT_THROWS_NOTHING( fail2.initialize() ); + // username missing + TS_ASSERT_THROWS_NOTHING( fail2.setPropertyValue("Username", "uname") ); + TS_ASSERT_THROWS_NOTHING( fail2.setPropertyValue("Password", "whatever") ); + TS_ASSERT_THROWS_NOTHING( fail2.setPropertyValue("Action","LogIn") ); + + TS_ASSERT_THROWS_NOTHING( fail2.execute() ); + TS_ASSERT( !fail2.isExecuted() ); + } + + void test_errorResponseFromServerAfterLogout() + { + MockedErrorResponse_SCARFTomo err; + TS_ASSERT_THROWS_NOTHING( err.initialize() ); + TS_ASSERT_THROWS_NOTHING( err.setPropertyValue("Username", "foo") ); + TS_ASSERT_THROWS_NOTHING( err.setPropertyValue("Action", "Ping") ); + + TS_ASSERT_THROWS_NOTHING( err.execute() ); + TS_ASSERT( !err.isExecuted() ); + } + +private: + std::string goodUsername; + std::string goodPassword; + static const std::string SCARFName; +}; + +const std::string SCARFTomoReconstructionTest::SCARFName = "SCARF@STFC"; + +#endif // MANTID_REMOTEALGORITHMS_SCARFTOMORECONSTRUCTION_H_ diff --git a/Code/Mantid/Installers/colormaps/All_slice_viewer_cmaps_for_vsi.xml b/Code/Mantid/Installers/colormaps/All_slice_viewer_cmaps_for_vsi.xml new file mode 100644 index 000000000000..77d8d7cf7dde --- /dev/null +++ b/Code/Mantid/Installers/colormaps/All_slice_viewer_cmaps_for_vsi.xml @@ -0,0 +1,7674 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Code/Mantid/MantidPlot/icons/icons.qrc b/Code/Mantid/MantidPlot/icons/icons.qrc index 0b8c1a81c8b4..312749f081f8 100644 --- a/Code/Mantid/MantidPlot/icons/icons.qrc +++ b/Code/Mantid/MantidPlot/icons/icons.qrc @@ -236,5 +236,6 @@ Open-icon16x16.png Open-icon32x32.png fileclose.png + mdPlotting32x32.png diff --git a/Code/Mantid/MantidPlot/icons/mdPlotting32x32.png b/Code/Mantid/MantidPlot/icons/mdPlotting32x32.png new file mode 100644 index 000000000000..bb96d998ca0d Binary files /dev/null and b/Code/Mantid/MantidPlot/icons/mdPlotting32x32.png differ diff --git a/Code/Mantid/MantidPlot/pymantidplot/__init__.py b/Code/Mantid/MantidPlot/pymantidplot/__init__.py index 4497790bc16b..f08c88a65037 100644 --- a/Code/Mantid/MantidPlot/pymantidplot/__init__.py +++ b/Code/Mantid/MantidPlot/pymantidplot/__init__.py @@ -670,6 +670,8 @@ def plotSlice(source, label="", xydim=None, slicepoint=None, SliceViewer, e.g. setting the view and slice point. """ workspace_names = getWorkspaceNames(source) + __checkPlotSliceWorkspaces(workspace_names) + try: import mantidqtpython except: @@ -1032,4 +1034,37 @@ def __checkPlotMDWorkspaces(workspace_names): if not isinstance(mantid.api.mtd[name], mantid.api.IMDWorkspace): raise ValueError("Workspace '%s' is not an IMDWorkspace" % name) + +def __checkPlotSliceWorkspaces(ws_names): + """Checks that a list of workspaces is valid as input to plotSlice. + That means that the list should not be empty, all the workspaces + given must be present in the analysis data service, and all of + them must be MDworkspace. If any of these conditions is not met, + it raises an exception with specific error message. + + Throws Python-level exceptions (ValueError) if the list is empty + or any of the spaces don't exist or are not of IMDWorkspace type. + + Args: + ws_names: list of names of workspace(s) + + Returns: + Nothing, just throws exceptions in case of error/inconsistent input + + """ + if len(ws_names) == 0: + raise ValueError("No workspace name(s) given. You need to specify at least one.") + for name in ws_names: + if not mantid.api.mtd.doesExist(name): + raise ValueError("Workspace '%s' does not exist in the workspace list" % name) + + if not isinstance(mantid.api.mtd[name], mantid.api.IMDWorkspace): + if isinstance(mantid.api.mtd[name], mantid.api.IPeaksWorkspace): + raise ValueError("'%s' is not an IMDWorkspace as expected, but an " + "IPeaksWorkspace instead. Hint: if you want to overlay " + "peaks and use the Peaks Viewer, maybe " + "setPeaksWorkspaces is what you need?" % name) + else: + raise ValueError("%s is not an IMDWorkspace as expected." % name) + #----------------------------------------------------------------------------- diff --git a/Code/Mantid/MantidPlot/src/ConfigDialog.cpp b/Code/Mantid/MantidPlot/src/ConfigDialog.cpp index cafb5a066b9b..64e2b77e5de0 100644 --- a/Code/Mantid/MantidPlot/src/ConfigDialog.cpp +++ b/Code/Mantid/MantidPlot/src/ConfigDialog.cpp @@ -77,6 +77,9 @@ Description : Preferences dialog #include "MantidAPI/AlgorithmFactory.h" #include "MantidAPI/IPeakFunction.h" #include "MantidQtMantidWidgets/InstrumentSelector.h" +#include "MantidQtAPI/MdConstants.h" +#include "MantidQtAPI/MdSettings.h" +#include "MantidQtAPI/MdPlottingCmapsProvider.h" #include @@ -109,6 +112,7 @@ ConfigDialog::ConfigDialog( QWidget* parent, Qt::WFlags fl ) initPlotsPage(); initPlots3DPage(); initFittingPage(); + initMdPlottingPage(); generalDialog->addWidget(appTabWidget); generalDialog->addWidget(mtdTabWidget); @@ -116,6 +120,7 @@ ConfigDialog::ConfigDialog( QWidget* parent, Qt::WFlags fl ) generalDialog->addWidget(plotsTabWidget); generalDialog->addWidget(plots3D); generalDialog->addWidget(fitPage); + generalDialog->addWidget(mdPlottingTabWidget); QVBoxLayout * rightLayout = new QVBoxLayout(); lblPageHeader = new QLabel(); @@ -702,9 +707,202 @@ void ConfigDialog::initMantidPage() initCurveFittingTab(); initSendToProgramTab(); initMantidOptionsTab(); +} + +/** + * Configure a MD Plotting Page + */ +void ConfigDialog::initMdPlottingPage() +{ + mdPlottingTabWidget = new QTabWidget(generalDialog); + mdPlottingTabWidget->setUsesScrollButtons(false); + + // General MD Plotting tab + initMdPlottingGeneralTab(); + + // VSI tab + initMdPlottingVsiTab(); + + // Set the connections + setupMdPlottingConnections(); + + // Update the visibility of the Vsi tab if the General Md Color Map was selected the last time + if (m_mdSettings.getUsageGeneralMdColorMap()) + { + changeUsageGeneralMdColorMap(true); + } + + // Update the visibility of the Vsi tab if the last session checkbox was selected. + if (m_mdSettings.getUsageLastSession()) + { + changeUsageLastSession(true); + } +} + +/** + * Configure the general MD Plotting tab + */ +void ConfigDialog::initMdPlottingGeneralTab() +{ + // Ask if uniform colormap + mdPlottingGeneralPage = new QWidget(); + QVBoxLayout *generalTabLayout = new QVBoxLayout(mdPlottingGeneralPage); + mdPlottingGeneralFrame = new QGroupBox(mdPlottingGeneralPage); + generalTabLayout->addWidget(mdPlottingGeneralFrame ); + mdPlottingTabWidget->addTab(mdPlottingGeneralPage, QString()); + + // Color Map + mdPlottingGeneralFrame->setTitle("Use common Color Map for Slice Viewer and VSI"); + mdPlottingGeneralFrame->setCheckable(true); + mdPlottingGeneralFrame->setChecked(m_mdSettings.getUsageGeneralMdColorMap()); + + QGridLayout *gridVsiGeneralDefaultColorMap = new QGridLayout(mdPlottingGeneralFrame); + mdPlottingGeneralColorMap = new QComboBox(); + lblGeneralDefaultColorMap = new QLabel(); + gridVsiGeneralDefaultColorMap->addWidget(lblGeneralDefaultColorMap, 1, 0); + gridVsiGeneralDefaultColorMap->addWidget(mdPlottingGeneralColorMap, 1, 1); + + gridVsiGeneralDefaultColorMap->setRowStretch(2,1); + + QLabel* label = new QLabel("Note: Changes will not take effect until MantidPlot has been restarted."); + generalTabLayout->addWidget(label); + + // Set the color maps + MantidQt::API::MdPlottingCmapsProvider mdPlottingCmapsProvider; + QStringList colorMapNames; + QStringList colorMapFiles; + mdPlottingCmapsProvider.getColorMapsForMdPlotting(colorMapNames, colorMapFiles); + + if (colorMapNames.size() == colorMapFiles.size()) + { + for (int index = 0; index < colorMapNames.size(); ++index) + { + mdPlottingGeneralColorMap->addItem(colorMapNames[index], colorMapFiles[index]); + } + } + int currentIndex = mdPlottingGeneralColorMap->findData(m_mdSettings.getGeneralMdColorMapName(), Qt::DisplayRole); + if (currentIndex != -1) + { + mdPlottingGeneralColorMap->setCurrentIndex(currentIndex); + } } +/** + * Configure the VSI tab + */ +void ConfigDialog::initMdPlottingVsiTab() +{ + vsiPage = new QWidget(); + QVBoxLayout *vsiTabLayout = new QVBoxLayout(vsiPage); + QGroupBox *frame = new QGroupBox(); + vsiTabLayout->addWidget(frame); + QGridLayout *grid = new QGridLayout(frame); + mdPlottingTabWidget->addTab(vsiPage, QString()); + + // Usage of the last setting + vsiLastSession = new QCheckBox(); + lblVsiLastSession = new QLabel(); + grid->addWidget(lblVsiLastSession , 0, 0); + grid->addWidget(vsiLastSession , 0, 1); + vsiLastSession->setChecked(m_mdSettings.getUsageLastSession()); + + // Color Map + vsiDefaultColorMap = new QComboBox(); + lblVsiDefaultColorMap = new QLabel(); + grid->addWidget(lblVsiDefaultColorMap, 1, 0); + grid->addWidget(vsiDefaultColorMap, 1, 1); + + // Background Color + vsiDefaultBackground = new ColorButton(); + lblVsiDefaultBackground = new QLabel(); + grid->addWidget(lblVsiDefaultBackground, 2, 0); + grid->addWidget(vsiDefaultBackground, 2, 1); + + const QColor backgroundColor = m_mdSettings.getUserSettingBackgroundColor(); + vsiDefaultBackground->setColor(backgroundColor); + + // Initial View when loading into the VSI + vsiInitialView = new QComboBox(); + lblVsiInitialView = new QLabel(); + grid->addWidget(lblVsiInitialView, 3, 0); + grid->addWidget(vsiInitialView, 3, 1); + + grid->setRowStretch(4,1); + + QLabel* label1 = new QLabel("Note: The General Tab settings take precedence over the VSI Tab settings."); + vsiTabLayout->addWidget(label1); + QLabel* label2 = new QLabel("Note: Changes will not take effect until the VSI has been restarted."); + vsiTabLayout->addWidget(label2); + + // Set the color map selection for the VSI + QStringList maps; + MantidQt::API::MdPlottingCmapsProvider mdPlottingCmapsProvider; + mdPlottingCmapsProvider.getColorMapsForVSI(maps); + + MantidQt::API::MdConstants mdConstants; + vsiDefaultColorMap->addItems(mdConstants.getVsiColorMaps()); + vsiDefaultColorMap->addItems(maps); + + int index = vsiDefaultColorMap->findData(m_mdSettings.getUserSettingColorMap(), Qt::DisplayRole); + if (index != -1) + { + vsiDefaultColorMap->setCurrentIndex(index); + } + + // Set the initial view selection for the VSI + QStringList views; + + views = mdConstants.getAllInitialViews(); + vsiInitialView->addItems(views); + + int indexInitialView = vsiInitialView->findData(m_mdSettings.getUserSettingInitialView(), Qt::DisplayRole); + + if (index != -1) + { + vsiInitialView->setCurrentIndex(indexInitialView); + } +} + +/** + * Set up the connections for Md Plotting + */ +void ConfigDialog::setupMdPlottingConnections() +{ + QObject::connect(this->mdPlottingGeneralFrame, SIGNAL(toggled(bool)), this, SLOT(changeUsageGeneralMdColorMap(bool))); + QObject::connect(this->vsiLastSession, SIGNAL(toggled(bool)), this, SLOT(changeUsageLastSession(bool))); +} + +/** + * Handle a change of the General Md Color Map selection. + * @param The state of the general MD color map checkbox + */ +void ConfigDialog::changeUsageGeneralMdColorMap(bool state) +{ + // Set the visibility of the default color map of the VSI + vsiDefaultColorMap->setDisabled(state); + lblVsiDefaultColorMap->setDisabled(state); +} + +/** + * Handle a change of the Last Session selection. + * @param The state of the last session checkbox. + */ +void ConfigDialog::changeUsageLastSession(bool state) +{ + // Set the visibility of the default color map of the VSI + if (!mdPlottingGeneralFrame->isChecked()) + { + vsiDefaultColorMap->setDisabled(state); + lblVsiDefaultColorMap->setDisabled(state); + } + + // Set the visibility of the background color button of the VSI + vsiDefaultBackground->setDisabled(state); + lblVsiDefaultBackground->setDisabled(state); +} + + /** * Configure a Mantid Options page on the config dialog */ @@ -1724,6 +1922,7 @@ void ConfigDialog::languageChange() itemsList->addItem( tr( "2D Plots" ) ); itemsList->addItem( tr( "3D Plots" ) ); itemsList->addItem( tr( "Fitting" ) ); + itemsList->addItem( tr( "MD Plotting" ) ); itemsList->setCurrentRow(0); itemsList->item(0)->setIcon(QIcon(getQPixmap("general_xpm"))); itemsList->item(1)->setIcon(QIcon(":/MantidPlot_Icon_32offset.png")); @@ -1731,6 +1930,7 @@ void ConfigDialog::languageChange() itemsList->item(3)->setIcon(QIcon(getQPixmap("config_curves_xpm"))); itemsList->item(4)->setIcon(QIcon(getQPixmap("logo_xpm"))); itemsList->item(5)->setIcon(QIcon(getQPixmap("fit_xpm"))); + itemsList->item(6)->setIcon(QIcon(":/mdPlotting32x32.png")); itemsList->setIconSize(QSize(32,32)); // calculate a sensible width for the items list // (default QListWidget size is 256 which looks too big) @@ -1986,6 +2186,16 @@ void ConfigDialog::languageChange() scaleErrorsBox->setText(tr("Scale Errors with sqrt(Chi^2/doF)")); groupBoxMultiPeak->setTitle(tr("Display Peak Curves for Multi-peak Fits")); lblPeaksColor->setText(tr("Peaks Color")); + + // MDPlotting change + mdPlottingTabWidget->setTabText(mdPlottingTabWidget->indexOf(vsiPage), tr("VSI")); + lblVsiDefaultColorMap->setText(tr("Default Color Map")); + lblVsiDefaultBackground->setText(tr("Background Color")); + lblVsiLastSession->setText(tr("Use the settings of the last VSI session")); + lblVsiInitialView->setText(tr("Initial View")); + + mdPlottingTabWidget->setTabText(mdPlottingTabWidget->indexOf(mdPlottingGeneralPage), tr("General")); + lblGeneralDefaultColorMap->setText(tr("General Color Map")); } void ConfigDialog::accept() @@ -2215,6 +2425,61 @@ void ConfigDialog::apply() "Unable to update Mantid user properties file.\n" "Configuration will not be saved."); } + + // MD Plotting + updateMdPlottingSettings(); +} + +/** + * Update the MD Plotting settings + */ +void ConfigDialog::updateMdPlottingSettings() +{ + //////// GENERAL TAB + + // Read the common color map check box + if (mdPlottingGeneralFrame->isChecked()) + { + m_mdSettings.setUsageGeneralMdColorMap(true); + } + else + { + m_mdSettings.setUsageGeneralMdColorMap(false); + } + + if (mdPlottingGeneralColorMap) + { + QString generalTabColorMapName = mdPlottingGeneralColorMap->currentText(); + QString generalTabColorMapFile = mdPlottingGeneralColorMap->itemData(mdPlottingGeneralColorMap->currentIndex()).toString(); + + m_mdSettings.setGeneralMdColorMap(generalTabColorMapName, generalTabColorMapFile); + } + + ///// VSI TAB + + // Read the Vsi color map + if (vsiDefaultColorMap) + { + m_mdSettings.setUserSettingColorMap(vsiDefaultColorMap->currentText()); + } + + // Read if the usage of the last color map should be performed + if (vsiLastSession) + { + m_mdSettings.setUsageLastSession(vsiLastSession->isChecked()); + } + + // Read the background selection + if (vsiDefaultBackground) + { + m_mdSettings.setUserSettingBackgroundColor(vsiDefaultBackground->color()); + } + + // Read the initial view selection + if (vsiInitialView) + { + m_mdSettings.setUserSettingIntialView(vsiInitialView->currentText()); + } } void ConfigDialog::updateDirSearchSettings() diff --git a/Code/Mantid/MantidPlot/src/ConfigDialog.h b/Code/Mantid/MantidPlot/src/ConfigDialog.h index ce1726b95cb2..05f5a7d17d66 100644 --- a/Code/Mantid/MantidPlot/src/ConfigDialog.h +++ b/Code/Mantid/MantidPlot/src/ConfigDialog.h @@ -32,6 +32,7 @@ Description : Preferences dialog #include #include #include +#include "MantidQtAPI/MdSettings.h" class QLineEdit; class QGroupBox; @@ -155,6 +156,13 @@ class ConfigDialog : public QDialog void populateProgramTree(); void updateProgramTree(); + // MD Plotting + void initMdPlottingPage(); + void initMdPlottingGeneralTab(); + void initMdPlottingVsiTab(); + void updateMdPlottingSettings(); + void setupMdPlottingConnections(); + QTreeWidgetItem* createCheckedTreeItem(QString name,bool checkBoxState); QStringList buildHiddenCategoryString(QTreeWidgetItem *parent = 0); @@ -204,6 +212,15 @@ class ConfigDialog : public QDialog QTreeWidget *treeCategories; QTreeWidget *treePrograms; + //MDPlotting + QTabWidget* mdPlottingTabWidget; + QWidget *vsiPage, *mdPlottingGeneralPage; + QComboBox *vsiDefaultColorMap, *vsiInitialView, *mdPlottingGeneralColorMap; + QLabel *lblVsiDefaultColorMap, *lblVsiDefaultBackground, *lblGeneralDefaultColorMap, *lblBoxGeneralDefaultColorMap, *lblVsiLastSession, *lblVsiInitialView; + ColorButton *vsiDefaultBackground; + QGroupBox* mdPlottingGeneralFrame; + QCheckBox* vsiLastSession; + MantidQt::API::MdSettings m_mdSettings; QPushButton* buttonAxesFont, *buttonNumbersFont, *buttonLegendFont, *buttonTitleFont, *fontsBtn; QCheckBox *boxSearchUpdates, *boxOrthogonal, *logBox, *plotLabelBox, *scaleErrorsBox; @@ -257,6 +274,10 @@ class ConfigDialog : public QDialog QLineEdit *pythonConfigDirLine; #endif QCheckBox *boxUpdateTableValues; + + public slots: + void changeUsageGeneralMdColorMap(bool state); + void changeUsageLastSession(bool state); }; #endif // CONFIGDIALOG_H diff --git a/Code/Mantid/MantidQt/API/CMakeLists.txt b/Code/Mantid/MantidQt/API/CMakeLists.txt index 935d03fa4826..c801a52ededf 100644 --- a/Code/Mantid/MantidQt/API/CMakeLists.txt +++ b/Code/Mantid/MantidQt/API/CMakeLists.txt @@ -17,6 +17,7 @@ set ( SRC_FILES src/MantidQwtIMDWorkspaceData.cpp src/MantidWidget.cpp src/MdConstants.cpp + src/MdPlottingCmapsProvider.cpp src/MdSettings.cpp src/Message.cpp src/OptionsPropertyWidget.cpp @@ -83,6 +84,7 @@ set ( INC_FILES inc/MantidQtAPI/MantidQwtIMDWorkspaceData.h inc/MantidQtAPI/MantidQwtWorkspaceData.h inc/MantidQtAPI/MdConstants.h + inc/MantidQtAPI/MdPlottingCmapsProvider.h inc/MantidQtAPI/MdSettings.h inc/MantidQtAPI/PropertyWidgetFactory.h inc/MantidQtAPI/QwtRasterDataMD.h diff --git a/Code/Mantid/MantidQt/API/inc/MantidQtAPI/MdConstants.h b/Code/Mantid/MantidQt/API/inc/MantidQtAPI/MdConstants.h index 1561750bc510..54c5f903b8dd 100644 --- a/Code/Mantid/MantidQt/API/inc/MantidQtAPI/MdConstants.h +++ b/Code/Mantid/MantidQt/API/inc/MantidQtAPI/MdConstants.h @@ -2,6 +2,9 @@ #define MDCONSTANTS_H_ #include "DllOption.h" +#include +#include +#include namespace MantidQt { @@ -42,11 +45,47 @@ namespace MantidQt ~MdConstants(); + /** + * Initialize constants which are required to store and persist MD settings. + */ + void initializeSettingsConstants(); + + /** + * Initialize constants which are required for the view + */ + void initializeViewConstants(); + + QString getGeneralMdColorMap() const; + + QColor getDefaultBackgroundColor() const; + + QStringList getVsiColorMaps() const; + + QString getStandardView() const; + + QString getMultiSliceView() const; + + QString getThreeSliceView() const; + + QString getSplatterPlotView() const; + + QString getTechniqueDependence() const; + double getColorScaleStandardMax(); + QStringList getAllInitialViews() const; + double getLogScaleDefaultValue(); private: + QString m_generalMdColorMap; + QColor m_defaultBackgroundColor; + QStringList m_vsiColorMaps; + QString m_standardView; + QString m_multiSliceView; + QString m_threeSliceView; + QString m_splatterPlotView; + QString m_techniqueDependence; const double m_colorScaleStandardMax; const double m_logScaleDefaultValue; diff --git a/Code/Mantid/MantidQt/API/inc/MantidQtAPI/MdPlottingCmapsProvider.h b/Code/Mantid/MantidQt/API/inc/MantidQtAPI/MdPlottingCmapsProvider.h new file mode 100644 index 000000000000..1130adb9750a --- /dev/null +++ b/Code/Mantid/MantidQt/API/inc/MantidQtAPI/MdPlottingCmapsProvider.h @@ -0,0 +1,90 @@ +#ifndef MDPLOTTINGCMAPSPROVIDER_H_ +#define MDPLOTTINGCMAPSPROVIDER_H_ + +#include "DllOption.h" +#include +#include + +class QStringList; + +namespace MantidQt +{ + namespace API + { + /** + * + This helper class allows for reading and processing the names of the available MD color map files + + @date 7/1/2015 + + Copyright © 2011 ISIS Rutherford Appleton Laboratory, NScD Oak Ridge National Laboratory & European Spallation Source + + This file is part of Mantid. + + Mantid is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + Mantid is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + + File change history is stored at: + Code Documentation is available at: + */ + + class EXPORT_OPT_MANTIDQT_API MdPlottingCmapsProvider + { + public: + MdPlottingCmapsProvider(); + + ~MdPlottingCmapsProvider(); + + /** + * Get the name of all available color maps for general MD plotting. + * @param colorMapNames Reference to a list with the names of the color maps. + * @param colorMapFiles Reference to a corresponding list with the file paths for the color maps. + */ + void getColorMapsForMdPlotting(QStringList& colorMapNames, QStringList& colorMapFiles); + + /** + * Get the name of all available color maps for the VSI (at least the ones stored in files). + * @param colorMapNames Reference to a list with the names of the color maps. + */ + void getColorMapsForVSI(QStringList& colorMapNames); + + private: + /** + * Gets all files from directory of a given file type. + * @param colorMapNames Reference to a list of color map names. + * @param colorMapFiles Reference to a list of file paths for the corresponding color maps. + * @param colorMapDirectory Directory where the color maps are stored. + * @param fileType suffix of the desired files. + */ + void appendAllFileNamesForFileType(QStringList& colorMapNames, QStringList& colorMapFiles, QString colorMapDirectory, QString fileType); + + /** + * Gets all the color map names + * @param colorMapNames Reference to a list of color map names. + * @param fullFilePath File path to the xml files with the color map definitions. + */ + void appendVSIColorMaps(QStringList& colorMapNames, QString fullFilePath); + + /** + * Compare the colormap names of the Slice Viewer and the VSI and extract all indicees of the list of Slice Viewer color maps + * which also exist in the list of the VSI color maps. + * @param colorMapNamesSliceViewer A list of color maps of the Slice Viewer. + * @param colorMapNamesVsi A list of color maps for the VSI. + * @returns A vector of indices for the slice viewer list. + */ + std::vector getSliceViewerIndicesForCommonColorMaps(QStringList colorMapNamesSliceViewer,QStringList colorMapNamesVsi); + }; + } +} + +#endif diff --git a/Code/Mantid/MantidQt/API/inc/MantidQtAPI/MdSettings.h b/Code/Mantid/MantidQt/API/inc/MantidQtAPI/MdSettings.h index 346fd3f3a69f..40c0ae9e8547 100644 --- a/Code/Mantid/MantidQt/API/inc/MantidQtAPI/MdSettings.h +++ b/Code/Mantid/MantidQt/API/inc/MantidQtAPI/MdSettings.h @@ -3,7 +3,9 @@ #include "DllOption.h" #include "MantidQtAPI/MdConstants.h" +#include #include +#include namespace MantidQt { @@ -45,21 +47,145 @@ namespace MantidQt ~MdSettings(); /** - * Sets if the color scale was log in the last session - * @param logScale The state of the log scale. + * Set the UserSetting color map for the vsi. + *@param colorMap UserSetting colormap for the vsi */ + void setUserSettingColorMap(QString colorMap); + + /** + * Get the UserSetting color map for the vsi. + * @returns The UserSetting color map for the vsi. + */ + QString getUserSettingColorMap(); + + /** + * Get the LastSession color map + */ + QString getLastSessionColorMap(); + + /** + * Set the LastSession color map + * @param colormap The colormap for the VSI. + */ + void setLastSessionColorMap(QString colorMap); + + /** + * Get the background color for the user setting. + * @returns The background color. + */ + QColor getUserSettingBackgroundColor(); + + /** + * Get the default background color. + * @returns The default background color. + */ + QColor getDefaultBackgroundColor(); + + /** + * Set the background color for the user setting. + * @param backgroundColor The background color. + */ + void setUserSettingBackgroundColor(QColor backgroundColor); + + /** + * Get the background color for the last session. + * @returns The background color. + */ + QColor getLastSessionBackgroundColor(); + + /** + * Set the background color for the user setting. + * @param backgroundColor The background color. + */ + void setLastSessionBackgroundColor(QColor backgroundColor); + + /** + * Set the general MD color map + * @param colorMapName The name of the general color map. + * @param colorMapFile The file name of the general color map. + */ + void setGeneralMdColorMap(QString colorMapName, QString colorMapFile); + + /** + * Get the general MD color map file + * @returns The file path to the general md color map .map file. + */ + QString getGeneralMdColorMapFile(); + + /** + * Get the general MD color map name + * @returns The name of the general Md color map. + */ + QString getGeneralMdColorMapName(); + + /** + * Set the flag if general color map is desired or not. + * @param flag If a general color map is desired or not. + */ + void setUsageGeneralMdColorMap(bool flag); + + /** + * Get the flag if the general color map is desired or not. + * @returns Is a general color map desired? + */ + bool getUsageGeneralMdColorMap(); + + /** + * Set the flag which indicates if the last active color map is supposed to be used. + * @param flag If the last active color map is supposed to be used or not. + */ + void setUsageLastSession(bool flag); + + /** + * Get the flag which indicates if the last active color map is supposed to be used. + * @returns Is the last active color map to be used? + */ + bool getUsageLastSession(); + + /** + * Get user setting for the initial view. + * @returns The initial view + */ + QString getUserSettingInitialView(); + + /** + * Sets if the color scale was log in the last session + * @param logScale The state of the log scale. + */ void setLastSessionLogScale(bool logScale); + /** + * Set the user setting for the initial view. + * @param initialView The selected initial view. + */ + void setUserSettingIntialView(QString initialView); + /** * Retrieves the state of the last session's log scale. * @returns Was a log scale state? */ - bool getLastSessionLogScale(); - + bool getLastSessionLogScale(); + private: MdConstants m_mdConstants; QString m_vsiGroup; + QString m_generalMdGroup; + QString m_sliceViewerGroup; + + QString m_lblUserSettingColorMap; + QString m_lblLastSessionColorMap; + QString m_lblGeneralMdColorMap; + QString m_lblGeneralMdColorMapName; + QString m_lblUseGeneralMdColorMap; + QString m_lblUseLastSessionColorMap; + + QString m_lblUserSettingBackgroundColor; + QString m_lblLastSessionBackgroundColor; + + QString m_lblSliceViewerColorMap; + + QString m_lblUserSettingInitialView; QString m_lblLastSessionLogScale; }; } diff --git a/Code/Mantid/MantidQt/API/src/MdConstants.cpp b/Code/Mantid/MantidQt/API/src/MdConstants.cpp index 680269da3247..d07c67b26b2e 100644 --- a/Code/Mantid/MantidQt/API/src/MdConstants.cpp +++ b/Code/Mantid/MantidQt/API/src/MdConstants.cpp @@ -1,4 +1,8 @@ #include "MantidQtAPI/MdConstants.h" +#include +#include +#include +#include namespace MantidQt { @@ -6,19 +10,135 @@ namespace MantidQt { MdConstants::MdConstants() : m_colorScaleStandardMax(0.1), m_logScaleDefaultValue(0.1) { + initializeSettingsConstants(); + initializeViewConstants(); }; MdConstants::~MdConstants(){}; + void MdConstants::initializeSettingsConstants() + { + // General MD Color Map + m_generalMdColorMap = "ColdFire"; + + // Background color + m_defaultBackgroundColor = QColor(84,89,109); + + // Populate the optional color maps + m_vsiColorMaps.append("Cool to Warm"); + m_vsiColorMaps.append("Blue to Red Rainbow"); + m_vsiColorMaps.append("Red to Blue Rainbow"); + m_vsiColorMaps.append("Grayscale"); + m_vsiColorMaps.append("X Ray"); + m_vsiColorMaps.append("Blue to Yellow"); + } + + void MdConstants::initializeViewConstants() + { + m_techniqueDependence = "Technique-Dependent"; + m_standardView = "Standard"; + m_multiSliceView = "Multi Slice"; + m_threeSliceView = "Three Slice"; + m_splatterPlotView = "Splatter Plot"; + } + + /** + * Gets the general MD color map. + *@returns The general MD color map. + */ + QString MdConstants::getGeneralMdColorMap() const + { + return m_generalMdColorMap; + } + + /** + * Gets the label for the background color. + *@returns The label for the background color. + */ + QColor MdConstants::getDefaultBackgroundColor() const + { + return m_defaultBackgroundColor; + } + + /** + * Gets a list of VSI color maps. + *@returns The list of VSI color maps. + */ + QStringList MdConstants::getVsiColorMaps() const + { + return m_vsiColorMaps; + } + + /** + * Get the standard view. + *@returns The standard view in the VSI. + */ + QString MdConstants::getStandardView() const + { + return m_standardView; + } + + /** + * Get the multi slice view. + *@returns The multi slice view in the VSI. + */ + QString MdConstants::getMultiSliceView() const + { + return m_multiSliceView; + } + + /** + * Get the three slice view. + *@returns The three slice view in the VSI. + */ + QString MdConstants::getThreeSliceView() const + { + return m_threeSliceView; + } + + /** + * Get the splatter plot view. + *@returns The splatter plot view in the VSI. + */ + QString MdConstants::getSplatterPlotView() const + { + return m_splatterPlotView; + } + double MdConstants::getColorScaleStandardMax() { return m_colorScaleStandardMax; } double MdConstants::getLogScaleDefaultValue() - { return m_logScaleDefaultValue; } + + /** + * Get the technique dependence. + *@returns The technique dependence. + */ + QString MdConstants::getTechniqueDependence() const + { + return m_techniqueDependence; + } + + /** + * Get a list of all initial views. + *@returns A list of all viewss, including a technique-dependent view + */ + QStringList MdConstants::getAllInitialViews() const + { + QStringList views; + + views.append(getTechniqueDependence()); + views.append(getStandardView()); + views.append(getMultiSliceView()); + views.append(getThreeSliceView()); + views.append(getSplatterPlotView()); + + return views; + } } } diff --git a/Code/Mantid/MantidQt/API/src/MdPlottingCmapsProvider.cpp b/Code/Mantid/MantidQt/API/src/MdPlottingCmapsProvider.cpp new file mode 100644 index 000000000000..aefde8d82258 --- /dev/null +++ b/Code/Mantid/MantidQt/API/src/MdPlottingCmapsProvider.cpp @@ -0,0 +1,152 @@ +#include "MantidQtAPI/MdPlottingCmapsProvider.h" +#include "MantidKernel/ConfigService.h" +#include "MantidKernel/Logger.h" +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + + + +namespace MantidQt{ + namespace API{ + namespace + { + /// Static logger + Mantid::Kernel::Logger g_log("MdViewerWidget"); + } + + MdPlottingCmapsProvider::MdPlottingCmapsProvider() + { + } + + MdPlottingCmapsProvider::~MdPlottingCmapsProvider() + { + } + + void MdPlottingCmapsProvider::getColorMapsForMdPlotting(QStringList& colorMapNames, QStringList& colorMapFiles) + { + // Get the installed color maps directory. + QString colorMapDirectory = QString::fromStdString(Mantid::Kernel::ConfigService::Instance().getString("colormaps.directory")); + if (colorMapDirectory.isEmpty()) + { + return; + } + + // We show only those color maps as options which can be found in the .map files and in the .xml files of the VSI + QStringList colorMapNamesSliceViewer; + QStringList colorMapFilesSliceViewer; + appendAllFileNamesForFileType(colorMapNamesSliceViewer, colorMapFilesSliceViewer, colorMapDirectory, "map"); + + QStringList colorMapNamesVsi; + getColorMapsForVSI(colorMapNamesVsi); + + std::vector indexList = getSliceViewerIndicesForCommonColorMaps(colorMapNamesSliceViewer, colorMapNamesVsi); + + for (std::vector::iterator it = indexList.begin(); it != indexList.end(); ++it) + { + colorMapNames.append(colorMapNamesSliceViewer[*it]); + colorMapFiles.append(colorMapFilesSliceViewer[*it]); + } + } + + void MdPlottingCmapsProvider::getColorMapsForVSI(QStringList& colorMapNames) + { + // Get the installed color maps directory. + QString colorMapDirectory = QString::fromStdString(Mantid::Kernel::ConfigService::Instance().getString("colormaps.directory")); + if (colorMapDirectory.isEmpty()) + { + return; + } + + QStringList colormapXMLFiles; + QStringList colorMapXMLNames; + + // Extract all file names + appendAllFileNamesForFileType(colorMapXMLNames, colormapXMLFiles, colorMapDirectory, "xml"); + + for (QStringList::iterator it = colormapXMLFiles.begin(); it != colormapXMLFiles.end(); ++it) + { + appendVSIColorMaps(colorMapNames, *it); + } + } + + void MdPlottingCmapsProvider::appendVSIColorMaps(QStringList& colorMapNames, QString fullFilePath) + { + std::string path = fullFilePath.toStdString(); + std::ifstream input(path.c_str(), std::ifstream::in); + + Poco::XML::InputSource source(input); + + try + { + Poco::XML::DOMParser parser; + + Poco::AutoPtr doc = parser.parse(&source); + + Poco::XML::Element* root = doc->documentElement(); + + // Get all color maps + Poco::XML::NodeList* nodes = root->getElementsByTagName("ColorMap"); + + Poco::XML::Node* node = NULL; + + Poco::XML::Element* element = NULL; + + for (unsigned long i = 0; i < nodes->length(); ++i) + { + node = nodes->item(i); + element = dynamic_cast(node); + std::string nameOfMap = static_cast(element->getAttribute("name")); + colorMapNames.append(QString(nameOfMap.c_str())); + } + } + catch(Poco::Exception& exc) + { + g_log.warning() << "There was an issue with reading color maps:" << exc.displayText() <<"\n"; + } + } + + void MdPlottingCmapsProvider::appendAllFileNamesForFileType(QStringList& colorMapNames, QStringList& colorMapFiles, QString colorMapDirectory, QString fileType) + { + QDir directory(colorMapDirectory); + + QStringList filter(QString("*.%1").arg(fileType)); + + QFileInfoList info = directory.entryInfoList(filter, QDir::Files); + + for (QFileInfoList::iterator it = info.begin(); it != info.end(); ++it) + { + colorMapNames.append(it->baseName()); + colorMapFiles.append(it->absFilePath()); + } + } + + std::vector MdPlottingCmapsProvider::getSliceViewerIndicesForCommonColorMaps(QStringList colorMapNamesSliceViewer,QStringList colorMapNamesVsi) + { + int index = 0; + + std::vector indexVector; + + for (QStringList::iterator it = colorMapNamesSliceViewer.begin(); it != colorMapNamesSliceViewer.end(); ++it) + { + if (colorMapNamesVsi.indexOf(*it) != -1) + { + indexVector.push_back(index); + } + + index++; + } + + return indexVector; + } + } +} \ No newline at end of file diff --git a/Code/Mantid/MantidQt/API/src/MdSettings.cpp b/Code/Mantid/MantidQt/API/src/MdSettings.cpp index 97c364171b53..c91292587786 100644 --- a/Code/Mantid/MantidQt/API/src/MdSettings.cpp +++ b/Code/Mantid/MantidQt/API/src/MdSettings.cpp @@ -1,16 +1,191 @@ #include "MantidQtAPI/MdSettings.h" +#include "MantidQtAPI/MdConstants.h" +#include "boost/scoped_ptr.hpp" #include #include using namespace MantidQt::API; MdSettings::MdSettings() : m_vsiGroup("Mantid/MdPlotting/Vsi"), + m_generalMdGroup("Mantid/MdPlotting/General"), + m_sliceViewerGroup("Mantid/SliceViewer"),// This is the same as in Slice Viewer !! + m_lblUserSettingColorMap("usersettingcolormap"), + m_lblLastSessionColorMap("lastsessioncolormap"), + m_lblGeneralMdColorMap("generalcolormap"), + m_lblGeneralMdColorMapName("generalcolormapname"), + m_lblUseGeneralMdColorMap("usegeneralcolormap"), + m_lblUseLastSessionColorMap("uselastsessioncolormap"), + m_lblUserSettingBackgroundColor("usersettingbackgroundcolor"), + m_lblLastSessionBackgroundColor("lastsessionbackgroundcolor"), + m_lblSliceViewerColorMap("ColormapFile"), // This is the same as in Slice Viewer !!, + m_lblUserSettingInitialView("initialview"), m_lblLastSessionLogScale("lastsessionlogscale") { + m_mdConstants.initializeSettingsConstants(); +} + +MdSettings::~MdSettings(){} + +QString MdSettings::getUserSettingColorMap() +{ + QSettings settings; + + settings.beginGroup(m_vsiGroup); + QString userSettingColorMap = settings.value(m_lblUserSettingColorMap, QString("")).toString(); + settings.endGroup(); + + return userSettingColorMap; +} + +void MdSettings::setUserSettingColorMap(QString colorMap) +{ + QSettings settings; + + settings.beginGroup(m_vsiGroup); + settings.setValue(m_lblUserSettingColorMap, colorMap); + settings.endGroup(); +} + +QString MdSettings::getLastSessionColorMap() +{ + QSettings settings; + + settings.beginGroup(m_vsiGroup); + QString colormap = settings.value(m_lblLastSessionColorMap, QString("")).toString(); + settings.endGroup(); + + return colormap; +} + +void MdSettings::setLastSessionColorMap(QString colorMap) +{ + QSettings settings; + + settings.beginGroup(m_vsiGroup); + settings.setValue(m_lblLastSessionColorMap, colorMap); + settings.endGroup(); +} + +QColor MdSettings::getUserSettingBackgroundColor() +{ + QSettings settings; -}; + settings.beginGroup(m_vsiGroup); + QColor backgroundColor= settings.value(m_lblUserSettingBackgroundColor, + m_mdConstants.getDefaultBackgroundColor()).value(); + settings.endGroup(); + + return backgroundColor; +} + +void MdSettings::setUserSettingBackgroundColor(QColor backgroundColor) +{ + QSettings settings; + + settings.beginGroup(m_vsiGroup); + settings.setValue(m_lblUserSettingBackgroundColor, backgroundColor); + settings.endGroup(); +} + +QColor MdSettings::getLastSessionBackgroundColor() +{ + QSettings settings; -MdSettings::~MdSettings(){}; + settings.beginGroup(m_vsiGroup); + QColor backgroundColor= settings.value(m_lblLastSessionBackgroundColor, + m_mdConstants.getDefaultBackgroundColor()).value(); + settings.endGroup(); + + return backgroundColor; +} + +QColor MdSettings::getDefaultBackgroundColor() +{ + return m_mdConstants.getDefaultBackgroundColor(); +} + +void MdSettings::setLastSessionBackgroundColor(QColor backgroundColor) +{ + QSettings settings; + + settings.beginGroup(m_vsiGroup); + settings.setValue(m_lblLastSessionBackgroundColor, backgroundColor); + settings.endGroup(); +} + +void MdSettings::setGeneralMdColorMap(QString colorMapName, QString colorMapFile) +{ + QSettings settings; + + settings.beginGroup(m_generalMdGroup); + settings.setValue(m_lblGeneralMdColorMapName, colorMapName); + settings.setValue(m_lblGeneralMdColorMap, colorMapFile); + settings.endGroup(); +} + +QString MdSettings::getGeneralMdColorMapFile() +{ + QSettings settings; + + settings.beginGroup(m_generalMdGroup); + QString colorMap = settings.value(m_lblGeneralMdColorMap, QString("")).toString(); + settings.endGroup(); + + return colorMap; +} + + +QString MdSettings::getGeneralMdColorMapName() +{ + QSettings settings; + + settings.beginGroup(m_generalMdGroup); + QString colorMap = settings.value(m_lblGeneralMdColorMapName, m_mdConstants.getGeneralMdColorMap()).toString(); + settings.endGroup(); + + return colorMap; +} + + +void MdSettings::setUsageGeneralMdColorMap(bool flag) +{ + QSettings settings; + + settings.beginGroup(m_generalMdGroup); + settings.setValue(m_lblUseGeneralMdColorMap, flag); + settings.endGroup(); +} + +bool MdSettings::getUsageGeneralMdColorMap() +{ + QSettings settings; + + settings.beginGroup(m_generalMdGroup); + bool flag = settings.value(m_lblUseGeneralMdColorMap, false).asBool(); + settings.endGroup(); + + return flag; +} + +void MdSettings::setUsageLastSession(bool flag) +{ + QSettings settings; + + settings.beginGroup(m_vsiGroup); + settings.setValue(m_lblUseLastSessionColorMap, flag); + settings.endGroup(); +} + +bool MdSettings::getUsageLastSession() +{ + QSettings settings; + + settings.beginGroup(m_vsiGroup); + bool flag = settings.value(m_lblUseLastSessionColorMap, false).asBool(); + settings.endGroup(); + + return flag; +} void MdSettings::setLastSessionLogScale(bool logScale) { @@ -21,6 +196,17 @@ void MdSettings::setLastSessionLogScale(bool logScale) settings.endGroup(); } +QString MdSettings::getUserSettingInitialView() +{ + QSettings settings; + + settings.beginGroup(m_vsiGroup); + QString initialView = settings.value(m_lblUserSettingInitialView, m_mdConstants.getTechniqueDependence()).asString(); + settings.endGroup(); + + return initialView; +} + bool MdSettings::getLastSessionLogScale() { QSettings settings; @@ -32,3 +218,12 @@ bool MdSettings::getLastSessionLogScale() return logScale; } + +void MdSettings::setUserSettingIntialView(QString initialView) +{ + QSettings settings; + + settings.beginGroup(m_vsiGroup); + settings.setValue(m_lblUserSettingInitialView, initialView); + settings.endGroup(); +} \ No newline at end of file diff --git a/Code/Mantid/MantidQt/CustomInterfaces/CMakeLists.txt b/Code/Mantid/MantidQt/CustomInterfaces/CMakeLists.txt index ea898a3f890a..48369aceee03 100644 --- a/Code/Mantid/MantidQt/CustomInterfaces/CMakeLists.txt +++ b/Code/Mantid/MantidQt/CustomInterfaces/CMakeLists.txt @@ -10,14 +10,12 @@ set ( SRC_FILES src/Indirect/Fury.cpp src/Indirect/FuryFit.cpp src/Indirect/IDATab.cpp + src/Indirect/ILLEnergyTransfer.cpp src/Indirect/IndirectBayes.cpp src/Indirect/IndirectBayesTab.cpp - src/Indirect/IndirectCalibration.cpp - src/Indirect/IndirectConvertToEnergy.cpp src/Indirect/IndirectDataAnalysis.cpp src/Indirect/IndirectDataReduction.cpp src/Indirect/IndirectDataReductionTab.cpp - src/Indirect/IndirectDiagnostics.cpp src/Indirect/IndirectDiffractionReduction.cpp src/Indirect/IndirectLoadILL.cpp src/Indirect/IndirectMolDyn.cpp @@ -32,6 +30,9 @@ set ( SRC_FILES src/Indirect/IndirectToolsTab.cpp src/Indirect/IndirectTransmission.cpp src/Indirect/IndirectTransmissionCalc.cpp + src/Indirect/ISISCalibration.cpp + src/Indirect/ISISDiagnostics.cpp + src/Indirect/ISISEnergyTransfer.cpp src/Indirect/JumpFit.cpp src/Indirect/MSDFit.cpp src/Indirect/Quasi.cpp @@ -90,14 +91,12 @@ set ( INC_FILES inc/MantidQtCustomInterfaces/Indirect/Elwin.h inc/MantidQtCustomInterfaces/Indirect/Fury.h inc/MantidQtCustomInterfaces/Indirect/FuryFit.h + inc/MantidQtCustomInterfaces/Indirect/ILLEnergyTransfer.h inc/MantidQtCustomInterfaces/Indirect/IndirectBayes.h inc/MantidQtCustomInterfaces/Indirect/IndirectBayesTab.h - inc/MantidQtCustomInterfaces/Indirect/IndirectCalibration.h - inc/MantidQtCustomInterfaces/Indirect/IndirectConvertToEnergy.h inc/MantidQtCustomInterfaces/Indirect/IndirectDataAnalysis.h inc/MantidQtCustomInterfaces/Indirect/IndirectDataReduction.h inc/MantidQtCustomInterfaces/Indirect/IndirectDataReductionTab.h - inc/MantidQtCustomInterfaces/Indirect/IndirectDiagnostics.h inc/MantidQtCustomInterfaces/Indirect/IndirectDiffractionReduction.h inc/MantidQtCustomInterfaces/Indirect/IndirectLoadILL.h inc/MantidQtCustomInterfaces/Indirect/IndirectMolDyn.h @@ -117,6 +116,9 @@ set ( INC_FILES inc/MantidQtCustomInterfaces/Indirect/Quasi.h inc/MantidQtCustomInterfaces/Indirect/ResNorm.h inc/MantidQtCustomInterfaces/Indirect/Stretch.h + inc/MantidQtCustomInterfaces/Indirect/ISISCalibration.h + inc/MantidQtCustomInterfaces/Indirect/ISISDiagnostics.h + inc/MantidQtCustomInterfaces/Indirect/ISISEnergyTransfer.h inc/MantidQtCustomInterfaces/IReflPresenter.h inc/MantidQtCustomInterfaces/IReflSearcher.h inc/MantidQtCustomInterfaces/MantidEV.h @@ -178,14 +180,12 @@ set ( MOC_FILES inc/MantidQtCustomInterfaces/Background.h inc/MantidQtCustomInterfaces/Indirect/Elwin.h inc/MantidQtCustomInterfaces/Indirect/Fury.h inc/MantidQtCustomInterfaces/Indirect/FuryFit.h + inc/MantidQtCustomInterfaces/Indirect/ILLEnergyTransfer.h inc/MantidQtCustomInterfaces/Indirect/IndirectBayes.h inc/MantidQtCustomInterfaces/Indirect/IndirectBayesTab.h - inc/MantidQtCustomInterfaces/Indirect/IndirectCalibration.h - inc/MantidQtCustomInterfaces/Indirect/IndirectConvertToEnergy.h inc/MantidQtCustomInterfaces/Indirect/IndirectDataAnalysis.h inc/MantidQtCustomInterfaces/Indirect/IndirectDataReduction.h inc/MantidQtCustomInterfaces/Indirect/IndirectDataReductionTab.h - inc/MantidQtCustomInterfaces/Indirect/IndirectDiagnostics.h inc/MantidQtCustomInterfaces/Indirect/IndirectDiffractionReduction.h inc/MantidQtCustomInterfaces/Indirect/IndirectLoadILL.h inc/MantidQtCustomInterfaces/Indirect/IndirectMolDyn.h @@ -205,6 +205,9 @@ set ( MOC_FILES inc/MantidQtCustomInterfaces/Background.h inc/MantidQtCustomInterfaces/Indirect/Quasi.h inc/MantidQtCustomInterfaces/Indirect/ResNorm.h inc/MantidQtCustomInterfaces/Indirect/Stretch.h + inc/MantidQtCustomInterfaces/Indirect/ISISCalibration.h + inc/MantidQtCustomInterfaces/Indirect/ISISDiagnostics.h + inc/MantidQtCustomInterfaces/Indirect/ISISEnergyTransfer.h inc/MantidQtCustomInterfaces/MultiDatasetFit.h inc/MantidQtCustomInterfaces/Muon/ALCBaselineModellingPresenter.h inc/MantidQtCustomInterfaces/Muon/ALCBaselineModellingView.h @@ -245,12 +248,10 @@ set ( UI_FILES inc/MantidQtCustomInterfaces/AddWorkspace.ui inc/MantidQtCustomInterfaces/Indirect/Elwin.ui inc/MantidQtCustomInterfaces/Indirect/Fury.ui inc/MantidQtCustomInterfaces/Indirect/FuryFit.ui + inc/MantidQtCustomInterfaces/Indirect/ILLEnergyTransfer.ui inc/MantidQtCustomInterfaces/Indirect/IndirectBayes.ui - inc/MantidQtCustomInterfaces/Indirect/IndirectCalibration.ui - inc/MantidQtCustomInterfaces/Indirect/IndirectConvertToEnergy.ui inc/MantidQtCustomInterfaces/Indirect/IndirectDataAnalysis.ui inc/MantidQtCustomInterfaces/Indirect/IndirectDataReduction.ui - inc/MantidQtCustomInterfaces/Indirect/IndirectDiagnostics.ui inc/MantidQtCustomInterfaces/Indirect/IndirectDiffractionReduction.ui inc/MantidQtCustomInterfaces/Indirect/IndirectLoadILL.ui inc/MantidQtCustomInterfaces/Indirect/IndirectMolDyn.ui @@ -267,6 +268,9 @@ set ( UI_FILES inc/MantidQtCustomInterfaces/AddWorkspace.ui inc/MantidQtCustomInterfaces/Indirect/Quasi.ui inc/MantidQtCustomInterfaces/Indirect/ResNorm.ui inc/MantidQtCustomInterfaces/Indirect/Stretch.ui + inc/MantidQtCustomInterfaces/Indirect/ISISCalibration.ui + inc/MantidQtCustomInterfaces/Indirect/ISISDiagnostics.ui + inc/MantidQtCustomInterfaces/Indirect/ISISEnergyTransfer.ui inc/MantidQtCustomInterfaces/MultiDatasetFit.ui inc/MantidQtCustomInterfaces/Muon/ALCBaselineModellingView.ui inc/MantidQtCustomInterfaces/Muon/ALCDataLoadingView.ui diff --git a/Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/Indirect/CalcCorr.ui b/Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/Indirect/CalcCorr.ui index 0cc9c2cd7374..4329c2f27e08 100644 --- a/Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/Indirect/CalcCorr.ui +++ b/Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/Indirect/CalcCorr.ui @@ -209,7 +209,7 @@ 1 - 0 + 1 @@ -522,7 +522,47 @@ 0 - + + + + 0 + 0 + + + + + 0 + + + + + + + + + + + + + + + 0 + 0 + + + + color: rgb(255, 0, 0); + + + * + + + + + + + + 0 @@ -599,46 +639,6 @@ - - - - 0 - 0 - - - - - 0 - - - - - - - - - - - - - - - 0 - 0 - - - - color: rgb(255, 0, 0); - - - * - - - - - - - @@ -674,12 +674,12 @@ - Input + Formula - Formula + Input @@ -746,7 +746,43 @@ 0 - + + + + 0 + 0 + + + + + 0 + + + + + + + + + + + 0 + 0 + + + + color: rgb(255, 0, 0); + + + * + + + + + + + + true @@ -850,42 +886,6 @@ - - - - 0 - 0 - - - - - 0 - - - - - - - - - - - 0 - 0 - - - - color: rgb(255, 0, 0); - - - * - - - - - - - @@ -924,12 +924,12 @@ - Input + Formula - Formula + Input @@ -1024,6 +1024,63 @@
MantidQtMantidWidgets/DataSelector.h
+ + ckUseCan + cbShape + lets + letc1 + letc2 + ler1 + ler2 + ler3 + leavar + lewidth + lesamden + cbSampleInputType + lesamsigs + lesamsiga + leSampleFormula + lecanden + cbCanInputType + lecansigs + lecansiga + leCanFormula + cbPlotOutput + ckSave + - + + + cbCanInputType + currentIndexChanged(int) + swCanInputType + setCurrentIndex(int) + + + 193 + 405 + + + 440 + 405 + + + + + cbSampleInputType + currentIndexChanged(int) + swSampleInputType + setCurrentIndex(int) + + + 193 + 310 + + + 440 + 310 + + + + diff --git a/Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/Indirect/ConvFit.h b/Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/Indirect/ConvFit.h index 2c4c4959d4bc..97921431d007 100644 --- a/Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/Indirect/ConvFit.h +++ b/Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/Indirect/ConvFit.h @@ -29,7 +29,7 @@ namespace IDA void typeSelection(int index); void bgTypeSelection(int index); void newDataLoaded(const QString wsName); - void plotInput(); + void updatePlot(); void plotGuess(); void singleFit(); void specMinChanged(int value); diff --git a/Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/Indirect/FuryFit.h b/Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/Indirect/FuryFit.h index f941762f2473..66cf514feca4 100644 --- a/Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/Indirect/FuryFit.h +++ b/Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/Indirect/FuryFit.h @@ -37,7 +37,7 @@ namespace IDA private slots: void typeSelection(int index); void newDataLoaded(const QString wsName); - void plotInput(); + void updatePlot(); void specMinChanged(int value); void specMaxChanged(int value); void xMinSelected(double val); diff --git a/Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/Indirect/ILLEnergyTransfer.h b/Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/Indirect/ILLEnergyTransfer.h new file mode 100644 index 000000000000..03ef246dbbdf --- /dev/null +++ b/Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/Indirect/ILLEnergyTransfer.h @@ -0,0 +1,62 @@ +#ifndef MANTIDQTCUSTOMINTERFACES_ILLENERGYTRANSFER_H_ +#define MANTIDQTCUSTOMINTERFACES_ILLENERGYTRANSFER_H_ + +#include "IndirectDataReductionTab.h" +#include "ui_ILLEnergyTransfer.h" +#include "MantidKernel/System.h" + +namespace MantidQt +{ +namespace CustomInterfaces +{ + /** ILLEnergyTransfer + + @author Dan Nixon + @date 23/07/2014 + + Copyright © 2013 ISIS Rutherford Appleton Laboratory, NScD Oak Ridge National Laboratory & European Spallation Source + + This file is part of Mantid. + + Mantid is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + Mantid is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + + File change history is stored at: + Code Documentation is available at: + */ + class DLLExport ILLEnergyTransfer : public IndirectDataReductionTab + { + Q_OBJECT + + public: + ILLEnergyTransfer(IndirectDataReduction * idrUI, QWidget * parent = 0); + virtual ~ILLEnergyTransfer(); + + virtual void setup(); + virtual void run(); + + public slots: + virtual bool validate(); + + private slots: + void algorithmComplete(bool error); + void setInstrumentDefault(); + + private: + Ui::ILLEnergyTransfer m_uiForm; + + }; +} // namespace CustomInterfaces +} // namespace Mantid + +#endif //MANTIDQTCUSTOMINTERFACES_ILLENERGYTRANSFER_H_ diff --git a/Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/Indirect/ILLEnergyTransfer.ui b/Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/Indirect/ILLEnergyTransfer.ui new file mode 100644 index 000000000000..c99655b2f0fa --- /dev/null +++ b/Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/Indirect/ILLEnergyTransfer.ui @@ -0,0 +1,192 @@ + + + ILLEnergyTransfer + + + + 0 + 0 + 600 + 600 + + + + + 500 + 0 + + + + Form + + + + + + Input + + + + + + Run File + + + + + + + + + + Grouping + + + + 0 + + + 0 + + + + + + Default + + + + + Map File + + + + + + + + 0 + + + + + + 0 + + + 0 + + + + + Map File + + + + .map + + + + + + + + + + + + + + + Options + + + + + + Use Mirror Mode + + + + + + + + + + Qt::Vertical + + + + 20 + 0 + + + + + + + + Output + + + + + + Plot Result + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + Save Result + + + + + + + + + + + MantidQt::MantidWidgets::MWRunFiles + QWidget +
MantidQtMantidWidgets/MWRunFiles.h
+ 1 +
+
+ + + + cbGroupingType + currentIndexChanged(int) + swGroupingTypes + setCurrentIndex(int) + + + 60 + 161 + + + 343 + 161 + + + + +
diff --git a/Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/Indirect/IndirectCalibration.h b/Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/Indirect/ISISCalibration.h similarity index 81% rename from Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/Indirect/IndirectCalibration.h rename to Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/Indirect/ISISCalibration.h index 295f3e5229b3..e5089329de9b 100644 --- a/Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/Indirect/IndirectCalibration.h +++ b/Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/Indirect/ISISCalibration.h @@ -1,8 +1,8 @@ -#ifndef MANTIDQTCUSTOMINTERFACES_INDIRECTCALIBRATION_H_ -#define MANTIDQTCUSTOMINTERFACES_INDIRECTCALIBRATION_H_ +#ifndef MANTIDQTCUSTOMINTERFACES_ISISCALIBRATION_H_ +#define MANTIDQTCUSTOMINTERFACES_ISISCALIBRATION_H_ #include "IndirectDataReductionTab.h" -#include "ui_IndirectCalibration.h" +#include "ui_ISISCalibration.h" #include "MantidKernel/System.h" #include "MantidQtCustomInterfaces/UserInputValidator.h" @@ -10,7 +10,8 @@ namespace MantidQt { namespace CustomInterfaces { - /** IndirectCalibration + /** ISISCalibration + Handles vanadium run calibration for ISIS instruments. @author Dan Nixon @date 23/07/2014 @@ -35,13 +36,13 @@ namespace CustomInterfaces File change history is stored at: Code Documentation is available at: */ - class DLLExport IndirectCalibration : public IndirectDataReductionTab + class DLLExport ISISCalibration : public IndirectDataReductionTab { Q_OBJECT public: - IndirectCalibration(IndirectDataReduction * idrUI, QWidget * parent = 0); - virtual ~IndirectCalibration(); + ISISCalibration(IndirectDataReduction * idrUI, QWidget * parent = 0); + virtual ~ISISCalibration(); virtual void setup(); virtual void run(); @@ -64,11 +65,11 @@ namespace CustomInterfaces private: void createRESfile(const QString& file); - Ui::IndirectCalibration m_uiForm; + Ui::ISISCalibration m_uiForm; QString m_lastCalPlotFilename; }; } // namespace CustomInterfaces } // namespace Mantid -#endif //MANTIDQTCUSTOMINTERFACES_INDIRECTCALIBRATION_H_ +#endif //MANTIDQTCUSTOMINTERFACES_ISISCALIBRATION_H_ diff --git a/Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/Indirect/IndirectCalibration.ui b/Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/Indirect/ISISCalibration.ui similarity index 96% rename from Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/Indirect/IndirectCalibration.ui rename to Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/Indirect/ISISCalibration.ui index 1c86fc8dab5d..fe7044fd91db 100644 --- a/Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/Indirect/IndirectCalibration.ui +++ b/Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/Indirect/ISISCalibration.ui @@ -1,15 +1,21 @@ - IndirectCalibration - + ISISCalibration + 0 0 - 423 + 500 339 + + + 500 + 0 + + Form @@ -76,7 +82,7 @@ 999.990000000000009 - 1.0 + 1.000000000000000
@@ -173,7 +179,7 @@ 999.990000000000009 - 1.0 + 1.000000000000000 @@ -237,17 +243,17 @@ - - MantidQt::MantidWidgets::MWRunFiles - QWidget -
MantidQtMantidWidgets/MWRunFiles.h
-
MantidQt::MantidWidgets::PreviewPlot QWidget
MantidQtMantidWidgets/PreviewPlot.h
1
+ + MantidQt::MantidWidgets::MWRunFiles + QWidget +
MantidQtMantidWidgets/MWRunFiles.h
+
diff --git a/Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/Indirect/IndirectDiagnostics.h b/Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/Indirect/ISISDiagnostics.h similarity index 80% rename from Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/Indirect/IndirectDiagnostics.h rename to Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/Indirect/ISISDiagnostics.h index 5020695b6fe4..d07b10691bb1 100644 --- a/Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/Indirect/IndirectDiagnostics.h +++ b/Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/Indirect/ISISDiagnostics.h @@ -1,8 +1,8 @@ -#ifndef MANTIDQTCUSTOMINTERFACES_INDIRECTDIAGNOSTICS_H_ -#define MANTIDQTCUSTOMINTERFACES_INDIRECTDIAGNOSTICS_H_ +#ifndef MANTIDQTCUSTOMINTERFACES_ISISDIAGNOSTICS_H_ +#define MANTIDQTCUSTOMINTERFACES_ISISDIAGNOSTICS_H_ #include "IndirectDataReductionTab.h" -#include "ui_IndirectDiagnostics.h" +#include "ui_ISISDiagnostics.h" #include "MantidAPI/MatrixWorkspace.h" #include "MantidKernel/System.h" @@ -28,7 +28,8 @@ namespace MantidQt { namespace CustomInterfaces { - /** IndirectDiagnostics + /** ISISDiagnostics + Handles time integration diagnostics for ISIS instruments. @author Dan Nixon @date 23/07/2014 @@ -53,24 +54,24 @@ namespace CustomInterfaces File change history is stored at: Code Documentation is available at: */ - class DLLExport IndirectDiagnostics : public IndirectDataReductionTab + class DLLExport ISISDiagnostics : public IndirectDataReductionTab { Q_OBJECT public: - IndirectDiagnostics(IndirectDataReduction * idrUI, QWidget * parent = 0); - virtual ~IndirectDiagnostics(); + ISISDiagnostics(IndirectDataReduction * idrUI, QWidget * parent = 0); + virtual ~ISISDiagnostics(); virtual void setup(); virtual void run(); virtual bool validate(); private slots: - void slicePlotRaw(); + void handleNewFile(); void sliceTwoRanges(QtProperty*, bool); void sliceCalib(bool state); void rangeSelectorDropped(double, double); - void sliceUpdateRS(QtProperty*, double); + void doublePropertyChanged(QtProperty*, double); void setDefaultInstDetails(); void updatePreviewPlot(); void sliceAlgDone(bool error); @@ -79,11 +80,10 @@ namespace CustomInterfaces void pbRunFinished(); //< Called when the FileFinder has finished finding the files. private: - Ui::IndirectDiagnostics m_uiForm; - QString m_lastDiagFilename; + Ui::ISISDiagnostics m_uiForm; }; } // namespace CustomInterfaces } // namespace Mantid -#endif //MANTIDQTCUSTOMINTERFACES_INDIRECTDIAGNOSTICS_H__ +#endif //MANTIDQTCUSTOMINTERFACES_ISISDIAGNOSTICS_H_ diff --git a/Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/Indirect/IndirectDiagnostics.ui b/Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/Indirect/ISISDiagnostics.ui similarity index 96% rename from Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/Indirect/IndirectDiagnostics.ui rename to Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/Indirect/ISISDiagnostics.ui index 86d24761770d..f00f6fe4e5dd 100644 --- a/Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/Indirect/IndirectDiagnostics.ui +++ b/Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/Indirect/ISISDiagnostics.ui @@ -1,7 +1,7 @@ - IndirectDiagnostics - + ISISDiagnostics + 0 @@ -10,6 +10,12 @@ 448 + + + 500 + 0 + + Form @@ -179,11 +185,6 @@ - - MantidQt::MantidWidgets::MWRunFiles - QWidget -
MantidQtMantidWidgets/MWRunFiles.h
-
MantidQt::MantidWidgets::DataSelector QWidget @@ -195,6 +196,11 @@
MantidQtMantidWidgets/PreviewPlot.h
1
+ + MantidQt::MantidWidgets::MWRunFiles + QWidget +
MantidQtMantidWidgets/MWRunFiles.h
+
diff --git a/Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/Indirect/IndirectConvertToEnergy.h b/Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/Indirect/ISISEnergyTransfer.h similarity index 81% rename from Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/Indirect/IndirectConvertToEnergy.h rename to Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/Indirect/ISISEnergyTransfer.h index 55e065000367..167b3f9c1e28 100644 --- a/Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/Indirect/IndirectConvertToEnergy.h +++ b/Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/Indirect/ISISEnergyTransfer.h @@ -1,8 +1,8 @@ -#ifndef MANTIDQTCUSTOMINTERFACES_INDIRECTCONVERTTOENERGY_H_ -#define MANTIDQTCUSTOMINTERFACES_INDIRECTCONVERTTOENERGY_H_ +#ifndef MANTIDQTCUSTOMINTERFACES_ISISENERGYTRANSFER_H_ +#define MANTIDQTCUSTOMINTERFACES_ISISENERGYTRANSFER_H_ #include "IndirectDataReductionTab.h" -#include "ui_IndirectConvertToEnergy.h" +#include "ui_ISISEnergyTransfer.h" #include "MantidKernel/System.h" #include "MantidQtCustomInterfaces/Background.h" @@ -10,7 +10,8 @@ namespace MantidQt { namespace CustomInterfaces { - /** IndirectConvertToEnergy + /** ISISEnergyTransfer + Handles an energy transfer reduction for ISIS instruments. @author Dan Nixon @date 23/07/2014 @@ -35,13 +36,13 @@ namespace CustomInterfaces File change history is stored at: Code Documentation is available at: */ - class DLLExport IndirectConvertToEnergy : public IndirectDataReductionTab + class DLLExport ISISEnergyTransfer : public IndirectDataReductionTab { Q_OBJECT public: - IndirectConvertToEnergy(IndirectDataReduction * idrUI, QWidget * parent = 0); - virtual ~IndirectConvertToEnergy(); + ISISEnergyTransfer(IndirectDataReduction * idrUI, QWidget * parent = 0); + virtual ~ISISEnergyTransfer(); virtual void setup(); virtual void run(); @@ -60,7 +61,7 @@ namespace CustomInterfaces void plotRawComplete(bool error); //< Called when the Plot Raw algorithmm chain completes private: - Ui::IndirectConvertToEnergy m_uiForm; + Ui::ISISEnergyTransfer m_uiForm; QString createMapFile(const QString& groupType); ///< create the mapping file with which to group results std::vector getSaveFormats(); ///< get a vector of save formats @@ -69,4 +70,4 @@ namespace CustomInterfaces } // namespace CustomInterfaces } // namespace Mantid -#endif //MANTIDQTCUSTOMINTERFACES_INDIRECTCONVERTTOENERGY_H_ +#endif //MANTIDQTCUSTOMINTERFACES_ISISENERGYTRANSFER_H_ diff --git a/Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/Indirect/IndirectConvertToEnergy.ui b/Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/Indirect/ISISEnergyTransfer.ui similarity index 99% rename from Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/Indirect/IndirectConvertToEnergy.ui rename to Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/Indirect/ISISEnergyTransfer.ui index c0b72ee847eb..9d02ad63d362 100644 --- a/Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/Indirect/IndirectConvertToEnergy.ui +++ b/Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/Indirect/ISISEnergyTransfer.ui @@ -1,7 +1,7 @@ - IndirectConvertToEnergy - + ISISEnergyTransfer + 0 @@ -10,6 +10,12 @@ 629 + + + 500 + 0 + + Form @@ -916,14 +922,14 @@ - MantidQt::MantidWidgets::MWRunFiles + MantidQt::MantidWidgets::DataSelector QWidget -
MantidQtMantidWidgets/MWRunFiles.h
+
MantidQtMantidWidgets/DataSelector.h
- MantidQt::MantidWidgets::DataSelector + MantidQt::MantidWidgets::MWRunFiles QWidget -
MantidQtMantidWidgets/DataSelector.h
+
MantidQtMantidWidgets/MWRunFiles.h
diff --git a/Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/Indirect/IndirectDataReduction.h b/Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/Indirect/IndirectDataReduction.h index bb3a724082a0..234d7e0df8f4 100644 --- a/Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/Indirect/IndirectDataReduction.h +++ b/Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/Indirect/IndirectDataReduction.h @@ -8,9 +8,11 @@ #include "MantidQtAPI/AlgorithmRunner.h" #include "MantidQtAPI/UserSubWindow.h" +#include "MantidQtCustomInterfaces/Indirect/IndirectDataReductionTab.h" + +#include +#include -#include -#include namespace MantidQt { @@ -70,7 +72,7 @@ namespace MantidQt virtual void initLocalPython(); /// Handled configuration changes - void handleDirectoryChange(Mantid::Kernel::ConfigValChangeNotification_ptr pNf); + void handleConfigChange(Mantid::Kernel::ConfigValChangeNotification_ptr pNf); Mantid::API::MatrixWorkspace_sptr loadInstrumentIfNotExist(std::string instrumentName, std::string analyser = "", std::string reflection = ""); @@ -83,6 +85,8 @@ namespace MantidQt void newInstrumentConfiguration(); private slots: + /// Shows/hides tabs based on facility + void filterUiForFacility(QString facility); /// Opens the help page for the current tab void helpClicked(); /// Exports the current tab algorithms as a Python script @@ -112,6 +116,46 @@ namespace MantidQt /// Set and show an instrument-specific widget virtual void closeEvent(QCloseEvent* close); + /** + * Adds a tab to the cache of tabs that can be shown. + * + * THis method is used to ensure that the tabs are always loaded and their + * layouts setup for the sake of screenshoting them for documentation. + * + * @param T Tab type, must be subclass of IndirectDataReductionTab + * @param name Name to be displayed on tab + */ + template + void addTab(const QString & name) + { + QWidget * tabWidget = new QWidget(m_uiForm.twIDRTabs); + QVBoxLayout * tabLayout = new QVBoxLayout(tabWidget); + tabWidget->setLayout(tabLayout); + + QScrollArea * tabScrollArea = new QScrollArea(tabWidget); + tabLayout->addWidget(tabScrollArea); + tabScrollArea->setWidgetResizable(true); + + QWidget * tabContent = new QWidget(tabScrollArea); + tabContent->setObjectName("tab" + QString(name).remove(QRegExp("[ ,()]"))); + tabScrollArea->setWidget(tabContent); + tabScrollArea->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); + + IndirectDataReductionTab * tabIDRContent = new T(this, tabContent); + tabIDRContent->setupTab(); + tabContent->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); + + connect(tabIDRContent, SIGNAL(runAsPythonScript(const QString&, bool)), this, SIGNAL(runAsPythonScript(const QString&, bool))); + connect(tabIDRContent, SIGNAL(showMessageBox(const QString&)), this, SLOT(showMessageBox(const QString&))); + connect(tabIDRContent, SIGNAL(updateRunButton(bool, QString, QString)), this, SLOT(updateRunButton(bool, QString, QString))); + + // Add to the cache + m_tabs[name] = qMakePair(tabWidget, tabIDRContent); + + // Add all tabs to UI initially + m_uiForm.twIDRTabs->addTab(tabWidget, name); + } + friend class IndirectDataReductionTab; /// The .ui form generated by Qt Designer Ui::IndirectDataReduction m_uiForm; @@ -123,7 +167,7 @@ namespace MantidQt MantidQt::API::AlgorithmRunner* m_algRunner; // All indirect tabs - std::map m_tabs; + QMap> m_tabs; /// Poco observer for changes in user directory settings Poco::NObserver m_changeObserver; diff --git a/Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/Indirect/IndirectDataReduction.ui b/Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/Indirect/IndirectDataReduction.ui index b06ef0ed8c1b..441c1b631011 100644 --- a/Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/Indirect/IndirectDataReduction.ui +++ b/Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/Indirect/IndirectDataReduction.ui @@ -38,11 +38,9 @@ TOF Indirect Geometry Spectroscopy + Reactor Indirect Geometry Spectroscopy - - ISIS - false @@ -62,11 +60,8 @@ 0 - - - - 0 + -1 @@ -74,174 +69,6 @@ 14 - - - Energy Transfer - - - - - - true - - - - - 0 - 0 - 100 - 100 - - - - - - - - - - Calibration - - - - - - true - - - - - 0 - 0 - 100 - 100 - - - - - - - - - - Diagnostics - - - - - - true - - - - - 0 - 0 - 100 - 100 - - - - - - - - - - Transmission - - - - - - true - - - - - 0 - 0 - 100 - 100 - - - - - - - - - - Symmetrise - - - - - - true - - - - - 0 - 0 - 100 - 100 - - - - - - - - - - S(Q, w) - - - - - - true - - - - - 0 - 0 - 100 - 100 - - - - - - - - - - Moments - - - - - - true - - - - - 0 - 0 - 100 - 100 - - - - - - -
diff --git a/Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/Indirect/IndirectDataReductionTab.h b/Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/Indirect/IndirectDataReductionTab.h index 876aa020bb57..a9003092e942 100644 --- a/Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/Indirect/IndirectDataReductionTab.h +++ b/Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/Indirect/IndirectDataReductionTab.h @@ -10,7 +10,6 @@ #include "MantidQtAPI/QwtWorkspaceSpectrumData.h" #include "MantidQtMantidWidgets/IndirectInstrumentConfig.h" #include "IndirectTab.h" -#include "IndirectDataReduction.h" #include "MantidQtMantidWidgets/RangeSelector.h" #include @@ -43,6 +42,8 @@ namespace MantidQt { namespace CustomInterfaces { + class IndirectDataReduction; + /** IndirectDataReductionTab This class defines common functionality of tabs used in the Indirect Data Reduction interface. diff --git a/Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/Indirect/IndirectMoments.ui b/Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/Indirect/IndirectMoments.ui index d31ce9b5b209..52314f281d2e 100644 --- a/Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/Indirect/IndirectMoments.ui +++ b/Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/Indirect/IndirectMoments.ui @@ -6,10 +6,16 @@ 0 0 - 444 + 500 398 + + + 500 + 0 + + Form diff --git a/Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/Indirect/IndirectSqw.ui b/Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/Indirect/IndirectSqw.ui index 0b0e45ea1d7a..65b93659d26c 100644 --- a/Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/Indirect/IndirectSqw.ui +++ b/Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/Indirect/IndirectSqw.ui @@ -10,6 +10,12 @@ 268 + + + 500 + 0 + + Form diff --git a/Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/Indirect/IndirectSymmetrise.ui b/Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/Indirect/IndirectSymmetrise.ui index 8887984e52d0..bfb1670f7b03 100644 --- a/Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/Indirect/IndirectSymmetrise.ui +++ b/Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/Indirect/IndirectSymmetrise.ui @@ -6,10 +6,16 @@ 0 0 - 488 - 269 + 500 + 270 + + + 500 + 0 + + Form diff --git a/Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/Indirect/IndirectTransmission.ui b/Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/Indirect/IndirectTransmission.ui index d3f4ab2e34a3..4a1688b91c87 100644 --- a/Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/Indirect/IndirectTransmission.ui +++ b/Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/Indirect/IndirectTransmission.ui @@ -10,6 +10,12 @@ 360 + + + 500 + 0 + + Form diff --git a/Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/Indirect/MSDFit.h b/Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/Indirect/MSDFit.h index c5b9b28516fa..d561a10ee3d6 100644 --- a/Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/Indirect/MSDFit.h +++ b/Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/Indirect/MSDFit.h @@ -25,7 +25,7 @@ namespace IDA private slots: void singleFit(); - void plotFit(QString wsName); + void plotFit(QString wsName = QString(), int specNo = -1); void newDataLoaded(const QString wsName); void plotInput(); void specMinChanged(int value); diff --git a/Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/Muon/ALCDataLoadingView.h b/Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/Muon/ALCDataLoadingView.h index 50f1291b2bb9..439423305fa1 100644 --- a/Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/Muon/ALCDataLoadingView.h +++ b/Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/Muon/ALCDataLoadingView.h @@ -53,6 +53,8 @@ namespace CustomInterfaces std::string firstRun() const; std::string lastRun() const; std::string log() const; + std::string deadTimeType() const; + std::string deadTimeFile() const; std::string calculationType() const; boost::optional< std::pair > timeRange() const; diff --git a/Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/Muon/ALCDataLoadingView.ui b/Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/Muon/ALCDataLoadingView.ui index 9dea3843ec4c..9780978e28ef 100644 --- a/Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/Muon/ALCDataLoadingView.ui +++ b/Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/Muon/ALCDataLoadingView.ui @@ -97,6 +97,88 @@
+ + + Dead Time Correction + + + + + + + + None + + + true + + + deadTimeCorrType + + + + + + + From Data File + + + deadTimeCorrType + + + + + + + From Custom File + + + deadTimeCorrType + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + + + + 0 + 0 + + + + + + + false + + + false + + + + + + + + + Calculation @@ -313,8 +395,15 @@ + + fromCustomFile + toggled(bool) + deadTimeFile + setEnabled(bool) +
+ diff --git a/Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/Muon/IALCDataLoadingView.h b/Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/Muon/IALCDataLoadingView.h index aecda2b2f69e..cb4ce9f9643b 100644 --- a/Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/Muon/IALCDataLoadingView.h +++ b/Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/Muon/IALCDataLoadingView.h @@ -53,6 +53,12 @@ namespace CustomInterfaces /// @return Log name virtual std::string log() const = 0; + /// @return dead time correction type to use + virtual std::string deadTimeType() const = 0; + + /// @return dead time correction file + virtual std::string deadTimeFile() const = 0; + /// @return Selected calculation type - "Integral" or "Differential" virtual std::string calculationType() const = 0; diff --git a/Code/Mantid/MantidQt/CustomInterfaces/src/Indirect/CalcCorr.cpp b/Code/Mantid/MantidQt/CustomInterfaces/src/Indirect/CalcCorr.cpp index 462fb4a2e0b7..21b2211abb35 100644 --- a/Code/Mantid/MantidQt/CustomInterfaces/src/Indirect/CalcCorr.cpp +++ b/Code/Mantid/MantidQt/CustomInterfaces/src/Indirect/CalcCorr.cpp @@ -111,8 +111,6 @@ namespace IDA connect(m_uiForm.cbShape, SIGNAL(currentIndexChanged(int)), this, SLOT(shape(int))); connect(m_uiForm.ckUseCan, SIGNAL(toggled(bool)), this, SLOT(useCanChecked(bool))); connect(m_uiForm.letc1, SIGNAL(editingFinished()), this, SLOT(tcSync())); - connect(m_uiForm.cbSampleInputType, SIGNAL(currentIndexChanged(int)), m_uiForm.swSampleInputType, SLOT(setCurrentIndex(int))); - connect(m_uiForm.cbCanInputType, SIGNAL(currentIndexChanged(int)), m_uiForm.swCanInputType, SLOT(setCurrentIndex(int))); connect(m_uiForm.dsSampleInput, SIGNAL(dataReady(const QString&)), this, SLOT(getBeamWidthFromWorkspace(const QString&))); // Sort the fields into various lists. diff --git a/Code/Mantid/MantidQt/CustomInterfaces/src/Indirect/ConvFit.cpp b/Code/Mantid/MantidQt/CustomInterfaces/src/Indirect/ConvFit.cpp index ebf92f8aec32..58ba4caaaf9e 100644 --- a/Code/Mantid/MantidQt/CustomInterfaces/src/Indirect/ConvFit.cpp +++ b/Code/Mantid/MantidQt/CustomInterfaces/src/Indirect/ConvFit.cpp @@ -121,7 +121,7 @@ namespace IDA bgTypeSelection(m_uiForm.cbBackground->currentIndex()); // Replot input automatically when file / spec no changes - connect(m_uiForm.spPlotSpectrum, SIGNAL(valueChanged(int)), this, SLOT(plotInput())); + connect(m_uiForm.spPlotSpectrum, SIGNAL(valueChanged(int)), this, SLOT(updatePlot())); connect(m_uiForm.dsSampleInput, SIGNAL(dataReady(const QString&)), this, SLOT(newDataLoaded(const QString&))); connect(m_uiForm.spSpectraMin, SIGNAL(valueChanged(int)), this, SLOT(specMinChanged(int))); @@ -203,6 +203,8 @@ namespace IDA QString inputWsName = QString::fromStdString(m_cfInputWS->getName()); QString resultWsName = inputWsName.left(inputWsName.lastIndexOf("_")) + "_conv_" + fitType + bgType + specMin + "_to_" + specMax + "_Workspaces"; m_pythonExportWsName = resultWsName.toStdString(); + + updatePlot(); } /** @@ -260,7 +262,7 @@ namespace IDA m_uiForm.spSpectraMax->setMinimum(0); m_uiForm.spSpectraMax->setValue(maxSpecIndex); - plotInput(); + updatePlot(); } namespace @@ -670,7 +672,7 @@ namespace IDA } } - void ConvFit::plotInput() + void ConvFit::updatePlot() { using Mantid::Kernel::Exception::NotFoundError; @@ -707,6 +709,17 @@ namespace IDA m_dblManager->setValue(m_properties["Lorentzian 1.FWHM"], resolution); m_dblManager->setValue(m_properties["Lorentzian 2.FWHM"], resolution); } + + // If there is a result plot then plot it + if(AnalysisDataService::Instance().doesExist(m_pythonExportWsName)) + { + WorkspaceGroup_sptr outputGroup = AnalysisDataService::Instance().retrieveWS(m_pythonExportWsName); + if(specNo >= static_cast(outputGroup->size())) + return; + MatrixWorkspace_sptr ws = boost::dynamic_pointer_cast(outputGroup->getItem(specNo)); + if(ws) + m_uiForm.ppPlot->addSpectrum("Fit", ws, 1, Qt::red); + } } void ConvFit::plotGuess() @@ -723,7 +736,7 @@ namespace IDA if ( m_cfInputWS == NULL ) { - plotInput(); + updatePlot(); } const size_t binIndexLow = m_cfInputWS->binIndexOf(m_dblManager->value(m_properties["StartX"])); @@ -777,7 +790,7 @@ namespace IDA if(!validate()) return; - plotInput(); + updatePlot(); m_uiForm.ckPlotGuess->setChecked(false); @@ -897,6 +910,8 @@ namespace IDA m_dblManager->setValue(m_properties["Lorentzian 2.PeakCentre"], parameters[pref+"PeakCentre"]); m_dblManager->setValue(m_properties["Lorentzian 2.FWHM"], parameters[pref+"FWHM"]); } + + m_pythonExportWsName = ""; } /** diff --git a/Code/Mantid/MantidQt/CustomInterfaces/src/Indirect/FuryFit.cpp b/Code/Mantid/MantidQt/CustomInterfaces/src/Indirect/FuryFit.cpp index 9b01afb73004..8c8840ab7ace 100644 --- a/Code/Mantid/MantidQt/CustomInterfaces/src/Indirect/FuryFit.cpp +++ b/Code/Mantid/MantidQt/CustomInterfaces/src/Indirect/FuryFit.cpp @@ -103,9 +103,9 @@ namespace IDA connect(m_uiForm.cbFitType, SIGNAL(currentIndexChanged(int)), this, SLOT(typeSelection(int))); connect(m_uiForm.pbSingle, SIGNAL(clicked()), this, SLOT(singleFit())); - connect(m_uiForm.dsSampleInput, SIGNAL(filesFound()), this, SLOT(plotInput())); + connect(m_uiForm.dsSampleInput, SIGNAL(filesFound()), this, SLOT(updatePlot())); - connect(m_uiForm.spPlotSpectrum, SIGNAL(valueChanged(int)), this, SLOT(plotInput())); + connect(m_uiForm.spPlotSpectrum, SIGNAL(valueChanged(int)), this, SLOT(updatePlot())); connect(m_uiForm.spSpectraMin, SIGNAL(valueChanged(int)), this, SLOT(specMinChanged(int))); connect(m_uiForm.spSpectraMax, SIGNAL(valueChanged(int)), this, SLOT(specMaxChanged(int))); @@ -171,6 +171,8 @@ namespace IDA QString inputWsName = QString::fromStdString(m_ffInputWS->getName()); QString resultWsName = inputWsName.left(inputWsName.lastIndexOf("_")) + "_fury_" + fitType + specMin + "_to_" + specMax + "_Workspaces"; m_pythonExportWsName = resultWsName.toStdString(); + + updatePlot(); } bool FuryFit::validate() @@ -218,7 +220,7 @@ namespace IDA m_uiForm.spSpectraMax->setMinimum(0); m_uiForm.spSpectraMax->setValue(maxSpecIndex); - plotInput(); + updatePlot(); } CompositeFunction_sptr FuryFit::createFunction(bool tie) @@ -380,7 +382,7 @@ namespace IDA plotGuess(NULL); } - void FuryFit::plotInput() + void FuryFit::updatePlot() { if(!m_ffInputWS) { @@ -412,6 +414,17 @@ namespace IDA { showMessageBox(exc.what()); } + + // If there is a result plot then plot it + if(AnalysisDataService::Instance().doesExist(m_pythonExportWsName)) + { + WorkspaceGroup_sptr outputGroup = AnalysisDataService::Instance().retrieveWS(m_pythonExportWsName); + if(specNo >= static_cast(outputGroup->size())) + return; + MatrixWorkspace_sptr ws = boost::dynamic_pointer_cast(outputGroup->getItem(specNo)); + if(ws) + m_uiForm.ppPlot->addSpectrum("Fit", ws, 1, Qt::red); + } } void FuryFit::setDefaultParameters(const QString& name) @@ -568,7 +581,7 @@ namespace IDA } QString ftype = fitTypeString(); - plotInput(); + updatePlot(); if ( m_ffInputWS == NULL ) { return; @@ -648,6 +661,8 @@ namespace IDA plotGuess(NULL); // Now show the fitted curve of the mini plot m_uiForm.ppPlot->addSpectrum("Fit", outputNm+"_Workspace", 1, Qt::red); + + m_pythonExportWsName = ""; } void FuryFit::plotGuess(QtProperty*) diff --git a/Code/Mantid/MantidQt/CustomInterfaces/src/Indirect/ILLEnergyTransfer.cpp b/Code/Mantid/MantidQt/CustomInterfaces/src/Indirect/ILLEnergyTransfer.cpp new file mode 100644 index 000000000000..d3aa64a03692 --- /dev/null +++ b/Code/Mantid/MantidQt/CustomInterfaces/src/Indirect/ILLEnergyTransfer.cpp @@ -0,0 +1,146 @@ +#include "MantidQtCustomInterfaces/Indirect/ILLEnergyTransfer.h" + +#include "MantidQtCustomInterfaces/Background.h" +#include "MantidQtCustomInterfaces/UserInputValidator.h" + +#include +#include + +using namespace Mantid::API; + +namespace MantidQt +{ +namespace CustomInterfaces +{ + //---------------------------------------------------------------------------------------------- + /** Constructor + */ + ILLEnergyTransfer::ILLEnergyTransfer(IndirectDataReduction * idrUI, QWidget * parent) : + IndirectDataReductionTab(idrUI, parent) + { + m_uiForm.setupUi(parent); + + connect(this, SIGNAL(newInstrumentConfiguration()), this, SLOT(setInstrumentDefault())); + connect(m_batchAlgoRunner, SIGNAL(batchComplete(bool)), this, SLOT(algorithmComplete(bool))); + + // Validate to remove invalid markers + validateTab(); + } + + + //---------------------------------------------------------------------------------------------- + /** Destructor + */ + ILLEnergyTransfer::~ILLEnergyTransfer() + { + } + + + void ILLEnergyTransfer::setup() + { + } + + + bool ILLEnergyTransfer::validate() + { + UserInputValidator uiv; + + // Validate run file + if(!m_uiForm.rfInput->isValid()) + uiv.addErrorMessage("Run File is invalid."); + + // Validate map file if it is being used + bool useMapFile = m_uiForm.cbGroupingType->currentText() == "Map File"; + if(useMapFile && !m_uiForm.rfInput->isValid()) + uiv.addErrorMessage("Map File is invalid."); + + // Show error message for errors + if(!uiv.isAllInputValid()) + showMessageBox(uiv.generateErrorMessage()); + + return uiv.isAllInputValid(); + } + + + void ILLEnergyTransfer::run() + { + std::map instDetails = getInstrumentDetails(); + + IAlgorithm_sptr reductionAlg = AlgorithmManager::Instance().create("IndirectILLReduction"); + reductionAlg->initialize(); + + reductionAlg->setProperty("Analyser", instDetails["analyser"].toStdString()); + reductionAlg->setProperty("Reflection", instDetails["reflection"].toStdString()); + + // Handle einput files + QString runFilename = m_uiForm.rfInput->getFirstFilename(); + reductionAlg->setProperty("Run", runFilename.toStdString()); + + // Handle mapping file + bool useMapFile = m_uiForm.cbGroupingType->currentText() == "Map File"; + if(useMapFile) + { + QString mapFilename = m_uiForm.rfMapFile->getFirstFilename(); + reductionAlg->setProperty("MapFile", mapFilename.toStdString()); + } + + // Set mirror mode option + bool mirrorMode = m_uiForm.ckMirrorMode->isChecked(); + reductionAlg->setProperty("MirrorMode", mirrorMode); + + // Get the name format for output files + QFileInfo runFileInfo(runFilename); + QString outputFilenameBase = runFileInfo.baseName() + + "_" + instDetails["analyser"] + + "_" + instDetails["reflection"]; + std::string outputFilenameBaseStd = outputFilenameBase.toStdString(); + + // Set left and right workspaces when using mirror mode + if(mirrorMode) + { + reductionAlg->setProperty("LeftWorkspace", outputFilenameBaseStd + "_left"); + reductionAlg->setProperty("RightWorkspace", outputFilenameBaseStd + "_right"); + } + + // Set output workspace properties + reductionAlg->setProperty("RawWorkspace", outputFilenameBaseStd + "_raw"); + reductionAlg->setProperty("ReducedWorkspace", outputFilenameBaseStd + "_red"); + + // Set output options + reductionAlg->setProperty("Plot", m_uiForm.ckPlot->isChecked()); + reductionAlg->setProperty("Save", m_uiForm.ckSave->isChecked()); + + m_batchAlgoRunner->addAlgorithm(reductionAlg); + m_batchAlgoRunner->executeBatchAsync(); + } + + + /** + * Handles completion of the algorithm. + * + * @param error True if the algorithm was stopped due to error, false otherwise + */ + void ILLEnergyTransfer::algorithmComplete(bool error) + { + if(error) + return; + + // Nothing to do here + } + + + /** + * Called when the instrument has changed, used to update default values. + */ + void ILLEnergyTransfer::setInstrumentDefault() + { + std::map instDetails = getInstrumentDetails(); + + // Set instrument in run file widgets + m_uiForm.rfInput->setInstrumentOverride(instDetails["instrument"]); + m_uiForm.rfMapFile->setInstrumentOverride(instDetails["instrument"]); + } + + +} // namespace CustomInterfaces +} // namespace Mantid diff --git a/Code/Mantid/MantidQt/CustomInterfaces/src/Indirect/IndirectCalibration.cpp b/Code/Mantid/MantidQt/CustomInterfaces/src/Indirect/ISISCalibration.cpp similarity index 96% rename from Code/Mantid/MantidQt/CustomInterfaces/src/Indirect/IndirectCalibration.cpp rename to Code/Mantid/MantidQt/CustomInterfaces/src/Indirect/ISISCalibration.cpp index 4554eb11e15d..058459d8cc98 100644 --- a/Code/Mantid/MantidQt/CustomInterfaces/src/Indirect/IndirectCalibration.cpp +++ b/Code/Mantid/MantidQt/CustomInterfaces/src/Indirect/ISISCalibration.cpp @@ -1,4 +1,4 @@ -#include "MantidQtCustomInterfaces/Indirect/IndirectCalibration.h" +#include "MantidQtCustomInterfaces/Indirect/ISISCalibration.h" #include "MantidKernel/Logger.h" @@ -8,7 +8,7 @@ using namespace Mantid::API; namespace { - Mantid::Kernel::Logger g_log("IndirectCalibration"); + Mantid::Kernel::Logger g_log("ISISCalibration"); } using namespace Mantid::API; @@ -21,7 +21,7 @@ namespace CustomInterfaces //---------------------------------------------------------------------------------------------- /** Constructor */ - IndirectCalibration::IndirectCalibration(IndirectDataReduction * idrUI, QWidget * parent) : + ISISCalibration::ISISCalibration(IndirectDataReduction * idrUI, QWidget * parent) : IndirectDataReductionTab(idrUI, parent), m_lastCalPlotFilename("") { @@ -143,15 +143,15 @@ namespace CustomInterfaces //---------------------------------------------------------------------------------------------- /** Destructor */ - IndirectCalibration::~IndirectCalibration() + ISISCalibration::~ISISCalibration() { } - void IndirectCalibration::setup() + void ISISCalibration::setup() { } - void IndirectCalibration::run() + void ISISCalibration::run() { // Get properties QString firstFile = m_uiForm.leRunNo->getFirstFilename(); @@ -281,7 +281,7 @@ namespace CustomInterfaces m_batchAlgoRunner->executeBatchAsync(); } - void IndirectCalibration::algorithmComplete(bool error) + void ISISCalibration::algorithmComplete(bool error) { if(error) return; @@ -294,7 +294,7 @@ namespace CustomInterfaces } } - bool IndirectCalibration::validate() + bool ISISCalibration::validate() { MantidQt::CustomInterfaces::UserInputValidator uiv; @@ -330,7 +330,7 @@ namespace CustomInterfaces /** * Sets default spectra, peak and background ranges. */ - void IndirectCalibration::setDefaultInstDetails() + void ISISCalibration::setDefaultInstDetails() { // Get spectra, peak and background details std::map instDetails = getInstrumentDetails(); @@ -355,7 +355,7 @@ namespace CustomInterfaces /** * Replots the raw data mini plot and the energy mini plot */ - void IndirectCalibration::calPlotRaw() + void ISISCalibration::calPlotRaw() { setDefaultInstDetails(); @@ -408,7 +408,7 @@ namespace CustomInterfaces /** * Replots the energy mini plot */ - void IndirectCalibration::calPlotEnergy() + void ISISCalibration::calPlotEnergy() { if ( ! m_uiForm.leRunNo->isValid() ) { @@ -473,7 +473,7 @@ namespace CustomInterfaces * * @param ws :: Mantid workspace containing the loaded instument */ - void IndirectCalibration::calSetDefaultResolution(MatrixWorkspace_const_sptr ws) + void ISISCalibration::calSetDefaultResolution(MatrixWorkspace_const_sptr ws) { auto inst = ws->getInstrument(); auto analyser = inst->getStringParameter("analyser"); @@ -509,7 +509,7 @@ namespace CustomInterfaces * * @param val :: New minumum value */ - void IndirectCalibration::calMinChanged(double val) + void ISISCalibration::calMinChanged(double val) { MantidWidgets::RangeSelector* from = qobject_cast(sender()); if ( from == m_rangeSelectors["CalPeak"] ) @@ -536,7 +536,7 @@ namespace CustomInterfaces * * @param val :: New maxumum value */ - void IndirectCalibration::calMaxChanged(double val) + void ISISCalibration::calMaxChanged(double val) { MantidWidgets::RangeSelector* from = qobject_cast(sender()); if ( from == m_rangeSelectors["CalPeak"] ) @@ -563,7 +563,7 @@ namespace CustomInterfaces * @param prop :: The property to update * @param val :: New value for property */ - void IndirectCalibration::calUpdateRS(QtProperty* prop, double val) + void ISISCalibration::calUpdateRS(QtProperty* prop, double val) { if ( prop == m_properties["CalPeakMin"] ) m_rangeSelectors["CalPeak"]->setMinimum(val); else if ( prop == m_properties["CalPeakMax"] ) m_rangeSelectors["CalPeak"]->setMaximum(val); @@ -580,7 +580,7 @@ namespace CustomInterfaces * * @param state :: whether checkbox is checked or unchecked */ - void IndirectCalibration::resCheck(bool state) + void ISISCalibration::resCheck(bool state) { m_rangeSelectors["ResPeak"]->setVisible(state); m_rangeSelectors["ResBackground"]->setVisible(state); @@ -593,7 +593,7 @@ namespace CustomInterfaces /** * Called when a user starts to type / edit the runs to load. */ - void IndirectCalibration::pbRunEditing() + void ISISCalibration::pbRunEditing() { emit updateRunButton(false, "Editing...", "Run numbers are curently being edited."); } @@ -601,7 +601,7 @@ namespace CustomInterfaces /** * Called when the FileFinder starts finding the files. */ - void IndirectCalibration::pbRunFinding() + void ISISCalibration::pbRunFinding() { emit updateRunButton(false, "Finding files...", "Searchig for data files for the run numbers entered..."); m_uiForm.leRunNo->setEnabled(false); @@ -610,7 +610,7 @@ namespace CustomInterfaces /** * Called when the FileFinder has finished finding the files. */ - void IndirectCalibration::pbRunFinished() + void ISISCalibration::pbRunFinished() { if(!m_uiForm.leRunNo->isValid()) { diff --git a/Code/Mantid/MantidQt/CustomInterfaces/src/Indirect/IndirectDiagnostics.cpp b/Code/Mantid/MantidQt/CustomInterfaces/src/Indirect/ISISDiagnostics.cpp similarity index 75% rename from Code/Mantid/MantidQt/CustomInterfaces/src/Indirect/IndirectDiagnostics.cpp rename to Code/Mantid/MantidQt/CustomInterfaces/src/Indirect/ISISDiagnostics.cpp index c773f40c4c8b..2150358f795b 100644 --- a/Code/Mantid/MantidQt/CustomInterfaces/src/Indirect/IndirectDiagnostics.cpp +++ b/Code/Mantid/MantidQt/CustomInterfaces/src/Indirect/ISISDiagnostics.cpp @@ -1,4 +1,4 @@ -#include "MantidQtCustomInterfaces/Indirect/IndirectDiagnostics.h" +#include "MantidQtCustomInterfaces/Indirect/ISISDiagnostics.h" #include "MantidAPI/MatrixWorkspace.h" #include "MantidKernel/Logger.h" @@ -10,7 +10,7 @@ using namespace Mantid::API; namespace { - Mantid::Kernel::Logger g_log("IndirectDiagnostics"); + Mantid::Kernel::Logger g_log("ISISDiagnostics"); } namespace MantidQt @@ -20,9 +20,8 @@ namespace CustomInterfaces //---------------------------------------------------------------------------------------------- /** Constructor */ - IndirectDiagnostics::IndirectDiagnostics(IndirectDataReduction * idrUI, QWidget * parent) : - IndirectDataReductionTab(idrUI, parent), - m_lastDiagFilename("") + ISISDiagnostics::ISISDiagnostics(IndirectDataReduction * idrUI, QWidget * parent) : + IndirectDataReductionTab(idrUI, parent) { m_uiForm.setupUi(parent); @@ -37,12 +36,17 @@ namespace CustomInterfaces m_propTrees["SlicePropTree"]->setFactoryForManager(m_blnManager, checkboxFactory); // Create Properties - m_properties["SpecMin"] = m_dblManager->addProperty("Spectra Min"); - m_properties["SpecMax"] = m_dblManager->addProperty("Spectra Max"); + m_properties["PreviewSpec"] = m_dblManager->addProperty("Preview Spectrum"); + m_dblManager->setDecimals(m_properties["PreviewSpec"], 0); + m_dblManager->setMinimum(m_properties["PreviewSpec"], 1); + m_properties["SpecMin"] = m_dblManager->addProperty("Spectra Min"); m_dblManager->setDecimals(m_properties["SpecMin"], 0); m_dblManager->setMinimum(m_properties["SpecMin"], 1); + + m_properties["SpecMax"] = m_dblManager->addProperty("Spectra Max"); m_dblManager->setDecimals(m_properties["SpecMax"], 0); + m_dblManager->setMinimum(m_properties["SpecMax"], 1); m_properties["PeakStart"] = m_dblManager->addProperty("Start"); m_properties["PeakEnd"] = m_dblManager->addProperty("End"); @@ -52,19 +56,20 @@ namespace CustomInterfaces m_properties["UseTwoRanges"] = m_blnManager->addProperty("Use Two Ranges"); - m_properties["Range1"] = m_grpManager->addProperty("Peak"); - m_properties["Range1"]->addSubProperty(m_properties["PeakStart"]); - m_properties["Range1"]->addSubProperty(m_properties["PeakEnd"]); + m_properties["PeakRange"] = m_grpManager->addProperty("Peak"); + m_properties["PeakRange"]->addSubProperty(m_properties["PeakStart"]); + m_properties["PeakRange"]->addSubProperty(m_properties["PeakEnd"]); - m_properties["Range2"] = m_grpManager->addProperty("Background"); - m_properties["Range2"]->addSubProperty(m_properties["BackgroundStart"]); - m_properties["Range2"]->addSubProperty(m_properties["BackgroundEnd"]); + m_properties["BackgroundRange"] = m_grpManager->addProperty("Background"); + m_properties["BackgroundRange"]->addSubProperty(m_properties["BackgroundStart"]); + m_properties["BackgroundRange"]->addSubProperty(m_properties["BackgroundEnd"]); + m_propTrees["SlicePropTree"]->addProperty(m_properties["PreviewSpec"]); m_propTrees["SlicePropTree"]->addProperty(m_properties["SpecMin"]); m_propTrees["SlicePropTree"]->addProperty(m_properties["SpecMax"]); - m_propTrees["SlicePropTree"]->addProperty(m_properties["Range1"]); + m_propTrees["SlicePropTree"]->addProperty(m_properties["PeakRange"]); m_propTrees["SlicePropTree"]->addProperty(m_properties["UseTwoRanges"]); - m_propTrees["SlicePropTree"]->addProperty(m_properties["Range2"]); + m_propTrees["SlicePropTree"]->addProperty(m_properties["BackgroundRange"]); // Slice plot m_rangeSelectors["SlicePeak"] = new MantidWidgets::RangeSelector(m_uiForm.ppRawPlot); @@ -84,14 +89,15 @@ namespace CustomInterfaces 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))); + connect(m_dblManager, SIGNAL(valueChanged(QtProperty*, double)), this, SLOT(doublePropertyChanged(QtProperty*, double))); // Enable/disable second range options when checkbox is toggled connect(m_blnManager, SIGNAL(valueChanged(QtProperty*, bool)), this, SLOT(sliceTwoRanges(QtProperty*, bool))); // Enables/disables calibration file selection when user toggles Use Calibratin File checkbox connect(m_uiForm.ckUseCalibration, SIGNAL(toggled(bool)), this, SLOT(sliceCalib(bool))); // Plot slice miniplot when file has finished loading - connect(m_uiForm.dsInputFiles, SIGNAL(filesFound()), this, SLOT(slicePlotRaw())); + connect(m_uiForm.dsInputFiles, SIGNAL(filesFoundChanged()), this, SLOT(handleNewFile())); + connect(m_uiForm.dsInputFiles, SIGNAL(filesFoundChanged()), this, SLOT(updatePreviewPlot())); // Shows message on run buton when user is inputting a run number connect(m_uiForm.dsInputFiles, SIGNAL(fileTextChanged(const QString &)), this, SLOT(pbRunEditing())); // Shows message on run button when Mantid is finding the file for a given run number @@ -99,6 +105,8 @@ namespace CustomInterfaces // Reverts run button back to normal when file finding has finished connect(m_uiForm.dsInputFiles, SIGNAL(fileFindingFinished()), this, SLOT(pbRunFinished())); + connect(m_blnManager, SIGNAL(valueChanged(QtProperty*, bool)), this, SLOT(updatePreviewPlot())); + // Update preview plot when slice algorithm completes connect(m_batchAlgoRunner, SIGNAL(batchComplete(bool)), this, SLOT(sliceAlgDone(bool))); @@ -111,15 +119,15 @@ namespace CustomInterfaces //---------------------------------------------------------------------------------------------- /** Destructor */ - IndirectDiagnostics::~IndirectDiagnostics() + ISISDiagnostics::~ISISDiagnostics() { } - void IndirectDiagnostics::setup() + void ISISDiagnostics::setup() { } - void IndirectDiagnostics::run() + void ISISDiagnostics::run() { QString suffix = "_" + getInstrumentConfiguration()->getAnalyserName() + getInstrumentConfiguration()->getReflectionName() + "_slice"; @@ -161,7 +169,7 @@ namespace CustomInterfaces runAlgorithm(sliceAlg); } - bool IndirectDiagnostics::validate() + bool ISISDiagnostics::validate() { UserInputValidator uiv; @@ -200,19 +208,31 @@ namespace CustomInterfaces /** * Sets default spectra, peak and background ranges. */ - void IndirectDiagnostics::setDefaultInstDetails() + void ISISDiagnostics::setDefaultInstDetails() { - //Get spectra, peak and background details + // Get spectra, peak and background details std::map instDetails = getInstrumentDetails(); // Set the search instrument for runs m_uiForm.dsInputFiles->setInstrumentOverride(instDetails["instrument"]); - //Set spectra range - m_dblManager->setValue(m_properties["SpecMin"], instDetails["spectra-min"].toDouble()); - m_dblManager->setValue(m_properties["SpecMax"], instDetails["spectra-max"].toDouble()); + double specMin = instDetails["spectra-min"].toDouble(); + double specMax = instDetails["spectra-max"].toDouble(); + + // Set spectra range + m_dblManager->setMinimum(m_properties["SpecMin"], specMin); + m_dblManager->setMaximum(m_properties["SpecMin"], specMax); + m_dblManager->setValue(m_properties["SpecMin"], specMin); - //Set peak and background ranges + m_dblManager->setMinimum(m_properties["SpecMax"], specMin); + m_dblManager->setMaximum(m_properties["SpecMax"], specMax); + m_dblManager->setValue(m_properties["SpecMax"], specMax); + + m_dblManager->setMinimum(m_properties["PreviewSpec"], specMin); + m_dblManager->setMaximum(m_properties["PreviewSpec"], specMax); + m_dblManager->setValue(m_properties["PreviewSpec"], specMin); + + // Set peak and background ranges if(instDetails.size() >= 8) { setRangeSelector("SlicePeak", m_properties["PeakStart"], m_properties["PeakEnd"], @@ -222,61 +242,39 @@ namespace CustomInterfaces } } - /** - * Redraw the raw input plot - */ - void IndirectDiagnostics::slicePlotRaw() + void ISISDiagnostics::handleNewFile() { - QString filename = m_uiForm.dsInputFiles->getFirstFilename(); - - // Only update if we have a different file - if(filename == m_lastDiagFilename) + if(!m_uiForm.dsInputFiles->isValid()) return; - m_lastDiagFilename = filename; + QString filename = m_uiForm.dsInputFiles->getFirstFilename(); - disconnect(m_dblManager, SIGNAL(valueChanged(QtProperty*, double)), this, SLOT(updatePreviewPlot())); - disconnect(m_blnManager, SIGNAL(valueChanged(QtProperty*, bool)), this, SLOT(updatePreviewPlot())); + QFileInfo fi(filename); + QString wsname = fi.baseName(); - setDefaultInstDetails(); + int specMin = static_cast(m_dblManager->value(m_properties["SpecMin"])); + int specMax = static_cast(m_dblManager->value(m_properties["SpecMax"])); - if ( m_uiForm.dsInputFiles->isValid() ) + if(!loadFile(filename, wsname, specMin, specMax)) { - QFileInfo fi(filename); - QString wsname = fi.baseName(); - - 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; - } + emit showMessageBox("Unable to load file.\nCheck whether your file exists and matches the selected instrument in the EnergyTransfer tab."); + return; + } - Mantid::API::MatrixWorkspace_sptr input = boost::dynamic_pointer_cast( - Mantid::API::AnalysisDataService::Instance().retrieve(wsname.toStdString())); + Mantid::API::MatrixWorkspace_sptr input = boost::dynamic_pointer_cast( + Mantid::API::AnalysisDataService::Instance().retrieve(wsname.toStdString())); - const Mantid::MantidVec & dataX = input->readX(0); - QPair range(dataX.front(), dataX.back()); + const Mantid::MantidVec & dataX = input->readX(0); + QPair range(dataX.front(), dataX.back()); + int previewSpec = static_cast(m_dblManager->value(m_properties["PreviewSpec"])) - specMin; - m_uiForm.ppRawPlot->clear(); - m_uiForm.ppRawPlot->addSpectrum("Raw", input, 0); + m_uiForm.ppRawPlot->clear(); + m_uiForm.ppRawPlot->addSpectrum("Raw", input, previewSpec); - setPlotPropertyRange("SlicePeak", m_properties["PeakStart"], m_properties["PeakEnd"], range); - setPlotPropertyRange("SliceBackground", m_properties["BackgroundStart"], m_properties["BackgroundEnd"], range); + setPlotPropertyRange("SlicePeak", m_properties["PeakStart"], m_properties["PeakEnd"], range); + setPlotPropertyRange("SliceBackground", m_properties["BackgroundStart"], m_properties["BackgroundEnd"], range); - m_uiForm.ppRawPlot->resizeX(); - } - else - { - 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(); + m_uiForm.ppRawPlot->resizeX(); } /** @@ -284,7 +282,7 @@ namespace CustomInterfaces * * @param state :: True to show the second range selectors, false to hide */ - void IndirectDiagnostics::sliceTwoRanges(QtProperty*, bool state) + void ISISDiagnostics::sliceTwoRanges(QtProperty*, bool state) { m_rangeSelectors["SliceBackground"]->setVisible(state); } @@ -294,12 +292,12 @@ namespace CustomInterfaces * * @param state :: True to enable calibration file, false otherwise */ - void IndirectDiagnostics::sliceCalib(bool state) + void ISISDiagnostics::sliceCalib(bool state) { m_uiForm.dsCalibration->setEnabled(state); } - void IndirectDiagnostics::rangeSelectorDropped(double min, double max) + void ISISDiagnostics::rangeSelectorDropped(double min, double max) { MantidWidgets::RangeSelector* from = qobject_cast(sender()); @@ -316,24 +314,31 @@ namespace CustomInterfaces } /** - * Update the value of a range selector given a QtProperty + * Handles a double property being changed in the property browser. * * @param prop :: Pointer to the QtProperty - * @param val :: New value of the range selector + * @param val :: New value */ - void IndirectDiagnostics::sliceUpdateRS(QtProperty* prop, double val) + void ISISDiagnostics::doublePropertyChanged(QtProperty* prop, double val) { if(prop == m_properties["PeakStart"]) m_rangeSelectors["SlicePeak"]->setMinimum(val); else if(prop == m_properties["PeakEnd"]) m_rangeSelectors["SlicePeak"]->setMaximum(val); else if(prop == m_properties["BackgroundStart"]) m_rangeSelectors["SliceBackground"]->setMinimum(val); else if(prop == m_properties["BackgroundEnd"]) m_rangeSelectors["SliceBackground"]->setMaximum(val); + else if(prop == m_properties["PreviewSpec"]) handleNewFile(); + + if(prop != m_properties["PreviewSpec"]) + updatePreviewPlot(); } /** * Runs the slice algorithm with preview properties. */ - void IndirectDiagnostics::updatePreviewPlot() + void ISISDiagnostics::updatePreviewPlot() { + if (!m_uiForm.dsInputFiles->isValid()) + return; + QString suffix = getInstrumentConfiguration()->getAnalyserName() + getInstrumentConfiguration()->getReflectionName() + "_slice"; QString filenames = m_uiForm.dsInputFiles->getFilenames().join(","); @@ -381,7 +386,7 @@ namespace CustomInterfaces * * @param error True if the algorithm was stopped due to error, false otherwise */ - void IndirectDiagnostics::sliceAlgDone(bool error) + void ISISDiagnostics::sliceAlgDone(bool error) { if(error) return; @@ -420,7 +425,7 @@ namespace CustomInterfaces /** * Called when a user starts to type / edit the runs to load. */ - void IndirectDiagnostics::pbRunEditing() + void ISISDiagnostics::pbRunEditing() { emit updateRunButton(false, "Editing...", "Run numbers are curently being edited."); } @@ -428,7 +433,7 @@ namespace CustomInterfaces /** * Called when the FileFinder starts finding the files. */ - void IndirectDiagnostics::pbRunFinding() + void ISISDiagnostics::pbRunFinding() { emit updateRunButton(false, "Finding files...", "Searchig for data files for the run numbers entered..."); m_uiForm.dsInputFiles->setEnabled(false); @@ -437,7 +442,7 @@ namespace CustomInterfaces /** * Called when the FileFinder has finished finding the files. */ - void IndirectDiagnostics::pbRunFinished() + void ISISDiagnostics::pbRunFinished() { if(!m_uiForm.dsInputFiles->isValid()) { diff --git a/Code/Mantid/MantidQt/CustomInterfaces/src/Indirect/IndirectConvertToEnergy.cpp b/Code/Mantid/MantidQt/CustomInterfaces/src/Indirect/ISISEnergyTransfer.cpp similarity index 94% rename from Code/Mantid/MantidQt/CustomInterfaces/src/Indirect/IndirectConvertToEnergy.cpp rename to Code/Mantid/MantidQt/CustomInterfaces/src/Indirect/ISISEnergyTransfer.cpp index 90fdee795845..d277978e14fd 100644 --- a/Code/Mantid/MantidQt/CustomInterfaces/src/Indirect/IndirectConvertToEnergy.cpp +++ b/Code/Mantid/MantidQt/CustomInterfaces/src/Indirect/ISISEnergyTransfer.cpp @@ -1,4 +1,4 @@ -#include "MantidQtCustomInterfaces/Indirect/IndirectConvertToEnergy.h" +#include "MantidQtCustomInterfaces/Indirect/ISISEnergyTransfer.h" #include "MantidQtCustomInterfaces/Background.h" #include "MantidQtCustomInterfaces/UserInputValidator.h" @@ -15,7 +15,7 @@ namespace CustomInterfaces //---------------------------------------------------------------------------------------------- /** Constructor */ - IndirectConvertToEnergy::IndirectConvertToEnergy(IndirectDataReduction * idrUI, QWidget * parent) : + ISISEnergyTransfer::ISISEnergyTransfer(IndirectDataReduction * idrUI, QWidget * parent) : IndirectDataReductionTab(idrUI, parent) { m_uiForm.setupUi(parent); @@ -50,17 +50,17 @@ namespace CustomInterfaces //---------------------------------------------------------------------------------------------- /** Destructor */ - IndirectConvertToEnergy::~IndirectConvertToEnergy() + ISISEnergyTransfer::~ISISEnergyTransfer() { } - void IndirectConvertToEnergy::setup() + void ISISEnergyTransfer::setup() { } - bool IndirectConvertToEnergy::validate() + bool ISISEnergyTransfer::validate() { UserInputValidator uiv; @@ -103,7 +103,7 @@ namespace CustomInterfaces } - void IndirectConvertToEnergy::run() + void ISISEnergyTransfer::run() { using MantidQt::API::BatchAlgorithmRunner; @@ -196,7 +196,7 @@ namespace CustomInterfaces * * @param error True if the algorithm was stopped due to error, false otherwise */ - void IndirectConvertToEnergy::algorithmComplete(bool error) + void ISISEnergyTransfer::algorithmComplete(bool error) { disconnect(m_batchAlgoRunner, SIGNAL(batchComplete(bool)), this, SLOT(algorithmComplete(bool))); @@ -219,7 +219,7 @@ namespace CustomInterfaces /** * Called when the instrument has changed, used to update default values. */ - void IndirectConvertToEnergy::setInstrumentDefault() + void ISISEnergyTransfer::setInstrumentDefault() { std::map instDetails = getInstrumentDetails(); @@ -298,7 +298,7 @@ namespace CustomInterfaces * This function runs when the user makes a selection on the cbGroupingOptions QComboBox. * @param groupType :: Value of selection made by user. */ - void IndirectConvertToEnergy::mappingOptionSelected(const QString& groupType) + void ISISEnergyTransfer::mappingOptionSelected(const QString& groupType) { if ( groupType == "File" ) { @@ -319,7 +319,7 @@ namespace CustomInterfaces * @param groupType :: Type of grouping (All, Group, Indiviual) * @return path to mapping file, or an empty string if file could not be created. */ - QString IndirectConvertToEnergy::createMapFile(const QString& groupType) + QString ISISEnergyTransfer::createMapFile(const QString& groupType) { QString specRange = m_uiForm.spSpectraMin->text() + "," + m_uiForm.spSpectraMax->text(); @@ -361,7 +361,7 @@ namespace CustomInterfaces * * @return A vector of save formats */ - std::vector IndirectConvertToEnergy::getSaveFormats() + std::vector ISISEnergyTransfer::getSaveFormats() { std::vector fileFormats; @@ -384,7 +384,7 @@ namespace CustomInterfaces /** * Plots raw time data from .raw file before any data conversion has been performed. */ - void IndirectConvertToEnergy::plotRaw() + void ISISEnergyTransfer::plotRaw() { using MantidQt::API::BatchAlgorithmRunner; @@ -461,7 +461,7 @@ namespace CustomInterfaces * * @param error Indicates if the algorithm chain failed */ - void IndirectConvertToEnergy::plotRawComplete(bool error) + void ISISEnergyTransfer::plotRawComplete(bool error) { disconnect(m_batchAlgoRunner, SIGNAL(batchComplete(bool)), this, SLOT(plotRawComplete(bool))); @@ -479,7 +479,7 @@ namespace CustomInterfaces /** * Called when a user starts to type / edit the runs to load. */ - void IndirectConvertToEnergy::pbRunEditing() + void ISISEnergyTransfer::pbRunEditing() { emit updateRunButton(false, "Editing...", "Run numbers are curently being edited."); } @@ -487,7 +487,7 @@ namespace CustomInterfaces /** * Called when the FileFinder starts finding the files. */ - void IndirectConvertToEnergy::pbRunFinding() + void ISISEnergyTransfer::pbRunFinding() { emit updateRunButton(false, "Finding files...", "Searchig for data files for the run numbers entered..."); m_uiForm.dsRunFiles->setEnabled(false); @@ -496,7 +496,7 @@ namespace CustomInterfaces /** * Called when the FileFinder has finished finding the files. */ - void IndirectConvertToEnergy::pbRunFinished() + void ISISEnergyTransfer::pbRunFinished() { if(!m_uiForm.dsRunFiles->isValid()) { diff --git a/Code/Mantid/MantidQt/CustomInterfaces/src/Indirect/IndirectDataReduction.cpp b/Code/Mantid/MantidQt/CustomInterfaces/src/Indirect/IndirectDataReduction.cpp index 3f88108cc96c..f167fa71ea6e 100644 --- a/Code/Mantid/MantidQt/CustomInterfaces/src/Indirect/IndirectDataReduction.cpp +++ b/Code/Mantid/MantidQt/CustomInterfaces/src/Indirect/IndirectDataReduction.cpp @@ -9,14 +9,14 @@ #include "MantidKernel/ConfigService.h" #include "MantidQtAPI/HelpWindow.h" #include "MantidQtAPI/ManageUserDirectories.h" -#include "MantidQtCustomInterfaces/Indirect/IndirectCalibration.h" -#include "MantidQtCustomInterfaces/Indirect/IndirectConvertToEnergy.h" -#include "MantidQtCustomInterfaces/Indirect/IndirectDataReductionTab.h" -#include "MantidQtCustomInterfaces/Indirect/IndirectDiagnostics.h" #include "MantidQtCustomInterfaces/Indirect/IndirectMoments.h" #include "MantidQtCustomInterfaces/Indirect/IndirectSqw.h" #include "MantidQtCustomInterfaces/Indirect/IndirectSymmetrise.h" #include "MantidQtCustomInterfaces/Indirect/IndirectTransmission.h" +#include "MantidQtCustomInterfaces/Indirect/ISISCalibration.h" +#include "MantidQtCustomInterfaces/Indirect/ISISDiagnostics.h" +#include "MantidQtCustomInterfaces/Indirect/ISISEnergyTransfer.h" +#include "MantidQtCustomInterfaces/Indirect/ILLEnergyTransfer.h" #include #include @@ -55,10 +55,12 @@ IndirectDataReduction::IndirectDataReduction(QWidget *parent) : m_instrument(""), m_settingsGroup("CustomInterfaces/IndirectDataReduction"), m_algRunner(new MantidQt::API::AlgorithmRunner(this)), - m_changeObserver(*this, &IndirectDataReduction::handleDirectoryChange) + m_changeObserver(*this, &IndirectDataReduction::handleConfigChange) { // Signals to report load instrument algo result connect(m_algRunner, SIGNAL(algorithmComplete(bool)), this, SLOT(instrumentLoadingDone(bool))); + + Mantid::Kernel::ConfigService::Instance().addObserver(m_changeObserver); } @@ -67,6 +69,8 @@ IndirectDataReduction::IndirectDataReduction(QWidget *parent) : */ IndirectDataReduction::~IndirectDataReduction() { + Mantid::Kernel::ConfigService::Instance().removeObserver(m_changeObserver); + // Make sure no algos are running after the window has been closed m_algRunner->cancelRunningAlgorithm(); @@ -90,7 +94,7 @@ void IndirectDataReduction::helpClicked() void IndirectDataReduction::exportTabPython() { QString tabName = m_uiForm.twIDRTabs->tabText(m_uiForm.twIDRTabs->currentIndex()); - m_tabs[tabName]->exportPythonScript(); + m_tabs[tabName].second->exportPythonScript(); } @@ -101,7 +105,7 @@ void IndirectDataReduction::exportTabPython() void IndirectDataReduction::runClicked() { QString tabName = m_uiForm.twIDRTabs->tabText(m_uiForm.twIDRTabs->currentIndex()); - m_tabs[tabName]->runTab(); + m_tabs[tabName].second->runTab(); } @@ -116,13 +120,14 @@ void IndirectDataReduction::initLayout() updateRunButton(false, "Loading UI", "Initialising user interface components..."); // Create the tabs - m_tabs["Energy Transfer"] = new IndirectConvertToEnergy(this, m_uiForm.twIDRTabs->findChild("loEnergyTransfer")); - m_tabs["Calibration"] = new IndirectCalibration(this, m_uiForm.twIDRTabs->findChild("loCalibration")); - m_tabs["Diagnostics"] = new IndirectDiagnostics(this, m_uiForm.twIDRTabs->findChild("loDiagnostics")); - m_tabs["Transmission"] = new IndirectTransmission(this, m_uiForm.twIDRTabs->findChild("loTransmission")); - m_tabs["Symmetrise"] = new IndirectSymmetrise(this, m_uiForm.twIDRTabs->findChild("loSymmetrise")); - m_tabs["S(Q, w)"] = new IndirectSqw(this, m_uiForm.twIDRTabs->findChild("loSofQW")); - m_tabs["Moments"] = new IndirectMoments(this, m_uiForm.twIDRTabs->findChild("loMoments")); + addTab("ISIS Energy Transfer"); + addTab("ISIS Calibration"); + addTab("ISIS Diagnostics"); + addTab("Transmission"); + addTab("Symmetrise"); + addTab("S(Q, w)"); + addTab("Moments"); + addTab("ILL Energy Transfer"); // Connect "?" (Help) Button connect(m_uiForm.pbHelp, SIGNAL(clicked()), this, SLOT(helpClicked())); @@ -136,22 +141,16 @@ void IndirectDataReduction::initLayout() // Reset the Run button state when the tab is changed connect(m_uiForm.twIDRTabs, 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(); - } - // Handle instrument configuration changes connect(m_uiForm.iicInstrumentConfiguration, SIGNAL(instrumentConfigurationUpdated(const QString &, const QString &, const QString &)), this, SLOT(instrumentSetupChanged(const QString &, const QString &, const QString &))); // Update the instrument configuration across the UI m_uiForm.iicInstrumentConfiguration->newInstrumentConfiguration(); + + std::string facility = Mantid::Kernel::ConfigService::Instance().getString("default.facility"); + filterUiForFacility(QString::fromStdString(facility)); + emit newInstrumentConfiguration(); } @@ -203,28 +202,37 @@ Mantid::API::MatrixWorkspace_sptr IndirectDataReduction::loadInstrumentIfNotExis { std::string idfDirectory = Mantid::Kernel::ConfigService::Instance().getString("instrumentDefinition.directory"); - std::string parameterFilename = idfDirectory + instrumentName + "_Definition.xml"; - IAlgorithm_sptr loadAlg = AlgorithmManager::Instance().create("LoadEmptyInstrument"); - loadAlg->setChild(true); - loadAlg->initialize(); - loadAlg->setProperty("Filename", parameterFilename); - loadAlg->setProperty("OutputWorkspace", "__IDR_Inst"); - loadAlg->execute(); - MatrixWorkspace_sptr instWorkspace = loadAlg->getProperty("OutputWorkspace"); - - // Load the IPF if given an analyser and reflection - if(!analyser.empty() && !reflection.empty()) + try { - std::string ipfFilename = idfDirectory + instrumentName + "_" + analyser + "_" + reflection + "_Parameters.xml"; - IAlgorithm_sptr loadParamAlg = AlgorithmManager::Instance().create("LoadParameterFile"); - loadParamAlg->setChild(true); - loadParamAlg->initialize(); - loadParamAlg->setProperty("Filename", ipfFilename); - loadParamAlg->setProperty("Workspace", instWorkspace); - loadParamAlg->execute(); - } + std::string parameterFilename = idfDirectory + instrumentName + "_Definition.xml"; + IAlgorithm_sptr loadAlg = AlgorithmManager::Instance().create("LoadEmptyInstrument"); + loadAlg->setChild(true); + loadAlg->initialize(); + loadAlg->setProperty("Filename", parameterFilename); + loadAlg->setProperty("OutputWorkspace", "__IDR_Inst"); + loadAlg->execute(); + MatrixWorkspace_sptr instWorkspace = loadAlg->getProperty("OutputWorkspace"); + + // 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->setChild(true); + loadParamAlg->initialize(); + loadParamAlg->setProperty("Filename", ipfFilename); + loadParamAlg->setProperty("Workspace", instWorkspace); + loadParamAlg->execute(); + } - return instWorkspace; + return instWorkspace; + } + catch(std::exception &ex) + { + g_log.error() << "Failed to load instrument with error: " + << ex.what() << std::endl; + return MatrixWorkspace_sptr(); + } } @@ -293,7 +301,9 @@ std::map IndirectDataReduction::getInstrumentDetails() catch(Mantid::Kernel::Exception::NotFoundError &nfe) { UNUSED_ARG(nfe); - g_log.warning() << "Could not find parameter " << *it << " in instrument " << instrumentName << std::endl; + g_log.warning() << "Could not find parameter " << *it + << " in instrument " << instrumentName + << std::endl; } } @@ -335,19 +345,16 @@ void IndirectDataReduction::instrumentLoadingDone(bool error) { if(error) { - g_log.error("Instument loading failed! (this can be caused by having both direct and indirect interfaces open)"); - updateRunButton(false, "No Instrument", "No instrument is currently loaded."); + g_log.error("Instument loading failed! This instrument (or analyser/reflection configuration) may not be supported by the interface."); return; } - - updateRunButton(); } /** * Remove the Poco observer on the config service when the interfaces is closed. * - * @param close CLose event (unused) + * @param close Close event (unused) */ void IndirectDataReduction::closeEvent(QCloseEvent* close) { @@ -357,14 +364,28 @@ void IndirectDataReduction::closeEvent(QCloseEvent* close) /** - * Reloads settings if the default sata search or save directories have been changed. + * Handles configuration values being changed. + * + * Currently checks for data search paths and default facility. + * + * @param pNf Poco notification */ -void IndirectDataReduction::handleDirectoryChange(Mantid::Kernel::ConfigValChangeNotification_ptr pNf) +void IndirectDataReduction::handleConfigChange(Mantid::Kernel::ConfigValChangeNotification_ptr pNf) { std::string key = pNf->key(); + std::string value = pNf->curValue(); if(key == "datasearch.directories" || key == "defaultsave.directory") + { readSettings(); + } + else if(key == "default.facility") + { + QString facility = QString::fromStdString(value); + + filterUiForFacility(facility); + m_uiForm.iicInstrumentConfiguration->setFacility(facility); + } } @@ -440,6 +461,70 @@ void IndirectDataReduction::saveSettings() } +/** + * Filters the displayed tabs based on the current facility. + * + * @param facility Name of facility + */ +void IndirectDataReduction::filterUiForFacility(QString facility) +{ + g_log.information() << "Facility selected: " + << facility.toStdString() + << std::endl; + + QStringList enabledTabs; + QStringList disabledInstruments; + + // Add facility specific tabs and disable instruments + if(facility == "ISIS") + { + enabledTabs << "ISIS Energy Transfer" + << "ISIS Calibration" + << "ISIS Diagnostics"; + } + else if(facility == "ILL") + { + enabledTabs << "ILL Energy Transfer"; + disabledInstruments << "IN10" << "IN13" << "IN16"; + } + + // These tabs work at any facility (always at end of tabs) + enabledTabs << "Transmission" << "Symmetrise" << "S(Q, w)" << "Moments"; + + // First remove all tabs + while(m_uiForm.twIDRTabs->count() > 0) + { + // Disconnect the instrument changed signal + QString tabName = m_uiForm.twIDRTabs->tabText(0); + disconnect(this, SIGNAL(newInstrumentConfiguration()), + m_tabs[tabName].second, SIGNAL(newInstrumentConfiguration())); + + // Remove the tab + m_uiForm.twIDRTabs->removeTab(0); + + g_log.debug() << "Removing tab " << tabName.toStdString() + << std::endl; + } + + // Add the required tabs + for(auto it = enabledTabs.begin(); it != enabledTabs.end(); ++it) + { + // Connect the insturment changed signal + connect(this, SIGNAL(newInstrumentConfiguration()), + m_tabs[*it].second, SIGNAL(newInstrumentConfiguration())); + + // Add the tab + m_uiForm.twIDRTabs->addTab(m_tabs[*it].first, *it); + + g_log.debug() << "Adding tab " << (*it).toStdString() + << std::endl; + } + + // Disable instruments as required + m_uiForm.iicInstrumentConfiguration->setDisabledInstruments(disabledInstruments); +} + + /** * Handles showing the manage directory dialog box. */ diff --git a/Code/Mantid/MantidQt/CustomInterfaces/src/Indirect/IndirectDataReductionTab.cpp b/Code/Mantid/MantidQt/CustomInterfaces/src/Indirect/IndirectDataReductionTab.cpp index 9176f0f49095..87c0f817542f 100644 --- a/Code/Mantid/MantidQt/CustomInterfaces/src/Indirect/IndirectDataReductionTab.cpp +++ b/Code/Mantid/MantidQt/CustomInterfaces/src/Indirect/IndirectDataReductionTab.cpp @@ -2,6 +2,7 @@ #include "MantidAPI/AlgorithmManager.h" #include "MantidKernel/Logger.h" +#include "MantidQtCustomInterfaces/Indirect/IndirectDataReduction.h" using namespace Mantid::API; using namespace Mantid::Geometry; diff --git a/Code/Mantid/MantidQt/CustomInterfaces/src/Indirect/IndirectDiffractionReduction.cpp b/Code/Mantid/MantidQt/CustomInterfaces/src/Indirect/IndirectDiffractionReduction.cpp index 7a144c27460b..ec4de290209d 100644 --- a/Code/Mantid/MantidQt/CustomInterfaces/src/Indirect/IndirectDiffractionReduction.cpp +++ b/Code/Mantid/MantidQt/CustomInterfaces/src/Indirect/IndirectDiffractionReduction.cpp @@ -95,10 +95,13 @@ void IndirectDiffractionReduction::initLayout() // Update invalid rebinning markers validateRebin(); + + // Update instrument dependant widgets + m_uiForm.iicInstrumentConfiguration->newInstrumentConfiguration(); } /** - * Runs a diffraction reduction when the user clieks Run. + * Runs a diffraction reduction when the user clicks Run. */ void IndirectDiffractionReduction::demonRun() { diff --git a/Code/Mantid/MantidQt/CustomInterfaces/src/Indirect/MSDFit.cpp b/Code/Mantid/MantidQt/CustomInterfaces/src/Indirect/MSDFit.cpp index 25b268e35b41..945d2d64ba0e 100644 --- a/Code/Mantid/MantidQt/CustomInterfaces/src/Indirect/MSDFit.cpp +++ b/Code/Mantid/MantidQt/CustomInterfaces/src/Indirect/MSDFit.cpp @@ -53,6 +53,7 @@ namespace IDA connect(m_uiForm.dsSampleInput, SIGNAL(dataReady(const QString&)), this, SLOT(newDataLoaded(const QString&))); connect(m_uiForm.pbSingleFit, SIGNAL(clicked()), this, SLOT(singleFit())); connect(m_uiForm.spPlotSpectrum, SIGNAL(valueChanged(int)), this, SLOT(plotInput())); + connect(m_uiForm.spPlotSpectrum, SIGNAL(valueChanged(int)), this, SLOT(plotFit())); connect(m_uiForm.spSpectraMin, SIGNAL(valueChanged(int)), this, SLOT(specMinChanged(int))); connect(m_uiForm.spSpectraMax, SIGNAL(valueChanged(int)), this, SLOT(specMaxChanged(int))); @@ -83,6 +84,9 @@ namespace IDA // Set the result workspace for Python script export QString dataName = m_uiForm.dsSampleInput->getCurrentDataName(); m_pythonExportWsName = dataName.left(dataName.lastIndexOf("_")).toStdString() + "_msd"; + + // Plot the fit result + plotFit(); } void MSDFit::singleFit() @@ -103,7 +107,7 @@ namespace IDA "print output \n"; QString pyOutput = runPythonCode(pyInput).trimmed(); - plotFit(pyOutput); + plotFit(pyOutput, 0); } bool MSDFit::validate() @@ -131,16 +135,36 @@ namespace IDA m_uiForm.dsSampleInput->readSettings(settings.group()); } - void MSDFit::plotFit(QString wsName) + /** + * Plots fitted data on the mini plot. + * + * @param wsName Name of fit _Workspaces workspace group (defaults to + * Python export WS name + _Workspaces) + * @param specNo Spectrum number relating to input workspace to plot fit + * for (defaults to value of preview spectrum index) + */ + void MSDFit::plotFit(QString wsName, int specNo) { + if(wsName.isEmpty()) + wsName = QString::fromStdString(m_pythonExportWsName) + "_Workspaces"; + + if(specNo == -1) + specNo = m_uiForm.spPlotSpectrum->value(); + if(Mantid::API::AnalysisDataService::Instance().doesExist(wsName.toStdString())) { + // Remove the old fit + m_uiForm.ppPlot->removeSpectrum("Fit"); + // Get the workspace auto groupWs = Mantid::API::AnalysisDataService::Instance().retrieveWS(wsName.toStdString()); - auto ws = boost::dynamic_pointer_cast(groupWs->getItem(0)); - // Remove the old fit - m_uiForm.ppPlot->removeSpectrum("Fit"); + // If the user has just done a single fit then we probably havent got a workspace to plot + // when the change the spectrum selector + if(specNo >= static_cast(groupWs->size())) + return; + + auto ws = boost::dynamic_pointer_cast(groupWs->getItem(specNo)); // Plot the new fit m_uiForm.ppPlot->addSpectrum("Fit", ws, 1, Qt::red); diff --git a/Code/Mantid/MantidQt/CustomInterfaces/src/Muon/ALCDataLoadingPresenter.cpp b/Code/Mantid/MantidQt/CustomInterfaces/src/Muon/ALCDataLoadingPresenter.cpp index 6f01828916a9..4e98e7c4483a 100644 --- a/Code/Mantid/MantidQt/CustomInterfaces/src/Muon/ALCDataLoadingPresenter.cpp +++ b/Code/Mantid/MantidQt/CustomInterfaces/src/Muon/ALCDataLoadingPresenter.cpp @@ -43,6 +43,7 @@ namespace CustomInterfaces alg->setProperty("LastRun", m_view->lastRun()); alg->setProperty("LogValue", m_view->log()); alg->setProperty("Type", m_view->calculationType()); + alg->setProperty("DeadTimeCorrType",m_view->deadTimeType()); // If time limiting requested, set min/max times if (auto timeRange = m_view->timeRange()) @@ -50,6 +51,9 @@ namespace CustomInterfaces alg->setProperty("TimeMin", timeRange->first); alg->setProperty("TimeMax", timeRange->second); } + if (m_view->deadTimeType() == "FromSpecifiedFile") { + alg->setProperty("DeadTimeCorrFile",m_view->deadTimeFile()); + } alg->setPropertyValue("OutputWorkspace", "__NotUsed"); alg->execute(); @@ -78,9 +82,11 @@ namespace CustomInterfaces IAlgorithm_sptr load = AlgorithmManager::Instance().create("LoadMuonNexus"); load->setChild(true); // Don't want workspaces in the ADS load->setProperty("Filename", m_view->firstRun()); - // Don't load any data - we need logs only - load->setPropertyValue("SpectrumMin","0"); - load->setPropertyValue("SpectrumMax","0"); + // We need logs only but we have to use LoadMuonNexus + // (can't use LoadMuonLogs as not all the logs would be + // loaded), so we load the minimum amount of data, i.e., one spectrum + load->setPropertyValue("SpectrumMin","1"); + load->setPropertyValue("SpectrumMax","1"); load->setPropertyValue("OutputWorkspace", "__NotUsed"); load->execute(); diff --git a/Code/Mantid/MantidQt/CustomInterfaces/src/Muon/ALCDataLoadingView.cpp b/Code/Mantid/MantidQt/CustomInterfaces/src/Muon/ALCDataLoadingView.cpp index 463c1c14bd79..a49de5f85cc4 100644 --- a/Code/Mantid/MantidQt/CustomInterfaces/src/Muon/ALCDataLoadingView.cpp +++ b/Code/Mantid/MantidQt/CustomInterfaces/src/Muon/ALCDataLoadingView.cpp @@ -64,6 +64,27 @@ namespace CustomInterfaces return m_ui.calculationType->checkedButton()->text().toStdString(); } + std::string ALCDataLoadingView::deadTimeType() const + { + std::string checkedButton = m_ui.deadTimeCorrType->checkedButton()->text().toStdString(); + if ( checkedButton == "From Data File" ) { + return std::string("FromRunData"); + } else if ( checkedButton == "From Custom File" ) { + return std::string("FromSpecifiedFile"); + } else { + return checkedButton; + } + } + + std::string ALCDataLoadingView::deadTimeFile() const + { + if (deadTimeType()=="FromSpecifiedFile") { + return m_ui.deadTimeFile->getFirstFilename().toStdString(); + } else { + return ""; + } + } + boost::optional< std::pair > ALCDataLoadingView::timeRange() const { if (m_ui.timeLimit->isChecked()) diff --git a/Code/Mantid/MantidQt/CustomInterfaces/test/ALCDataLoadingPresenterTest.h b/Code/Mantid/MantidQt/CustomInterfaces/test/ALCDataLoadingPresenterTest.h index 6ea396802ca4..f1a4c14eb447 100644 --- a/Code/Mantid/MantidQt/CustomInterfaces/test/ALCDataLoadingPresenterTest.h +++ b/Code/Mantid/MantidQt/CustomInterfaces/test/ALCDataLoadingPresenterTest.h @@ -34,6 +34,8 @@ class MockALCDataLoadingView : public IALCDataLoadingView MOCK_CONST_METHOD0(log, std::string()); MOCK_CONST_METHOD0(calculationType, std::string()); MOCK_CONST_METHOD0(timeRange, boost::optional()); + MOCK_CONST_METHOD0(deadTimeType, std::string()); + MOCK_CONST_METHOD0(deadTimeFile, std::string()); MOCK_METHOD0(initialize, void()); MOCK_METHOD1(setDataCurve, void(const QwtData&)); @@ -77,6 +79,7 @@ class ALCDataLoadingPresenterTest : public CxxTest::TestSuite ON_CALL(*m_view, calculationType()).WillByDefault(Return("Integral")); ON_CALL(*m_view, log()).WillByDefault(Return("sample_magn_field")); ON_CALL(*m_view, timeRange()).WillByDefault(Return(boost::none)); + ON_CALL(*m_view, deadTimeType()).WillByDefault(Return("None")); } void tearDown() @@ -186,6 +189,32 @@ class ALCDataLoadingPresenterTest : public CxxTest::TestSuite EXPECT_CALL(*m_view, displayError(StrNe(""))).Times(1); m_view->requestLoading(); } + + void test_correctionsFromDataFile () + { + // Change dead time correction type + // Test results with corrections from run data + ON_CALL(*m_view, deadTimeType()).WillByDefault(Return("FromRunData")); + EXPECT_CALL(*m_view, deadTimeType()).Times(2); + EXPECT_CALL(*m_view, deadTimeFile()).Times(0); + EXPECT_CALL(*m_view, restoreCursor()).Times(1); + EXPECT_CALL(*m_view, setDataCurve(AllOf(Property(&QwtData::size,3), + QwtDataY(0, 0.150616, 1E-3), + QwtDataY(1, 0.143444, 1E-3), + QwtDataY(2, 0.128856, 1E-3)))); + m_view->requestLoading(); + } + + void test_correctionsFromCustomFile () + { + // Change dead time correction type + // Test only expected number of calls + ON_CALL(*m_view, deadTimeType()).WillByDefault(Return("FromSpecifiedFile")); + EXPECT_CALL(*m_view, deadTimeType()).Times(2); + EXPECT_CALL(*m_view, deadTimeFile()).Times(1); + EXPECT_CALL(*m_view, restoreCursor()).Times(1); + m_view->requestLoading(); + } }; diff --git a/Code/Mantid/MantidQt/MantidWidgets/CMakeLists.txt b/Code/Mantid/MantidQt/MantidWidgets/CMakeLists.txt index 565630f797c6..77ebfa4a0ec9 100644 --- a/Code/Mantid/MantidQt/MantidWidgets/CMakeLists.txt +++ b/Code/Mantid/MantidQt/MantidWidgets/CMakeLists.txt @@ -139,7 +139,6 @@ find_package (Qt4 REQUIRED QtHelp QtWebKit QtNetwork QUIET) include(${QT_USE_FILE}) include_directories ( ../../QtPropertyBrowser/src ) - qt4_wrap_cpp ( MOCCED_FILES ${MOC_FILES} ) set ( ALL_SRC ${SRC_FILES} ${MOCCED_FILES} ) diff --git a/Code/Mantid/MantidQt/MantidWidgets/inc/MantidQtMantidWidgets/IndirectInstrumentConfig.h b/Code/Mantid/MantidQt/MantidWidgets/inc/MantidQtMantidWidgets/IndirectInstrumentConfig.h index 4940ab6a8f50..b800b92636e8 100644 --- a/Code/Mantid/MantidQt/MantidWidgets/inc/MantidQtMantidWidgets/IndirectInstrumentConfig.h +++ b/Code/Mantid/MantidQt/MantidWidgets/inc/MantidQtMantidWidgets/IndirectInstrumentConfig.h @@ -98,13 +98,15 @@ namespace MantidQt void newInstrumentConfiguration(); signals: - /// Emmitted when the instrument configuration is changed + /// Emitted when the instrument configuration is changed void instrumentConfigurationUpdated(const QString & instrumentName, const QString & analyserName, const QString & reflectionName); private slots: - /// Updates the list of analysers and reflections based on the selected instrument + /// Handles an instrument being selected void updateInstrumentConfigurations(const QString & instrumentName); + /// Updates the list of analysers when an instrument is selected + bool updateAnalysersList(Mantid::API::MatrixWorkspace_sptr ws); /// Updates the list of reflections when an analyser is selected void updateReflectionsList(int index); /// Filters out any disabled instruments diff --git a/Code/Mantid/MantidQt/MantidWidgets/inc/MantidQtMantidWidgets/MWRunFiles.h b/Code/Mantid/MantidQt/MantidWidgets/inc/MantidQtMantidWidgets/MWRunFiles.h index ce42e952f78d..621f107a7761 100644 --- a/Code/Mantid/MantidQt/MantidWidgets/inc/MantidQtMantidWidgets/MWRunFiles.h +++ b/Code/Mantid/MantidQt/MantidWidgets/inc/MantidQtMantidWidgets/MWRunFiles.h @@ -206,6 +206,8 @@ namespace MantidQt void findingFiles(); /// Emitted when files have been found void filesFound(); + /// Emitted when files have been found that are different to what was found last time + void filesFoundChanged(); /// Emitted when file finding is finished (files may or may not have been found). void fileFindingFinished(); /// Emitted when the live button is toggled @@ -282,6 +284,8 @@ namespace MantidQt Ui::MWRunFiles m_uiForm; /// An array of valid file names derived from the entries in the leNumber LineEdit QStringList m_foundFiles; + /// An array of the last valid file names found + QStringList m_lastFoundFiles; /// The last directory viewed by the browse dialog QString m_lastDir; /// A file filter for the file browser diff --git a/Code/Mantid/MantidQt/MantidWidgets/inc/MantidQtMantidWidgets/SlicingAlgorithmDialog.h b/Code/Mantid/MantidQt/MantidWidgets/inc/MantidQtMantidWidgets/SlicingAlgorithmDialog.h index cbf45bd91840..4bd0af204676 100644 --- a/Code/Mantid/MantidQt/MantidWidgets/inc/MantidQtMantidWidgets/SlicingAlgorithmDialog.h +++ b/Code/Mantid/MantidQt/MantidWidgets/inc/MantidQtMantidWidgets/SlicingAlgorithmDialog.h @@ -8,10 +8,11 @@ #include "MantidQtAPI/AlgorithmDialog.h" #include "MantidAPI/IAlgorithm.h" #include "MantidAPI/Algorithm.h" +#include "WidgetDllOption.h" namespace MantidQt { -namespace CustomDialogs +namespace MantidWidgets { typedef QMap PropertyDimensionMap; @@ -26,7 +27,7 @@ This custom dialog provides two advantages over the default custom generated one 2) It pre-populates those dimension input controls based on existing values. */ -class SlicingAlgorithmDialog : public MantidQt::API::AlgorithmDialog +class EXPORT_OPT_MANTIDQT_MANTIDWIDGETS SlicingAlgorithmDialog : public MantidQt::API::AlgorithmDialog { Q_OBJECT public: @@ -37,6 +38,12 @@ class SlicingAlgorithmDialog : public MantidQt::API::AlgorithmDialog /// Destructor ~SlicingAlgorithmDialog(); + // Customisation for the VSI + void customiseLayoutForVsi(std::string initialWorkspace); + + ///Reset the aligned dim values for the VSI + void resestAlignedDimProperty(size_t index, QString propertyValue); + protected: /// view @@ -45,6 +52,9 @@ class SlicingAlgorithmDialog : public MantidQt::API::AlgorithmDialog /// Common slice md setup void commonSliceMDSetup(const bool); + /// Build dimension inputs. + void buildDimensionInputs(const bool bForceForget=false); + protected slots: void onWorkspaceChanged(); @@ -80,9 +90,6 @@ protected slots: /// Gets the output workspace name provided QString getCurrentOutputWorkspaceName() const; - /// Build dimension inputs. - void buildDimensionInputs(const bool bForceForget=false); - /// Build dimension inputs. void makeDimensionInputs(const QString& propertyPrefix, QLayout* owningLayout, QString(*format)(Mantid::Geometry::IMDDimension_const_sptr), History history); @@ -116,13 +123,14 @@ protected slots: Class SliceMDDialog Concrete SlicingAlgorithm Dialog geared for SliceMD */ -class SliceMDDialog : public SlicingAlgorithmDialog +class EXPORT_OPT_MANTIDQT_MANTIDWIDGETS SliceMDDialog : public SlicingAlgorithmDialog { Q_OBJECT public: SliceMDDialog(QWidget* parent=NULL) : SlicingAlgorithmDialog(parent) { } + ~SliceMDDialog(){} void customiseInitLayout(); @@ -132,7 +140,7 @@ class SliceMDDialog : public SlicingAlgorithmDialog Class BinMDDialog Concrete BinMDDialog Dialog geared for BinMD */ -class BinMDDialog : public SlicingAlgorithmDialog +class EXPORT_OPT_MANTIDQT_MANTIDWIDGETS BinMDDialog : public SlicingAlgorithmDialog { Q_OBJECT public: diff --git a/Code/Mantid/MantidQt/MantidWidgets/src/IndirectInstrumentConfig.cpp b/Code/Mantid/MantidQt/MantidWidgets/src/IndirectInstrumentConfig.cpp index b38c577d6742..77a28a51facd 100644 --- a/Code/Mantid/MantidQt/MantidWidgets/src/IndirectInstrumentConfig.cpp +++ b/Code/Mantid/MantidQt/MantidWidgets/src/IndirectInstrumentConfig.cpp @@ -312,23 +312,60 @@ namespace MantidQt m_uiForm.cbAnalyser->clear(); - IAlgorithm_sptr loadInstAlg = AlgorithmManager::Instance().create("CreateSimulationWorkspace"); - loadInstAlg->initialize(); - loadInstAlg->setChild(true); - loadInstAlg->setProperty("Instrument", instrumentName.toStdString()); - loadInstAlg->setProperty("BinParams", "0,0.5,1"); - loadInstAlg->setProperty("OutputWorkspace", "__empty_instrument_workspace"); - loadInstAlg->execute(); - MatrixWorkspace_sptr instWorkspace = loadInstAlg->getProperty("OutputWorkspace"); + // Try to load the instrument into an empty workspace + MatrixWorkspace_sptr instWorkspace; + try + { + IAlgorithm_sptr loadInstAlg = AlgorithmManager::Instance().create("CreateSimulationWorkspace"); + loadInstAlg->initialize(); + loadInstAlg->setChild(true); + loadInstAlg->setLogging(false); + loadInstAlg->setProperty("Instrument", instrumentName.toStdString()); + loadInstAlg->setProperty("BinParams", "0,0.5,1"); + loadInstAlg->setProperty("OutputWorkspace", "__empty_instrument_workspace"); + loadInstAlg->execute(); + instWorkspace = loadInstAlg->getProperty("OutputWorkspace"); + } + catch(...) + { + } + + // Try to update the list of analysers + bool valid = updateAnalysersList(instWorkspace); + m_uiForm.cbAnalyser->setEnabled(valid); + if(!valid) + m_uiForm.cbAnalyser->addItem("No Valid Analysers"); + + // Update the list of reflections + int index = m_uiForm.cbAnalyser->currentIndex(); + updateReflectionsList(index); + + m_uiForm.cbAnalyser->blockSignals(analyserPreviousBlocking); + } + + + /** + * Update the list of analysers based on an instrument workspace. + * + * @param ws Instrument workspace + * @return If the workspace contained valid analysers + */ + bool IndirectInstrumentConfig::updateAnalysersList(MatrixWorkspace_sptr ws) + { + if(!ws) + return false; QList> instrumentModes; - Instrument_const_sptr instrument = instWorkspace->getInstrument(); + Instrument_const_sptr instrument = ws->getInstrument(); std::vector ipfAnalysers = instrument->getStringParameter("analysers"); - if(ipfAnalysers.size() == 0) - return; + QStringList analysers; + if(ipfAnalysers.size() > 0) + analysers = QString::fromStdString(ipfAnalysers[0]).split(","); - QStringList analysers = QString::fromStdString(ipfAnalysers[0]).split(","); + // Do not try to display analysers if there are none + if(analysers.size() == 0) + return false; for(auto it = analysers.begin(); it != analysers.end(); ++it) { @@ -353,10 +390,7 @@ namespace MantidQt } } - int index = m_uiForm.cbAnalyser->currentIndex(); - updateReflectionsList(index); - - m_uiForm.cbAnalyser->blockSignals(analyserPreviousBlocking); + return true; } diff --git a/Code/Mantid/MantidQt/MantidWidgets/src/MWRunFiles.cpp b/Code/Mantid/MantidQt/MantidWidgets/src/MWRunFiles.cpp index 1410da0b8e49..d46513eaa59c 100644 --- a/Code/Mantid/MantidQt/MantidWidgets/src/MWRunFiles.cpp +++ b/Code/Mantid/MantidQt/MantidWidgets/src/MWRunFiles.cpp @@ -196,7 +196,7 @@ MWRunFiles::MWRunFiles(QWidget *parent) : MantidWidget(parent), m_findRunFiles(true), m_allowMultipleFiles(false), m_isOptional(false), m_multiEntry(false), m_buttonOpt(Text), m_fileProblem(""), m_entryNumProblem(""), m_algorithmProperty(""), m_fileExtensions(), m_extsAsSingleOption(true), - m_liveButtonState(Hide), m_foundFiles(), m_lastDir(), m_fileFilter() + m_liveButtonState(Hide), m_foundFiles(), m_lastFoundFiles(), m_lastDir(), m_fileFilter() { m_thread = new FindFilesThread(this); @@ -840,6 +840,7 @@ void MWRunFiles::inspectThreadResult() return; } + m_lastFoundFiles = m_foundFiles; m_foundFiles.clear(); for( size_t i = 0; i < filenames.size(); ++i) @@ -861,6 +862,7 @@ void MWRunFiles::inspectThreadResult() // Only emit the signal if file(s) were found if ( ! m_foundFiles.isEmpty() ) emit filesFound(); + if ( m_lastFoundFiles != m_foundFiles ) emit filesFoundChanged(); } /** diff --git a/Code/Mantid/MantidQt/MantidWidgets/src/SlicingAlgorithmDialog.cpp b/Code/Mantid/MantidQt/MantidWidgets/src/SlicingAlgorithmDialog.cpp index accd00dacb6a..e44a8a5f785d 100644 --- a/Code/Mantid/MantidQt/MantidWidgets/src/SlicingAlgorithmDialog.cpp +++ b/Code/Mantid/MantidQt/MantidWidgets/src/SlicingAlgorithmDialog.cpp @@ -14,7 +14,7 @@ using namespace Mantid::Geometry; namespace MantidQt { - namespace CustomDialogs + namespace MantidWidgets { DECLARE_DIALOG(SliceMDDialog); DECLARE_DIALOG(BinMDDialog); @@ -433,6 +433,64 @@ namespace MantidQt return ui.ck_calculate->isChecked(); } + /** + *Customise the layout for usage in the Vsi + */ + void SlicingAlgorithmDialog::customiseLayoutForVsi(std::string initialWorkspace) + { + // File back-end + ui.file_backend_layout->setVisible(false); + + // Output workspace + ui.lbl_workspace_output->setVisible(false); + ui.txt_output->setVisible(false); + + // Input workspace + ui.workspace_selector->setVisible(false); + ui.lbl_workspace_input->setVisible(false); + + // Reset the input workspace + ui.workspace_selector->clear(); + ui.workspace_selector->addItem(initialWorkspace.c_str()); + + // Turn off history of the aligned dimension fields; + buildDimensionInputs(true); + } + + /** + * Resets the axis dimensions externally. + * @param propertyName The name of the axis dimension. + * @param propertyValue The new value of the axis dimension. + */ + void SlicingAlgorithmDialog::resestAlignedDimProperty(size_t index, QString propertyValue) + { + QString alignedDim = "AlignedDim"; + + const QString propertyName = alignedDim.copy().append(QString().number(index)); + + if (!m_tied_properties.contains(propertyName)) + { + return; + } + + QWidget* widget = m_tied_properties[propertyName]; + + if (!widget) + { + return; + } + + QLineEdit* edit = dynamic_cast(widget); + + if (!edit) + { + return; + } + + edit->setText(propertyValue); + } + + /*--------------------------------------------------------------------------------------------- SliceMDDialog Methods ---------------------------------------------------------------------------------------------*/ diff --git a/Code/Mantid/MantidQt/SliceViewer/inc/MantidQtSliceViewer/SliceViewer.h b/Code/Mantid/MantidQt/SliceViewer/inc/MantidQtSliceViewer/SliceViewer.h index db9e0442aa94..ba322744687a 100644 --- a/Code/Mantid/MantidQt/SliceViewer/inc/MantidQtSliceViewer/SliceViewer.h +++ b/Code/Mantid/MantidQt/SliceViewer/inc/MantidQtSliceViewer/SliceViewer.h @@ -11,6 +11,7 @@ #include "MantidKernel/Logger.h" #include "MantidKernel/VMD.h" #include "MantidQtAPI/MantidColorMap.h" +#include "MantidQtAPI/MdSettings.h" #include "MantidQtMantidWidgets/SafeQwtPlot.h" #include "MantidQtAPI/SyncedCheckboxes.h" #include "MantidQtSliceViewer/LineOverlay.h" @@ -319,6 +320,9 @@ public slots: /// If true, the rebinned overlayWS is locked until refreshed. bool m_rebinLocked; + /// Md Settings for color maps + boost::shared_ptr m_mdSettings; + /// Logger Mantid::Kernel::Logger m_logger; diff --git a/Code/Mantid/MantidQt/SliceViewer/src/LineViewer.cpp b/Code/Mantid/MantidQt/SliceViewer/src/LineViewer.cpp index 73fec226f411..0be3451b0d4b 100644 --- a/Code/Mantid/MantidQt/SliceViewer/src/LineViewer.cpp +++ b/Code/Mantid/MantidQt/SliceViewer/src/LineViewer.cpp @@ -656,6 +656,8 @@ bool LineViewer::getFixedBinWidthMode() const * @param ws :: IMDWorkspace */ void LineViewer::setWorkspace(Mantid::API::IMDWorkspace_sptr ws) { + if(!ws) + throw std::runtime_error("LineViewer::setWorkspace(): Invalid workspace."); m_ws = ws; m_thickness = VMD(ws->getNumDims()); createDimensionWidgets(); diff --git a/Code/Mantid/MantidQt/SliceViewer/src/SliceViewer.cpp b/Code/Mantid/MantidQt/SliceViewer/src/SliceViewer.cpp index c476feb1a48e..0efa8cadb6fd 100644 --- a/Code/Mantid/MantidQt/SliceViewer/src/SliceViewer.cpp +++ b/Code/Mantid/MantidQt/SliceViewer/src/SliceViewer.cpp @@ -24,6 +24,7 @@ #include "MantidKernel/ReadLock.h" #include "MantidQtAPI/FileDialogHandler.h" #include "MantidQtAPI/PlotAxis.h" +#include "MantidQtAPI/MdSettings.h" #include "MantidQtAPI/SignalRange.h" #include "MantidQtSliceViewer/SliceViewer.h" #include "MantidQtSliceViewer/CustomTools.h" @@ -73,11 +74,13 @@ SliceViewer::SliceViewer(QWidget *parent) : QWidget(parent), m_ws(), m_firstWorkspaceOpen(false), m_dimensions(), m_data(NULL), m_X(), m_Y(), m_dimX(0), m_dimY(1), m_logColor(false), m_fastRender(true), m_rebinMode(false), m_rebinLocked(true), + m_mdSettings(new MantidQt::API::MdSettings()), m_logger("SliceViewer"), m_peaksPresenter(boost::make_shared(this)), m_proxyPeaksPresenter( - boost::make_shared(m_peaksPresenter)), - m_peaksSliderWidget(NULL) { + boost::make_shared(m_peaksPresenter)), + m_peaksSliderWidget(NULL){ + ui.setupUi(this); m_inf = std::numeric_limits::infinity(); @@ -166,8 +169,18 @@ void SliceViewer::loadSettings() { QSettings settings; settings.beginGroup("Mantid/SliceViewer"); bool scaleType = (bool)settings.value("LogColorScale", 0).toInt(); - // Load Colormap. If the file is invalid the default stored colour map is used - m_currentColorMapFile = settings.value("ColormapFile", "").toString(); + + //Load Colormap. If the file is invalid the default stored colour map is used. If the + // user selected a unified color map for the SliceViewer and the VSI, then this is loaded. + if (m_mdSettings != NULL && m_mdSettings->getUsageGeneralMdColorMap()) + { + m_currentColorMapFile = m_mdSettings->getGeneralMdColorMapFile(); + } + else + { + m_currentColorMapFile = settings.value("ColormapFile", "").toString(); + } + // Set values from settings if (!m_currentColorMapFile.isEmpty()) loadColorMap(m_currentColorMapFile); diff --git a/Code/Mantid/Testing/Data/SystemTest/2011B_HR60b1.irf.md5 b/Code/Mantid/Testing/Data/SystemTest/2011B_HR60b1.irf.md5 new file mode 100644 index 000000000000..5e6b5d227eff --- /dev/null +++ b/Code/Mantid/Testing/Data/SystemTest/2011B_HR60b1.irf.md5 @@ -0,0 +1 @@ +782b7dc98e3f622d3a6b4e5f0d94882a \ No newline at end of file diff --git a/Code/Mantid/Testing/Data/SystemTest/4844b1.inp.md5 b/Code/Mantid/Testing/Data/SystemTest/4844b1.inp.md5 new file mode 100644 index 000000000000..df8ae0c0484b --- /dev/null +++ b/Code/Mantid/Testing/Data/SystemTest/4844b1.inp.md5 @@ -0,0 +1 @@ +3aee25065551a3b12dc456fc8f66d00b \ No newline at end of file diff --git a/Code/Mantid/Testing/Data/SystemTest/4to1.map.md5 b/Code/Mantid/Testing/Data/SystemTest/4to1.map.md5 new file mode 100644 index 000000000000..ed7768893d50 --- /dev/null +++ b/Code/Mantid/Testing/Data/SystemTest/4to1.map.md5 @@ -0,0 +1 @@ +22e092416e12d3efee213cb7f2d7e9c9 \ No newline at end of file diff --git a/Code/Mantid/Testing/Data/SystemTest/4to1_mid_lowang.map.md5 b/Code/Mantid/Testing/Data/SystemTest/4to1_mid_lowang.map.md5 new file mode 100644 index 000000000000..446bc149215a --- /dev/null +++ b/Code/Mantid/Testing/Data/SystemTest/4to1_mid_lowang.map.md5 @@ -0,0 +1 @@ +94467b5a7549b87985852b104552784e \ No newline at end of file diff --git a/Code/Mantid/Testing/Data/SystemTest/ARCS_23961_event.nxs.md5 b/Code/Mantid/Testing/Data/SystemTest/ARCS_23961_event.nxs.md5 new file mode 100644 index 000000000000..dbe4217b2a55 --- /dev/null +++ b/Code/Mantid/Testing/Data/SystemTest/ARCS_23961_event.nxs.md5 @@ -0,0 +1 @@ +e025ef994f9f77b369bab1b3c640d5ed \ No newline at end of file diff --git a/Code/Mantid/Testing/Data/SystemTest/ARGUSFwdGrouping.xml.md5 b/Code/Mantid/Testing/Data/SystemTest/ARGUSFwdGrouping.xml.md5 new file mode 100644 index 000000000000..9675fbd08661 --- /dev/null +++ b/Code/Mantid/Testing/Data/SystemTest/ARGUSFwdGrouping.xml.md5 @@ -0,0 +1 @@ +c00bb47c27a7fffd52970cf059a8de11 \ No newline at end of file diff --git a/Code/Mantid/Testing/Data/SystemTest/ARGUSGrouping.xml.md5 b/Code/Mantid/Testing/Data/SystemTest/ARGUSGrouping.xml.md5 new file mode 100644 index 000000000000..076c1207dcf2 --- /dev/null +++ b/Code/Mantid/Testing/Data/SystemTest/ARGUSGrouping.xml.md5 @@ -0,0 +1 @@ +24eb8612bcbcd76edce74dcb7c3c5fef \ No newline at end of file diff --git a/Code/Mantid/Testing/Data/SystemTest/BASIS_AutoReduction_Mask.xml.md5 b/Code/Mantid/Testing/Data/SystemTest/BASIS_AutoReduction_Mask.xml.md5 new file mode 100644 index 000000000000..9bd8cd18950a --- /dev/null +++ b/Code/Mantid/Testing/Data/SystemTest/BASIS_AutoReduction_Mask.xml.md5 @@ -0,0 +1 @@ +de50fa5bea7540e47bb4fe987642236d \ No newline at end of file diff --git a/Code/Mantid/Testing/Data/SystemTest/BSS_13387_event.nxs.expected.md5 b/Code/Mantid/Testing/Data/SystemTest/BSS_13387_event.nxs.expected.md5 new file mode 100644 index 000000000000..5c36defee038 --- /dev/null +++ b/Code/Mantid/Testing/Data/SystemTest/BSS_13387_event.nxs.expected.md5 @@ -0,0 +1 @@ +8be1b5ef4ac6834d48e481afcf865033 \ No newline at end of file diff --git a/Code/Mantid/Testing/Data/SystemTest/BSS_13387_event.nxs.md5 b/Code/Mantid/Testing/Data/SystemTest/BSS_13387_event.nxs.md5 new file mode 100644 index 000000000000..3aa4405f7e33 --- /dev/null +++ b/Code/Mantid/Testing/Data/SystemTest/BSS_13387_event.nxs.md5 @@ -0,0 +1 @@ +6357b83d42c4604120cce423273e8557 \ No newline at end of file diff --git a/Code/Mantid/Testing/Data/SystemTest/BioSANS_test_data.xml.expected.md5 b/Code/Mantid/Testing/Data/SystemTest/BioSANS_test_data.xml.expected.md5 new file mode 100644 index 000000000000..e71bf219c043 --- /dev/null +++ b/Code/Mantid/Testing/Data/SystemTest/BioSANS_test_data.xml.expected.md5 @@ -0,0 +1 @@ +b492f3887d317bb99f9555f2d7870670 \ No newline at end of file diff --git a/Code/Mantid/Testing/Data/SystemTest/BioSANS_test_data.xml.md5 b/Code/Mantid/Testing/Data/SystemTest/BioSANS_test_data.xml.md5 new file mode 100644 index 000000000000..c98c7829fbea --- /dev/null +++ b/Code/Mantid/Testing/Data/SystemTest/BioSANS_test_data.xml.md5 @@ -0,0 +1 @@ +b57f47fb9acc40fdd27ffa61c4c20b0d \ No newline at end of file diff --git a/Code/Mantid/Testing/Data/SystemTest/CNCS_23936_event.nxs.md5 b/Code/Mantid/Testing/Data/SystemTest/CNCS_23936_event.nxs.md5 new file mode 100644 index 000000000000..9b2091837ba9 --- /dev/null +++ b/Code/Mantid/Testing/Data/SystemTest/CNCS_23936_event.nxs.md5 @@ -0,0 +1 @@ +15636909d23a6bc9829a1138f8dd890c \ No newline at end of file diff --git a/Code/Mantid/Testing/Data/SystemTest/CNCS_23937_event.nxs.md5 b/Code/Mantid/Testing/Data/SystemTest/CNCS_23937_event.nxs.md5 new file mode 100644 index 000000000000..7e68d2572667 --- /dev/null +++ b/Code/Mantid/Testing/Data/SystemTest/CNCS_23937_event.nxs.md5 @@ -0,0 +1 @@ +6a51a2596f8e40eec04bc5ab03fc933a \ No newline at end of file diff --git a/Code/Mantid/Testing/Data/SystemTest/CNCS_51936_event.nxs.md5 b/Code/Mantid/Testing/Data/SystemTest/CNCS_51936_event.nxs.md5 new file mode 100644 index 000000000000..95edae0fd0b4 --- /dev/null +++ b/Code/Mantid/Testing/Data/SystemTest/CNCS_51936_event.nxs.md5 @@ -0,0 +1 @@ +5ba401e489260a44374b5be12b780911 \ No newline at end of file diff --git a/Code/Mantid/Testing/Data/SystemTest/CNCS_7860_coarse.nxspe.md5 b/Code/Mantid/Testing/Data/SystemTest/CNCS_7860_coarse.nxspe.md5 new file mode 100644 index 000000000000..e3d5af7016e5 --- /dev/null +++ b/Code/Mantid/Testing/Data/SystemTest/CNCS_7860_coarse.nxspe.md5 @@ -0,0 +1 @@ +7f703c487ee5b0897b6d061add949834 \ No newline at end of file diff --git a/Code/Mantid/Testing/Data/SystemTest/CNCS_7860_event.nxs.md5 b/Code/Mantid/Testing/Data/SystemTest/CNCS_7860_event.nxs.md5 new file mode 100644 index 000000000000..e9d50bece851 --- /dev/null +++ b/Code/Mantid/Testing/Data/SystemTest/CNCS_7860_event.nxs.md5 @@ -0,0 +1 @@ +1db1853f94b381aca96412fef9629f3f \ No newline at end of file diff --git a/Code/Mantid/Testing/Data/SystemTest/CNCS_7860_neutron_event.dat.md5 b/Code/Mantid/Testing/Data/SystemTest/CNCS_7860_neutron_event.dat.md5 new file mode 100644 index 000000000000..cf91b93fbcf0 --- /dev/null +++ b/Code/Mantid/Testing/Data/SystemTest/CNCS_7860_neutron_event.dat.md5 @@ -0,0 +1 @@ +1f4da354e50d8463b7139d596d9a1366 \ No newline at end of file diff --git a/Code/Mantid/Testing/Data/SystemTest/CNCS_7860_pulseid.dat.md5 b/Code/Mantid/Testing/Data/SystemTest/CNCS_7860_pulseid.dat.md5 new file mode 100644 index 000000000000..a1bd450b5779 --- /dev/null +++ b/Code/Mantid/Testing/Data/SystemTest/CNCS_7860_pulseid.dat.md5 @@ -0,0 +1 @@ +eab9e0adb1ed4aa1a3214420bab1ab8c \ No newline at end of file diff --git a/Code/Mantid/Testing/Data/SystemTest/CNCS_TS_2008_08_18.dat.md5 b/Code/Mantid/Testing/Data/SystemTest/CNCS_TS_2008_08_18.dat.md5 new file mode 100644 index 000000000000..c18bc1cc078e --- /dev/null +++ b/Code/Mantid/Testing/Data/SystemTest/CNCS_TS_2008_08_18.dat.md5 @@ -0,0 +1 @@ +14748b9643b88ec4c8d1f123c591a4ef \ No newline at end of file diff --git a/Code/Mantid/Testing/Data/SystemTest/CSP74683.s02.expected.md5 b/Code/Mantid/Testing/Data/SystemTest/CSP74683.s02.expected.md5 new file mode 100644 index 000000000000..7eb4706a659b --- /dev/null +++ b/Code/Mantid/Testing/Data/SystemTest/CSP74683.s02.expected.md5 @@ -0,0 +1 @@ +939a2e73a030a64495796ff671d785f5 \ No newline at end of file diff --git a/Code/Mantid/Testing/Data/SystemTest/CSP74683.s02.md5 b/Code/Mantid/Testing/Data/SystemTest/CSP74683.s02.md5 new file mode 100644 index 000000000000..1445519b0fa0 --- /dev/null +++ b/Code/Mantid/Testing/Data/SystemTest/CSP74683.s02.md5 @@ -0,0 +1 @@ +e08dd055e368564ff32e722ee932a583 \ No newline at end of file diff --git a/Code/Mantid/Testing/Data/SystemTest/CSP85423.nxs.md5 b/Code/Mantid/Testing/Data/SystemTest/CSP85423.nxs.md5 new file mode 100644 index 000000000000..38ffefaeca73 --- /dev/null +++ b/Code/Mantid/Testing/Data/SystemTest/CSP85423.nxs.md5 @@ -0,0 +1 @@ +5825cb8d544a9eea249fb90a4e95ea9e \ No newline at end of file diff --git a/Code/Mantid/Testing/Data/SystemTest/CSP85423.raw.expected.md5 b/Code/Mantid/Testing/Data/SystemTest/CSP85423.raw.expected.md5 new file mode 100644 index 000000000000..e95ff204c87f --- /dev/null +++ b/Code/Mantid/Testing/Data/SystemTest/CSP85423.raw.expected.md5 @@ -0,0 +1 @@ +8a5b2d754c00923b0fad290cc8d66f22 \ No newline at end of file diff --git a/Code/Mantid/Testing/Data/SystemTest/CSP85423.raw.md5 b/Code/Mantid/Testing/Data/SystemTest/CSP85423.raw.md5 new file mode 100644 index 000000000000..5cdc096340d3 --- /dev/null +++ b/Code/Mantid/Testing/Data/SystemTest/CSP85423.raw.md5 @@ -0,0 +1 @@ +29df04a67598fb027aac95bfb8ffcd46 \ No newline at end of file diff --git a/Code/Mantid/Testing/Data/SystemTest/DISF_NaF.cdl.md5 b/Code/Mantid/Testing/Data/SystemTest/DISF_NaF.cdl.md5 new file mode 100644 index 000000000000..950972b4e8a3 --- /dev/null +++ b/Code/Mantid/Testing/Data/SystemTest/DISF_NaF.cdl.md5 @@ -0,0 +1 @@ +f91cf99979a149df6d8cebe80e704e76 \ No newline at end of file diff --git a/Code/Mantid/Testing/Data/SystemTest/DaveAscii.grp.expected.md5 b/Code/Mantid/Testing/Data/SystemTest/DaveAscii.grp.expected.md5 new file mode 100644 index 000000000000..64d2ef6a995f --- /dev/null +++ b/Code/Mantid/Testing/Data/SystemTest/DaveAscii.grp.expected.md5 @@ -0,0 +1 @@ +94fd8c6fc3ef1d0c5ad6c619b17820d0 \ No newline at end of file diff --git a/Code/Mantid/Testing/Data/SystemTest/DaveAscii.grp.md5 b/Code/Mantid/Testing/Data/SystemTest/DaveAscii.grp.md5 new file mode 100644 index 000000000000..9d61f3583a10 --- /dev/null +++ b/Code/Mantid/Testing/Data/SystemTest/DaveAscii.grp.md5 @@ -0,0 +1 @@ +cdca8002133b27f4f536536bf3d64fd6 \ No newline at end of file diff --git a/Code/Mantid/Testing/Data/SystemTest/EMU03087.nxs.md5 b/Code/Mantid/Testing/Data/SystemTest/EMU03087.nxs.md5 new file mode 100644 index 000000000000..e7410c667d93 --- /dev/null +++ b/Code/Mantid/Testing/Data/SystemTest/EMU03087.nxs.md5 @@ -0,0 +1 @@ +9e429b623c2c9e6c492d4877bfa905fd \ No newline at end of file diff --git a/Code/Mantid/Testing/Data/SystemTest/EMUFwdGrouping.xml.md5 b/Code/Mantid/Testing/Data/SystemTest/EMUFwdGrouping.xml.md5 new file mode 100644 index 000000000000..57877ba42122 --- /dev/null +++ b/Code/Mantid/Testing/Data/SystemTest/EMUFwdGrouping.xml.md5 @@ -0,0 +1 @@ +f50ba52957c62c146241b9478c08c4ba \ No newline at end of file diff --git a/Code/Mantid/Testing/Data/SystemTest/EMUGrouping.xml.md5 b/Code/Mantid/Testing/Data/SystemTest/EMUGrouping.xml.md5 new file mode 100644 index 000000000000..fe1edaac2aea --- /dev/null +++ b/Code/Mantid/Testing/Data/SystemTest/EMUGrouping.xml.md5 @@ -0,0 +1 @@ +5b402854d36c9ee3f3cd2b534fbd476f \ No newline at end of file diff --git a/Code/Mantid/Testing/Data/SystemTest/ENGINX00193749.nxs.md5 b/Code/Mantid/Testing/Data/SystemTest/ENGINX00193749.nxs.md5 new file mode 100644 index 000000000000..e3e95ccdb125 --- /dev/null +++ b/Code/Mantid/Testing/Data/SystemTest/ENGINX00193749.nxs.md5 @@ -0,0 +1 @@ +22fc488c3f71eae634a18799dd04da72 \ No newline at end of file diff --git a/Code/Mantid/Testing/Data/SystemTest/EQSANS_1466_event.nxs.md5 b/Code/Mantid/Testing/Data/SystemTest/EQSANS_1466_event.nxs.md5 new file mode 100644 index 000000000000..9c7d016b0561 --- /dev/null +++ b/Code/Mantid/Testing/Data/SystemTest/EQSANS_1466_event.nxs.md5 @@ -0,0 +1 @@ +70e4fde81382e905bf5906267c004af2 \ No newline at end of file diff --git a/Code/Mantid/Testing/Data/SystemTest/EQSANS_3293_event.nxs.md5 b/Code/Mantid/Testing/Data/SystemTest/EQSANS_3293_event.nxs.md5 new file mode 100644 index 000000000000..cbba03f9eb59 --- /dev/null +++ b/Code/Mantid/Testing/Data/SystemTest/EQSANS_3293_event.nxs.md5 @@ -0,0 +1 @@ +6a1d295d866b93f917f514965eaed146 \ No newline at end of file diff --git a/Code/Mantid/Testing/Data/SystemTest/EQSANS_4061_event.nxs.md5 b/Code/Mantid/Testing/Data/SystemTest/EQSANS_4061_event.nxs.md5 new file mode 100644 index 000000000000..a7a25c7b99a9 --- /dev/null +++ b/Code/Mantid/Testing/Data/SystemTest/EQSANS_4061_event.nxs.md5 @@ -0,0 +1 @@ +6d67fac803c7a7817d6577659e6b68a6 \ No newline at end of file diff --git a/Code/Mantid/Testing/Data/SystemTest/EQSANS_sensitivity.nxs.md5 b/Code/Mantid/Testing/Data/SystemTest/EQSANS_sensitivity.nxs.md5 new file mode 100644 index 000000000000..ffaa4214b2a7 --- /dev/null +++ b/Code/Mantid/Testing/Data/SystemTest/EQSANS_sensitivity.nxs.md5 @@ -0,0 +1 @@ +32f4b241fcb34d0aaa773d54a8e6ce39 \ No newline at end of file diff --git a/Code/Mantid/Testing/Data/SystemTest/EVS01250.raw.md5 b/Code/Mantid/Testing/Data/SystemTest/EVS01250.raw.md5 new file mode 100644 index 000000000000..51753a33a3d2 --- /dev/null +++ b/Code/Mantid/Testing/Data/SystemTest/EVS01250.raw.md5 @@ -0,0 +1 @@ +288700a8d99195ebda6ceab2f9c1ce5d \ No newline at end of file diff --git a/Code/Mantid/Testing/Data/SystemTest/EVS08500.raw.md5 b/Code/Mantid/Testing/Data/SystemTest/EVS08500.raw.md5 new file mode 100644 index 000000000000..0cea831feda8 --- /dev/null +++ b/Code/Mantid/Testing/Data/SystemTest/EVS08500.raw.md5 @@ -0,0 +1 @@ +87e3d36199905c08406f0a5ff01f437f \ No newline at end of file diff --git a/Code/Mantid/Testing/Data/SystemTest/EVS09000.raw.md5 b/Code/Mantid/Testing/Data/SystemTest/EVS09000.raw.md5 new file mode 100644 index 000000000000..99aba38e2ce4 --- /dev/null +++ b/Code/Mantid/Testing/Data/SystemTest/EVS09000.raw.md5 @@ -0,0 +1 @@ +c9fcad0ee6484530fcfb5f7c7d961013 \ No newline at end of file diff --git a/Code/Mantid/Testing/Data/SystemTest/EVS14188.raw.md5 b/Code/Mantid/Testing/Data/SystemTest/EVS14188.raw.md5 new file mode 100644 index 000000000000..7bf13d9fd9c8 --- /dev/null +++ b/Code/Mantid/Testing/Data/SystemTest/EVS14188.raw.md5 @@ -0,0 +1 @@ +0dfe0f45875b771e5bee239f52ee88f0 \ No newline at end of file diff --git a/Code/Mantid/Testing/Data/SystemTest/EVS14189.raw.md5 b/Code/Mantid/Testing/Data/SystemTest/EVS14189.raw.md5 new file mode 100644 index 000000000000..9976fceca66f --- /dev/null +++ b/Code/Mantid/Testing/Data/SystemTest/EVS14189.raw.md5 @@ -0,0 +1 @@ +092e09b0841410e467e212c4419dbe7c \ No newline at end of file diff --git a/Code/Mantid/Testing/Data/SystemTest/EVS14190.raw.md5 b/Code/Mantid/Testing/Data/SystemTest/EVS14190.raw.md5 new file mode 100644 index 000000000000..cbc302e4c75e --- /dev/null +++ b/Code/Mantid/Testing/Data/SystemTest/EVS14190.raw.md5 @@ -0,0 +1 @@ +1ec07788d893b630d34d5416ba341e3f \ No newline at end of file diff --git a/Code/Mantid/Testing/Data/SystemTest/EVS15289.raw.md5 b/Code/Mantid/Testing/Data/SystemTest/EVS15289.raw.md5 new file mode 100644 index 000000000000..dc2506b23352 --- /dev/null +++ b/Code/Mantid/Testing/Data/SystemTest/EVS15289.raw.md5 @@ -0,0 +1 @@ +ea1cb1b0d1daa9579fbeb4acf3716162 \ No newline at end of file diff --git a/Code/Mantid/Testing/Data/SystemTest/Example.spe.expected.md5 b/Code/Mantid/Testing/Data/SystemTest/Example.spe.expected.md5 new file mode 100644 index 000000000000..98d27fd9c86e --- /dev/null +++ b/Code/Mantid/Testing/Data/SystemTest/Example.spe.expected.md5 @@ -0,0 +1 @@ +768506380e69bc73455c026aeedc9f29 \ No newline at end of file diff --git a/Code/Mantid/Testing/Data/SystemTest/Example.spe.md5 b/Code/Mantid/Testing/Data/SystemTest/Example.spe.md5 new file mode 100644 index 000000000000..7edefbcf614e --- /dev/null +++ b/Code/Mantid/Testing/Data/SystemTest/Example.spe.md5 @@ -0,0 +1 @@ +89a6b74ad90a47de1e8757805850b7e4 \ No newline at end of file diff --git a/Code/Mantid/Testing/Data/SystemTest/GEM58654.raw.md5 b/Code/Mantid/Testing/Data/SystemTest/GEM58654.raw.md5 new file mode 100644 index 000000000000..f5f127eae9bc --- /dev/null +++ b/Code/Mantid/Testing/Data/SystemTest/GEM58654.raw.md5 @@ -0,0 +1 @@ +006ecdb2618d1f239bee6bc25c1af045 \ No newline at end of file diff --git a/Code/Mantid/Testing/Data/SystemTest/GEM59378.raw.md5 b/Code/Mantid/Testing/Data/SystemTest/GEM59378.raw.md5 new file mode 100644 index 000000000000..02bae552a617 --- /dev/null +++ b/Code/Mantid/Testing/Data/SystemTest/GEM59378.raw.md5 @@ -0,0 +1 @@ +732efb1fc6c05b565fb2d580bef71c0b \ No newline at end of file diff --git a/Code/Mantid/Testing/Data/SystemTest/GEM59381.raw.md5 b/Code/Mantid/Testing/Data/SystemTest/GEM59381.raw.md5 new file mode 100644 index 000000000000..37b9e5875b06 --- /dev/null +++ b/Code/Mantid/Testing/Data/SystemTest/GEM59381.raw.md5 @@ -0,0 +1 @@ +7072bc869f1463526b0263b09f0f4555 \ No newline at end of file diff --git a/Code/Mantid/Testing/Data/SystemTest/GPD900.nxs.md5 b/Code/Mantid/Testing/Data/SystemTest/GPD900.nxs.md5 new file mode 100644 index 000000000000..e31a1d109724 --- /dev/null +++ b/Code/Mantid/Testing/Data/SystemTest/GPD900.nxs.md5 @@ -0,0 +1 @@ +fc9c83eee2ebf727bf136c06e44cbe32 \ No newline at end of file diff --git a/Code/Mantid/Testing/Data/SystemTest/GPS5397.NXS.md5 b/Code/Mantid/Testing/Data/SystemTest/GPS5397.NXS.md5 new file mode 100644 index 000000000000..1c8109c2aa58 --- /dev/null +++ b/Code/Mantid/Testing/Data/SystemTest/GPS5397.NXS.md5 @@ -0,0 +1 @@ +a62b87f08a6f23a7e5f9e6492c66b1f3 \ No newline at end of file diff --git a/Code/Mantid/Testing/Data/SystemTest/HRP38094Calib.nxs.md5 b/Code/Mantid/Testing/Data/SystemTest/HRP38094Calib.nxs.md5 new file mode 100644 index 000000000000..a42678741a08 --- /dev/null +++ b/Code/Mantid/Testing/Data/SystemTest/HRP38094Calib.nxs.md5 @@ -0,0 +1 @@ +4d4bcc71f80b705c00a724f0961cc3dc \ No newline at end of file diff --git a/Code/Mantid/Testing/Data/SystemTest/HRP39180.RAW.md5 b/Code/Mantid/Testing/Data/SystemTest/HRP39180.RAW.md5 new file mode 100644 index 000000000000..027bfb088aac --- /dev/null +++ b/Code/Mantid/Testing/Data/SystemTest/HRP39180.RAW.md5 @@ -0,0 +1 @@ +7d19937fbfb68e962c190454a128fde6 \ No newline at end of file diff --git a/Code/Mantid/Testing/Data/SystemTest/HYSA_2934.nxs.h5.md5 b/Code/Mantid/Testing/Data/SystemTest/HYSA_2934.nxs.h5.md5 new file mode 100644 index 000000000000..b85870efd5d3 --- /dev/null +++ b/Code/Mantid/Testing/Data/SystemTest/HYSA_2934.nxs.h5.md5 @@ -0,0 +1 @@ +789e36a0ff5a1a925cf205102420f3d9 \ No newline at end of file diff --git a/Code/Mantid/Testing/Data/SystemTest/HYSA_mask.xml.md5 b/Code/Mantid/Testing/Data/SystemTest/HYSA_mask.xml.md5 new file mode 100644 index 000000000000..4ea0f5b32957 --- /dev/null +++ b/Code/Mantid/Testing/Data/SystemTest/HYSA_mask.xml.md5 @@ -0,0 +1 @@ +e76e7bbd9fe21e7fc5e2d30d426f5c52 \ No newline at end of file diff --git a/Code/Mantid/Testing/Data/SystemTest/HYS_13656_event.nxs.md5 b/Code/Mantid/Testing/Data/SystemTest/HYS_13656_event.nxs.md5 new file mode 100644 index 000000000000..036d7e4d5752 --- /dev/null +++ b/Code/Mantid/Testing/Data/SystemTest/HYS_13656_event.nxs.md5 @@ -0,0 +1 @@ +d53fd5e947bfd1deda2ff3be04af978b \ No newline at end of file diff --git a/Code/Mantid/Testing/Data/SystemTest/HYS_13657_event.nxs.md5 b/Code/Mantid/Testing/Data/SystemTest/HYS_13657_event.nxs.md5 new file mode 100644 index 000000000000..9bedff0371eb --- /dev/null +++ b/Code/Mantid/Testing/Data/SystemTest/HYS_13657_event.nxs.md5 @@ -0,0 +1 @@ +eef07e3d71813e8c6bc3428da59bea52 \ No newline at end of file diff --git a/Code/Mantid/Testing/Data/SystemTest/HYS_13658_event.nxs.md5 b/Code/Mantid/Testing/Data/SystemTest/HYS_13658_event.nxs.md5 new file mode 100644 index 000000000000..5d054f30dc0a --- /dev/null +++ b/Code/Mantid/Testing/Data/SystemTest/HYS_13658_event.nxs.md5 @@ -0,0 +1 @@ +6d9cbe5bab593c506f7adb396d4e0d38 \ No newline at end of file diff --git a/Code/Mantid/Testing/Data/SystemTest/HiFi0Grouping.xml.md5 b/Code/Mantid/Testing/Data/SystemTest/HiFi0Grouping.xml.md5 new file mode 100644 index 000000000000..aad2d8f6ab2f --- /dev/null +++ b/Code/Mantid/Testing/Data/SystemTest/HiFi0Grouping.xml.md5 @@ -0,0 +1 @@ +68c559ee5d9d509f907f13b67e1e67e7 \ No newline at end of file diff --git a/Code/Mantid/Testing/Data/SystemTest/HiFiGrouping.xml.md5 b/Code/Mantid/Testing/Data/SystemTest/HiFiGrouping.xml.md5 new file mode 100644 index 000000000000..5ad33bff4549 --- /dev/null +++ b/Code/Mantid/Testing/Data/SystemTest/HiFiGrouping.xml.md5 @@ -0,0 +1 @@ +5a3eaf7f1e9d9173afd0a124f6b3b3b6 \ No newline at end of file diff --git a/Code/Mantid/Testing/Data/SystemTest/ILL/001420.nxs.md5 b/Code/Mantid/Testing/Data/SystemTest/ILL/001420.nxs.md5 new file mode 100644 index 000000000000..cfaa07241720 --- /dev/null +++ b/Code/Mantid/Testing/Data/SystemTest/ILL/001420.nxs.md5 @@ -0,0 +1 @@ +3d7981dda48aed0b6b4abf1e8e03b118 \ No newline at end of file diff --git a/Code/Mantid/Testing/Data/SystemTest/ILL/001422.nxs.md5 b/Code/Mantid/Testing/Data/SystemTest/ILL/001422.nxs.md5 new file mode 100644 index 000000000000..9c7c1302b97b --- /dev/null +++ b/Code/Mantid/Testing/Data/SystemTest/ILL/001422.nxs.md5 @@ -0,0 +1 @@ +5dee58331051229ab32045bfb5dd19b5 \ No newline at end of file diff --git a/Code/Mantid/Testing/Data/SystemTest/ILL/001425.nxs.md5 b/Code/Mantid/Testing/Data/SystemTest/ILL/001425.nxs.md5 new file mode 100644 index 000000000000..79c129065e68 --- /dev/null +++ b/Code/Mantid/Testing/Data/SystemTest/ILL/001425.nxs.md5 @@ -0,0 +1 @@ +a5c7449af9f0d4a46dd06b5074d9da60 \ No newline at end of file diff --git a/Code/Mantid/Testing/Data/SystemTest/ILL/001427.nxs.md5 b/Code/Mantid/Testing/Data/SystemTest/ILL/001427.nxs.md5 new file mode 100644 index 000000000000..9c968d06f28f --- /dev/null +++ b/Code/Mantid/Testing/Data/SystemTest/ILL/001427.nxs.md5 @@ -0,0 +1 @@ +687284902a5639ad30a9fbf392531521 \ No newline at end of file diff --git a/Code/Mantid/Testing/Data/SystemTest/ILL/001428.nxs.md5 b/Code/Mantid/Testing/Data/SystemTest/ILL/001428.nxs.md5 new file mode 100644 index 000000000000..6afbbc85b13c --- /dev/null +++ b/Code/Mantid/Testing/Data/SystemTest/ILL/001428.nxs.md5 @@ -0,0 +1 @@ +899de6ba09da9137a863d420d6b5da7a \ No newline at end of file diff --git a/Code/Mantid/Testing/Data/SystemTest/ILL/001431.nxs.md5 b/Code/Mantid/Testing/Data/SystemTest/ILL/001431.nxs.md5 new file mode 100644 index 000000000000..1017fc28e91a --- /dev/null +++ b/Code/Mantid/Testing/Data/SystemTest/ILL/001431.nxs.md5 @@ -0,0 +1 @@ +37685dac3fc533fe858ea492ad08f586 \ No newline at end of file diff --git a/Code/Mantid/Testing/Data/SystemTest/ILL/068288.nxs.md5 b/Code/Mantid/Testing/Data/SystemTest/ILL/068288.nxs.md5 new file mode 100644 index 000000000000..17b183afdfb1 --- /dev/null +++ b/Code/Mantid/Testing/Data/SystemTest/ILL/068288.nxs.md5 @@ -0,0 +1 @@ +e32972f10816293f8ea1ac12c22cdaf6 \ No newline at end of file diff --git a/Code/Mantid/Testing/Data/SystemTest/ILL/068288.txt.md5 b/Code/Mantid/Testing/Data/SystemTest/ILL/068288.txt.md5 new file mode 100644 index 000000000000..4d22e243f443 --- /dev/null +++ b/Code/Mantid/Testing/Data/SystemTest/ILL/068288.txt.md5 @@ -0,0 +1 @@ +dc0f9e0fe7179a519f6c8aacca1ca263 \ No newline at end of file diff --git a/Code/Mantid/Testing/Data/SystemTest/ILL/ILLIN4_074252.nxs.md5 b/Code/Mantid/Testing/Data/SystemTest/ILL/ILLIN4_074252.nxs.md5 new file mode 100644 index 000000000000..4c349b3eed9d --- /dev/null +++ b/Code/Mantid/Testing/Data/SystemTest/ILL/ILLIN4_074252.nxs.md5 @@ -0,0 +1 @@ +ff532b468480e9944fb63c6174ebb784 \ No newline at end of file diff --git a/Code/Mantid/Testing/Data/SystemTest/ILL/ILLIN5_Sample_096003.nxs.md5 b/Code/Mantid/Testing/Data/SystemTest/ILL/ILLIN5_Sample_096003.nxs.md5 new file mode 100644 index 000000000000..a8e697da6d82 --- /dev/null +++ b/Code/Mantid/Testing/Data/SystemTest/ILL/ILLIN5_Sample_096003.nxs.md5 @@ -0,0 +1 @@ +4080373fa8fff38ecd3c03ce8106fdcf \ No newline at end of file diff --git a/Code/Mantid/Testing/Data/SystemTest/ILL/ILLIN5_Vana_095893.nxs.md5 b/Code/Mantid/Testing/Data/SystemTest/ILL/ILLIN5_Vana_095893.nxs.md5 new file mode 100644 index 000000000000..579720f498a0 --- /dev/null +++ b/Code/Mantid/Testing/Data/SystemTest/ILL/ILLIN5_Vana_095893.nxs.md5 @@ -0,0 +1 @@ +0b1622b169d428387a21490c01293883 \ No newline at end of file diff --git a/Code/Mantid/Testing/Data/SystemTest/ILL/ILL_D2B_121459.txt.md5 b/Code/Mantid/Testing/Data/SystemTest/ILL/ILL_D2B_121459.txt.md5 new file mode 100644 index 000000000000..701be987a944 --- /dev/null +++ b/Code/Mantid/Testing/Data/SystemTest/ILL/ILL_D2B_121459.txt.md5 @@ -0,0 +1 @@ +8d15b5a6a6229a554838b08de6840475 \ No newline at end of file diff --git a/Code/Mantid/Testing/Data/SystemTest/ILL/cry1_2.tif.md5 b/Code/Mantid/Testing/Data/SystemTest/ILL/cry1_2.tif.md5 new file mode 100644 index 000000000000..deb34bc0e6c0 --- /dev/null +++ b/Code/Mantid/Testing/Data/SystemTest/ILL/cry1_2.tif.md5 @@ -0,0 +1 @@ +477087f5295c9ad2ed1e6d97c83448b4 \ No newline at end of file diff --git a/Code/Mantid/Testing/Data/SystemTest/ILL/readme.txt.md5 b/Code/Mantid/Testing/Data/SystemTest/ILL/readme.txt.md5 new file mode 100644 index 000000000000..6943c0536336 --- /dev/null +++ b/Code/Mantid/Testing/Data/SystemTest/ILL/readme.txt.md5 @@ -0,0 +1 @@ +b3bf6e75bfdd75eb072f0faba265b517 \ No newline at end of file diff --git a/Code/Mantid/Testing/Data/SystemTest/IN10_P3OT_350K.inx.md5 b/Code/Mantid/Testing/Data/SystemTest/IN10_P3OT_350K.inx.md5 new file mode 100644 index 000000000000..d3043efbbf34 --- /dev/null +++ b/Code/Mantid/Testing/Data/SystemTest/IN10_P3OT_350K.inx.md5 @@ -0,0 +1 @@ +014feb8a5bd6742214c62ac10dfc520f \ No newline at end of file diff --git a/Code/Mantid/Testing/Data/SystemTest/IN13_16347.asc.md5 b/Code/Mantid/Testing/Data/SystemTest/IN13_16347.asc.md5 new file mode 100644 index 000000000000..cb3c1f3079d2 --- /dev/null +++ b/Code/Mantid/Testing/Data/SystemTest/IN13_16347.asc.md5 @@ -0,0 +1 @@ +0e4c7f203a7435bac9b89a6b2af0d7d6 \ No newline at end of file diff --git a/Code/Mantid/Testing/Data/SystemTest/IN16_65722.asc.md5 b/Code/Mantid/Testing/Data/SystemTest/IN16_65722.asc.md5 new file mode 100644 index 000000000000..1ad003b631fa --- /dev/null +++ b/Code/Mantid/Testing/Data/SystemTest/IN16_65722.asc.md5 @@ -0,0 +1 @@ +117b324feb514a1555cfb31236c91cdc \ No newline at end of file diff --git a/Code/Mantid/Testing/Data/SystemTest/INTER00007709.nxs.md5 b/Code/Mantid/Testing/Data/SystemTest/INTER00007709.nxs.md5 new file mode 100644 index 000000000000..ad764b46d520 --- /dev/null +++ b/Code/Mantid/Testing/Data/SystemTest/INTER00007709.nxs.md5 @@ -0,0 +1 @@ +553279cf0558c9e6a11d8733cbb42312 \ No newline at end of file diff --git a/Code/Mantid/Testing/Data/SystemTest/INTER00007709.raw.md5 b/Code/Mantid/Testing/Data/SystemTest/INTER00007709.raw.md5 new file mode 100644 index 000000000000..49af23c8113e --- /dev/null +++ b/Code/Mantid/Testing/Data/SystemTest/INTER00007709.raw.md5 @@ -0,0 +1 @@ +2e0fc90e879d7515810865d0b7ae7e8b \ No newline at end of file diff --git a/Code/Mantid/Testing/Data/SystemTest/INTER00013460.nxs.md5 b/Code/Mantid/Testing/Data/SystemTest/INTER00013460.nxs.md5 new file mode 100644 index 000000000000..305891f3aa26 --- /dev/null +++ b/Code/Mantid/Testing/Data/SystemTest/INTER00013460.nxs.md5 @@ -0,0 +1 @@ +48a7bcc64dc710d0c070277fb7ad07fc \ No newline at end of file diff --git a/Code/Mantid/Testing/Data/SystemTest/INTER00013462.nxs.md5 b/Code/Mantid/Testing/Data/SystemTest/INTER00013462.nxs.md5 new file mode 100644 index 000000000000..970b4444b722 --- /dev/null +++ b/Code/Mantid/Testing/Data/SystemTest/INTER00013462.nxs.md5 @@ -0,0 +1 @@ +7cccfa84334ef3c802b9070a25e69282 \ No newline at end of file diff --git a/Code/Mantid/Testing/Data/SystemTest/INTER00013463.nxs.md5 b/Code/Mantid/Testing/Data/SystemTest/INTER00013463.nxs.md5 new file mode 100644 index 000000000000..4ab031b4b115 --- /dev/null +++ b/Code/Mantid/Testing/Data/SystemTest/INTER00013463.nxs.md5 @@ -0,0 +1 @@ +8eaaaebd489daed2fb0b39325def6cf7 \ No newline at end of file diff --git a/Code/Mantid/Testing/Data/SystemTest/INTER00013464.nxs.md5 b/Code/Mantid/Testing/Data/SystemTest/INTER00013464.nxs.md5 new file mode 100644 index 000000000000..394d5e250f5e --- /dev/null +++ b/Code/Mantid/Testing/Data/SystemTest/INTER00013464.nxs.md5 @@ -0,0 +1 @@ +5ece063b283ea715559b84235ade6843 \ No newline at end of file diff --git a/Code/Mantid/Testing/Data/SystemTest/INTER00013469.nxs.md5 b/Code/Mantid/Testing/Data/SystemTest/INTER00013469.nxs.md5 new file mode 100644 index 000000000000..c196cd92f53f --- /dev/null +++ b/Code/Mantid/Testing/Data/SystemTest/INTER00013469.nxs.md5 @@ -0,0 +1 @@ +cad4fd5cb02bf4e7f8987c56ca6e0127 \ No newline at end of file diff --git a/Code/Mantid/Testing/Data/SystemTest/IP0005.dat.md5 b/Code/Mantid/Testing/Data/SystemTest/IP0005.dat.md5 new file mode 100644 index 000000000000..5266783b222a --- /dev/null +++ b/Code/Mantid/Testing/Data/SystemTest/IP0005.dat.md5 @@ -0,0 +1 @@ +31834c0613be7294a98fe8568f4d0ce2 \ No newline at end of file diff --git a/Code/Mantid/Testing/Data/SystemTest/IRS26173.RAW.md5 b/Code/Mantid/Testing/Data/SystemTest/IRS26173.RAW.md5 new file mode 100644 index 000000000000..548fe00c5bf9 --- /dev/null +++ b/Code/Mantid/Testing/Data/SystemTest/IRS26173.RAW.md5 @@ -0,0 +1 @@ +d192eb96f4c3e9db2c6db7e48966e6f2 \ No newline at end of file diff --git a/Code/Mantid/Testing/Data/SystemTest/IRS26176.RAW.md5 b/Code/Mantid/Testing/Data/SystemTest/IRS26176.RAW.md5 new file mode 100644 index 000000000000..7e1970a0a69a --- /dev/null +++ b/Code/Mantid/Testing/Data/SystemTest/IRS26176.RAW.md5 @@ -0,0 +1 @@ +d2f57a477fe1b30cf057ef092969209c \ No newline at end of file diff --git a/Code/Mantid/Testing/Data/SystemTest/IRS53664.raw.md5 b/Code/Mantid/Testing/Data/SystemTest/IRS53664.raw.md5 new file mode 100644 index 000000000000..04eae1300022 --- /dev/null +++ b/Code/Mantid/Testing/Data/SystemTest/IRS53664.raw.md5 @@ -0,0 +1 @@ +b516224c119632e7efda626d00868f61 \ No newline at end of file diff --git a/Code/Mantid/Testing/Data/SystemTest/LB4844b1.hkl.md5 b/Code/Mantid/Testing/Data/SystemTest/LB4844b1.hkl.md5 new file mode 100644 index 000000000000..74e43ebd5361 --- /dev/null +++ b/Code/Mantid/Testing/Data/SystemTest/LB4844b1.hkl.md5 @@ -0,0 +1 @@ +2d78e74e74e8c51dcdda91feeaf736be \ No newline at end of file diff --git a/Code/Mantid/Testing/Data/SystemTest/LET00005545.raw.md5 b/Code/Mantid/Testing/Data/SystemTest/LET00005545.raw.md5 new file mode 100644 index 000000000000..9f7d0e35eda3 --- /dev/null +++ b/Code/Mantid/Testing/Data/SystemTest/LET00005545.raw.md5 @@ -0,0 +1 @@ +7977a1c7ffcf434b375b73f94b69a923 \ No newline at end of file diff --git a/Code/Mantid/Testing/Data/SystemTest/LET00006278.nxs.md5 b/Code/Mantid/Testing/Data/SystemTest/LET00006278.nxs.md5 new file mode 100644 index 000000000000..67f04f723244 --- /dev/null +++ b/Code/Mantid/Testing/Data/SystemTest/LET00006278.nxs.md5 @@ -0,0 +1 @@ +9f9ac3443b96e9ee8d62674d31a152dc \ No newline at end of file diff --git a/Code/Mantid/Testing/Data/SystemTest/LET00014305.nxs.md5 b/Code/Mantid/Testing/Data/SystemTest/LET00014305.nxs.md5 new file mode 100644 index 000000000000..9ee19003e2bf --- /dev/null +++ b/Code/Mantid/Testing/Data/SystemTest/LET00014305.nxs.md5 @@ -0,0 +1 @@ +17071d677d445cb6179daeb9d4708ed9 \ No newline at end of file diff --git a/Code/Mantid/Testing/Data/SystemTest/LET00014319.nxs.md5 b/Code/Mantid/Testing/Data/SystemTest/LET00014319.nxs.md5 new file mode 100644 index 000000000000..c3ab294a1238 --- /dev/null +++ b/Code/Mantid/Testing/Data/SystemTest/LET00014319.nxs.md5 @@ -0,0 +1 @@ +8623c7aa494e3b3c0826ef4ac26d3ecb \ No newline at end of file diff --git a/Code/Mantid/Testing/Data/SystemTest/LET_hard.msk.md5 b/Code/Mantid/Testing/Data/SystemTest/LET_hard.msk.md5 new file mode 100644 index 000000000000..b9d71840fb97 --- /dev/null +++ b/Code/Mantid/Testing/Data/SystemTest/LET_hard.msk.md5 @@ -0,0 +1 @@ +b3c302ea8ca596ea3df2dd970dd0e6eb \ No newline at end of file diff --git a/Code/Mantid/Testing/Data/SystemTest/LOQ/DIRECT.041.expected.md5 b/Code/Mantid/Testing/Data/SystemTest/LOQ/DIRECT.041.expected.md5 new file mode 100644 index 000000000000..d8b951325857 --- /dev/null +++ b/Code/Mantid/Testing/Data/SystemTest/LOQ/DIRECT.041.expected.md5 @@ -0,0 +1 @@ +91812981d5ab8ad262c496c666c5b82e \ No newline at end of file diff --git a/Code/Mantid/Testing/Data/SystemTest/LOQ/DIRECT.041.md5 b/Code/Mantid/Testing/Data/SystemTest/LOQ/DIRECT.041.md5 new file mode 100644 index 000000000000..d3a8057d9580 --- /dev/null +++ b/Code/Mantid/Testing/Data/SystemTest/LOQ/DIRECT.041.md5 @@ -0,0 +1 @@ +3ef252c9337498b1f6b137d5705a489a \ No newline at end of file diff --git a/Code/Mantid/Testing/Data/SystemTest/LOQ/DIRECTHAB.983.md5 b/Code/Mantid/Testing/Data/SystemTest/LOQ/DIRECTHAB.983.md5 new file mode 100644 index 000000000000..09cff050f0de --- /dev/null +++ b/Code/Mantid/Testing/Data/SystemTest/LOQ/DIRECTHAB.983.md5 @@ -0,0 +1 @@ +d985472d01f094292ca4c22042438ed7 \ No newline at end of file diff --git a/Code/Mantid/Testing/Data/SystemTest/LOQ/FLAT_CELL.061.md5 b/Code/Mantid/Testing/Data/SystemTest/LOQ/FLAT_CELL.061.md5 new file mode 100644 index 000000000000..dc9a3cb7bb18 --- /dev/null +++ b/Code/Mantid/Testing/Data/SystemTest/LOQ/FLAT_CELL.061.md5 @@ -0,0 +1 @@ +6cc3b1e43ef1c42b4c31d82b4b869e13 \ No newline at end of file diff --git a/Code/Mantid/Testing/Data/SystemTest/LOQ/LOQ54431.raw.md5 b/Code/Mantid/Testing/Data/SystemTest/LOQ/LOQ54431.raw.md5 new file mode 100644 index 000000000000..a91c0115568d --- /dev/null +++ b/Code/Mantid/Testing/Data/SystemTest/LOQ/LOQ54431.raw.md5 @@ -0,0 +1 @@ +1c9fbe14a01f67360fd0efc893c29915 \ No newline at end of file diff --git a/Code/Mantid/Testing/Data/SystemTest/LOQ/LOQ54432.raw.md5 b/Code/Mantid/Testing/Data/SystemTest/LOQ/LOQ54432.raw.md5 new file mode 100644 index 000000000000..4d2367d2f3c4 --- /dev/null +++ b/Code/Mantid/Testing/Data/SystemTest/LOQ/LOQ54432.raw.md5 @@ -0,0 +1 @@ +39129303843e41fa060cc4b50413ff3a \ No newline at end of file diff --git a/Code/Mantid/Testing/Data/SystemTest/LOQ/LOQ54433.raw.md5 b/Code/Mantid/Testing/Data/SystemTest/LOQ/LOQ54433.raw.md5 new file mode 100644 index 000000000000..91250967d5fc --- /dev/null +++ b/Code/Mantid/Testing/Data/SystemTest/LOQ/LOQ54433.raw.md5 @@ -0,0 +1 @@ +c61cdb20660880cb67367a8027d5ce38 \ No newline at end of file diff --git a/Code/Mantid/Testing/Data/SystemTest/LOQ/LOQ54434.raw.md5 b/Code/Mantid/Testing/Data/SystemTest/LOQ/LOQ54434.raw.md5 new file mode 100644 index 000000000000..8e27cf1474d2 --- /dev/null +++ b/Code/Mantid/Testing/Data/SystemTest/LOQ/LOQ54434.raw.md5 @@ -0,0 +1 @@ +21d631ba6ef8bbe82a4aa2ad0e493483 \ No newline at end of file diff --git a/Code/Mantid/Testing/Data/SystemTest/LOQ/LOQ54435.raw.expected.md5 b/Code/Mantid/Testing/Data/SystemTest/LOQ/LOQ54435.raw.expected.md5 new file mode 100644 index 000000000000..14e759dd3c2a --- /dev/null +++ b/Code/Mantid/Testing/Data/SystemTest/LOQ/LOQ54435.raw.expected.md5 @@ -0,0 +1 @@ +5bd2143d9e1ffc21d17a74d2e6bc66a7 \ No newline at end of file diff --git a/Code/Mantid/Testing/Data/SystemTest/LOQ/LOQ54435.raw.md5 b/Code/Mantid/Testing/Data/SystemTest/LOQ/LOQ54435.raw.md5 new file mode 100644 index 000000000000..06e6d188a0af --- /dev/null +++ b/Code/Mantid/Testing/Data/SystemTest/LOQ/LOQ54435.raw.md5 @@ -0,0 +1 @@ +23414d617df652a121e72bf4775d26d0 \ No newline at end of file diff --git a/Code/Mantid/Testing/Data/SystemTest/LOQ/LOQ74014.nxs.md5 b/Code/Mantid/Testing/Data/SystemTest/LOQ/LOQ74014.nxs.md5 new file mode 100644 index 000000000000..66b8432b4789 --- /dev/null +++ b/Code/Mantid/Testing/Data/SystemTest/LOQ/LOQ74014.nxs.md5 @@ -0,0 +1 @@ +ee8bbab4b40dbd3d03eb7ea6978347b3 \ No newline at end of file diff --git a/Code/Mantid/Testing/Data/SystemTest/LOQ/LOQ74019.nxs.md5 b/Code/Mantid/Testing/Data/SystemTest/LOQ/LOQ74019.nxs.md5 new file mode 100644 index 000000000000..875829d7c48a --- /dev/null +++ b/Code/Mantid/Testing/Data/SystemTest/LOQ/LOQ74019.nxs.md5 @@ -0,0 +1 @@ +4fa3e5a8948d2ad3a56857052ace25e2 \ No newline at end of file diff --git a/Code/Mantid/Testing/Data/SystemTest/LOQ/LOQ74020.nxs.expected.md5 b/Code/Mantid/Testing/Data/SystemTest/LOQ/LOQ74020.nxs.expected.md5 new file mode 100644 index 000000000000..14e759dd3c2a --- /dev/null +++ b/Code/Mantid/Testing/Data/SystemTest/LOQ/LOQ74020.nxs.expected.md5 @@ -0,0 +1 @@ +5bd2143d9e1ffc21d17a74d2e6bc66a7 \ No newline at end of file diff --git a/Code/Mantid/Testing/Data/SystemTest/LOQ/LOQ74020.nxs.md5 b/Code/Mantid/Testing/Data/SystemTest/LOQ/LOQ74020.nxs.md5 new file mode 100644 index 000000000000..79227fa80449 --- /dev/null +++ b/Code/Mantid/Testing/Data/SystemTest/LOQ/LOQ74020.nxs.md5 @@ -0,0 +1 @@ +7510d60552cb3a777653c80c7864d1c2 \ No newline at end of file diff --git a/Code/Mantid/Testing/Data/SystemTest/LOQ/LOQ74024.nxs.md5 b/Code/Mantid/Testing/Data/SystemTest/LOQ/LOQ74024.nxs.md5 new file mode 100644 index 000000000000..74e01f2069b5 --- /dev/null +++ b/Code/Mantid/Testing/Data/SystemTest/LOQ/LOQ74024.nxs.md5 @@ -0,0 +1 @@ +7d98ba43433d1136841d4cb4145477fe \ No newline at end of file diff --git a/Code/Mantid/Testing/Data/SystemTest/LOQ/LOQ74044.nxs.md5 b/Code/Mantid/Testing/Data/SystemTest/LOQ/LOQ74044.nxs.md5 new file mode 100644 index 000000000000..98861883fdf9 --- /dev/null +++ b/Code/Mantid/Testing/Data/SystemTest/LOQ/LOQ74044.nxs.md5 @@ -0,0 +1 @@ +79020b3973e727f535dd90295773b589 \ No newline at end of file diff --git a/Code/Mantid/Testing/Data/SystemTest/LOQ/LOQ99618.RAW.md5 b/Code/Mantid/Testing/Data/SystemTest/LOQ/LOQ99618.RAW.md5 new file mode 100644 index 000000000000..50028464d74a --- /dev/null +++ b/Code/Mantid/Testing/Data/SystemTest/LOQ/LOQ99618.RAW.md5 @@ -0,0 +1 @@ +38f0f7a4fed35d0bf929a48bc1d48329 \ No newline at end of file diff --git a/Code/Mantid/Testing/Data/SystemTest/LOQ/LOQ99619.RAW.md5 b/Code/Mantid/Testing/Data/SystemTest/LOQ/LOQ99619.RAW.md5 new file mode 100644 index 000000000000..38377b405313 --- /dev/null +++ b/Code/Mantid/Testing/Data/SystemTest/LOQ/LOQ99619.RAW.md5 @@ -0,0 +1 @@ +b059b7981a79eab7e3944ce1705b0e5b \ No newline at end of file diff --git a/Code/Mantid/Testing/Data/SystemTest/LOQ/LOQ99620.RAW.md5 b/Code/Mantid/Testing/Data/SystemTest/LOQ/LOQ99620.RAW.md5 new file mode 100644 index 000000000000..078c3a9e1f52 --- /dev/null +++ b/Code/Mantid/Testing/Data/SystemTest/LOQ/LOQ99620.RAW.md5 @@ -0,0 +1 @@ +5919d98eb5ce072037b645c90f9408f1 \ No newline at end of file diff --git a/Code/Mantid/Testing/Data/SystemTest/LOQ/LOQ99630.RAW.md5 b/Code/Mantid/Testing/Data/SystemTest/LOQ/LOQ99630.RAW.md5 new file mode 100644 index 000000000000..5dd343393e5b --- /dev/null +++ b/Code/Mantid/Testing/Data/SystemTest/LOQ/LOQ99630.RAW.md5 @@ -0,0 +1 @@ +b799728beb5c248d1666530aff3aa3a7 \ No newline at end of file diff --git a/Code/Mantid/Testing/Data/SystemTest/LOQ/LOQ99631.RAW.md5 b/Code/Mantid/Testing/Data/SystemTest/LOQ/LOQ99631.RAW.md5 new file mode 100644 index 000000000000..6259ab3527f1 --- /dev/null +++ b/Code/Mantid/Testing/Data/SystemTest/LOQ/LOQ99631.RAW.md5 @@ -0,0 +1 @@ +d0cb52334141991c4316e44baf50cc9f \ No newline at end of file diff --git a/Code/Mantid/Testing/Data/SystemTest/LOQ/MANTID_FLAT_CELL.115.md5 b/Code/Mantid/Testing/Data/SystemTest/LOQ/MANTID_FLAT_CELL.115.md5 new file mode 100644 index 000000000000..dc8b1032ae05 --- /dev/null +++ b/Code/Mantid/Testing/Data/SystemTest/LOQ/MANTID_FLAT_CELL.115.md5 @@ -0,0 +1 @@ +b77c5ca172c5afbc75c0930c2324de5e \ No newline at end of file diff --git a/Code/Mantid/Testing/Data/SystemTest/LOQ/MASK.094AA.md5 b/Code/Mantid/Testing/Data/SystemTest/LOQ/MASK.094AA.md5 new file mode 100644 index 000000000000..a512a0c9d0ab --- /dev/null +++ b/Code/Mantid/Testing/Data/SystemTest/LOQ/MASK.094AA.md5 @@ -0,0 +1 @@ +e3d65671d63c32341011c5b583330b75 \ No newline at end of file diff --git a/Code/Mantid/Testing/Data/SystemTest/LOQ/MaskLOQData.txt.md5 b/Code/Mantid/Testing/Data/SystemTest/LOQ/MaskLOQData.txt.md5 new file mode 100644 index 000000000000..f120ea6a273a --- /dev/null +++ b/Code/Mantid/Testing/Data/SystemTest/LOQ/MaskLOQData.txt.md5 @@ -0,0 +1 @@ +c1ff7d0082fa8166d86de2cff6bbbea0 \ No newline at end of file diff --git a/Code/Mantid/Testing/Data/SystemTest/LOQ/batch_input.csv.md5 b/Code/Mantid/Testing/Data/SystemTest/LOQ/batch_input.csv.md5 new file mode 100644 index 000000000000..207312e61fdc --- /dev/null +++ b/Code/Mantid/Testing/Data/SystemTest/LOQ/batch_input.csv.md5 @@ -0,0 +1 @@ +77cbbf76e5b5ba54c838ddabf182a9e6 \ No newline at end of file diff --git a/Code/Mantid/Testing/Data/SystemTest/LOQ/loq_batch_mode_reduction.csv.md5 b/Code/Mantid/Testing/Data/SystemTest/LOQ/loq_batch_mode_reduction.csv.md5 new file mode 100644 index 000000000000..637c24d83f64 --- /dev/null +++ b/Code/Mantid/Testing/Data/SystemTest/LOQ/loq_batch_mode_reduction.csv.md5 @@ -0,0 +1 @@ +192c33710f11c74fe438385aea37778d \ No newline at end of file diff --git a/Code/Mantid/Testing/Data/SystemTest/LoadSNSspec.txt.expected.md5 b/Code/Mantid/Testing/Data/SystemTest/LoadSNSspec.txt.expected.md5 new file mode 100644 index 000000000000..ffa1d1435362 --- /dev/null +++ b/Code/Mantid/Testing/Data/SystemTest/LoadSNSspec.txt.expected.md5 @@ -0,0 +1 @@ +1ee0d8c3046738200c7397712cc83863 \ No newline at end of file diff --git a/Code/Mantid/Testing/Data/SystemTest/LoadSNSspec.txt.md5 b/Code/Mantid/Testing/Data/SystemTest/LoadSNSspec.txt.md5 new file mode 100644 index 000000000000..5a342a0da17b --- /dev/null +++ b/Code/Mantid/Testing/Data/SystemTest/LoadSNSspec.txt.md5 @@ -0,0 +1 @@ +c4b2d32526d7d9ae494e097faee2ca2b \ No newline at end of file diff --git a/Code/Mantid/Testing/Data/SystemTest/MAP17186.raw.md5 b/Code/Mantid/Testing/Data/SystemTest/MAP17186.raw.md5 new file mode 100644 index 000000000000..3d60c539f87e --- /dev/null +++ b/Code/Mantid/Testing/Data/SystemTest/MAP17186.raw.md5 @@ -0,0 +1 @@ +b1ac23cde1845f3d971e8faac9d7f3c0 \ No newline at end of file diff --git a/Code/Mantid/Testing/Data/SystemTest/MAP17269.raw.md5 b/Code/Mantid/Testing/Data/SystemTest/MAP17269.raw.md5 new file mode 100644 index 000000000000..5feb9685ce32 --- /dev/null +++ b/Code/Mantid/Testing/Data/SystemTest/MAP17269.raw.md5 @@ -0,0 +1 @@ +c05b03092f93f5528123b9e7671dd41e \ No newline at end of file diff --git a/Code/Mantid/Testing/Data/SystemTest/MAP17589.raw.md5 b/Code/Mantid/Testing/Data/SystemTest/MAP17589.raw.md5 new file mode 100644 index 000000000000..abffdac991be --- /dev/null +++ b/Code/Mantid/Testing/Data/SystemTest/MAP17589.raw.md5 @@ -0,0 +1 @@ +0dc353ccffa2502f319485ae25307ea2 \ No newline at end of file diff --git a/Code/Mantid/Testing/Data/SystemTest/MAPS00018314.nxs.md5 b/Code/Mantid/Testing/Data/SystemTest/MAPS00018314.nxs.md5 new file mode 100644 index 000000000000..1b74bb72ff02 --- /dev/null +++ b/Code/Mantid/Testing/Data/SystemTest/MAPS00018314.nxs.md5 @@ -0,0 +1 @@ +cc3254c5bd7b8ea440b55084fdfebfe9 \ No newline at end of file diff --git a/Code/Mantid/Testing/Data/SystemTest/MAR11001.RAW.md5 b/Code/Mantid/Testing/Data/SystemTest/MAR11001.RAW.md5 new file mode 100644 index 000000000000..ff8028f323c5 --- /dev/null +++ b/Code/Mantid/Testing/Data/SystemTest/MAR11001.RAW.md5 @@ -0,0 +1 @@ +50e486c21f0343044f1c9b2dfbba1cd8 \ No newline at end of file diff --git a/Code/Mantid/Testing/Data/SystemTest/MAR11015.RAW.md5 b/Code/Mantid/Testing/Data/SystemTest/MAR11015.RAW.md5 new file mode 100644 index 000000000000..a381a12f6aed --- /dev/null +++ b/Code/Mantid/Testing/Data/SystemTest/MAR11015.RAW.md5 @@ -0,0 +1 @@ +22402246b0d14072b1fd9e6d920c3bb6 \ No newline at end of file diff --git a/Code/Mantid/Testing/Data/SystemTest/MAR11060.RAW.md5 b/Code/Mantid/Testing/Data/SystemTest/MAR11060.RAW.md5 new file mode 100644 index 000000000000..30bd575f0f1e --- /dev/null +++ b/Code/Mantid/Testing/Data/SystemTest/MAR11060.RAW.md5 @@ -0,0 +1 @@ +3541bd5715fb57d8cdf884c500d8e485 \ No newline at end of file diff --git a/Code/Mantid/Testing/Data/SystemTest/MER06398.raw.md5 b/Code/Mantid/Testing/Data/SystemTest/MER06398.raw.md5 new file mode 100644 index 000000000000..8a5917b30f3b --- /dev/null +++ b/Code/Mantid/Testing/Data/SystemTest/MER06398.raw.md5 @@ -0,0 +1 @@ +5a097f59d2a389b67e9c1a546bc1e76a \ No newline at end of file diff --git a/Code/Mantid/Testing/Data/SystemTest/MER06399.raw.md5 b/Code/Mantid/Testing/Data/SystemTest/MER06399.raw.md5 new file mode 100644 index 000000000000..1e1b02468968 --- /dev/null +++ b/Code/Mantid/Testing/Data/SystemTest/MER06399.raw.md5 @@ -0,0 +1 @@ +26b436546cdfbab20706d16541337d31 \ No newline at end of file diff --git a/Code/Mantid/Testing/Data/SystemTest/MER18492.nxs.md5 b/Code/Mantid/Testing/Data/SystemTest/MER18492.nxs.md5 new file mode 100644 index 000000000000..0dd1ef8ce85a --- /dev/null +++ b/Code/Mantid/Testing/Data/SystemTest/MER18492.nxs.md5 @@ -0,0 +1 @@ +471afe9bea1c1bead2561a3f51797079 \ No newline at end of file diff --git a/Code/Mantid/Testing/Data/SystemTest/MUSR00015192.nxs.md5 b/Code/Mantid/Testing/Data/SystemTest/MUSR00015192.nxs.md5 new file mode 100644 index 000000000000..58b845d4f895 --- /dev/null +++ b/Code/Mantid/Testing/Data/SystemTest/MUSR00015192.nxs.md5 @@ -0,0 +1 @@ +4e32ae1ef608f8e6a92b56a8ee6b1571 \ No newline at end of file diff --git a/Code/Mantid/Testing/Data/SystemTest/MUT53578.NXS.md5 b/Code/Mantid/Testing/Data/SystemTest/MUT53578.NXS.md5 new file mode 100644 index 000000000000..d931cafb783b --- /dev/null +++ b/Code/Mantid/Testing/Data/SystemTest/MUT53578.NXS.md5 @@ -0,0 +1 @@ +c87e83a67952640a0c6015271721f117 \ No newline at end of file diff --git a/Code/Mantid/Testing/Data/SystemTest/MuSR1Grouping.xml.md5 b/Code/Mantid/Testing/Data/SystemTest/MuSR1Grouping.xml.md5 new file mode 100644 index 000000000000..cc6c685ece9c --- /dev/null +++ b/Code/Mantid/Testing/Data/SystemTest/MuSR1Grouping.xml.md5 @@ -0,0 +1 @@ +2fae2cc815aaf7f3b02444f3894cc1d3 \ No newline at end of file diff --git a/Code/Mantid/Testing/Data/SystemTest/MuSRGrouping.xml.md5 b/Code/Mantid/Testing/Data/SystemTest/MuSRGrouping.xml.md5 new file mode 100644 index 000000000000..8219e367c3a5 --- /dev/null +++ b/Code/Mantid/Testing/Data/SystemTest/MuSRGrouping.xml.md5 @@ -0,0 +1 @@ +90f55d46bfcee129cd51a21bde05df4f \ No newline at end of file diff --git a/Code/Mantid/Testing/Data/SystemTest/OFFSPEC00010791.nxs.md5 b/Code/Mantid/Testing/Data/SystemTest/OFFSPEC00010791.nxs.md5 new file mode 100644 index 000000000000..bd72c4741772 --- /dev/null +++ b/Code/Mantid/Testing/Data/SystemTest/OFFSPEC00010791.nxs.md5 @@ -0,0 +1 @@ +b5aeec621f5b8ca789a1433df3f69e3f \ No newline at end of file diff --git a/Code/Mantid/Testing/Data/SystemTest/OFFSPEC00010791.raw.md5 b/Code/Mantid/Testing/Data/SystemTest/OFFSPEC00010791.raw.md5 new file mode 100644 index 000000000000..066eaa306eb9 --- /dev/null +++ b/Code/Mantid/Testing/Data/SystemTest/OFFSPEC00010791.raw.md5 @@ -0,0 +1 @@ +dd4be87435acad9a6afc6c04b3b58738 \ No newline at end of file diff --git a/Code/Mantid/Testing/Data/SystemTest/OFFSPEC00010792.raw.md5 b/Code/Mantid/Testing/Data/SystemTest/OFFSPEC00010792.raw.md5 new file mode 100644 index 000000000000..70c61e4d4524 --- /dev/null +++ b/Code/Mantid/Testing/Data/SystemTest/OFFSPEC00010792.raw.md5 @@ -0,0 +1 @@ +fc5f60a6d869e76841ec9eae592dcfe5 \ No newline at end of file diff --git a/Code/Mantid/Testing/Data/SystemTest/OFFSPEC00010793.raw.md5 b/Code/Mantid/Testing/Data/SystemTest/OFFSPEC00010793.raw.md5 new file mode 100644 index 000000000000..23051d5462f6 --- /dev/null +++ b/Code/Mantid/Testing/Data/SystemTest/OFFSPEC00010793.raw.md5 @@ -0,0 +1 @@ +793d51d14340f8e6d181824edfe0a3a2 \ No newline at end of file diff --git a/Code/Mantid/Testing/Data/SystemTest/OSI89813.raw.md5 b/Code/Mantid/Testing/Data/SystemTest/OSI89813.raw.md5 new file mode 100644 index 000000000000..9c5103dd2e82 --- /dev/null +++ b/Code/Mantid/Testing/Data/SystemTest/OSI89813.raw.md5 @@ -0,0 +1 @@ +f4185ed12be187868f11278501ed0392 \ No newline at end of file diff --git a/Code/Mantid/Testing/Data/SystemTest/OSI89814.raw.md5 b/Code/Mantid/Testing/Data/SystemTest/OSI89814.raw.md5 new file mode 100644 index 000000000000..409791e38ada --- /dev/null +++ b/Code/Mantid/Testing/Data/SystemTest/OSI89814.raw.md5 @@ -0,0 +1 @@ +5fe26418f96d8493c5208389335c7de8 \ No newline at end of file diff --git a/Code/Mantid/Testing/Data/SystemTest/OSI89815.raw.md5 b/Code/Mantid/Testing/Data/SystemTest/OSI89815.raw.md5 new file mode 100644 index 000000000000..8b013159c626 --- /dev/null +++ b/Code/Mantid/Testing/Data/SystemTest/OSI89815.raw.md5 @@ -0,0 +1 @@ +0e73bf29d4f82c81497dbe112d72e9b3 \ No newline at end of file diff --git a/Code/Mantid/Testing/Data/SystemTest/OSI97919.raw.md5 b/Code/Mantid/Testing/Data/SystemTest/OSI97919.raw.md5 new file mode 100644 index 000000000000..bb0d5944ab76 --- /dev/null +++ b/Code/Mantid/Testing/Data/SystemTest/OSI97919.raw.md5 @@ -0,0 +1 @@ +b14d5df129e0bdfd9c8d044c51a6a152 \ No newline at end of file diff --git a/Code/Mantid/Testing/Data/SystemTest/OSI97935.raw.md5 b/Code/Mantid/Testing/Data/SystemTest/OSI97935.raw.md5 new file mode 100644 index 000000000000..9c5a0afc03b3 --- /dev/null +++ b/Code/Mantid/Testing/Data/SystemTest/OSI97935.raw.md5 @@ -0,0 +1 @@ +68f03777839a611f1dcef2e36fce12f0 \ No newline at end of file diff --git a/Code/Mantid/Testing/Data/SystemTest/OSIRIS00106550.raw.md5 b/Code/Mantid/Testing/Data/SystemTest/OSIRIS00106550.raw.md5 new file mode 100644 index 000000000000..684d5cfd5b0c --- /dev/null +++ b/Code/Mantid/Testing/Data/SystemTest/OSIRIS00106550.raw.md5 @@ -0,0 +1 @@ +dd2ee5f0275de759eb8c6e07b8e26d7e \ No newline at end of file diff --git a/Code/Mantid/Testing/Data/SystemTest/OSIRIS00106551.raw.md5 b/Code/Mantid/Testing/Data/SystemTest/OSIRIS00106551.raw.md5 new file mode 100644 index 000000000000..d60365e192ad --- /dev/null +++ b/Code/Mantid/Testing/Data/SystemTest/OSIRIS00106551.raw.md5 @@ -0,0 +1 @@ +957bb4d8c3dea31513615c4a2bdfe397 \ No newline at end of file diff --git a/Code/Mantid/Testing/Data/SystemTest/PEARL/PEARL00074795.raw.md5 b/Code/Mantid/Testing/Data/SystemTest/PEARL/PEARL00074795.raw.md5 new file mode 100644 index 000000000000..f73a062b431c --- /dev/null +++ b/Code/Mantid/Testing/Data/SystemTest/PEARL/PEARL00074795.raw.md5 @@ -0,0 +1 @@ +4ceff2293b7a199156e5a65080573822 \ No newline at end of file diff --git a/Code/Mantid/Testing/Data/SystemTest/PEARL/PEARL00074796.raw.md5 b/Code/Mantid/Testing/Data/SystemTest/PEARL/PEARL00074796.raw.md5 new file mode 100644 index 000000000000..b0f1a75fd735 --- /dev/null +++ b/Code/Mantid/Testing/Data/SystemTest/PEARL/PEARL00074796.raw.md5 @@ -0,0 +1 @@ +6dce82c8176e415b95bf4e9f39c3699f \ No newline at end of file diff --git a/Code/Mantid/Testing/Data/SystemTest/PEARL/PEARL00074797.raw.md5 b/Code/Mantid/Testing/Data/SystemTest/PEARL/PEARL00074797.raw.md5 new file mode 100644 index 000000000000..089940256de7 --- /dev/null +++ b/Code/Mantid/Testing/Data/SystemTest/PEARL/PEARL00074797.raw.md5 @@ -0,0 +1 @@ +3822ef1c5fa001db744407bc11cb4f58 \ No newline at end of file diff --git a/Code/Mantid/Testing/Data/SystemTest/PEARL/PEARL00074798.raw.md5 b/Code/Mantid/Testing/Data/SystemTest/PEARL/PEARL00074798.raw.md5 new file mode 100644 index 000000000000..5d3e1a68e9c6 --- /dev/null +++ b/Code/Mantid/Testing/Data/SystemTest/PEARL/PEARL00074798.raw.md5 @@ -0,0 +1 @@ +46210a507a9de1cf29498ea799dc2ba5 \ No newline at end of file diff --git a/Code/Mantid/Testing/Data/SystemTest/PEARL/PEARL00074799.raw.md5 b/Code/Mantid/Testing/Data/SystemTest/PEARL/PEARL00074799.raw.md5 new file mode 100644 index 000000000000..0f2b79745ad6 --- /dev/null +++ b/Code/Mantid/Testing/Data/SystemTest/PEARL/PEARL00074799.raw.md5 @@ -0,0 +1 @@ +f096dd92e5b6d929ebb192715df46a71 \ No newline at end of file diff --git a/Code/Mantid/Testing/Data/SystemTest/PEARL/PEARL00074800.raw.md5 b/Code/Mantid/Testing/Data/SystemTest/PEARL/PEARL00074800.raw.md5 new file mode 100644 index 000000000000..b5977c09a4af --- /dev/null +++ b/Code/Mantid/Testing/Data/SystemTest/PEARL/PEARL00074800.raw.md5 @@ -0,0 +1 @@ +ac2e0d4c8220e5f1de1b5dc95a82585d \ No newline at end of file diff --git a/Code/Mantid/Testing/Data/SystemTest/PEARL/PEARL00075318.raw.md5 b/Code/Mantid/Testing/Data/SystemTest/PEARL/PEARL00075318.raw.md5 new file mode 100644 index 000000000000..0df4f270d296 --- /dev/null +++ b/Code/Mantid/Testing/Data/SystemTest/PEARL/PEARL00075318.raw.md5 @@ -0,0 +1 @@ +ad3d6a9ff98b33640a47e868a281561a \ No newline at end of file diff --git a/Code/Mantid/Testing/Data/SystemTest/PEARL/PEARL00075319.raw.md5 b/Code/Mantid/Testing/Data/SystemTest/PEARL/PEARL00075319.raw.md5 new file mode 100644 index 000000000000..ea495cde1f14 --- /dev/null +++ b/Code/Mantid/Testing/Data/SystemTest/PEARL/PEARL00075319.raw.md5 @@ -0,0 +1 @@ +c8a586b0b4ae6f15e38c699e965c399d \ No newline at end of file diff --git a/Code/Mantid/Testing/Data/SystemTest/PEARL/PEARL00075320.raw.md5 b/Code/Mantid/Testing/Data/SystemTest/PEARL/PEARL00075320.raw.md5 new file mode 100644 index 000000000000..5c2190ff866f --- /dev/null +++ b/Code/Mantid/Testing/Data/SystemTest/PEARL/PEARL00075320.raw.md5 @@ -0,0 +1 @@ +fcaf71668a6bf3602b501a43a9a63e79 \ No newline at end of file diff --git a/Code/Mantid/Testing/Data/SystemTest/PEARL/PEARL00075321.raw.md5 b/Code/Mantid/Testing/Data/SystemTest/PEARL/PEARL00075321.raw.md5 new file mode 100644 index 000000000000..e59c055dfe77 --- /dev/null +++ b/Code/Mantid/Testing/Data/SystemTest/PEARL/PEARL00075321.raw.md5 @@ -0,0 +1 @@ +ca6842b202989530f3bf06e0ab5613ae \ No newline at end of file diff --git a/Code/Mantid/Testing/Data/SystemTest/PEARL/PEARL00075322.raw.md5 b/Code/Mantid/Testing/Data/SystemTest/PEARL/PEARL00075322.raw.md5 new file mode 100644 index 000000000000..300fbfbf4ccb --- /dev/null +++ b/Code/Mantid/Testing/Data/SystemTest/PEARL/PEARL00075322.raw.md5 @@ -0,0 +1 @@ +7ecc4166518d751cbb2d7e34af816df2 \ No newline at end of file diff --git a/Code/Mantid/Testing/Data/SystemTest/PEARL/PEARL00075323.raw.md5 b/Code/Mantid/Testing/Data/SystemTest/PEARL/PEARL00075323.raw.md5 new file mode 100644 index 000000000000..83e27bfa1d2c --- /dev/null +++ b/Code/Mantid/Testing/Data/SystemTest/PEARL/PEARL00075323.raw.md5 @@ -0,0 +1 @@ +991a7eec8989fa8a27b2d95ea425ea6c \ No newline at end of file diff --git a/Code/Mantid/Testing/Data/SystemTest/PEARL/PRL112_DC25_10MM_FF.OUT.md5 b/Code/Mantid/Testing/Data/SystemTest/PEARL/PRL112_DC25_10MM_FF.OUT.md5 new file mode 100644 index 000000000000..37e4cb121220 --- /dev/null +++ b/Code/Mantid/Testing/Data/SystemTest/PEARL/PRL112_DC25_10MM_FF.OUT.md5 @@ -0,0 +1 @@ +ef84ea197398c92bf293dc11112e01f7 \ No newline at end of file diff --git a/Code/Mantid/Testing/Data/SystemTest/PEARL/pearl_group_12_1_TT70.cal.md5 b/Code/Mantid/Testing/Data/SystemTest/PEARL/pearl_group_12_1_TT70.cal.md5 new file mode 100644 index 000000000000..15a5cef4d7e0 --- /dev/null +++ b/Code/Mantid/Testing/Data/SystemTest/PEARL/pearl_group_12_1_TT70.cal.md5 @@ -0,0 +1 @@ +c9de242d62f0ed357c26233ba9027bf8 \ No newline at end of file diff --git a/Code/Mantid/Testing/Data/SystemTest/PEARL/pearl_offset_12_1.cal.md5 b/Code/Mantid/Testing/Data/SystemTest/PEARL/pearl_offset_12_1.cal.md5 new file mode 100644 index 000000000000..ebee40af4e4e --- /dev/null +++ b/Code/Mantid/Testing/Data/SystemTest/PEARL/pearl_offset_12_1.cal.md5 @@ -0,0 +1 @@ +1d5fa39bd7594ebfa0743d49315ada7a \ No newline at end of file diff --git a/Code/Mantid/Testing/Data/SystemTest/PEARL/van_spline_TT70_cycle_12_1.nxs.md5 b/Code/Mantid/Testing/Data/SystemTest/PEARL/van_spline_TT70_cycle_12_1.nxs.md5 new file mode 100644 index 000000000000..5e4d7aed4400 --- /dev/null +++ b/Code/Mantid/Testing/Data/SystemTest/PEARL/van_spline_TT70_cycle_12_1.nxs.md5 @@ -0,0 +1 @@ +98a188e0d125d75453df5663ef68c357 \ No newline at end of file diff --git a/Code/Mantid/Testing/Data/SystemTest/PEARL00073987.raw.md5 b/Code/Mantid/Testing/Data/SystemTest/PEARL00073987.raw.md5 new file mode 100644 index 000000000000..2228a4cd56d1 --- /dev/null +++ b/Code/Mantid/Testing/Data/SystemTest/PEARL00073987.raw.md5 @@ -0,0 +1 @@ +152893906f33c5bfa97f10af9caeeaee \ No newline at end of file diff --git a/Code/Mantid/Testing/Data/SystemTest/PG3_11485-1.dat.md5 b/Code/Mantid/Testing/Data/SystemTest/PG3_11485-1.dat.md5 new file mode 100644 index 000000000000..bea93f25fcaa --- /dev/null +++ b/Code/Mantid/Testing/Data/SystemTest/PG3_11485-1.dat.md5 @@ -0,0 +1 @@ +29efc05d00c620c5431cc9a6f3bcf4e9 \ No newline at end of file diff --git a/Code/Mantid/Testing/Data/SystemTest/PG3_2538_event.nxs.md5 b/Code/Mantid/Testing/Data/SystemTest/PG3_2538_event.nxs.md5 new file mode 100644 index 000000000000..1c5ecdd8d4e1 --- /dev/null +++ b/Code/Mantid/Testing/Data/SystemTest/PG3_2538_event.nxs.md5 @@ -0,0 +1 @@ +8802e6c9713c726b42d3a3ed67af4f41 \ No newline at end of file diff --git a/Code/Mantid/Testing/Data/SystemTest/PG3_9829_event.nxs.md5 b/Code/Mantid/Testing/Data/SystemTest/PG3_9829_event.nxs.md5 new file mode 100644 index 000000000000..36d303ecbdc5 --- /dev/null +++ b/Code/Mantid/Testing/Data/SystemTest/PG3_9829_event.nxs.md5 @@ -0,0 +1 @@ +7da8521104ea29127bbd37952d795a08 \ No newline at end of file diff --git a/Code/Mantid/Testing/Data/SystemTest/PG3_9830_event.nxs.expected.md5 b/Code/Mantid/Testing/Data/SystemTest/PG3_9830_event.nxs.expected.md5 new file mode 100644 index 000000000000..11f933a9e096 --- /dev/null +++ b/Code/Mantid/Testing/Data/SystemTest/PG3_9830_event.nxs.expected.md5 @@ -0,0 +1 @@ +7f677d6b9721c8094fd1ace6a18daa6d \ No newline at end of file diff --git a/Code/Mantid/Testing/Data/SystemTest/PG3_9830_event.nxs.md5 b/Code/Mantid/Testing/Data/SystemTest/PG3_9830_event.nxs.md5 new file mode 100644 index 000000000000..6c98dd0fe714 --- /dev/null +++ b/Code/Mantid/Testing/Data/SystemTest/PG3_9830_event.nxs.md5 @@ -0,0 +1 @@ +fcde23c252775f048b3607825da28be1 \ No newline at end of file diff --git a/Code/Mantid/Testing/Data/SystemTest/PG3_FERNS_d4832_2011_08_24.cal.md5 b/Code/Mantid/Testing/Data/SystemTest/PG3_FERNS_d4832_2011_08_24.cal.md5 new file mode 100644 index 000000000000..29712f5f4736 --- /dev/null +++ b/Code/Mantid/Testing/Data/SystemTest/PG3_FERNS_d4832_2011_08_24.cal.md5 @@ -0,0 +1 @@ +c181221ebef9fcf30114954268c7a6b6 \ No newline at end of file diff --git a/Code/Mantid/Testing/Data/SystemTest/PG3_characterization_2011_08_31-HR.txt.md5 b/Code/Mantid/Testing/Data/SystemTest/PG3_characterization_2011_08_31-HR.txt.md5 new file mode 100644 index 000000000000..23712c1bda24 --- /dev/null +++ b/Code/Mantid/Testing/Data/SystemTest/PG3_characterization_2011_08_31-HR.txt.md5 @@ -0,0 +1 @@ +f1f64cdec62b0f81307c1c1821a6f3e6 \ No newline at end of file diff --git a/Code/Mantid/Testing/Data/SystemTest/PG3_characterization_2012_02_23-HR-ILL.txt.md5 b/Code/Mantid/Testing/Data/SystemTest/PG3_characterization_2012_02_23-HR-ILL.txt.md5 new file mode 100644 index 000000000000..0c8753c1a0d3 --- /dev/null +++ b/Code/Mantid/Testing/Data/SystemTest/PG3_characterization_2012_02_23-HR-ILL.txt.md5 @@ -0,0 +1 @@ +5a1a61f873991a18edb8021d1dab5deb \ No newline at end of file diff --git a/Code/Mantid/Testing/Data/SystemTest/POLREF00003014.raw.md5 b/Code/Mantid/Testing/Data/SystemTest/POLREF00003014.raw.md5 new file mode 100644 index 000000000000..ebf83e66a543 --- /dev/null +++ b/Code/Mantid/Testing/Data/SystemTest/POLREF00003014.raw.md5 @@ -0,0 +1 @@ +803d6c0c46644348d115b76a4e484da3 \ No newline at end of file diff --git a/Code/Mantid/Testing/Data/SystemTest/POLREF00004699.nxs.md5 b/Code/Mantid/Testing/Data/SystemTest/POLREF00004699.nxs.md5 new file mode 100644 index 000000000000..a3affca4152c --- /dev/null +++ b/Code/Mantid/Testing/Data/SystemTest/POLREF00004699.nxs.md5 @@ -0,0 +1 @@ +9e593315b97d5287788cc47879c576d5 \ No newline at end of file diff --git a/Code/Mantid/Testing/Data/SystemTest/POLREF00004699.raw.md5 b/Code/Mantid/Testing/Data/SystemTest/POLREF00004699.raw.md5 new file mode 100644 index 000000000000..17c0decf8f75 --- /dev/null +++ b/Code/Mantid/Testing/Data/SystemTest/POLREF00004699.raw.md5 @@ -0,0 +1 @@ +f33a6a64e406a3769cce18ed59b0e9f3 \ No newline at end of file diff --git a/Code/Mantid/Testing/Data/SystemTest/PSI/deltat_tdc_gpd_0902.bin.md5 b/Code/Mantid/Testing/Data/SystemTest/PSI/deltat_tdc_gpd_0902.bin.md5 new file mode 100644 index 000000000000..fc344a06c6ee --- /dev/null +++ b/Code/Mantid/Testing/Data/SystemTest/PSI/deltat_tdc_gpd_0902.bin.md5 @@ -0,0 +1 @@ +7b569e8c701bfb445d91862b78a0bfa8 \ No newline at end of file diff --git a/Code/Mantid/Testing/Data/SystemTest/PSI/deltat_tdc_gpd_0923.bin.md5 b/Code/Mantid/Testing/Data/SystemTest/PSI/deltat_tdc_gpd_0923.bin.md5 new file mode 100644 index 000000000000..46cb4db0283c --- /dev/null +++ b/Code/Mantid/Testing/Data/SystemTest/PSI/deltat_tdc_gpd_0923.bin.md5 @@ -0,0 +1 @@ +f60f2487275ab9c8add9a909d34d0455 \ No newline at end of file diff --git a/Code/Mantid/Testing/Data/SystemTest/REF_L_70964_event.nxs.md5 b/Code/Mantid/Testing/Data/SystemTest/REF_L_70964_event.nxs.md5 new file mode 100644 index 000000000000..d168188dc671 --- /dev/null +++ b/Code/Mantid/Testing/Data/SystemTest/REF_L_70964_event.nxs.md5 @@ -0,0 +1 @@ +e97db54198780fc4601a4a3f95386822 \ No newline at end of file diff --git a/Code/Mantid/Testing/Data/SystemTest/REF_L_70977_event.nxs.md5 b/Code/Mantid/Testing/Data/SystemTest/REF_L_70977_event.nxs.md5 new file mode 100644 index 000000000000..f0074826f15a --- /dev/null +++ b/Code/Mantid/Testing/Data/SystemTest/REF_L_70977_event.nxs.md5 @@ -0,0 +1 @@ +c872c836549b86b6f80b78b4cc2b7705 \ No newline at end of file diff --git a/Code/Mantid/Testing/Data/SystemTest/REF_M_9684_event.nxs.md5 b/Code/Mantid/Testing/Data/SystemTest/REF_M_9684_event.nxs.md5 new file mode 100644 index 000000000000..1eeb87527438 --- /dev/null +++ b/Code/Mantid/Testing/Data/SystemTest/REF_M_9684_event.nxs.md5 @@ -0,0 +1 @@ +37c24a6379ec1564a515845a883036da \ No newline at end of file diff --git a/Code/Mantid/Testing/Data/SystemTest/REF_M_9709_event.nxs.md5 b/Code/Mantid/Testing/Data/SystemTest/REF_M_9709_event.nxs.md5 new file mode 100644 index 000000000000..db6c221b51b8 --- /dev/null +++ b/Code/Mantid/Testing/Data/SystemTest/REF_M_9709_event.nxs.md5 @@ -0,0 +1 @@ +72c8a1e5791fc05de7f4423c782a2ddd \ No newline at end of file diff --git a/Code/Mantid/Testing/Data/SystemTest/SANS2D/992 Descriptions.txt.md5 b/Code/Mantid/Testing/Data/SystemTest/SANS2D/992 Descriptions.txt.md5 new file mode 100644 index 000000000000..09da28f65736 --- /dev/null +++ b/Code/Mantid/Testing/Data/SystemTest/SANS2D/992 Descriptions.txt.md5 @@ -0,0 +1 @@ +b83665d8d4fa8c641ba7ad3002dfa26b \ No newline at end of file diff --git a/Code/Mantid/Testing/Data/SystemTest/SANS2D/BioSANS_dark_current.xml.md5 b/Code/Mantid/Testing/Data/SystemTest/SANS2D/BioSANS_dark_current.xml.md5 new file mode 100644 index 000000000000..177d92525ad7 --- /dev/null +++ b/Code/Mantid/Testing/Data/SystemTest/SANS2D/BioSANS_dark_current.xml.md5 @@ -0,0 +1 @@ +693f6b3936103df5ea0ef7507d404504 \ No newline at end of file diff --git a/Code/Mantid/Testing/Data/SystemTest/SANS2D/BioSANS_empty_cell.xml.md5 b/Code/Mantid/Testing/Data/SystemTest/SANS2D/BioSANS_empty_cell.xml.md5 new file mode 100644 index 000000000000..734ecd5d3646 --- /dev/null +++ b/Code/Mantid/Testing/Data/SystemTest/SANS2D/BioSANS_empty_cell.xml.md5 @@ -0,0 +1 @@ +c45ee522d529f7b4c4d9915865437923 \ No newline at end of file diff --git a/Code/Mantid/Testing/Data/SystemTest/SANS2D/BioSANS_empty_trans.xml.md5 b/Code/Mantid/Testing/Data/SystemTest/SANS2D/BioSANS_empty_trans.xml.md5 new file mode 100644 index 000000000000..6314291c1ad8 --- /dev/null +++ b/Code/Mantid/Testing/Data/SystemTest/SANS2D/BioSANS_empty_trans.xml.md5 @@ -0,0 +1 @@ +bad3dae91a7d4a1c37a58513ee84e5e5 \ No newline at end of file diff --git a/Code/Mantid/Testing/Data/SystemTest/SANS2D/BioSANS_exp61_scan0004_0001.xml.md5 b/Code/Mantid/Testing/Data/SystemTest/SANS2D/BioSANS_exp61_scan0004_0001.xml.md5 new file mode 100644 index 000000000000..32d7858bd723 --- /dev/null +++ b/Code/Mantid/Testing/Data/SystemTest/SANS2D/BioSANS_exp61_scan0004_0001.xml.md5 @@ -0,0 +1 @@ +1a0bfaf69c44b1c4bb742df814e4f0b6 \ No newline at end of file diff --git a/Code/Mantid/Testing/Data/SystemTest/SANS2D/BioSANS_flood_data.xml.md5 b/Code/Mantid/Testing/Data/SystemTest/SANS2D/BioSANS_flood_data.xml.md5 new file mode 100644 index 000000000000..222a563cdc9a --- /dev/null +++ b/Code/Mantid/Testing/Data/SystemTest/SANS2D/BioSANS_flood_data.xml.md5 @@ -0,0 +1 @@ +e20062cf90c41e955354fe4adb1ddd6d \ No newline at end of file diff --git a/Code/Mantid/Testing/Data/SystemTest/SANS2D/BioSANS_sample_trans.xml.md5 b/Code/Mantid/Testing/Data/SystemTest/SANS2D/BioSANS_sample_trans.xml.md5 new file mode 100644 index 000000000000..7037b670c4dd --- /dev/null +++ b/Code/Mantid/Testing/Data/SystemTest/SANS2D/BioSANS_sample_trans.xml.md5 @@ -0,0 +1 @@ +67897a9fcff729c6d970e319f8619e1c \ No newline at end of file diff --git a/Code/Mantid/Testing/Data/SystemTest/SANS2D/BioSANS_test_data.xml.md5 b/Code/Mantid/Testing/Data/SystemTest/SANS2D/BioSANS_test_data.xml.md5 new file mode 100644 index 000000000000..c98c7829fbea --- /dev/null +++ b/Code/Mantid/Testing/Data/SystemTest/SANS2D/BioSANS_test_data.xml.md5 @@ -0,0 +1 @@ +b57f47fb9acc40fdd27ffa61c4c20b0d \ No newline at end of file diff --git a/Code/Mantid/Testing/Data/SystemTest/SANS2D/DIRECTM1_15785_12m_31Oct12_v12.dat.md5 b/Code/Mantid/Testing/Data/SystemTest/SANS2D/DIRECTM1_15785_12m_31Oct12_v12.dat.md5 new file mode 100644 index 000000000000..7791d551248e --- /dev/null +++ b/Code/Mantid/Testing/Data/SystemTest/SANS2D/DIRECTM1_15785_12m_31Oct12_v12.dat.md5 @@ -0,0 +1 @@ +5f22ded9ba4829277a932e28c14a2e12 \ No newline at end of file diff --git a/Code/Mantid/Testing/Data/SystemTest/SANS2D/DIRECT_RUN524.dat.md5 b/Code/Mantid/Testing/Data/SystemTest/SANS2D/DIRECT_RUN524.dat.md5 new file mode 100644 index 000000000000..9e3592586008 --- /dev/null +++ b/Code/Mantid/Testing/Data/SystemTest/SANS2D/DIRECT_RUN524.dat.md5 @@ -0,0 +1 @@ +3bc686c6f2dd5c3f317bfe156736db5d \ No newline at end of file diff --git a/Code/Mantid/Testing/Data/SystemTest/SANS2D/MASKSANS2D.091A.md5 b/Code/Mantid/Testing/Data/SystemTest/SANS2D/MASKSANS2D.091A.md5 new file mode 100644 index 000000000000..24b5771222ff --- /dev/null +++ b/Code/Mantid/Testing/Data/SystemTest/SANS2D/MASKSANS2D.091A.md5 @@ -0,0 +1 @@ +94dadd87d2f9676963ae17f64c86365e \ No newline at end of file diff --git a/Code/Mantid/Testing/Data/SystemTest/SANS2D/MASKSANS2D_094i_RKH.txt.md5 b/Code/Mantid/Testing/Data/SystemTest/SANS2D/MASKSANS2D_094i_RKH.txt.md5 new file mode 100644 index 000000000000..83545b498478 --- /dev/null +++ b/Code/Mantid/Testing/Data/SystemTest/SANS2D/MASKSANS2D_094i_RKH.txt.md5 @@ -0,0 +1 @@ +d7c55d49da7f562ef830fa146079dea9 \ No newline at end of file diff --git a/Code/Mantid/Testing/Data/SystemTest/SANS2D/MASKSANS2Doptions.091A.md5 b/Code/Mantid/Testing/Data/SystemTest/SANS2D/MASKSANS2Doptions.091A.md5 new file mode 100644 index 000000000000..3802b8537d6e --- /dev/null +++ b/Code/Mantid/Testing/Data/SystemTest/SANS2D/MASKSANS2Doptions.091A.md5 @@ -0,0 +1 @@ +2af536d73e5fc1bee3b944890ef8c456 \ No newline at end of file diff --git a/Code/Mantid/Testing/Data/SystemTest/SANS2D/MaskSANS2DReductionGUI.txt.md5 b/Code/Mantid/Testing/Data/SystemTest/SANS2D/MaskSANS2DReductionGUI.txt.md5 new file mode 100644 index 000000000000..8cf8a93b6b87 --- /dev/null +++ b/Code/Mantid/Testing/Data/SystemTest/SANS2D/MaskSANS2DReductionGUI.txt.md5 @@ -0,0 +1 @@ +e3a2e8c2963575e7ac00a6e48a430986 \ No newline at end of file diff --git a/Code/Mantid/Testing/Data/SystemTest/SANS2D/MaskSANS2DReductionGUI_LimitEventsTime.txt.md5 b/Code/Mantid/Testing/Data/SystemTest/SANS2D/MaskSANS2DReductionGUI_LimitEventsTime.txt.md5 new file mode 100644 index 000000000000..d6a8036d1c2d --- /dev/null +++ b/Code/Mantid/Testing/Data/SystemTest/SANS2D/MaskSANS2DReductionGUI_LimitEventsTime.txt.md5 @@ -0,0 +1 @@ +fe37af8e0338120d6428c5bd856331ca \ No newline at end of file diff --git a/Code/Mantid/Testing/Data/SystemTest/SANS2D/MaskSANS2DReductionGUI_MaskFiles.txt.md5 b/Code/Mantid/Testing/Data/SystemTest/SANS2D/MaskSANS2DReductionGUI_MaskFiles.txt.md5 new file mode 100644 index 000000000000..a033646bffd7 --- /dev/null +++ b/Code/Mantid/Testing/Data/SystemTest/SANS2D/MaskSANS2DReductionGUI_MaskFiles.txt.md5 @@ -0,0 +1 @@ +34601d3b76594fb4bea3a9b92f489809 \ No newline at end of file diff --git a/Code/Mantid/Testing/Data/SystemTest/SANS2D/SANS2D00000808.log.md5 b/Code/Mantid/Testing/Data/SystemTest/SANS2D/SANS2D00000808.log.md5 new file mode 100644 index 000000000000..48117734e998 --- /dev/null +++ b/Code/Mantid/Testing/Data/SystemTest/SANS2D/SANS2D00000808.log.md5 @@ -0,0 +1 @@ +fb640232fd3c360473c67bad720e5932 \ No newline at end of file diff --git a/Code/Mantid/Testing/Data/SystemTest/SANS2D/SANS2D00000808.nxs.md5 b/Code/Mantid/Testing/Data/SystemTest/SANS2D/SANS2D00000808.nxs.md5 new file mode 100644 index 000000000000..ffb250ada0d9 --- /dev/null +++ b/Code/Mantid/Testing/Data/SystemTest/SANS2D/SANS2D00000808.nxs.md5 @@ -0,0 +1 @@ +e5c22cf69fdd0d007c29aa51c6537004 \ No newline at end of file diff --git a/Code/Mantid/Testing/Data/SystemTest/SANS2D/SANS2D00000808.raw.md5 b/Code/Mantid/Testing/Data/SystemTest/SANS2D/SANS2D00000808.raw.md5 new file mode 100644 index 000000000000..4773047af339 --- /dev/null +++ b/Code/Mantid/Testing/Data/SystemTest/SANS2D/SANS2D00000808.raw.md5 @@ -0,0 +1 @@ +b12c17b209dda89623848c0d6747812b \ No newline at end of file diff --git a/Code/Mantid/Testing/Data/SystemTest/SANS2D/SANS2D00000808_Changer.txt.md5 b/Code/Mantid/Testing/Data/SystemTest/SANS2D/SANS2D00000808_Changer.txt.md5 new file mode 100644 index 000000000000..c9d0bbbe0143 --- /dev/null +++ b/Code/Mantid/Testing/Data/SystemTest/SANS2D/SANS2D00000808_Changer.txt.md5 @@ -0,0 +1 @@ +7ce1923fa9bd002d59c70859dbed99bd \ No newline at end of file diff --git a/Code/Mantid/Testing/Data/SystemTest/SANS2D/SANS2D00000808_Det1_Temp.txt.md5 b/Code/Mantid/Testing/Data/SystemTest/SANS2D/SANS2D00000808_Det1_Temp.txt.md5 new file mode 100644 index 000000000000..4240326f93a9 --- /dev/null +++ b/Code/Mantid/Testing/Data/SystemTest/SANS2D/SANS2D00000808_Det1_Temp.txt.md5 @@ -0,0 +1 @@ +962836db6097f3151104534e3d5fca55 \ No newline at end of file diff --git a/Code/Mantid/Testing/Data/SystemTest/SANS2D/SANS2D00000808_Fast_Shutter.txt.md5 b/Code/Mantid/Testing/Data/SystemTest/SANS2D/SANS2D00000808_Fast_Shutter.txt.md5 new file mode 100644 index 000000000000..a2fca9508562 --- /dev/null +++ b/Code/Mantid/Testing/Data/SystemTest/SANS2D/SANS2D00000808_Fast_Shutter.txt.md5 @@ -0,0 +1 @@ +a52785d56a46df010c22a1fd9731f934 \ No newline at end of file diff --git a/Code/Mantid/Testing/Data/SystemTest/SANS2D/SANS2D00000808_Guide_Pressure.txt.md5 b/Code/Mantid/Testing/Data/SystemTest/SANS2D/SANS2D00000808_Guide_Pressure.txt.md5 new file mode 100644 index 000000000000..9f49520bc9f6 --- /dev/null +++ b/Code/Mantid/Testing/Data/SystemTest/SANS2D/SANS2D00000808_Guide_Pressure.txt.md5 @@ -0,0 +1 @@ +66d42e1dabde50d11dc0c11e5cf93672 \ No newline at end of file diff --git a/Code/Mantid/Testing/Data/SystemTest/SANS2D/SANS2D00000808_Height.txt.md5 b/Code/Mantid/Testing/Data/SystemTest/SANS2D/SANS2D00000808_Height.txt.md5 new file mode 100644 index 000000000000..344b623fe7d0 --- /dev/null +++ b/Code/Mantid/Testing/Data/SystemTest/SANS2D/SANS2D00000808_Height.txt.md5 @@ -0,0 +1 @@ +6ac12d3054ff76ea5d8c85ff573615dc \ No newline at end of file diff --git a/Code/Mantid/Testing/Data/SystemTest/SANS2D/SANS2D00000808_ICPdebug.txt.md5 b/Code/Mantid/Testing/Data/SystemTest/SANS2D/SANS2D00000808_ICPdebug.txt.md5 new file mode 100644 index 000000000000..53111f11c5be --- /dev/null +++ b/Code/Mantid/Testing/Data/SystemTest/SANS2D/SANS2D00000808_ICPdebug.txt.md5 @@ -0,0 +1 @@ +97b1a5e17c0704f87f8d85c2fa67bc4e \ No newline at end of file diff --git a/Code/Mantid/Testing/Data/SystemTest/SANS2D/SANS2D00000808_ICPevent.txt.md5 b/Code/Mantid/Testing/Data/SystemTest/SANS2D/SANS2D00000808_ICPevent.txt.md5 new file mode 100644 index 000000000000..eaf40da27ccf --- /dev/null +++ b/Code/Mantid/Testing/Data/SystemTest/SANS2D/SANS2D00000808_ICPevent.txt.md5 @@ -0,0 +1 @@ +5e75937f29fd4bdd31eb19c4983b93e9 \ No newline at end of file diff --git a/Code/Mantid/Testing/Data/SystemTest/SANS2D/SANS2D00000808_ICPstatus.txt.md5 b/Code/Mantid/Testing/Data/SystemTest/SANS2D/SANS2D00000808_ICPstatus.txt.md5 new file mode 100644 index 000000000000..39f091165248 --- /dev/null +++ b/Code/Mantid/Testing/Data/SystemTest/SANS2D/SANS2D00000808_ICPstatus.txt.md5 @@ -0,0 +1 @@ +3f25bd1417ccfe1293abddda29834f9f \ No newline at end of file diff --git a/Code/Mantid/Testing/Data/SystemTest/SANS2D/SANS2D00000808_Julabo.txt.md5 b/Code/Mantid/Testing/Data/SystemTest/SANS2D/SANS2D00000808_Julabo.txt.md5 new file mode 100644 index 000000000000..f2469dbfd059 --- /dev/null +++ b/Code/Mantid/Testing/Data/SystemTest/SANS2D/SANS2D00000808_Julabo.txt.md5 @@ -0,0 +1 @@ +e4560aff7a6b8c0ac62f43e97882b88f \ No newline at end of file diff --git a/Code/Mantid/Testing/Data/SystemTest/SANS2D/SANS2D00000808_Moderator_Temp.txt.md5 b/Code/Mantid/Testing/Data/SystemTest/SANS2D/SANS2D00000808_Moderator_Temp.txt.md5 new file mode 100644 index 000000000000..3ee39f93165c --- /dev/null +++ b/Code/Mantid/Testing/Data/SystemTest/SANS2D/SANS2D00000808_Moderator_Temp.txt.md5 @@ -0,0 +1 @@ +c8b2c7bb50f71c4995c0132d75ff771d \ No newline at end of file diff --git a/Code/Mantid/Testing/Data/SystemTest/SANS2D/SANS2D00000808_Sample.txt.md5 b/Code/Mantid/Testing/Data/SystemTest/SANS2D/SANS2D00000808_Sample.txt.md5 new file mode 100644 index 000000000000..4e2c7175a6b7 --- /dev/null +++ b/Code/Mantid/Testing/Data/SystemTest/SANS2D/SANS2D00000808_Sample.txt.md5 @@ -0,0 +1 @@ +0d1624873013c3cd28c29e202e4f86f0 \ No newline at end of file diff --git a/Code/Mantid/Testing/Data/SystemTest/SANS2D/SANS2D00000808_Status.txt.md5 b/Code/Mantid/Testing/Data/SystemTest/SANS2D/SANS2D00000808_Status.txt.md5 new file mode 100644 index 000000000000..d60b12864fd5 --- /dev/null +++ b/Code/Mantid/Testing/Data/SystemTest/SANS2D/SANS2D00000808_Status.txt.md5 @@ -0,0 +1 @@ +220e459fad09b025b6f9331692b4eda8 \ No newline at end of file diff --git a/Code/Mantid/Testing/Data/SystemTest/SANS2D/SANS2D00000808_Table.txt.md5 b/Code/Mantid/Testing/Data/SystemTest/SANS2D/SANS2D00000808_Table.txt.md5 new file mode 100644 index 000000000000..7ac50ed04d2f --- /dev/null +++ b/Code/Mantid/Testing/Data/SystemTest/SANS2D/SANS2D00000808_Table.txt.md5 @@ -0,0 +1 @@ +1b5397ebeb74b00bf0d4d9eab7bfa303 \ No newline at end of file diff --git a/Code/Mantid/Testing/Data/SystemTest/SANS2D/SANS2D00000808_Tank_Pressure.txt.md5 b/Code/Mantid/Testing/Data/SystemTest/SANS2D/SANS2D00000808_Tank_Pressure.txt.md5 new file mode 100644 index 000000000000..55dcbc482415 --- /dev/null +++ b/Code/Mantid/Testing/Data/SystemTest/SANS2D/SANS2D00000808_Tank_Pressure.txt.md5 @@ -0,0 +1 @@ +ec236ab02579f5af79d01bd00bb55f7a \ No newline at end of file diff --git a/Code/Mantid/Testing/Data/SystemTest/SANS2D/SANS2D00000987.log.md5 b/Code/Mantid/Testing/Data/SystemTest/SANS2D/SANS2D00000987.log.md5 new file mode 100644 index 000000000000..04c61f1d097f --- /dev/null +++ b/Code/Mantid/Testing/Data/SystemTest/SANS2D/SANS2D00000987.log.md5 @@ -0,0 +1 @@ +838a48d37a3707d91f03289921e7c7a5 \ No newline at end of file diff --git a/Code/Mantid/Testing/Data/SystemTest/SANS2D/SANS2D00000987.raw.md5 b/Code/Mantid/Testing/Data/SystemTest/SANS2D/SANS2D00000987.raw.md5 new file mode 100644 index 000000000000..d9867f40af1f --- /dev/null +++ b/Code/Mantid/Testing/Data/SystemTest/SANS2D/SANS2D00000987.raw.md5 @@ -0,0 +1 @@ +3d9d2d375f4debdfe111ed456745745d \ No newline at end of file diff --git a/Code/Mantid/Testing/Data/SystemTest/SANS2D/SANS2D00000988.log.md5 b/Code/Mantid/Testing/Data/SystemTest/SANS2D/SANS2D00000988.log.md5 new file mode 100644 index 000000000000..6c4bef873fda --- /dev/null +++ b/Code/Mantid/Testing/Data/SystemTest/SANS2D/SANS2D00000988.log.md5 @@ -0,0 +1 @@ +915be6113f29fbfc66f86ac2a468867b \ No newline at end of file diff --git a/Code/Mantid/Testing/Data/SystemTest/SANS2D/SANS2D00000988.raw.md5 b/Code/Mantid/Testing/Data/SystemTest/SANS2D/SANS2D00000988.raw.md5 new file mode 100644 index 000000000000..be01f71bf35b --- /dev/null +++ b/Code/Mantid/Testing/Data/SystemTest/SANS2D/SANS2D00000988.raw.md5 @@ -0,0 +1 @@ +407506503150779c8b6dfa1fd005f938 \ No newline at end of file diff --git a/Code/Mantid/Testing/Data/SystemTest/SANS2D/SANS2D00000989.log.md5 b/Code/Mantid/Testing/Data/SystemTest/SANS2D/SANS2D00000989.log.md5 new file mode 100644 index 000000000000..9030bae37ca0 --- /dev/null +++ b/Code/Mantid/Testing/Data/SystemTest/SANS2D/SANS2D00000989.log.md5 @@ -0,0 +1 @@ +485b78cc6482e3aa99d2e4590c0b28a4 \ No newline at end of file diff --git a/Code/Mantid/Testing/Data/SystemTest/SANS2D/SANS2D00000989.raw.md5 b/Code/Mantid/Testing/Data/SystemTest/SANS2D/SANS2D00000989.raw.md5 new file mode 100644 index 000000000000..f844d75e22d6 --- /dev/null +++ b/Code/Mantid/Testing/Data/SystemTest/SANS2D/SANS2D00000989.raw.md5 @@ -0,0 +1 @@ +a8e4ae94a284ad3da9f49b8d07fa63b7 \ No newline at end of file diff --git a/Code/Mantid/Testing/Data/SystemTest/SANS2D/SANS2D00000992.log.md5 b/Code/Mantid/Testing/Data/SystemTest/SANS2D/SANS2D00000992.log.md5 new file mode 100644 index 000000000000..6b32d43fe4a4 --- /dev/null +++ b/Code/Mantid/Testing/Data/SystemTest/SANS2D/SANS2D00000992.log.md5 @@ -0,0 +1 @@ +debac79e54eb5e83f510d042e1a9cead \ No newline at end of file diff --git a/Code/Mantid/Testing/Data/SystemTest/SANS2D/SANS2D00000992.raw.md5 b/Code/Mantid/Testing/Data/SystemTest/SANS2D/SANS2D00000992.raw.md5 new file mode 100644 index 000000000000..bca2a4695cc5 --- /dev/null +++ b/Code/Mantid/Testing/Data/SystemTest/SANS2D/SANS2D00000992.raw.md5 @@ -0,0 +1 @@ +d4251aba2c0b2544a121c4393e9e19e1 \ No newline at end of file diff --git a/Code/Mantid/Testing/Data/SystemTest/SANS2D/SANS2D00000993.log.md5 b/Code/Mantid/Testing/Data/SystemTest/SANS2D/SANS2D00000993.log.md5 new file mode 100644 index 000000000000..295f5fe783cb --- /dev/null +++ b/Code/Mantid/Testing/Data/SystemTest/SANS2D/SANS2D00000993.log.md5 @@ -0,0 +1 @@ +2e89743b0487363a782a0c646569601a \ No newline at end of file diff --git a/Code/Mantid/Testing/Data/SystemTest/SANS2D/SANS2D00000993.raw.md5 b/Code/Mantid/Testing/Data/SystemTest/SANS2D/SANS2D00000993.raw.md5 new file mode 100644 index 000000000000..239b0d85a105 --- /dev/null +++ b/Code/Mantid/Testing/Data/SystemTest/SANS2D/SANS2D00000993.raw.md5 @@ -0,0 +1 @@ +114e6b0c7c42f7c6960ea70e96c9fa9e \ No newline at end of file diff --git a/Code/Mantid/Testing/Data/SystemTest/SANS2D/SANS2D00002500.log.md5 b/Code/Mantid/Testing/Data/SystemTest/SANS2D/SANS2D00002500.log.md5 new file mode 100644 index 000000000000..cba6ee35423f --- /dev/null +++ b/Code/Mantid/Testing/Data/SystemTest/SANS2D/SANS2D00002500.log.md5 @@ -0,0 +1 @@ +771ea597c49ebc970c86249f7a55f818 \ No newline at end of file diff --git a/Code/Mantid/Testing/Data/SystemTest/SANS2D/SANS2D00002500.nxs.md5 b/Code/Mantid/Testing/Data/SystemTest/SANS2D/SANS2D00002500.nxs.md5 new file mode 100644 index 000000000000..aff5e056b746 --- /dev/null +++ b/Code/Mantid/Testing/Data/SystemTest/SANS2D/SANS2D00002500.nxs.md5 @@ -0,0 +1 @@ +ff3e6380eaf519e483f4700050de4d8d \ No newline at end of file diff --git a/Code/Mantid/Testing/Data/SystemTest/SANS2D/SANS2D00005512.log.md5 b/Code/Mantid/Testing/Data/SystemTest/SANS2D/SANS2D00005512.log.md5 new file mode 100644 index 000000000000..519f342e6732 --- /dev/null +++ b/Code/Mantid/Testing/Data/SystemTest/SANS2D/SANS2D00005512.log.md5 @@ -0,0 +1 @@ +29b28f60cf46bb4f0aa7885b74b89aaa \ No newline at end of file diff --git a/Code/Mantid/Testing/Data/SystemTest/SANS2D/SANS2D00005512.nxs.md5 b/Code/Mantid/Testing/Data/SystemTest/SANS2D/SANS2D00005512.nxs.md5 new file mode 100644 index 000000000000..ad37a6aef982 --- /dev/null +++ b/Code/Mantid/Testing/Data/SystemTest/SANS2D/SANS2D00005512.nxs.md5 @@ -0,0 +1 @@ +28bde5a331c28631ced8d0db93cff62e \ No newline at end of file diff --git a/Code/Mantid/Testing/Data/SystemTest/SANS2D/SANS2D00005543.log.md5 b/Code/Mantid/Testing/Data/SystemTest/SANS2D/SANS2D00005543.log.md5 new file mode 100644 index 000000000000..cd9592e09380 --- /dev/null +++ b/Code/Mantid/Testing/Data/SystemTest/SANS2D/SANS2D00005543.log.md5 @@ -0,0 +1 @@ +c4ca6faa9bbcb04e9440c32ed5960983 \ No newline at end of file diff --git a/Code/Mantid/Testing/Data/SystemTest/SANS2D/SANS2D00005543.raw.md5 b/Code/Mantid/Testing/Data/SystemTest/SANS2D/SANS2D00005543.raw.md5 new file mode 100644 index 000000000000..2add0be8a29f --- /dev/null +++ b/Code/Mantid/Testing/Data/SystemTest/SANS2D/SANS2D00005543.raw.md5 @@ -0,0 +1 @@ +868d3b51913f89e659461603bf5a7d24 \ No newline at end of file diff --git a/Code/Mantid/Testing/Data/SystemTest/SANS2D/SANS2D00005544.log.md5 b/Code/Mantid/Testing/Data/SystemTest/SANS2D/SANS2D00005544.log.md5 new file mode 100644 index 000000000000..871bbd73f293 --- /dev/null +++ b/Code/Mantid/Testing/Data/SystemTest/SANS2D/SANS2D00005544.log.md5 @@ -0,0 +1 @@ +cf28a002bec63f3035e0ff9d9391376e \ No newline at end of file diff --git a/Code/Mantid/Testing/Data/SystemTest/SANS2D/SANS2D00005544.raw.md5 b/Code/Mantid/Testing/Data/SystemTest/SANS2D/SANS2D00005544.raw.md5 new file mode 100644 index 000000000000..b9add5ddf21b --- /dev/null +++ b/Code/Mantid/Testing/Data/SystemTest/SANS2D/SANS2D00005544.raw.md5 @@ -0,0 +1 @@ +20a07e3a4b122f027130135b407e0cc6 \ No newline at end of file diff --git a/Code/Mantid/Testing/Data/SystemTest/SANS2D/SANS2D00005545.log.md5 b/Code/Mantid/Testing/Data/SystemTest/SANS2D/SANS2D00005545.log.md5 new file mode 100644 index 000000000000..4c896d05aa4a --- /dev/null +++ b/Code/Mantid/Testing/Data/SystemTest/SANS2D/SANS2D00005545.log.md5 @@ -0,0 +1 @@ +768fb183592a8ebdb4f992b39a1d7ae4 \ No newline at end of file diff --git a/Code/Mantid/Testing/Data/SystemTest/SANS2D/SANS2D00005545.raw.md5 b/Code/Mantid/Testing/Data/SystemTest/SANS2D/SANS2D00005545.raw.md5 new file mode 100644 index 000000000000..2c1039d04ec1 --- /dev/null +++ b/Code/Mantid/Testing/Data/SystemTest/SANS2D/SANS2D00005545.raw.md5 @@ -0,0 +1 @@ +85d80b1ecd515fcd04e0f6e7cd9ba865 \ No newline at end of file diff --git a/Code/Mantid/Testing/Data/SystemTest/SANS2D/SANS2D00005546.log.md5 b/Code/Mantid/Testing/Data/SystemTest/SANS2D/SANS2D00005546.log.md5 new file mode 100644 index 000000000000..e7d1b5d9cec4 --- /dev/null +++ b/Code/Mantid/Testing/Data/SystemTest/SANS2D/SANS2D00005546.log.md5 @@ -0,0 +1 @@ +ef36151c791ee0e66c112228991a75cf \ No newline at end of file diff --git a/Code/Mantid/Testing/Data/SystemTest/SANS2D/SANS2D00005546.raw.md5 b/Code/Mantid/Testing/Data/SystemTest/SANS2D/SANS2D00005546.raw.md5 new file mode 100644 index 000000000000..3309588fd29b --- /dev/null +++ b/Code/Mantid/Testing/Data/SystemTest/SANS2D/SANS2D00005546.raw.md5 @@ -0,0 +1 @@ +572e379d5fc3d7a0da8863db1e31034f \ No newline at end of file diff --git a/Code/Mantid/Testing/Data/SystemTest/SANS2D/SANS2D00005547.log.md5 b/Code/Mantid/Testing/Data/SystemTest/SANS2D/SANS2D00005547.log.md5 new file mode 100644 index 000000000000..ac2be6e3e29c --- /dev/null +++ b/Code/Mantid/Testing/Data/SystemTest/SANS2D/SANS2D00005547.log.md5 @@ -0,0 +1 @@ +7640ee60f7654f255d92fb62989674d2 \ No newline at end of file diff --git a/Code/Mantid/Testing/Data/SystemTest/SANS2D/SANS2D00005547.raw.md5 b/Code/Mantid/Testing/Data/SystemTest/SANS2D/SANS2D00005547.raw.md5 new file mode 100644 index 000000000000..310a5054ee06 --- /dev/null +++ b/Code/Mantid/Testing/Data/SystemTest/SANS2D/SANS2D00005547.raw.md5 @@ -0,0 +1 @@ +f9f1b79e203a7e73350e5319862d6929 \ No newline at end of file diff --git a/Code/Mantid/Testing/Data/SystemTest/SANS2D/SANS2D00022023.nxs.md5 b/Code/Mantid/Testing/Data/SystemTest/SANS2D/SANS2D00022023.nxs.md5 new file mode 100644 index 000000000000..d6fceb808a62 --- /dev/null +++ b/Code/Mantid/Testing/Data/SystemTest/SANS2D/SANS2D00022023.nxs.md5 @@ -0,0 +1 @@ +fc7c75853e8e8b81e3c57e99daca2bc5 \ No newline at end of file diff --git a/Code/Mantid/Testing/Data/SystemTest/SANS2D/SANS2D00022024.nxs.md5 b/Code/Mantid/Testing/Data/SystemTest/SANS2D/SANS2D00022024.nxs.md5 new file mode 100644 index 000000000000..dabda7757bc1 --- /dev/null +++ b/Code/Mantid/Testing/Data/SystemTest/SANS2D/SANS2D00022024.nxs.md5 @@ -0,0 +1 @@ +d8df0c8d545bb4462e88e501f1677170 \ No newline at end of file diff --git a/Code/Mantid/Testing/Data/SystemTest/SANS2D/SANS2D00022041.nxs.md5 b/Code/Mantid/Testing/Data/SystemTest/SANS2D/SANS2D00022041.nxs.md5 new file mode 100644 index 000000000000..5b2bd57019d7 --- /dev/null +++ b/Code/Mantid/Testing/Data/SystemTest/SANS2D/SANS2D00022041.nxs.md5 @@ -0,0 +1 @@ +d83b0a7d037998b84bb995c59ae1a739 \ No newline at end of file diff --git a/Code/Mantid/Testing/Data/SystemTest/SANS2D/SANS2D00022048.nxs.md5 b/Code/Mantid/Testing/Data/SystemTest/SANS2D/SANS2D00022048.nxs.md5 new file mode 100644 index 000000000000..b0246a3db2c2 --- /dev/null +++ b/Code/Mantid/Testing/Data/SystemTest/SANS2D/SANS2D00022048.nxs.md5 @@ -0,0 +1 @@ +bb63c083b4fb7373f1a2a33d1b8946bb \ No newline at end of file diff --git a/Code/Mantid/Testing/Data/SystemTest/SANS2D/SANS2D_992_91A.csv.md5 b/Code/Mantid/Testing/Data/SystemTest/SANS2D/SANS2D_992_91A.csv.md5 new file mode 100644 index 000000000000..8194025547e8 --- /dev/null +++ b/Code/Mantid/Testing/Data/SystemTest/SANS2D/SANS2D_992_91A.csv.md5 @@ -0,0 +1 @@ +f51517af9de24c1a16ce859bfd06bcb1 \ No newline at end of file diff --git a/Code/Mantid/Testing/Data/SystemTest/SANS2D/SANS2D_mask_batch.csv.md5 b/Code/Mantid/Testing/Data/SystemTest/SANS2D/SANS2D_mask_batch.csv.md5 new file mode 100644 index 000000000000..bbf828a99b8e --- /dev/null +++ b/Code/Mantid/Testing/Data/SystemTest/SANS2D/SANS2D_mask_batch.csv.md5 @@ -0,0 +1 @@ +af6a7f37da246a48671a708f07c12cc3 \ No newline at end of file diff --git a/Code/Mantid/Testing/Data/SystemTest/SANS2D/SANS2D_multiPeriodTests.csv.md5 b/Code/Mantid/Testing/Data/SystemTest/SANS2D/SANS2D_multiPeriodTests.csv.md5 new file mode 100644 index 000000000000..de1caafb9bee --- /dev/null +++ b/Code/Mantid/Testing/Data/SystemTest/SANS2D/SANS2D_multiPeriodTests.csv.md5 @@ -0,0 +1 @@ +3b731c12bf74f993dbed03e7ebde1767 \ No newline at end of file diff --git a/Code/Mantid/Testing/Data/SystemTest/SANS2D/SANS2D_periodTests.csv.md5 b/Code/Mantid/Testing/Data/SystemTest/SANS2D/SANS2D_periodTests.csv.md5 new file mode 100644 index 000000000000..035923993bf6 --- /dev/null +++ b/Code/Mantid/Testing/Data/SystemTest/SANS2D/SANS2D_periodTests.csv.md5 @@ -0,0 +1 @@ +e5c5326817ebc5a588286753c4d4d5d0 \ No newline at end of file diff --git a/Code/Mantid/Testing/Data/SystemTest/SANS2D/linked_circles_mask.xml.md5 b/Code/Mantid/Testing/Data/SystemTest/SANS2D/linked_circles_mask.xml.md5 new file mode 100644 index 000000000000..c1e19a18887b --- /dev/null +++ b/Code/Mantid/Testing/Data/SystemTest/SANS2D/linked_circles_mask.xml.md5 @@ -0,0 +1 @@ +43656124fccd87c80a78bcd33b4f5f79 \ No newline at end of file diff --git a/Code/Mantid/Testing/Data/SystemTest/SANS2D/reduced_center_by_hand.txt.md5 b/Code/Mantid/Testing/Data/SystemTest/SANS2D/reduced_center_by_hand.txt.md5 new file mode 100644 index 000000000000..684c450a2e16 --- /dev/null +++ b/Code/Mantid/Testing/Data/SystemTest/SANS2D/reduced_center_by_hand.txt.md5 @@ -0,0 +1 @@ +bdf509c06cc5aa539af2adf09e87316b \ No newline at end of file diff --git a/Code/Mantid/Testing/Data/SystemTest/SANS2D/reduced_center_calculated.txt.md5 b/Code/Mantid/Testing/Data/SystemTest/SANS2D/reduced_center_calculated.txt.md5 new file mode 100644 index 000000000000..b032268804d7 --- /dev/null +++ b/Code/Mantid/Testing/Data/SystemTest/SANS2D/reduced_center_calculated.txt.md5 @@ -0,0 +1 @@ +bfbe49b343ad7ed8669de783407c54fa \ No newline at end of file diff --git a/Code/Mantid/Testing/Data/SystemTest/SANS2D/reduced_transmission.txt.md5 b/Code/Mantid/Testing/Data/SystemTest/SANS2D/reduced_transmission.txt.md5 new file mode 100644 index 000000000000..5575d900309a --- /dev/null +++ b/Code/Mantid/Testing/Data/SystemTest/SANS2D/reduced_transmission.txt.md5 @@ -0,0 +1 @@ +3e6ac1b488ee3c8e781caeb9d277333e \ No newline at end of file diff --git a/Code/Mantid/Testing/Data/SystemTest/SANS2D/sans2d_reduction_gui_batch.csv.md5 b/Code/Mantid/Testing/Data/SystemTest/SANS2D/sans2d_reduction_gui_batch.csv.md5 new file mode 100644 index 000000000000..2e8249a0cc9d --- /dev/null +++ b/Code/Mantid/Testing/Data/SystemTest/SANS2D/sans2d_reduction_gui_batch.csv.md5 @@ -0,0 +1 @@ +b9f3cdfba008eb7a3716e526805a29b2 \ No newline at end of file diff --git a/Code/Mantid/Testing/Data/SystemTest/SANS2D/target_circles_mask.xml.md5 b/Code/Mantid/Testing/Data/SystemTest/SANS2D/target_circles_mask.xml.md5 new file mode 100644 index 000000000000..68763f5a01a9 --- /dev/null +++ b/Code/Mantid/Testing/Data/SystemTest/SANS2D/target_circles_mask.xml.md5 @@ -0,0 +1 @@ +80a1897993d2f9fd3c67aff1abdccc9c \ No newline at end of file diff --git a/Code/Mantid/Testing/Data/SystemTest/SANS2D/testCansas1DMultiEntry.xml.md5 b/Code/Mantid/Testing/Data/SystemTest/SANS2D/testCansas1DMultiEntry.xml.md5 new file mode 100644 index 000000000000..3051d0594fcb --- /dev/null +++ b/Code/Mantid/Testing/Data/SystemTest/SANS2D/testCansas1DMultiEntry.xml.md5 @@ -0,0 +1 @@ +c5b0c1783fd7eacac15a68be1db5e5f7 \ No newline at end of file diff --git a/Code/Mantid/Testing/Data/SystemTest/SANSBeamFluxCorrectionMonitor.nxs.md5 b/Code/Mantid/Testing/Data/SystemTest/SANSBeamFluxCorrectionMonitor.nxs.md5 new file mode 100644 index 000000000000..0397785e3d97 --- /dev/null +++ b/Code/Mantid/Testing/Data/SystemTest/SANSBeamFluxCorrectionMonitor.nxs.md5 @@ -0,0 +1 @@ +f6d0acab540ec36871d72d3626fa0daf \ No newline at end of file diff --git a/Code/Mantid/Testing/Data/SystemTest/SEQ_11499_event.nxs.md5 b/Code/Mantid/Testing/Data/SystemTest/SEQ_11499_event.nxs.md5 new file mode 100644 index 000000000000..b6aa1729c9b6 --- /dev/null +++ b/Code/Mantid/Testing/Data/SystemTest/SEQ_11499_event.nxs.md5 @@ -0,0 +1 @@ +e9552fa854501f5eb32ae418b8b43dfa \ No newline at end of file diff --git a/Code/Mantid/Testing/Data/SystemTest/SEQ_12384_event.nxs.md5 b/Code/Mantid/Testing/Data/SystemTest/SEQ_12384_event.nxs.md5 new file mode 100644 index 000000000000..2cbcdadfd7d2 --- /dev/null +++ b/Code/Mantid/Testing/Data/SystemTest/SEQ_12384_event.nxs.md5 @@ -0,0 +1 @@ +aa3426c5de7461d7eaec71b06bb6e3ce \ No newline at end of file diff --git a/Code/Mantid/Testing/Data/SystemTest/SEQ_MDEW.nxs.expected.md5 b/Code/Mantid/Testing/Data/SystemTest/SEQ_MDEW.nxs.expected.md5 new file mode 100644 index 000000000000..53c90444733e --- /dev/null +++ b/Code/Mantid/Testing/Data/SystemTest/SEQ_MDEW.nxs.expected.md5 @@ -0,0 +1 @@ +dcafee769239affab7b3ef5fa18bab43 \ No newline at end of file diff --git a/Code/Mantid/Testing/Data/SystemTest/SEQ_MDEW.nxs.md5 b/Code/Mantid/Testing/Data/SystemTest/SEQ_MDEW.nxs.md5 new file mode 100644 index 000000000000..25a1ab5fb145 --- /dev/null +++ b/Code/Mantid/Testing/Data/SystemTest/SEQ_MDEW.nxs.md5 @@ -0,0 +1 @@ +9b7510c501550828acd5d6e3baed4a8d \ No newline at end of file diff --git a/Code/Mantid/Testing/Data/SystemTest/SEQ_van.nxs.md5 b/Code/Mantid/Testing/Data/SystemTest/SEQ_van.nxs.md5 new file mode 100644 index 000000000000..e459c4b88fb3 --- /dev/null +++ b/Code/Mantid/Testing/Data/SystemTest/SEQ_van.nxs.md5 @@ -0,0 +1 @@ +9455a8090b619288f63ce815f74de725 \ No newline at end of file diff --git a/Code/Mantid/Testing/Data/SystemTest/SRF92132.nxs.md5 b/Code/Mantid/Testing/Data/SystemTest/SRF92132.nxs.md5 new file mode 100644 index 000000000000..c9d8d6e055e6 --- /dev/null +++ b/Code/Mantid/Testing/Data/SystemTest/SRF92132.nxs.md5 @@ -0,0 +1 @@ +506bd7b87deb8a5ddcf8d48b389176bb \ No newline at end of file diff --git a/Code/Mantid/Testing/Data/SystemTest/SRF92132.raw.md5 b/Code/Mantid/Testing/Data/SystemTest/SRF92132.raw.md5 new file mode 100644 index 000000000000..806f040a991c --- /dev/null +++ b/Code/Mantid/Testing/Data/SystemTest/SRF92132.raw.md5 @@ -0,0 +1 @@ +f0ccfa2e54e1314bbae810ccddb5678c \ No newline at end of file diff --git a/Code/Mantid/Testing/Data/SystemTest/SXD23767.raw.md5 b/Code/Mantid/Testing/Data/SystemTest/SXD23767.raw.md5 new file mode 100644 index 000000000000..3d957debe9e4 --- /dev/null +++ b/Code/Mantid/Testing/Data/SystemTest/SXD23767.raw.md5 @@ -0,0 +1 @@ +3950f6d890c10dd67c320cab6054d3d8 \ No newline at end of file diff --git a/Code/Mantid/Testing/Data/SystemTest/TOPAZ_2011_02_16.DetCal.md5 b/Code/Mantid/Testing/Data/SystemTest/TOPAZ_2011_02_16.DetCal.md5 new file mode 100644 index 000000000000..fa64a701f124 --- /dev/null +++ b/Code/Mantid/Testing/Data/SystemTest/TOPAZ_2011_02_16.DetCal.md5 @@ -0,0 +1 @@ +b59cdd27141af1908f0fc7647864c63f \ No newline at end of file diff --git a/Code/Mantid/Testing/Data/SystemTest/TOPAZ_3007.peaks.md5 b/Code/Mantid/Testing/Data/SystemTest/TOPAZ_3007.peaks.md5 new file mode 100644 index 000000000000..843abe22cd23 --- /dev/null +++ b/Code/Mantid/Testing/Data/SystemTest/TOPAZ_3007.peaks.md5 @@ -0,0 +1 @@ +088caab2ce8d172e89789aed8c321075 \ No newline at end of file diff --git a/Code/Mantid/Testing/Data/SystemTest/TOPAZ_3007_bank_37_20_sec.nxs.md5 b/Code/Mantid/Testing/Data/SystemTest/TOPAZ_3007_bank_37_20_sec.nxs.md5 new file mode 100644 index 000000000000..8eee811b2f8d --- /dev/null +++ b/Code/Mantid/Testing/Data/SystemTest/TOPAZ_3007_bank_37_20_sec.nxs.md5 @@ -0,0 +1 @@ +dc7a31d110784d7779204342e99329c1 \ No newline at end of file diff --git a/Code/Mantid/Testing/Data/SystemTest/TOPAZ_3132_event.nxs.md5 b/Code/Mantid/Testing/Data/SystemTest/TOPAZ_3132_event.nxs.md5 new file mode 100644 index 000000000000..64638b1d3d4e --- /dev/null +++ b/Code/Mantid/Testing/Data/SystemTest/TOPAZ_3132_event.nxs.md5 @@ -0,0 +1 @@ +f3508a6670d300b4c4880c81dbf57bde \ No newline at end of file diff --git a/Code/Mantid/Testing/Data/SystemTest/TSC11453.raw.md5 b/Code/Mantid/Testing/Data/SystemTest/TSC11453.raw.md5 new file mode 100644 index 000000000000..3fde7775b32c --- /dev/null +++ b/Code/Mantid/Testing/Data/SystemTest/TSC11453.raw.md5 @@ -0,0 +1 @@ +a71ff8e98f4e4c8902f82d756df7d2ac \ No newline at end of file diff --git a/Code/Mantid/Testing/Data/SystemTest/TSC15352.raw.md5 b/Code/Mantid/Testing/Data/SystemTest/TSC15352.raw.md5 new file mode 100644 index 000000000000..abd044161937 --- /dev/null +++ b/Code/Mantid/Testing/Data/SystemTest/TSC15352.raw.md5 @@ -0,0 +1 @@ +c5d2cd48bc9dae1992f1db23e4978791 \ No newline at end of file diff --git a/Code/Mantid/Testing/Data/SystemTest/TSC15353.raw.md5 b/Code/Mantid/Testing/Data/SystemTest/TSC15353.raw.md5 new file mode 100644 index 000000000000..ff4e8e13dde9 --- /dev/null +++ b/Code/Mantid/Testing/Data/SystemTest/TSC15353.raw.md5 @@ -0,0 +1 @@ +9a116f7a1d90a1c6aad684d9c4b83c84 \ No newline at end of file diff --git a/Code/Mantid/Testing/Data/SystemTest/TSC15354.raw.md5 b/Code/Mantid/Testing/Data/SystemTest/TSC15354.raw.md5 new file mode 100644 index 000000000000..73f1bc52376b --- /dev/null +++ b/Code/Mantid/Testing/Data/SystemTest/TSC15354.raw.md5 @@ -0,0 +1 @@ +a60091cd306894e5f74ca97edce5a0c8 \ No newline at end of file diff --git a/Code/Mantid/Testing/Data/SystemTest/VULCAN_22946_NOM.dat.md5 b/Code/Mantid/Testing/Data/SystemTest/VULCAN_22946_NOM.dat.md5 new file mode 100644 index 000000000000..3222a8f5b084 --- /dev/null +++ b/Code/Mantid/Testing/Data/SystemTest/VULCAN_22946_NOM.dat.md5 @@ -0,0 +1 @@ +085f2789b9d799ec0bb1df03e0e9276f \ No newline at end of file diff --git a/Code/Mantid/Testing/Data/SystemTest/VULCAN_Calibrate_Seq.nxs.md5 b/Code/Mantid/Testing/Data/SystemTest/VULCAN_Calibrate_Seq.nxs.md5 new file mode 100644 index 000000000000..4ab89c1c17db --- /dev/null +++ b/Code/Mantid/Testing/Data/SystemTest/VULCAN_Calibrate_Seq.nxs.md5 @@ -0,0 +1 @@ +8bf633ef688f6ad66e251a883e760fc4 \ No newline at end of file diff --git a/Code/Mantid/Testing/Data/SystemTest/VULCAN_SNS_1.irf.md5 b/Code/Mantid/Testing/Data/SystemTest/VULCAN_SNS_1.irf.md5 new file mode 100644 index 000000000000..d6534fb7313e --- /dev/null +++ b/Code/Mantid/Testing/Data/SystemTest/VULCAN_SNS_1.irf.md5 @@ -0,0 +1 @@ +0cc4877fd416934183408980c8888d3c \ No newline at end of file diff --git a/Code/Mantid/Testing/Data/SystemTest/WBARCS.nxs.md5 b/Code/Mantid/Testing/Data/SystemTest/WBARCS.nxs.md5 new file mode 100644 index 000000000000..5ae6cdd9831b --- /dev/null +++ b/Code/Mantid/Testing/Data/SystemTest/WBARCS.nxs.md5 @@ -0,0 +1 @@ +ced0c7d1630684591f40c86c22e81993 \ No newline at end of file diff --git a/Code/Mantid/Testing/Data/SystemTest/WISH00016748.raw.md5 b/Code/Mantid/Testing/Data/SystemTest/WISH00016748.raw.md5 new file mode 100644 index 000000000000..620bca633886 --- /dev/null +++ b/Code/Mantid/Testing/Data/SystemTest/WISH00016748.raw.md5 @@ -0,0 +1 @@ +37ecc6f99662b57e405ed967bdc068af \ No newline at end of file diff --git a/Code/Mantid/Testing/Data/SystemTest/WSH_test.dat.md5 b/Code/Mantid/Testing/Data/SystemTest/WSH_test.dat.md5 new file mode 100644 index 000000000000..fc92d56413d3 --- /dev/null +++ b/Code/Mantid/Testing/Data/SystemTest/WSH_test.dat.md5 @@ -0,0 +1 @@ +5985c297c7b330280d9c64a9d12605d0 \ No newline at end of file diff --git a/Code/Mantid/Testing/Data/SystemTest/Wish_Diffuse_Scattering_A.nxs.md5 b/Code/Mantid/Testing/Data/SystemTest/Wish_Diffuse_Scattering_A.nxs.md5 new file mode 100644 index 000000000000..df0e1a3d1a01 --- /dev/null +++ b/Code/Mantid/Testing/Data/SystemTest/Wish_Diffuse_Scattering_A.nxs.md5 @@ -0,0 +1 @@ +be433d3b82e00c34159795c585c9d180 \ No newline at end of file diff --git a/Code/Mantid/Testing/Data/SystemTest/Wish_Diffuse_Scattering_B.nxs.md5 b/Code/Mantid/Testing/Data/SystemTest/Wish_Diffuse_Scattering_B.nxs.md5 new file mode 100644 index 000000000000..7ae3c4ab7a76 --- /dev/null +++ b/Code/Mantid/Testing/Data/SystemTest/Wish_Diffuse_Scattering_B.nxs.md5 @@ -0,0 +1 @@ +ea716926f7b66a67ddb315606b61b9c4 \ No newline at end of file diff --git a/Code/Mantid/Testing/Data/SystemTest/Wish_Diffuse_Scattering_C.nxs.md5 b/Code/Mantid/Testing/Data/SystemTest/Wish_Diffuse_Scattering_C.nxs.md5 new file mode 100644 index 000000000000..043a563f7885 --- /dev/null +++ b/Code/Mantid/Testing/Data/SystemTest/Wish_Diffuse_Scattering_C.nxs.md5 @@ -0,0 +1 @@ +6475e09edd0532e08219380ddf804c13 \ No newline at end of file diff --git a/Code/Mantid/Testing/Data/SystemTest/Wish_Diffuse_Scattering_ISAW_UB.mat.md5 b/Code/Mantid/Testing/Data/SystemTest/Wish_Diffuse_Scattering_ISAW_UB.mat.md5 new file mode 100644 index 000000000000..1c319911475a --- /dev/null +++ b/Code/Mantid/Testing/Data/SystemTest/Wish_Diffuse_Scattering_ISAW_UB.mat.md5 @@ -0,0 +1 @@ +79eba458d9165edfcd9016296d17fcb8 \ No newline at end of file diff --git a/Code/Mantid/Testing/Data/SystemTest/arg_powder.irf.md5 b/Code/Mantid/Testing/Data/SystemTest/arg_powder.irf.md5 new file mode 100644 index 000000000000..3b80be58a226 --- /dev/null +++ b/Code/Mantid/Testing/Data/SystemTest/arg_powder.irf.md5 @@ -0,0 +1 @@ +89f615f7436f7f11a6da120a2b037dac \ No newline at end of file diff --git a/Code/Mantid/Testing/Data/SystemTest/arg_si.dat.md5 b/Code/Mantid/Testing/Data/SystemTest/arg_si.dat.md5 new file mode 100644 index 000000000000..a72467fa0229 --- /dev/null +++ b/Code/Mantid/Testing/Data/SystemTest/arg_si.dat.md5 @@ -0,0 +1 @@ +7ef72daccc48e870a9f3bea792b03572 \ No newline at end of file diff --git a/Code/Mantid/Testing/Data/SystemTest/arg_si_bkgd_polynomial.nxs.md5 b/Code/Mantid/Testing/Data/SystemTest/arg_si_bkgd_polynomial.nxs.md5 new file mode 100644 index 000000000000..d1b391bf718b --- /dev/null +++ b/Code/Mantid/Testing/Data/SystemTest/arg_si_bkgd_polynomial.nxs.md5 @@ -0,0 +1 @@ +5107bb5b87b83dbe7a4b442d174dd2e5 \ No newline at end of file diff --git a/Code/Mantid/Testing/Data/SystemTest/argus0044309.nxs.md5 b/Code/Mantid/Testing/Data/SystemTest/argus0044309.nxs.md5 new file mode 100644 index 000000000000..8dda6bed932a --- /dev/null +++ b/Code/Mantid/Testing/Data/SystemTest/argus0044309.nxs.md5 @@ -0,0 +1 @@ +12c643504c50ae6b7643ad4757da2031 \ No newline at end of file diff --git a/Code/Mantid/Testing/Data/SystemTest/bl6_flux_at_sample.md5 b/Code/Mantid/Testing/Data/SystemTest/bl6_flux_at_sample.md5 new file mode 100644 index 000000000000..702cb09d3436 --- /dev/null +++ b/Code/Mantid/Testing/Data/SystemTest/bl6_flux_at_sample.md5 @@ -0,0 +1 @@ +8952dc1235e43f91e01d6e9c08aacaa2 \ No newline at end of file diff --git a/Code/Mantid/Testing/Data/SystemTest/det_LET_cycle12-3.dat.md5 b/Code/Mantid/Testing/Data/SystemTest/det_LET_cycle12-3.dat.md5 new file mode 100644 index 000000000000..1d981e4bcd2b --- /dev/null +++ b/Code/Mantid/Testing/Data/SystemTest/det_LET_cycle12-3.dat.md5 @@ -0,0 +1 @@ +484d1e78de16e16011452cd91a523342 \ No newline at end of file diff --git a/Code/Mantid/Testing/Data/SystemTest/det_corrected7.dat.md5 b/Code/Mantid/Testing/Data/SystemTest/det_corrected7.dat.md5 new file mode 100644 index 000000000000..efcf101c0e2f --- /dev/null +++ b/Code/Mantid/Testing/Data/SystemTest/det_corrected7.dat.md5 @@ -0,0 +1 @@ +18adc3908715d42cdb3cffc8a0355c82 \ No newline at end of file diff --git a/Code/Mantid/Testing/Data/SystemTest/det_corrected7.nxs.md5 b/Code/Mantid/Testing/Data/SystemTest/det_corrected7.nxs.md5 new file mode 100644 index 000000000000..cbaa36c20860 --- /dev/null +++ b/Code/Mantid/Testing/Data/SystemTest/det_corrected7.nxs.md5 @@ -0,0 +1 @@ +41ca6d5cfec8a63eba9497848b9150dc \ No newline at end of file diff --git a/Code/Mantid/Testing/Data/SystemTest/emptycryo3307-1foc.nx5.md5 b/Code/Mantid/Testing/Data/SystemTest/emptycryo3307-1foc.nx5.md5 new file mode 100644 index 000000000000..acabcee3ec3d --- /dev/null +++ b/Code/Mantid/Testing/Data/SystemTest/emptycryo3307-1foc.nx5.md5 @@ -0,0 +1 @@ +99a8a6db51560b770d54c837bbcc7b77 \ No newline at end of file diff --git a/Code/Mantid/Testing/Data/SystemTest/emu00031895.nxs.expected.md5 b/Code/Mantid/Testing/Data/SystemTest/emu00031895.nxs.expected.md5 new file mode 100644 index 000000000000..e95ff204c87f --- /dev/null +++ b/Code/Mantid/Testing/Data/SystemTest/emu00031895.nxs.expected.md5 @@ -0,0 +1 @@ +8a5b2d754c00923b0fad290cc8d66f22 \ No newline at end of file diff --git a/Code/Mantid/Testing/Data/SystemTest/emu00031895.nxs.md5 b/Code/Mantid/Testing/Data/SystemTest/emu00031895.nxs.md5 new file mode 100644 index 000000000000..3445751199c2 --- /dev/null +++ b/Code/Mantid/Testing/Data/SystemTest/emu00031895.nxs.md5 @@ -0,0 +1 @@ +f603ba2c4f736a439326cb92d6ccbc30 \ No newline at end of file diff --git a/Code/Mantid/Testing/Data/SystemTest/eqsans_beam_flux.txt.expected.md5 b/Code/Mantid/Testing/Data/SystemTest/eqsans_beam_flux.txt.expected.md5 new file mode 100644 index 000000000000..4b652a3338d8 --- /dev/null +++ b/Code/Mantid/Testing/Data/SystemTest/eqsans_beam_flux.txt.expected.md5 @@ -0,0 +1 @@ +e316ba709230d5f2e08ff3f6369772e7 \ No newline at end of file diff --git a/Code/Mantid/Testing/Data/SystemTest/eqsans_beam_flux.txt.md5 b/Code/Mantid/Testing/Data/SystemTest/eqsans_beam_flux.txt.md5 new file mode 100644 index 000000000000..4c8d98fcb673 --- /dev/null +++ b/Code/Mantid/Testing/Data/SystemTest/eqsans_beam_flux.txt.md5 @@ -0,0 +1 @@ +1af73113d3552aa9d9a8f2d9555c5283 \ No newline at end of file diff --git a/Code/Mantid/Testing/Data/SystemTest/eqsans_configuration.1463.md5 b/Code/Mantid/Testing/Data/SystemTest/eqsans_configuration.1463.md5 new file mode 100644 index 000000000000..a836b7655061 --- /dev/null +++ b/Code/Mantid/Testing/Data/SystemTest/eqsans_configuration.1463.md5 @@ -0,0 +1 @@ +bc23885d1cf90227f8a446942aa1eaf9 \ No newline at end of file diff --git a/Code/Mantid/Testing/Data/SystemTest/focus2010n000468.hdf.md5 b/Code/Mantid/Testing/Data/SystemTest/focus2010n000468.hdf.md5 new file mode 100644 index 000000000000..ed5b85c249f1 --- /dev/null +++ b/Code/Mantid/Testing/Data/SystemTest/focus2010n000468.hdf.md5 @@ -0,0 +1 @@ +7abb0e9c156f57ed1be09de0dffa185b \ No newline at end of file diff --git a/Code/Mantid/Testing/Data/SystemTest/gss-ExtendedHeader.gsa.expected.md5 b/Code/Mantid/Testing/Data/SystemTest/gss-ExtendedHeader.gsa.expected.md5 new file mode 100644 index 000000000000..1da0cb552e91 --- /dev/null +++ b/Code/Mantid/Testing/Data/SystemTest/gss-ExtendedHeader.gsa.expected.md5 @@ -0,0 +1 @@ +74001f54814f7aff18f41ceeea52e4ea \ No newline at end of file diff --git a/Code/Mantid/Testing/Data/SystemTest/gss-ExtendedHeader.gsa.md5 b/Code/Mantid/Testing/Data/SystemTest/gss-ExtendedHeader.gsa.md5 new file mode 100644 index 000000000000..c5bdc9e373d0 --- /dev/null +++ b/Code/Mantid/Testing/Data/SystemTest/gss-ExtendedHeader.gsa.md5 @@ -0,0 +1 @@ +e170c8b300df434e14d4cf825ca55c39 \ No newline at end of file diff --git a/Code/Mantid/Testing/Data/SystemTest/gss.txt.expected.md5 b/Code/Mantid/Testing/Data/SystemTest/gss.txt.expected.md5 new file mode 100644 index 000000000000..23110c75bfbe --- /dev/null +++ b/Code/Mantid/Testing/Data/SystemTest/gss.txt.expected.md5 @@ -0,0 +1 @@ +8211f97600d17fdc3f3a8cb0f1f3db74 \ No newline at end of file diff --git a/Code/Mantid/Testing/Data/SystemTest/gss.txt.md5 b/Code/Mantid/Testing/Data/SystemTest/gss.txt.md5 new file mode 100644 index 000000000000..92ced58531a5 --- /dev/null +++ b/Code/Mantid/Testing/Data/SystemTest/gss.txt.md5 @@ -0,0 +1 @@ +a9605ba3084699a1029cc46ed85f132d \ No newline at end of file diff --git a/Code/Mantid/Testing/Data/SystemTest/hifi00038401.nxs.md5 b/Code/Mantid/Testing/Data/SystemTest/hifi00038401.nxs.md5 new file mode 100644 index 000000000000..33395d9eff94 --- /dev/null +++ b/Code/Mantid/Testing/Data/SystemTest/hifi00038401.nxs.md5 @@ -0,0 +1 @@ +6976f143d4229105a3b3be600a7aedec \ No newline at end of file diff --git a/Code/Mantid/Testing/Data/SystemTest/irs21360.raw.md5 b/Code/Mantid/Testing/Data/SystemTest/irs21360.raw.md5 new file mode 100644 index 000000000000..096cad4ebc72 --- /dev/null +++ b/Code/Mantid/Testing/Data/SystemTest/irs21360.raw.md5 @@ -0,0 +1 @@ +1af1bee227e943bc3ab27067f2a20841 \ No newline at end of file diff --git a/Code/Mantid/Testing/Data/SystemTest/irs26173_diffspec_red.nxs.md5 b/Code/Mantid/Testing/Data/SystemTest/irs26173_diffspec_red.nxs.md5 new file mode 100644 index 000000000000..f9aed77f5847 --- /dev/null +++ b/Code/Mantid/Testing/Data/SystemTest/irs26173_diffspec_red.nxs.md5 @@ -0,0 +1 @@ +8490ef6a70376be917d4c95de655a93e \ No newline at end of file diff --git a/Code/Mantid/Testing/Data/SystemTest/irs26173_graphite002_ResNorm_Paras.nxs.md5 b/Code/Mantid/Testing/Data/SystemTest/irs26173_graphite002_ResNorm_Paras.nxs.md5 new file mode 100644 index 000000000000..8a36ac35784a --- /dev/null +++ b/Code/Mantid/Testing/Data/SystemTest/irs26173_graphite002_ResNorm_Paras.nxs.md5 @@ -0,0 +1 @@ +2945714e47295545060af5a689b219db \ No newline at end of file diff --git a/Code/Mantid/Testing/Data/SystemTest/irs26173_graphite002_red.nxs.md5 b/Code/Mantid/Testing/Data/SystemTest/irs26173_graphite002_red.nxs.md5 new file mode 100644 index 000000000000..dd49338b3125 --- /dev/null +++ b/Code/Mantid/Testing/Data/SystemTest/irs26173_graphite002_red.nxs.md5 @@ -0,0 +1 @@ +f52ac64ec23fb50b6d4649592aee4fdb \ No newline at end of file diff --git a/Code/Mantid/Testing/Data/SystemTest/irs26173_graphite002_res.nxs.md5 b/Code/Mantid/Testing/Data/SystemTest/irs26173_graphite002_res.nxs.md5 new file mode 100644 index 000000000000..f8094ffb61e4 --- /dev/null +++ b/Code/Mantid/Testing/Data/SystemTest/irs26173_graphite002_res.nxs.md5 @@ -0,0 +1 @@ +4a322a634e527c87fbef27f1cc9559d2 \ No newline at end of file diff --git a/Code/Mantid/Testing/Data/SystemTest/irs26176_diffspec_red.nxs.md5 b/Code/Mantid/Testing/Data/SystemTest/irs26176_diffspec_red.nxs.md5 new file mode 100644 index 000000000000..329b51f1e773 --- /dev/null +++ b/Code/Mantid/Testing/Data/SystemTest/irs26176_diffspec_red.nxs.md5 @@ -0,0 +1 @@ +1276ff194d27f1f353acb83b69251046 \ No newline at end of file diff --git a/Code/Mantid/Testing/Data/SystemTest/irs26176_graphite002_QLr_Parameters.nxs.md5 b/Code/Mantid/Testing/Data/SystemTest/irs26176_graphite002_QLr_Parameters.nxs.md5 new file mode 100644 index 000000000000..336732958174 --- /dev/null +++ b/Code/Mantid/Testing/Data/SystemTest/irs26176_graphite002_QLr_Parameters.nxs.md5 @@ -0,0 +1 @@ +c203f94895fa2323320baf5c5a964334 \ No newline at end of file diff --git a/Code/Mantid/Testing/Data/SystemTest/irs26176_graphite002_QLr_Workspace.nxs.md5 b/Code/Mantid/Testing/Data/SystemTest/irs26176_graphite002_QLr_Workspace.nxs.md5 new file mode 100644 index 000000000000..a994c0fd2760 --- /dev/null +++ b/Code/Mantid/Testing/Data/SystemTest/irs26176_graphite002_QLr_Workspace.nxs.md5 @@ -0,0 +1 @@ +7f527e9ae7034c72ccb52c26ce27dd85 \ No newline at end of file diff --git a/Code/Mantid/Testing/Data/SystemTest/irs26176_graphite002_cyl_Abs.nxs.md5 b/Code/Mantid/Testing/Data/SystemTest/irs26176_graphite002_cyl_Abs.nxs.md5 new file mode 100644 index 000000000000..98a9172ca63d --- /dev/null +++ b/Code/Mantid/Testing/Data/SystemTest/irs26176_graphite002_cyl_Abs.nxs.md5 @@ -0,0 +1 @@ +f4b31e993d1747f22074cd17365cf0eb \ No newline at end of file diff --git a/Code/Mantid/Testing/Data/SystemTest/irs26176_graphite002_red.nxs.md5 b/Code/Mantid/Testing/Data/SystemTest/irs26176_graphite002_red.nxs.md5 new file mode 100644 index 000000000000..1c698d0a291b --- /dev/null +++ b/Code/Mantid/Testing/Data/SystemTest/irs26176_graphite002_red.nxs.md5 @@ -0,0 +1 @@ +a69078cfcdf156b59327798cc71f4d51 \ No newline at end of file diff --git a/Code/Mantid/Testing/Data/SystemTest/irs26176_graphite002_width_water.dat.md5 b/Code/Mantid/Testing/Data/SystemTest/irs26176_graphite002_width_water.dat.md5 new file mode 100644 index 000000000000..616fc94bf08a --- /dev/null +++ b/Code/Mantid/Testing/Data/SystemTest/irs26176_graphite002_width_water.dat.md5 @@ -0,0 +1 @@ +5f644b83cedc654cd6db8e46a931abcd \ No newline at end of file diff --git a/Code/Mantid/Testing/Data/SystemTest/irs53664_graphite002_red.nxs.md5 b/Code/Mantid/Testing/Data/SystemTest/irs53664_graphite002_red.nxs.md5 new file mode 100644 index 000000000000..98407a035e67 --- /dev/null +++ b/Code/Mantid/Testing/Data/SystemTest/irs53664_graphite002_red.nxs.md5 @@ -0,0 +1 @@ +0cb5c709a46fb800d95d2cb603d987e7 \ No newline at end of file diff --git a/Code/Mantid/Testing/Data/SystemTest/irs53664_graphite002_res.nxs.md5 b/Code/Mantid/Testing/Data/SystemTest/irs53664_graphite002_res.nxs.md5 new file mode 100644 index 000000000000..04b40a693fec --- /dev/null +++ b/Code/Mantid/Testing/Data/SystemTest/irs53664_graphite002_res.nxs.md5 @@ -0,0 +1 @@ +b8954ad438382e2b2fc42e10804b723b \ No newline at end of file diff --git a/Code/Mantid/Testing/Data/SystemTest/irs53664_graphite002_sqw.nxs.md5 b/Code/Mantid/Testing/Data/SystemTest/irs53664_graphite002_sqw.nxs.md5 new file mode 100644 index 000000000000..be1e071b3510 --- /dev/null +++ b/Code/Mantid/Testing/Data/SystemTest/irs53664_graphite002_sqw.nxs.md5 @@ -0,0 +1 @@ +a44307fd76e7621cc5760fb95e952509 \ No newline at end of file diff --git a/Code/Mantid/Testing/Data/SystemTest/irs53665_graphite002_red.nxs.md5 b/Code/Mantid/Testing/Data/SystemTest/irs53665_graphite002_red.nxs.md5 new file mode 100644 index 000000000000..2c7a23fb9d2f --- /dev/null +++ b/Code/Mantid/Testing/Data/SystemTest/irs53665_graphite002_red.nxs.md5 @@ -0,0 +1 @@ +85eee839e87d2950d6d7fe3cb682a278 \ No newline at end of file diff --git a/Code/Mantid/Testing/Data/SystemTest/irs59330_graphite002_red.nxs.md5 b/Code/Mantid/Testing/Data/SystemTest/irs59330_graphite002_red.nxs.md5 new file mode 100644 index 000000000000..1f4e17cb872a --- /dev/null +++ b/Code/Mantid/Testing/Data/SystemTest/irs59330_graphite002_red.nxs.md5 @@ -0,0 +1 @@ +91259ccd4faadeb14531b11e13a9da02 \ No newline at end of file diff --git a/Code/Mantid/Testing/Data/SystemTest/mar11015.msk.md5 b/Code/Mantid/Testing/Data/SystemTest/mar11015.msk.md5 new file mode 100644 index 000000000000..1fceb0c45f62 --- /dev/null +++ b/Code/Mantid/Testing/Data/SystemTest/mar11015.msk.md5 @@ -0,0 +1 @@ +457525deab0a2181a688e93ef7e488ab \ No newline at end of file diff --git a/Code/Mantid/Testing/Data/SystemTest/mari_res.map.md5 b/Code/Mantid/Testing/Data/SystemTest/mari_res.map.md5 new file mode 100644 index 000000000000..2baed9700976 --- /dev/null +++ b/Code/Mantid/Testing/Data/SystemTest/mari_res.map.md5 @@ -0,0 +1 @@ +4605d5fc3c8eecceba8b7163007dcfb5 \ No newline at end of file diff --git a/Code/Mantid/Testing/Data/SystemTest/offsets_2011_cycle111b.cal.md5 b/Code/Mantid/Testing/Data/SystemTest/offsets_2011_cycle111b.cal.md5 new file mode 100644 index 000000000000..dc1c058a9704 --- /dev/null +++ b/Code/Mantid/Testing/Data/SystemTest/offsets_2011_cycle111b.cal.md5 @@ -0,0 +1 @@ +a68bb9c5ee1efa31d4aee1887ac4fe65 \ No newline at end of file diff --git a/Code/Mantid/Testing/Data/SystemTest/osi89757.raw.md5 b/Code/Mantid/Testing/Data/SystemTest/osi89757.raw.md5 new file mode 100644 index 000000000000..71b5a2ced04c --- /dev/null +++ b/Code/Mantid/Testing/Data/SystemTest/osi89757.raw.md5 @@ -0,0 +1 @@ +b3e68c7be153deeb1c80ca7b88ff40bb \ No newline at end of file diff --git a/Code/Mantid/Testing/Data/SystemTest/osi89758.raw.md5 b/Code/Mantid/Testing/Data/SystemTest/osi89758.raw.md5 new file mode 100644 index 000000000000..37124161c63e --- /dev/null +++ b/Code/Mantid/Testing/Data/SystemTest/osi89758.raw.md5 @@ -0,0 +1 @@ +540ed8df6e577c80c85c94a511ba6a1a \ No newline at end of file diff --git a/Code/Mantid/Testing/Data/SystemTest/osi89759.raw.md5 b/Code/Mantid/Testing/Data/SystemTest/osi89759.raw.md5 new file mode 100644 index 000000000000..fec076453806 --- /dev/null +++ b/Code/Mantid/Testing/Data/SystemTest/osi89759.raw.md5 @@ -0,0 +1 @@ +03dbd1be18460ca4808ff7ed7ce542b1 \ No newline at end of file diff --git a/Code/Mantid/Testing/Data/SystemTest/osi89760.raw.md5 b/Code/Mantid/Testing/Data/SystemTest/osi89760.raw.md5 new file mode 100644 index 000000000000..d182d8e18f6c --- /dev/null +++ b/Code/Mantid/Testing/Data/SystemTest/osi89760.raw.md5 @@ -0,0 +1 @@ +8cc3fda1d5fcc4dbe305e57df6b373ef \ No newline at end of file diff --git a/Code/Mantid/Testing/Data/SystemTest/osi89761.raw.md5 b/Code/Mantid/Testing/Data/SystemTest/osi89761.raw.md5 new file mode 100644 index 000000000000..0375e2093541 --- /dev/null +++ b/Code/Mantid/Testing/Data/SystemTest/osi89761.raw.md5 @@ -0,0 +1 @@ +5eaac20a41b6efc9a3c741fa2f9ace28 \ No newline at end of file diff --git a/Code/Mantid/Testing/Data/SystemTest/osi89816.raw.md5 b/Code/Mantid/Testing/Data/SystemTest/osi89816.raw.md5 new file mode 100644 index 000000000000..1d1f2ffc663b --- /dev/null +++ b/Code/Mantid/Testing/Data/SystemTest/osi89816.raw.md5 @@ -0,0 +1 @@ +58d630faf6063c43946bf74f97e2b346 \ No newline at end of file diff --git a/Code/Mantid/Testing/Data/SystemTest/osi89817.raw.md5 b/Code/Mantid/Testing/Data/SystemTest/osi89817.raw.md5 new file mode 100644 index 000000000000..4f77994edff0 --- /dev/null +++ b/Code/Mantid/Testing/Data/SystemTest/osi89817.raw.md5 @@ -0,0 +1 @@ +8d11c55ef23f918a46bd948bf38285a5 \ No newline at end of file diff --git a/Code/Mantid/Testing/Data/SystemTest/osi92762_graphite002_red.nxs.md5 b/Code/Mantid/Testing/Data/SystemTest/osi92762_graphite002_red.nxs.md5 new file mode 100644 index 000000000000..0aa6d93d2d3c --- /dev/null +++ b/Code/Mantid/Testing/Data/SystemTest/osi92762_graphite002_red.nxs.md5 @@ -0,0 +1 @@ +20a9596d32dbea75141735b8ea9f37e9 \ No newline at end of file diff --git a/Code/Mantid/Testing/Data/SystemTest/osi92763_graphite002_red.nxs.md5 b/Code/Mantid/Testing/Data/SystemTest/osi92763_graphite002_red.nxs.md5 new file mode 100644 index 000000000000..f3f921533fcb --- /dev/null +++ b/Code/Mantid/Testing/Data/SystemTest/osi92763_graphite002_red.nxs.md5 @@ -0,0 +1 @@ +17d68730c8215fe8930f664b62b1dc5a \ No newline at end of file diff --git a/Code/Mantid/Testing/Data/SystemTest/osi97935_graphite002_red.nxs.md5 b/Code/Mantid/Testing/Data/SystemTest/osi97935_graphite002_red.nxs.md5 new file mode 100644 index 000000000000..c3e91533c15a --- /dev/null +++ b/Code/Mantid/Testing/Data/SystemTest/osi97935_graphite002_red.nxs.md5 @@ -0,0 +1 @@ +555b77ee572c01c6afd481dbd9031396 \ No newline at end of file diff --git a/Code/Mantid/Testing/Data/SystemTest/osi97935_graphite002_res.nxs.md5 b/Code/Mantid/Testing/Data/SystemTest/osi97935_graphite002_res.nxs.md5 new file mode 100644 index 000000000000..143aacb8045d --- /dev/null +++ b/Code/Mantid/Testing/Data/SystemTest/osi97935_graphite002_res.nxs.md5 @@ -0,0 +1 @@ +72d3814412d3b39ce613844f205ccf17 \ No newline at end of file diff --git a/Code/Mantid/Testing/Data/SystemTest/osi97935_graphite002_sqw.nxs.md5 b/Code/Mantid/Testing/Data/SystemTest/osi97935_graphite002_sqw.nxs.md5 new file mode 100644 index 000000000000..8ed9fd7d2be3 --- /dev/null +++ b/Code/Mantid/Testing/Data/SystemTest/osi97935_graphite002_sqw.nxs.md5 @@ -0,0 +1 @@ +c51d20458dd46ed70aa86f606b37c71f \ No newline at end of file diff --git a/Code/Mantid/Testing/Data/SystemTest/osi97936_graphite002_red.nxs.md5 b/Code/Mantid/Testing/Data/SystemTest/osi97936_graphite002_red.nxs.md5 new file mode 100644 index 000000000000..1422189316ab --- /dev/null +++ b/Code/Mantid/Testing/Data/SystemTest/osi97936_graphite002_red.nxs.md5 @@ -0,0 +1 @@ +c5e9021fca2b2b1b3c0e132dfa20f4ec \ No newline at end of file diff --git a/Code/Mantid/Testing/Data/SystemTest/osiris00101300.raw.md5 b/Code/Mantid/Testing/Data/SystemTest/osiris00101300.raw.md5 new file mode 100644 index 000000000000..cf161ac33374 --- /dev/null +++ b/Code/Mantid/Testing/Data/SystemTest/osiris00101300.raw.md5 @@ -0,0 +1 @@ +2e40b0764ec969baad2c653fe264d7d7 \ No newline at end of file diff --git a/Code/Mantid/Testing/Data/SystemTest/osiris_041_RES10.cal.md5 b/Code/Mantid/Testing/Data/SystemTest/osiris_041_RES10.cal.md5 new file mode 100644 index 000000000000..c7ab81f5411f --- /dev/null +++ b/Code/Mantid/Testing/Data/SystemTest/osiris_041_RES10.cal.md5 @@ -0,0 +1 @@ +25de3efd95d28f77e4df13891d54ee50 \ No newline at end of file diff --git a/Code/Mantid/Testing/Data/SystemTest/pearl_group_11_2_TT88.cal.md5 b/Code/Mantid/Testing/Data/SystemTest/pearl_group_11_2_TT88.cal.md5 new file mode 100644 index 000000000000..2519e386cb20 --- /dev/null +++ b/Code/Mantid/Testing/Data/SystemTest/pearl_group_11_2_TT88.cal.md5 @@ -0,0 +1 @@ +d681e34e8feb8927d82faba1cb08a606 \ No newline at end of file diff --git a/Code/Mantid/Testing/Data/SystemTest/pearl_offset_11_4.cal.md5 b/Code/Mantid/Testing/Data/SystemTest/pearl_offset_11_4.cal.md5 new file mode 100644 index 000000000000..951d301f4f16 --- /dev/null +++ b/Code/Mantid/Testing/Data/SystemTest/pearl_offset_11_4.cal.md5 @@ -0,0 +1 @@ +0176d3ee8e301d50ebf921b1e83b757e \ No newline at end of file diff --git a/Code/Mantid/Testing/Data/SystemTest/poldi2013n006903.hdf.md5 b/Code/Mantid/Testing/Data/SystemTest/poldi2013n006903.hdf.md5 new file mode 100644 index 000000000000..13d14cfcc638 --- /dev/null +++ b/Code/Mantid/Testing/Data/SystemTest/poldi2013n006903.hdf.md5 @@ -0,0 +1 @@ +cfceedf883c053498a993780118f4121 \ No newline at end of file diff --git a/Code/Mantid/Testing/Data/SystemTest/poldi2013n006904.hdf.md5 b/Code/Mantid/Testing/Data/SystemTest/poldi2013n006904.hdf.md5 new file mode 100644 index 000000000000..f6fdf03e9e9a --- /dev/null +++ b/Code/Mantid/Testing/Data/SystemTest/poldi2013n006904.hdf.md5 @@ -0,0 +1 @@ +ec6de73db6b2d70aba77bd236e2298b9 \ No newline at end of file diff --git a/Code/Mantid/Testing/Data/SystemTest/poldi2014n019874.hdf.md5 b/Code/Mantid/Testing/Data/SystemTest/poldi2014n019874.hdf.md5 new file mode 100644 index 000000000000..43ed5e225e34 --- /dev/null +++ b/Code/Mantid/Testing/Data/SystemTest/poldi2014n019874.hdf.md5 @@ -0,0 +1 @@ +422da5ed79328e8a825d9c87d95d644b \ No newline at end of file diff --git a/Code/Mantid/Testing/Data/SystemTest/poldi2014n019881.hdf.md5 b/Code/Mantid/Testing/Data/SystemTest/poldi2014n019881.hdf.md5 new file mode 100644 index 000000000000..c8ec606bad75 --- /dev/null +++ b/Code/Mantid/Testing/Data/SystemTest/poldi2014n019881.hdf.md5 @@ -0,0 +1 @@ +b7b4560ad521603017c84d4c4924a83c \ No newline at end of file diff --git a/Code/Mantid/Testing/Data/SystemTest/rings_103.map.md5 b/Code/Mantid/Testing/Data/SystemTest/rings_103.map.md5 new file mode 100644 index 000000000000..8b9f4368bd18 --- /dev/null +++ b/Code/Mantid/Testing/Data/SystemTest/rings_103.map.md5 @@ -0,0 +1 @@ +0e1a318682f455a6e82ed4b4f4439861 \ No newline at end of file diff --git a/Code/Mantid/Testing/Data/SystemTest/rings_113.map.md5 b/Code/Mantid/Testing/Data/SystemTest/rings_113.map.md5 new file mode 100644 index 000000000000..c0589876933f --- /dev/null +++ b/Code/Mantid/Testing/Data/SystemTest/rings_113.map.md5 @@ -0,0 +1 @@ +0586124e3d0a63e2902b2bd5ed179ded \ No newline at end of file diff --git a/Code/Mantid/Testing/Data/SystemTest/squaricn.castep.md5 b/Code/Mantid/Testing/Data/SystemTest/squaricn.castep.md5 new file mode 100644 index 000000000000..2ef8b29ca86e --- /dev/null +++ b/Code/Mantid/Testing/Data/SystemTest/squaricn.castep.md5 @@ -0,0 +1 @@ +916544e03a3dbc72bcd11f90c079c8a2 \ No newline at end of file diff --git a/Code/Mantid/Testing/Data/SystemTest/squaricn.phonon.md5 b/Code/Mantid/Testing/Data/SystemTest/squaricn.phonon.md5 new file mode 100644 index 000000000000..70e159441138 --- /dev/null +++ b/Code/Mantid/Testing/Data/SystemTest/squaricn.phonon.md5 @@ -0,0 +1 @@ +189ef0c498b11e77aef83e5bc9940289 \ No newline at end of file diff --git a/Code/Mantid/Testing/Data/SystemTest/van_gem59378_benchmark-0.nxs.md5 b/Code/Mantid/Testing/Data/SystemTest/van_gem59378_benchmark-0.nxs.md5 new file mode 100644 index 000000000000..57f6575c13c0 --- /dev/null +++ b/Code/Mantid/Testing/Data/SystemTest/van_gem59378_benchmark-0.nxs.md5 @@ -0,0 +1 @@ +3b6274d1a2441abc3b4fcac39ad6f2ec \ No newline at end of file diff --git a/Code/Mantid/Testing/Data/SystemTest/van_gem59378_benchmark-1.nxs.md5 b/Code/Mantid/Testing/Data/SystemTest/van_gem59378_benchmark-1.nxs.md5 new file mode 100644 index 000000000000..74a424044c26 --- /dev/null +++ b/Code/Mantid/Testing/Data/SystemTest/van_gem59378_benchmark-1.nxs.md5 @@ -0,0 +1 @@ +e12bf9f3bb9c7781cbb746a47ed8f260 \ No newline at end of file diff --git a/Code/Mantid/Testing/Data/SystemTest/van_gem59378_benchmark-2.nxs.md5 b/Code/Mantid/Testing/Data/SystemTest/van_gem59378_benchmark-2.nxs.md5 new file mode 100644 index 000000000000..989ecf5c4304 --- /dev/null +++ b/Code/Mantid/Testing/Data/SystemTest/van_gem59378_benchmark-2.nxs.md5 @@ -0,0 +1 @@ +6a145e40e18d0816635edf43e1b7c1c8 \ No newline at end of file diff --git a/Code/Mantid/Testing/Data/SystemTest/van_gem59378_benchmark-3.nxs.md5 b/Code/Mantid/Testing/Data/SystemTest/van_gem59378_benchmark-3.nxs.md5 new file mode 100644 index 000000000000..4d0ee1495ca7 --- /dev/null +++ b/Code/Mantid/Testing/Data/SystemTest/van_gem59378_benchmark-3.nxs.md5 @@ -0,0 +1 @@ +e19d6e5a4b0e855186e0f7a772f4e51a \ No newline at end of file diff --git a/Code/Mantid/Testing/Data/SystemTest/van_gem59378_benchmark-4.nxs.md5 b/Code/Mantid/Testing/Data/SystemTest/van_gem59378_benchmark-4.nxs.md5 new file mode 100644 index 000000000000..29502a6e1d07 --- /dev/null +++ b/Code/Mantid/Testing/Data/SystemTest/van_gem59378_benchmark-4.nxs.md5 @@ -0,0 +1 @@ +adf9cad5597d753af2385d0c89f39db9 \ No newline at end of file diff --git a/Code/Mantid/Testing/Data/SystemTest/van_gem59378_benchmark-5.nxs.md5 b/Code/Mantid/Testing/Data/SystemTest/van_gem59378_benchmark-5.nxs.md5 new file mode 100644 index 000000000000..ab05d34df815 --- /dev/null +++ b/Code/Mantid/Testing/Data/SystemTest/van_gem59378_benchmark-5.nxs.md5 @@ -0,0 +1 @@ +e4adfe73c353db095aa40d2981edb816 \ No newline at end of file diff --git a/Code/Mantid/Testing/Data/SystemTest/vana3123-1foc-SS.nx5.md5 b/Code/Mantid/Testing/Data/SystemTest/vana3123-1foc-SS.nx5.md5 new file mode 100644 index 000000000000..f762334deaff --- /dev/null +++ b/Code/Mantid/Testing/Data/SystemTest/vana3123-1foc-SS.nx5.md5 @@ -0,0 +1 @@ +4e8ba7a242fbe20843dd58f641af9440 \ No newline at end of file diff --git a/Code/Mantid/Testing/Data/SystemTest/wish_grouping_noends2_no_offsets_nov2009.cal.md5 b/Code/Mantid/Testing/Data/SystemTest/wish_grouping_noends2_no_offsets_nov2009.cal.md5 new file mode 100644 index 000000000000..f27ff00c0cc6 --- /dev/null +++ b/Code/Mantid/Testing/Data/SystemTest/wish_grouping_noends2_no_offsets_nov2009.cal.md5 @@ -0,0 +1 @@ +98ffbb1ed2169a07affc36b0180788d1 \ No newline at end of file diff --git a/Code/Mantid/Testing/Data/UnitTest/savu_test_data_process03.nxs.md5 b/Code/Mantid/Testing/Data/UnitTest/savu_test_data_process03.nxs.md5 new file mode 100644 index 000000000000..293777d97df1 --- /dev/null +++ b/Code/Mantid/Testing/Data/UnitTest/savu_test_data_process03.nxs.md5 @@ -0,0 +1 @@ +ffd6f39c0f70d4f56e2ea6abca229d8e diff --git a/Code/Mantid/Testing/SystemTests/lib/systemtests/stresstesting.py b/Code/Mantid/Testing/SystemTests/lib/systemtests/stresstesting.py index 31aa6f54b281..cfc73916b61a 100644 --- a/Code/Mantid/Testing/SystemTests/lib/systemtests/stresstesting.py +++ b/Code/Mantid/Testing/SystemTests/lib/systemtests/stresstesting.py @@ -119,8 +119,12 @@ def reportResult(self, name, value): ''' Send a result to be stored as a name,value pair ''' - print self.PREFIX + self.DELIMITER + name + self.DELIMITER + str(value) + '\n', - + output = self.PREFIX + self.DELIMITER + name + self.DELIMITER + str(value) + "\n" + # Ensure that this is all printed together and not mixed with stderr + sys.stdout.flush() + sys.stdout.write(output) + sys.stdout.flush() + def __verifyRequiredFile(self, filename): '''Return True if the specified file name is findable by Mantid.''' from mantid.api import FileFinder @@ -215,7 +219,13 @@ def validateASCII(self): """ Validate ASCII files using difflib. """ + from mantid.api import FileFinder (measured, expected) = self.validate() + if not os.path.isabs(measured): + measured = FileFinder.Instance().getFullPath(measured) + if not os.path.isabs(expected): + expected = FileFinder.Instance().getFullPath(expected) + measured = self.__prepASCIIFile(measured) expected = self.__prepASCIIFile(expected) diff --git a/Code/Mantid/Testing/SystemTests/scripts/mantidinstaller.py b/Code/Mantid/Testing/SystemTests/scripts/mantidinstaller.py index 88a6aeb13457..1723b34f29ff 100644 --- a/Code/Mantid/Testing/SystemTests/scripts/mantidinstaller.py +++ b/Code/Mantid/Testing/SystemTests/scripts/mantidinstaller.py @@ -69,7 +69,7 @@ def get_installer(package_dir, do_install=True): dist = platform.dist() if dist[0] == 'Ubuntu': return DebInstaller(package_dir, do_install) - elif dist[0] == 'redhat': + elif dist[0].lower() == 'redhat' or dist[0].lower() == 'fedora': return RPMInstaller(package_dir, do_install) else: scriptfailure('Unknown Linux flavour: %s' % str(dist)) diff --git a/Code/Mantid/Testing/SystemTests/tests/analysis/ARCSReductionTest.py b/Code/Mantid/Testing/SystemTests/tests/analysis/ARCSReductionTest.py new file mode 100644 index 000000000000..27fb1d5decd0 --- /dev/null +++ b/Code/Mantid/Testing/SystemTests/tests/analysis/ARCSReductionTest.py @@ -0,0 +1,82 @@ +""" +System test for ARCS reduction +""" + +from mantid.simpleapi import * +import os +import stresstesting +from numpy import * + +class ARCSReductionTest(stresstesting.MantidStressTest): + + def requiredFiles(self): + return ["ARCS_23961_event.nxs","WBARCS.nxs"] + + def requiredMemoryMB(self): + return 4000 + + def cleanup(self): + if os.path.exists(self.nxspeFile): + os.remove(self.nxspeFile) + if os.path.exists(self.vanFile1): + os.remove(self.vanFile1) + if os.path.exists(self.vanFile0): + os.remove(self.vanFile0) + return True + + + def runTest(self): + self.vanFile1=os.path.join(config.getString('defaultsave.directory'),'ARCSvan_1.nxs') + self.vanFile0=os.path.join(config.getString('defaultsave.directory'),'ARCSvan_0.nxs') + self.nxspeFile=os.path.join(config.getString('defaultsave.directory'),'ARCSsystemtest.nxspe') + config['default.facility']="SNS" + DgsReduction( + SampleInputFile="ARCS_23961_event.nxs", + OutputWorkspace="reduced", + IncidentBeamNormalisation="ByCurrent", + DetectorVanadiumInputFile="WBARCS.nxs", + UseBoundsForDetVan=True, + DetVanIntRangeLow=0.35, + DetVanIntRangeHigh=0.75, + DetVanIntRangeUnits="Wavelength", + SaveProcessedDetVan=True, + SaveProcDetVanFilename=self.vanFile0, + ) + DgsReduction( + SampleInputFile="ARCS_23961_event.nxs", + OutputWorkspace="reduced", + IncidentBeamNormalisation="ByCurrent", + DetectorVanadiumInputFile="WBARCS.nxs", + UseBoundsForDetVan=True, + DetVanIntRangeLow=0.35, + DetVanIntRangeHigh=0.75, + DetVanIntRangeUnits="Wavelength", + MedianTestLevelsUp=1., + SaveProcessedDetVan=True, + SaveProcDetVanFilename=self.vanFile1, + ) + + Ei=mtd["reduced"].run().get("Ei").value + SaveNXSPE(InputWorkspace="reduced",Filename=self.nxspeFile,Efixed=Ei,psi=0,KiOverKfScaling=True) + + def validate(self): + #test vanadium file + self.assertTrue(os.path.exists(self.vanFile0)) + self.assertTrue(os.path.exists(self.vanFile1)) + van0=Load(self.vanFile0) + van1=Load(self.vanFile1) + m0=ExtractMask(van0) + m1=ExtractMask(van1) + self.assertGreaterThan(len(m0[1]),len(m1[1])) #levelsUp=1 should have less pixels masked + DeleteWorkspace("m0") + DeleteWorkspace("m1") + DeleteWorkspace(van0) + DeleteWorkspace(van1) + self.assertTrue(os.path.exists(self.nxspeFile)) + nxspe=LoadNXSPE(self.nxspeFile) + self.disableChecking.append('Instrument') + + return 'nxspe','ARCSsystemtest.nxs' + + + diff --git a/Code/Mantid/Testing/SystemTests/tests/analysis/BASISAutoReduction.py b/Code/Mantid/Testing/SystemTests/tests/analysis/BASISAutoReduction.py new file mode 100644 index 000000000000..9c40107a8674 --- /dev/null +++ b/Code/Mantid/Testing/SystemTests/tests/analysis/BASISAutoReduction.py @@ -0,0 +1,53 @@ +""" +System Test for BASIS autoreduction +""" +from mantid.simpleapi import * + +import stresstesting +import shutil +import os + +class BASISAutoReductionTest(stresstesting.MantidStressTest): + + def requiredFiles(self): + return ['BSS_13387_event.nxs'] + + def cleanup(self): + return True + + def runTest(self): + idfdir = config['instrumentDefinition.directory'] + autows = 'data_ws' + autows_monitor = 'monitor_ws' + Load(Filename='BSS_13387_event.nxs', OutputWorkspace=autows) + LoadMask(Instrument='BASIS', OutputWorkspace='BASIS_MASK', InputFile='BASIS_AutoReduction_Mask.xml') + MaskDetectors(Workspace=autows, DetectorList="5,49,69,113,133,177,197,241,261,305,325,369,389,433,453,497,517,561,581,625,645,689,709,753,773,817,837,881,901,945,965,1009,1029,1073,1093,1137,1157,1201,1221,1265,1285,1329,1349,1393,1413,1457,1477,1521,1541,1585,1605,1649,1669,1713,1733,1777,1797,1841,1861,1905,1925,1969,1989,2033,2053,2097,2117,2161,2181,2225,2245,2289,2309,2353,2373,2417,2437,2481,2501,2545,2565,2609,2629,2673,2693,2737,2757,2801,2821,2865,2885,2929,2949,2993,3013,3057,3077,3121,3141,3185,3205,3249,3269,3313,3333,3377,3397,3441,3461,3505,3525,3569,3589-3633,3653-3697,3717-3761,3781-3825,3845-3889,3909-3953,3973-4017,4037-4081,4110,4154,4174,4218,4238,4282,4302,4346,4366,4410,4430,4474,4494,4538,4558,4602,4622,4666,4686,4730,4750,4794,4814,4858,4878,4922,4942,4986,5006,5050,5070,5114,5134,5178,5198,5242,5262,5306,5326,5370,5390,5434,5454,5498,5518,5562,5582,5626,5646,5690,5710,5754,5774,5818,5838,5882,5902,5946,5966,6010,6030,6074,6094,6138,6158,6202,6222,6266,6286,6330,6350,6394,6414,6458,6478,6522,6542,6586,6606,6650,6670,6714,6734,6778,6798,6842,6862,6906,6926,6970,6990,7034,7054,7098,7118,7162,7182,7226,7246,7290,7310,7354,7374,7418,7438,7482,7502,7546,7566,7610,7630,7674,7694-7738,7758-7802,7822-7866,7886-7930,7950-7994,8014-8058,8078-8122,8142-8186,8192-15871") #MaskedWorkspace='BASIS_MASK') + ModeratorTzeroLinear(InputWorkspace=autows,OutputWorkspace=autows) + LoadParameterFile(Workspace=autows, Filename=os.path.join(idfdir,'BASIS_silicon_111_Parameters.xml')) + LoadNexusMonitors(Filename='BSS_13387_event.nxs', OutputWorkspace=autows_monitor) + Rebin(InputWorkspace=autows_monitor,OutputWorkspace=autows_monitor,Params='10') + ConvertUnits(InputWorkspace=autows_monitor, OutputWorkspace=autows_monitor, Target='Wavelength') + OneMinusExponentialCor(InputWorkspace=autows_monitor, OutputWorkspace=autows_monitor, C='0.20749999999999999', C1='0.001276') + Scale(InputWorkspace=autows_monitor, OutputWorkspace=autows_monitor, Factor='9.9999999999999995e-07') + ConvertUnits(InputWorkspace=autows, OutputWorkspace=autows, Target='Wavelength', EMode='Indirect') + RebinToWorkspace(WorkspaceToRebin=autows, WorkspaceToMatch=autows_monitor, OutputWorkspace=autows) + Divide(LHSWorkspace=autows, RHSWorkspace=autows_monitor, OutputWorkspace=autows) + ConvertUnits(InputWorkspace=autows, OutputWorkspace=autows, Target='DeltaE', EMode='Indirect') + CorrectKiKf(InputWorkspace=autows, OutputWorkspace=autows,EMode='Indirect') + + Rebin(InputWorkspace=autows, OutputWorkspace=autows, Params='-0.12,0.0004,0.12') + #GroupDetectors(InputWorkspace=autows, OutputWorkspace=autows, MapFile='/SNS/BSS/shared/autoreduce/BASIS_Grouping.xml', Behaviour='Sum') + SofQW3(InputWorkspace=autows, OutputWorkspace=autows+'_sqw', QAxisBinning='0.2,0.2,2.0', EMode='Indirect', EFixed='2.082') + #SaveDaveGrp(Filename=dave_grp_filename, InputWorkspace=autows+'_sqw', ToMicroEV=True) + #SaveNexus(Filename="basis_auto_sqw.nxs", InputWorkspace=autows+'_sqw') + + def validate(self): + # Need to disable checking of the Spectra-Detector map because it isn't + # fully saved out to the nexus file; some masked detectors should be picked + # up with by the mask values in the spectra + self.tolerance = 1e-7 + self.disableChecking.append('Axes') + self.disableChecking.append('SpectraMap') + self.disableChecking.append('Instrument') + return 'data_ws_sqw','BASISAutoReduction.nxs' + diff --git a/Code/Mantid/Testing/SystemTests/tests/analysis/BuildSQWTest.py b/Code/Mantid/Testing/SystemTests/tests/analysis/BuildSQWTest.py new file mode 100644 index 000000000000..27fd99db6c9b --- /dev/null +++ b/Code/Mantid/Testing/SystemTests/tests/analysis/BuildSQWTest.py @@ -0,0 +1,157 @@ +""" + Defines a system test for converting a set of reduced direct inelastic data + to a single SQW file. + + The test requires as input the set of reduced files, which are ~16Gb along with + the result file that is ~30Gb. The files are not included with the standard + repository & required to be accessible from any machine that wishes to run the test. +""" +import stresstesting +from mantid.simpleapi import * + +import os + +# allow for multiple locations +FILE_LOCATIONS = ["/isis/mantid/localtestdata/"]#,"d:/Data/MantidSystemTests/BigData/Dropbox/LoadSQW"] + +class BuildSQWTest(stresstesting.MantidStressTest): + + _startrun = 15058 + _endrun = 15178 + _input_data = [] + _input_location = None + _created_files = [] + + def __init__(self): + super(BuildSQWTest, self).__init__() + prefix = "MAP" + ext = ".nxspe" + # MAP*.nxspe data files + self._input_data = ["%s%d%s" % (prefix,n,ext) for n in range(self._startrun,self._endrun+1)] + + def skipTests(self): + def check_dir(loc): + for filename in self._input_data: + path = os.path.join(loc, filename) + if not os.path.exists(path): + return False + return True + # end nested function + + all_found = False + for location in FILE_LOCATIONS: + if check_dir(location): + self._input_location = location + all_found = True + break + + skip = (not all_found) + return skip + + def runTest(self): + conversion_params = {} + conversion_params['QDimensions'] = 'Q3D' + conversion_params['dEAnalysisMode'] = 'Direct' + conversion_params['Q3DFrames'] = 'HKL' + conversion_params['QConversionScales'] = 'HKL' + conversion_params['PreprocDetectorsWS'] = '_preprocessed_detectors' + conversion_params['MinValues'] = '-7,-7,-7.,-72.0' + conversion_params['MaxValues'] = '7.,7.,7.,382.0' + conversion_params['SplitInto'] = 50 + conversion_params['MaxRecursionDepth'] = 1 + conversion_params['MinRecursionDepth'] = 1 + + self._created_files = [] + for source in self._input_data: + source_path = os.path.join(self._input_location, source) + target = os.path.join(config["defaultsave.directory"], "MD" + source.rstrip(".nxspe") + ".nxs") + # Make sure the target doesn't exist from a previous test + if os.path.exists(target): + os.remove(target) + + print "Converting '%s' to '%s' " % (source_path,target) + _cur_spe_ws = LoadNXSPE(Filename=source_path) + SetUB(Workspace=_cur_spe_ws,a='2.87',b='2.87',c='2.87') + # rotated by proper number of degrees around axis Y + # sample log Psi should already be there + SetGoniometer(Workspace=_cur_spe_ws,Axis0='Psi,0,1,0,1') + + conversion_params['InputWorkspace'] = _cur_spe_ws + _cur_md_ws = ConvertToMD(**conversion_params) + + SaveMD(InputWorkspace=_cur_md_ws,Filename=target) + self._created_files.append(target) + DeleteWorkspace(_cur_spe_ws) + DeleteWorkspace(_cur_md_ws) + # end conversion loop + + # Do the final merge + sqw_file = os.path.join(config["defaultsave.directory"],"BuildSQWTestCurrent.nxs") + finalSQW = MergeMDFiles(",".join(self._created_files),OutputFilename=sqw_file,Parallel='0') + self._created_files.append(sqw_file) + + def validate(self): + # LoadMD is unable to load the merged output file. See ticket #8480. + # At the moment this test is useful for benchmarking the conversion so it exists purely + # for timing purposes until #8480 is fixed + return True + + def cleanup(self): + for filename in self._created_files: + try: + os.remove(filename) + except OSError,exc: + mantid.logger.warning("Unable to remove created file '%s'" % filename) + +class LoadSQW_FileBasedTest(BuildSQWTest): + """ The test checks loading MD workspace from SQW file when target file is file based""" + + def __init__(self): + + self._input_data = ["Test22meV2f.sqw","Test22meVMD.nxs"] + + def runTest(self): + + MDws_file = os.path.join(config["defaultsave.directory"],"LoadSQWTestFileBased.nxs") + sqw_file = os.path.join(self._input_location,self._input_data[0]) + + wsMD=LoadSQW(Filename=sqw_file, OutputFilename=MDws_file) + + self._created_files=MDws_file; + + + def validate(self): + """Compare file-based MD files """ + ref_file = os.path.join(self._input_location, self._input_data[1]) + Reference=LoadMD(Filename=ref_file, FileBackEnd=True, Memory=100) + rez = CompareMDWorkspaces(Workspace1="wsMD",Workspace2=Reference,Tolerance=1.e-5,CheckEvents=False,IgnoreBoxID=False) + + DeleteWorkspace("wsMD"); + + return rez[0]; + +class LoadSQW_MemBasedTest(BuildSQWTest): + """ The test checks loading MD workspace from SQW file when target file is file based""" + + def __init__(self): + + self._input_data = ["Test22meV2f.sqw","Test22meVMD.nxs"] + + def runTest(self): + + sqw_file = os.path.join(self._input_location,self._input_data[0]) + + wsMD=LoadSQW(Filename=sqw_file) + + self._created_files=[]; + + + def validate(self): + """Compare memory-based vs file based MD workspaces """ + ref_file = os.path.join(self._input_location, self._input_data[1]) + Reference=LoadMD(Filename=ref_file, FileBackEnd=True, Memory=100) + rez = CompareMDWorkspaces(Workspace1="wsMD",Workspace2=Reference,Tolerance=1.e-5,CheckEvents=False,IgnoreBoxID=False) + + DeleteWorkspace("wsMD"); + + return rez[0]; \ No newline at end of file diff --git a/Code/Mantid/Testing/SystemTests/tests/analysis/CNCSReductionTest.py b/Code/Mantid/Testing/SystemTests/tests/analysis/CNCSReductionTest.py new file mode 100644 index 000000000000..60397945a8b3 --- /dev/null +++ b/Code/Mantid/Testing/SystemTests/tests/analysis/CNCSReductionTest.py @@ -0,0 +1,78 @@ +""" +System test for CNCS reduction +""" + +from mantid.simpleapi import * +import os +import stresstesting + +class CNCSReductionTest(stresstesting.MantidStressTest): + + def requiredFiles(self): + return ["CNCS_51936_event.nxs","CNCS_23936_event.nxs","CNCS_23937_event.nxs"] + + def requiredMemoryMB(self): + return 4000 + + def cleanup(self): + if os.path.exists(self.groupingFile): + os.remove(self.groupingFile) + if os.path.exists(self.parFile): + os.remove(self.parFile) + if os.path.exists(self.nxspeFile): + os.remove(self.nxspeFile) + if os.path.exists(self.vanFile): + os.remove(self.vanFile) + return True + + + def runTest(self): + self.groupingFile=os.path.join(config.getString('defaultsave.directory'),'CNCS_powder_group.xml') + self.parFile=os.path.join(config.getString('defaultsave.directory'),'CNCS_powder_group.par') + self.nxspeFile=os.path.join(config.getString('defaultsave.directory'),'CNCS_powder_group.nxspe') + self.vanFile=os.path.join(config.getString('defaultsave.directory'),'van.nx5') + + config['default.facility']="SNS" + Load(Filename='CNCS_23936-23937',OutputWorkspace='sum') + GenerateGroupingPowder(InputWorkspace="sum",AngleStep=0.5,GroupingFilename=self.groupingFile) + Ei=mtd['sum'].getRun()['EnergyRequest'].firstValue() + tib=SuggestTibCNCS(Ei) + erange=str(-Ei)+','+str(0.01*Ei)+','+str(0.95*Ei) + + DgsReduction( + SampleInputWorkspace="sum", + OutputWorkspace="reduced", + EnergyTransferRange="-0.2,0.05,2.2", + GroupingFile=self.groupingFile, + IncidentBeamNormalisation="ByCurrent", + TimeIndepBackgroundSub=True, + TibTofRangeStart=tib[0], + TibTofRangeEnd=tib[1], + DetectorVanadiumInputFile="CNCS_51936_event.nxs", + UseBoundsForDetVan=True, + DetVanIntRangeLow=52000.0, + DetVanIntRangeHigh=53000.0, + DetVanIntRangeUnits="TOF", + SaveProcessedDetVan=True, + SaveProcDetVanFilename=self.vanFile, + ) + + rotationdevice="SERotator2" + psi=mtd["reduced"].run().get(rotationdevice).value[0] + SaveNXSPE(InputWorkspace="reduced",Filename=self.nxspeFile,Efixed=Ei,psi=psi,KiOverKfScaling=True,ParFile=self.parFile) + + def validate(self): + #test vanadium file + self.assertTrue(os.path.exists(self.vanFile)) + van=Load(self.vanFile) + self.assertEqual(van.blocksize(),1) + self.assertEqual(van.getNumberHistograms(),51200) + DeleteWorkspace(van) + self.assertTrue(os.path.exists(self.nxspeFile)) + nxspe=LoadNXSPE(self.nxspeFile) + self.disableChecking.append('Instrument') + + return 'nxspe','CNCSReduction_TIBasEvents.nxs' + + + diff --git a/Code/Mantid/Testing/SystemTests/tests/analysis/CRISPLoadingTest.py b/Code/Mantid/Testing/SystemTests/tests/analysis/CRISPLoadingTest.py new file mode 100644 index 000000000000..885c8ddd3502 --- /dev/null +++ b/Code/Mantid/Testing/SystemTests/tests/analysis/CRISPLoadingTest.py @@ -0,0 +1,25 @@ +from LoadAndCheckBase import * + +''' +Test File loading and basic data integrity checks of CRISP data in Mantid. +''' +class CRISPLoadingTest(LoadAndCheckBase): + + def __init__(self): + super(self.__class__,self).__init__() + self.disableChecking.append("Instrument") + + def get_raw_workspace_filename(self): + return "CSP85423.raw" + + def get_nexus_workspace_filename(self): + return "CSP85423.nxs" + + def get_expected_number_of_periods(self): + return 2 + + def get_integrated_reference_workspace_filename(self): + return "CSP85423_1Integrated.nxs" + + def get_expected_instrument_name(self): + return "CRISP" \ No newline at end of file diff --git a/Code/Mantid/Testing/SystemTests/tests/analysis/CalibrateRectangularDetector_Test.py b/Code/Mantid/Testing/SystemTests/tests/analysis/CalibrateRectangularDetector_Test.py new file mode 100644 index 000000000000..152bc3cdb2f4 --- /dev/null +++ b/Code/Mantid/Testing/SystemTests/tests/analysis/CalibrateRectangularDetector_Test.py @@ -0,0 +1,109 @@ +import stresstesting +from mantid.simpleapi import * +from time import strftime +import os + +def _skip_test(): + """Helper function to determine if we run the test""" + import platform + + # Only runs on RHEL6 at the moment + if "Linux" not in platform.platform(): + return True + flavour = platform.linux_distribution()[2] + if flavour == 'Santiago': # Codename for RHEL6 + return False # Do not skip + else: + return True + +class PG3Calibration(stresstesting.MantidStressTest): + def cleanup(self): + os.remove(self.saved_cal_file) + + def skipTests(self): + return _skip_test() + + def requiredFiles(self): + files = ["PG3_2538_event.nxs"] + return files + + def requiredMemoryMB(self): + """Requires 3Gb""" + return 3000 + + def runTest(self): + # determine where to save + savedir = os.path.abspath(os.path.curdir) + + # run the actual code + output = CalibrateRectangularDetectors(OutputDirectory = savedir, SaveAs = 'calibration', FilterBadPulses = True, + GroupDetectorsBy = 'All', DiffractionFocusWorkspace = False, Binning = '0.5, -0.0004, 2.5', + MaxOffset=0.01, PeakPositions = '.6866,.7283,.8185,.8920,1.0758,1.2615,2.0599', + CrossCorrelation = False, Instrument = 'PG3', RunNumber = '2538', Extension = '_event.nxs') + + if isinstance(output, basestring): + self.saved_cal_file = output + else: + raise NotImplementedError("Output from CalibrateRectangularDetectors is NOT string for calibration file name!") + + # load saved cal file + LoadCalFile(InputWorkspace="PG3_2538_calibrated", CalFileName=self.saved_cal_file, WorkspaceName="PG3_2538", + MakeGroupingWorkspace=False) + MaskDetectors(Workspace="PG3_2538_offsets",MaskedWorkspace="PG3_2538_mask") + # load golden cal file + LoadCalFile(InputWorkspace="PG3_2538_calibrated", CalFileName="PG3_golden.cal", WorkspaceName="PG3_2538_golden", + MakeGroupingWorkspace=False) + MaskDetectors(Workspace="PG3_2538_golden_offsets",MaskedWorkspace="PG3_2538_golden_mask") + + def validateMethod(self): + return "ValidateWorkspaceToWorkspace" + + def validate(self): + self.tolerance = 2.0e-4 + return ('PG3_2538_offsets','PG3_2538_golden_offsets') + +class PG3CCCalibration(stresstesting.MantidStressTest): + def cleanup(self): + os.remove(self.saved_cal_file) + + def skipTests(self): + return _skip_test() + + def requiredFiles(self): + files = ["PG3_2538_event.nxs"] + return files + + def requiredMemoryMB(self): + """Requires 3Gb""" + return 3000 + + def runTest(self): + # determine where to save + savedir = os.path.abspath(os.path.curdir) + + # run the actual code + output = CalibrateRectangularDetectors(OutputDirectory = savedir, SaveAs = 'calibration', FilterBadPulses = True, + GroupDetectorsBy = 'All', DiffractionFocusWorkspace = False, Binning = '0.5, -0.0004, 2.5', + MaxOffset=0.01, PeakPositions = '0.7282933,1.261441',DetectorsPeaks = '17,6', + CrossCorrelation = True, Instrument = 'PG3', RunNumber = '2538', Extension = '_event.nxs') + + if isinstance(output, basestring): + self.saved_cal_file = output + else: + raise NotImplementedError("Output from CalibrateRectangularDetectors is NOT string for calibration file name!") + + # load saved cal file + LoadCalFile(InputWorkspace="PG3_2538_calibrated", CalFileName=self.saved_cal_file, WorkspaceName="PG3_2538", + MakeGroupingWorkspace=False) + MaskDetectors(Workspace="PG3_2538_offsets",MaskedWorkspace="PG3_2538_mask") + # load golden cal file + LoadCalFile(InputWorkspace="PG3_2538_calibrated", CalFileName="PG3_goldenCC.cal", WorkspaceName="PG3_2538_golden", + MakeGroupingWorkspace=False) + MaskDetectors(Workspace="PG3_2538_golden_offsets",MaskedWorkspace="PG3_2538_golden_mask") + + def validateMethod(self): + return "ValidateWorkspaceToWorkspace" + + def validate(self): + self.tolerance = 1.0e-4 + return ('PG3_2538_offsets','PG3_2538_golden_offsets') diff --git a/Code/Mantid/Testing/SystemTests/tests/analysis/CodeConventions.py b/Code/Mantid/Testing/SystemTests/tests/analysis/CodeConventions.py new file mode 100644 index 000000000000..ea29c2d0a312 --- /dev/null +++ b/Code/Mantid/Testing/SystemTests/tests/analysis/CodeConventions.py @@ -0,0 +1,216 @@ +import stresstesting +import mantid +from mantid.simpleapi import * +import re + +MAX_ALG_LEN = 40 # TODO convention says 20 is the maximum + +SPECIAL = ["InputWorkspace", "OutputWorkspace", "Workspace", + "ReductionProperties"] +SPECIAL_UPPER = [name.upper for name in SPECIAL] + +# TODO this list should be empty +ALG_BAD_PARAMS = { + "CalculateUMatrix(v1)":("a", "b", "c", "alpha", "beta", "gamma"), + "ConvertToMD(v1)":("dEAnalysisMode"), + "ConvertToMDMinMaxLocal(v1)":("dEAnalysisMode"), + "ConvertToMDMinMaxGlobal(v1)":("dEAnalysisMode"), + "FindUBUsingLatticeParameters(v1)":("a", "b", "c", "alpha", "beta", "gamma"), + "IndexSXPeaks(v1)":("a", "b", "c", "alpha", "beta", "gamma", "dTolerance"), + "ModeratorTzero(v1)":("tolTOF"), + "MuscatFunc(v1)":("dQ", "dW"), + "OptimizeCrystalPlacement(v1)":("nPeaks", "nParams", "nIndexed"), + "PDFFourierTransform(v1)":("rho0"), + "PoldiAutoCorrelation(v5)":("wlenmin", "wlenmax"), + "PoldiLoadChopperSlits(v1)":("nbLoadedSlits"), + "PoldiLoadSpectra(v1)":("nbSpectraLoaded"), + "PoldiProjectRun(v1)":("wlenmin", "wlenmax"), + "PoldiRemoveDeadWires(v1)":("nbExcludedWires", "nbAuteDeadWires"), + "SaveIsawQvector(v1)":("Qx_vector", "Qy_vector", "Qz_vector"), + "SCDCalibratePanels(v1)":("a", "b", "c", "alpha", "beta", "gamma", + "useL0", "usetimeOffset", "usePanelWidth", + "usePanelHeight", "usePanelPosition", + "usePanelOrientation", "tolerance", + "MaxPositionChange_meters"), + "SetUB(v1)":("a", "b", "c", "alpha", "beta", "gamma", "u", "v"), + "ViewBOA(v1)":("CD-Distance"), + "PoldiCreatePeaksFromCell(v1)":("a", "b", "c", "alpha", "beta", "gamma") + } + +# TODO this list should be empty +FUNC_BAD_NAME = ("Muon_ExpDecayOscTest") + +# TODO this list should be empty +FUNC_BAD_PARAMS = { + "Bk2BkExpConvPV":("TOF_h"), + "CubicSpline":("y0", "y1", "y2"), + "DiffRotDiscreteCircle":("f0.Height", "f0.Radius"), + "DiffSphere":("f0.Height", "f0.Radius"), + "LatticeErrors":("p0", "p1", "p2", "p3", "p4", "p5"), + "Muon_ExpDecayOscTest":("lambda", "frequency", "phi"), + "SCDPanelErrors":("f0_detWidthScale", "f0_detHeightScale", + "f0_Xoffset", "f0_Yoffset", "f0_Zoffset", + "f0_Xrot", "f0_Yrot", "f0_Zrot", + "l0", "t0"), + "StretchedExpFT":("height", "tau", "beta") + } + +class Algorithms(stresstesting.MantidStressTest): + def verifyAlgName(self, name): + if not self.algRegExp.match(name): + print "Algorithm " + name + " has a name that violates conventions" + return False + + if bool(len(name) > MAX_ALG_LEN): + print "%s has a name that is longer than " % name, \ + "%d characters (%d > %d)" % (MAX_ALG_LEN, len(name), MAX_ALG_LEN) + return False + + # passed all of the checks + return True + + def verifyCategories(self, name, categories): + if len(categories) <= 0: + print name + " has no categories" + + for category in categories: + if not self.categoryRegExp.match(category): + print name + " has a bad category " + category + return False + + return True + + def checkAllowed(self, alg_descr, name): + if alg_descr not in ALG_BAD_PARAMS.keys(): + return False + + return name in ALG_BAD_PARAMS[alg_descr] + + def verifyProperty(self, alg_descr, name): + upper = name.upper() + if (upper in SPECIAL_UPPER) and (not name in SPECIAL): + index = SPECIAL_UPPER.index(upper) + print alg_descr + " property (" + name + ") has special name "\ + + "with wrong case: " + name + " should be " + SPECIAL[index] + return False + + if not self.paramRegExp.match(name): + if not self.checkAllowed(alg_descr, name): + print alg_descr + " property (" + name +") violates conventions" + return False + + # passed all of the checks + return True + + def runTest(self): + self.__ranOk = 0 + self.algRegExp = re.compile(r'^[A-Z][a-zA-Z0-9]+$') + self.paramRegExp = re.compile(r'^[A-Z][a-zA-Z0-9]*$') + self.categoryRegExp = re.compile(r'^([A-Z][a-zA-Z]+\\?)+$') + + algs = AlgorithmFactory.getRegisteredAlgorithms(True) + + for (name, versions) in algs.iteritems(): + if not self.verifyAlgName(name): + self.__ranOk += 1 + continue + for version in versions: + # get an instance + alg = mantid.AlgorithmManager.create(name, version) + alg_descr = "%s(v%d)" % (name, version) + + # verify the categories + if not self.verifyCategories(alg_descr, alg.categories()): + self.__ranOk += 1 + + # verify the properties + props = alg.getProperties() + for prop in props: + if not self.verifyProperty(alg_descr, prop.name): + self.__ranOk += 1 + + + def validate(self): + if self.__ranOk > 0: + print "Found %d errors. Coding conventions found at" % self.__ranOk,\ + "http://www.mantidproject.org/Mantid_Standards" + return False + + return True + +class FitFunctions(stresstesting.MantidStressTest): + def verifyFuncName(self, name): + if name in FUNC_BAD_NAME: + return True + + if not self.funcRegExp.match(name): + print "Function " + name + " has a name that violates conventions" + return False + + if bool(len(name) > MAX_ALG_LEN): + print "%s has a name that is longer than " % name, \ + "%d characters (%d > %d)" % (MAX_ALG_LEN, len(name), MAX_ALG_LEN) + return False + + # passed all of the checks + return True + + def verifyCategories(self, name, categories): + if len(categories) <= 0: + print name + " has no categories" + + for category in categories: + # TODO remove the special case + if category == "C++ User Defined": + return True + + if not self.categoryRegExp.match(category): + print name + " has a bad category " + category + return False + + return True + + def checkAllowed(self, func, name): + if func not in FUNC_BAD_PARAMS.keys(): + return False + + return name in FUNC_BAD_PARAMS[func] + + def verifyParameter(self, alg_descr, name): + + if not self.paramRegExp.match(name): + if not self.checkAllowed(alg_descr, name): + print alg_descr + " property (" + name +") violates conventions" + return False + + # passed all of the checks + return True + + def runTest(self): + self.__ranOk = 0 + self.funcRegExp = re.compile(r'^[A-Z][a-zA-Z0-9]+$') + self.paramRegExp = re.compile(r'^[A-Z][a-zA-Z0-9]*$') + self.categoryRegExp = re.compile(r'^([A-Z][a-zA-Z]+\\?)+$') + + functions = mantid.api.FunctionFactory.getFunctionNames() + for name in functions: + if not self.verifyFuncName(name): + self.__ranOk += 1 + continue + + function = mantid.api.FunctionFactory.createFunction(name) + + if not self.verifyCategories(name, function.categories()): + self.__ranOk += 1 + + for i in xrange(function.numParams()): + if not self.verifyParameter(name, function.getParamName(i)): + self.__ranOk += 1 + + def validate(self): + if self.__ranOk > 0: + print "Found %d errors. Coding conventions found at" % self.__ranOk,\ + "http://www.mantidproject.org/Mantid_Standards" + return False + + return True diff --git a/Code/Mantid/Testing/SystemTests/tests/analysis/ConvertToMDworkflow.py b/Code/Mantid/Testing/SystemTests/tests/analysis/ConvertToMDworkflow.py new file mode 100644 index 000000000000..25ccc3e58010 --- /dev/null +++ b/Code/Mantid/Testing/SystemTests/tests/analysis/ConvertToMDworkflow.py @@ -0,0 +1,85 @@ +import stresstesting +from mantid.simpleapi import * +from mantid.api import Workspace + + +#---------------------------------------------------------------------- +class ConvertToMDworkflow(stresstesting.MantidStressTest): + """ + """ + + + + def runTest(self): + + # let's load test event workspace, which has been already preprocessed and available in Mantid Test folder + WS_Name='CNCS_7860_event' + Load(Filename=WS_Name,OutputWorkspace=WS_Name) + # this workspace has been obtained from an inelastic experiment with input energy Ei = 3. + # Usually this energy is stored in workspace + # but if it is not, we have to provide it for inelastic conversion to work. + AddSampleLog(Workspace=WS_Name,LogName='Ei',LogText='3.0',LogType='Number') + # disable multithreaded splitting as BoxID-s are assigned in random manner + # AddSampleLog(Workspace=WS_Name,LogName='NUM_THREADS',LogText='0',LogType='Number') + # + # set up target ws name and remove target workspace with the same name which can occasionally exist. + RezWS = 'WS_4D' + try: + DeleteWorkspace(RezWS) + except ValueError: + print "Target ws ",RezWS," not found in analysis data service\n" + # + #---> Start loop over contributing files + for i in xrange(0,20,5): + # the following operations simulate different workspaces, obtained from experiment using rotating crystal; + # For real experiment we usually just load these workspaces from nxspe files with proper Psi values defined there + # and have to set up ub matrix + SourceWS = 'SourcePart'+str(i) + # ws emulation begin ----> + CloneWorkspace(InputWorkspace=WS_Name,OutputWorkspace=SourceWS) + # using scattering on a crystal with cubic lattice and 1,0,0 direction along the beam. + SetUB(Workspace=SourceWS,a='1.4165',b='1.4165',c='1.4165',u='1,0,0',v='0,1,0') + # rotated by proper number of degrees around axis Y + AddSampleLog(Workspace=SourceWS,LogName='Psi',LogText=str(i)+'.0',LogType='Number Series') + SetGoniometer(Workspace=SourceWS,Axis0='Psi,0,1,0,1') + # ws emulation, end --------------------------------------------------------------------------------------- + + ConvertToMD(InputWorkspace=SourceWS,OutputWorkspace=RezWS,QDimensions='Q3D',QConversionScales='HKL',\ + OverwriteExisting=0,dEAnalysisMode='Direct',MinValues='-3,-3,-3,-1',MaxValues='3,3,3,3',\ + SplitInto="20,20,1,1") + # delete source workspace from memory; + DeleteWorkspace(SourceWS) + + + def validate(self): + """Returns the name of the workspace & file to compare""" + self.tolerance = 1e-5 + #elf.disableChecking.append('SpectraMap') + #elf.disableChecking.append('Instrument') + result = 'WS_4D' + reference = "ConvertToMDSample.nxs" + + valNames = [result,reference] + from mantid.simpleapi import Load,CompareMDWorkspaces,FrameworkManager,SaveNexus + + Load(Filename=reference,OutputWorkspace=valNames[1]) + + checker = AlgorithmManager.create("CompareMDWorkspaces") + checker.setLogging(True) + checker.setPropertyValue("Workspace1",result) + checker.setPropertyValue("Workspace2",valNames[1]) + checker.setPropertyValue("Tolerance", str(self.tolerance)) + checker.setPropertyValue("IgnoreBoxID", "1") + checker.setPropertyValue("CheckEvents", "1") + + checker.execute() + if checker.getPropertyValue("Equals") != "1": + print " Workspaces do not match, result: ",checker.getPropertyValue("Result") + print self.__class__.__name__ + SaveMD(InputWorkspace=valNames[0],Filename=self.__class__.__name__+'-mismatch.nxs') + return False + + + return True + + diff --git a/Code/Mantid/Testing/SystemTests/tests/analysis/DOSTest.py b/Code/Mantid/Testing/SystemTests/tests/analysis/DOSTest.py new file mode 100644 index 000000000000..956e027e37c2 --- /dev/null +++ b/Code/Mantid/Testing/SystemTests/tests/analysis/DOSTest.py @@ -0,0 +1,151 @@ +import stresstesting +from mantid.kernel import * +from mantid.api import * +from mantid.simpleapi import * + +class DOSPhononTest(stresstesting.MantidStressTest): + + def runTest(self): + file_name = 'squaricn.phonon' + self.ouput_ws_name = 'squaricn' + self.ref_result = 'II.DOSTest.nxs' + + DensityOfStates(File=file_name, OutputWorkspace=self.ouput_ws_name) + + def validate(self): + return self.ouput_ws_name, self.ref_result + +#------------------------------------------------------------------------------------ + +class DOSPhononCrossSectionScaleTest(stresstesting.MantidStressTest): + + def runTest(self): + file_name = 'squaricn.phonon' + self.ouput_ws_name = 'squaricn' + self.ref_result = 'II.DOSCrossSectionScaleTest.nxs' + + DensityOfStates(File=file_name, ScaleByCrossSection='Incoherent', OutputWorkspace=self.ouput_ws_name) + + def validate(self): + return self.ouput_ws_name, self.ref_result + +#------------------------------------------------------------------------------------ + +class DOSCastepTest(stresstesting.MantidStressTest): + + def runTest(self): + file_name = 'squaricn.castep' + self.ouput_ws_name = 'squaricn' + self.ref_result = 'II.DOSTest.nxs' + + DensityOfStates(File=file_name,OutputWorkspace=self.ouput_ws_name) + + def validate(self): + return self.ouput_ws_name, self.ref_result + +#------------------------------------------------------------------------------------ + +class DOSRamanActiveTest(stresstesting.MantidStressTest): + + def runTest(self): + file_name = 'squaricn.phonon' + spec_type = 'Raman_Active' + self.ouput_ws_name = 'squaricn' + self.ref_result = 'II.DOSRamanTest.nxs' + + DensityOfStates(File=file_name, SpectrumType=spec_type, OutputWorkspace=self.ouput_ws_name) + + def validate(self): + self.tolerance = 1e-3 + return self.ouput_ws_name, self.ref_result + +#------------------------------------------------------------------------------------ + +class DOSIRActiveTest(stresstesting.MantidStressTest): + + def runTest(self): + file_name = 'squaricn.phonon' + spec_type = 'IR_Active' + self.ouput_ws_name = 'squaricn' + self.ref_result = 'II.DOSIRTest.nxs' + + DensityOfStates(File=file_name, SpectrumType=spec_type, OutputWorkspace=self.ouput_ws_name) + + def validate(self): + return self.ouput_ws_name, self.ref_result + +#------------------------------------------------------------------------------------ + +class DOSPartialTest(stresstesting.MantidStressTest): + + def runTest(self): + file_name = 'squaricn.phonon' + spec_type = 'DOS' + self.ouput_ws_name = 'squaricn' + self.ref_result = 'II.DOSPartialTest.nxs' + + DensityOfStates(File=file_name, SpectrumType=spec_type, Ions="H,C,O", OutputWorkspace=self.ouput_ws_name) + + def validate(self): + return self.ouput_ws_name, self.ref_result + +#------------------------------------------------------------------------------------ + +class DOSPartialSummedContributionsTest(stresstesting.MantidStressTest): + """ + This test checks the reference result of the total DOS against + the summed partial contributions of all elements. The two should be roughly + equal to within a small degree of error. + """ + + def runTest(self): + + file_name = 'squaricn.phonon' + spec_type = 'DOS' + self.ouput_ws_name = 'squaricn' + self.ref_result = 'II.DOSTest.nxs' + self.tolerance = 1e-10 + + DensityOfStates(File=file_name, SpectrumType=spec_type, Ions="H,C,O", SumContributions=True, OutputWorkspace=self.ouput_ws_name) + + def validate(self): + return self.ouput_ws_name, self.ref_result + +#------------------------------------------------------------------------------------ + +class DOSPartialCrossSectionScaleTest(stresstesting.MantidStressTest): + + def runTest(self): + file_name = 'squaricn.phonon' + spec_type = 'DOS' + self.ouput_ws_name = 'squaricn' + self.ref_result = 'II.DOSPartialCrossSectionScaleTest.nxs' + + DensityOfStates(File=file_name, SpectrumType=spec_type, Ions="H,C,O", ScaleByCrossSection='Incoherent', + OutputWorkspace=self.ouput_ws_name) + + def validate(self): + return self.ouput_ws_name, self.ref_result + +#------------------------------------------------------------------------------------ + +class DOSPartialSummedContributionsCrossSectionScaleTest(stresstesting.MantidStressTest): + """ + This test checks the reference result of the total DOS against + the summed partial contributions of all elements. The two should be roughly + equal to within a small degree of error. + """ + + def runTest(self): + + file_name = 'squaricn.phonon' + spec_type = 'DOS' + self.ouput_ws_name = 'squaricn' + self.ref_result = 'II.DOSCrossSectionScaleTest.nxs' + self.tolerance = 1e-10 + + DensityOfStates(File=file_name, SpectrumType=spec_type, Ions="H,C,O", SumContributions=True, + ScaleByCrossSection='Incoherent', OutputWorkspace=self.ouput_ws_name) + + def validate(self): + return self.ouput_ws_name, self.ref_result diff --git a/Code/Mantid/Testing/SystemTests/tests/analysis/Diffraction_Workflow_Test.py b/Code/Mantid/Testing/SystemTests/tests/analysis/Diffraction_Workflow_Test.py new file mode 100644 index 000000000000..1749239bac9a --- /dev/null +++ b/Code/Mantid/Testing/SystemTests/tests/analysis/Diffraction_Workflow_Test.py @@ -0,0 +1,171 @@ +""" +System test that loads TOPAZ single-crystal data, +and runs Diffraction Workflow. +""" +import stresstesting +import numpy +from mantid.simpleapi import * +from mantid.api import FileFinder + +import os + +class Diffraction_Workflow_Test(stresstesting.MantidStressTest): + + def cleanup(self): + Files = ["TOPAZ_3132.hkl", + "TOPAZ_3132FFT.hkl"] + for file in Files: + absfile = FileFinder.getFullPath(file) + if os.path.exists(absfile): + os.remove(absfile) + return True + + def requiredMemoryMB(self): + """ Require about 4GB free """ + return 4000 + + def runTest(self): + import platform + if platform.system() == "Darwin": + import resource + # Activate core dumps to try & find the reason for the crashes + resource.setrlimit(resource.RLIMIT_CORE, (-1, -1)) + + # determine where to save + import os + savedir = os.path.abspath(os.path.curdir) + + + # Basic parameters for Triphylite Crystal + #Name of the workspaces to create + ws = "TOPAZ_3132" + filename = ws+"_event.nxs" + LoadEventNexus(Filename=filename,OutputWorkspace=ws,FilterByTofMin='3000',FilterByTofMax='16000') + + # Spherical Absorption and Lorentz Corrections + AnvredCorrection(InputWorkspace=ws,OutputWorkspace=ws,LinearScatteringCoef="0.451",LinearAbsorptionCoef="0.993",Radius="0.14") + + # Convert to Q space + ConvertToDiffractionMDWorkspace(InputWorkspace=ws,OutputWorkspace=ws+'_MD2',LorentzCorrection='0', + OutputDimensions='Q (lab frame)', SplitInto='2',SplitThreshold='150') #,Version=1 + # Find peaks (Reduced number of peaks so file comparison with reference does not fail with small differences) + FindPeaksMD(InputWorkspace=ws+'_MD2',MaxPeaks='20',OutputWorkspace=ws+'_peaksLattice') + # 3d integration to centroid peaks + CentroidPeaksMD(InputWorkspace=ws+'_MD2',CoordinatesToUse='Q (lab frame)', + PeakRadius='0.12',PeaksWorkspace=ws+'_peaksLattice',OutputWorkspace=ws+'_peaksLattice') + # Find the UB matrix using the peaks and known lattice parameters + FindUBUsingLatticeParameters(PeaksWorkspace=ws+'_peaksLattice',a='10.3522',b='6.0768',c='4.7276', + alpha='90',beta='90',gamma='90', NumInitial='20', Tolerance='0.12') + # And index to HKL + IndexPeaks(PeaksWorkspace=ws+'_peaksLattice', Tolerance='0.12') + # Integrate peaks in Q space using spheres + IntegratePeaksMD(InputWorkspace=ws+'_MD2',PeakRadius='0.12', + BackgroundOuterRadius='0.18',BackgroundInnerRadius='0.15', + PeaksWorkspace=ws+'_peaksLattice',OutputWorkspace=ws+'_peaksLattice') + # Save for SHELX + SaveHKL(InputWorkspace=ws+'_peaksLattice', Filename=savedir+'/'+ws+'.hkl') + + # Find peaks again for FFT + FindPeaksMD(InputWorkspace=ws+'_MD2',MaxPeaks='100',OutputWorkspace=ws+'_peaksFFT') + # 3d integration to centroid peaks + CentroidPeaksMD(InputWorkspace=ws+'_MD2', CoordinatesToUse='Q (lab frame)', + PeakRadius='0.12',PeaksWorkspace=ws+'_peaksFFT',OutputWorkspace=ws+'_peaksFFT') + # Find the UB matrix using FFT + FindUBUsingFFT(PeaksWorkspace=ws+'_peaksFFT',MinD=3.,MaxD=14.) + + ## TODO conventional cell + + # And index to HKL + alg = IndexPeaks(PeaksWorkspace=ws+'_peaksFFT', Tolerance='0.12') + + # Integrate peaks in Q space using spheres + IntegratePeaksMD(InputWorkspace=ws+'_MD2',PeakRadius='0.12', + BackgroundOuterRadius='0.18',BackgroundInnerRadius='0.15', + PeaksWorkspace=ws+'_peaksFFT',OutputWorkspace=ws+'_peaksFFT') + # Save for SHELX + SaveHKL(InputWorkspace=ws+'_peaksFFT', Filename=savedir+'/'+ws+'FFT.hkl') + + + # Copy the UB matrix back to the original workspace + CopySample(InputWorkspace=ws+'_peaksFFT',OutputWorkspace=ws, + CopyName='0',CopyMaterial='0',CopyEnvironment='0',CopyShape='0', CopyLattice=1) + # Convert to reciprocal space, in the sample frame + + ConvertToDiffractionMDWorkspace(InputWorkspace=ws,OutputWorkspace=ws+'_HKL', + OutputDimensions='HKL',LorentzCorrection='0', SplitInto='2',SplitThreshold='150') + # Bin to a regular grid + BinMD(InputWorkspace=ws+'_HKL',AlignedDim0="[H,0,0], -20, 20, 800",AlignedDim1="[0,K,0], -5, 5, 50", + AlignedDim2="[0,0,L], -10, 10, 800",OutputWorkspace=ws+'_binned') + + + originalUB = numpy.array(mtd["TOPAZ_3132"].sample().getOrientedLattice().getUB()) + w = mtd["TOPAZ_3132"] + s = w.sample() + ol = s.getOrientedLattice() + self.assertDelta( ol.a(), 4.712, 0.01, "Correct lattice a value not found.") + self.assertDelta( ol.b(), 6.06, 0.01, "Correct lattice b value not found.") + self.assertDelta( ol.c(), 10.41, 0.01, "Correct lattice c value not found.") + self.assertDelta( ol.alpha(), 90, 0.4, "Correct lattice angle alpha value not found.") + self.assertDelta( ol.beta(), 90, 0.4, "Correct lattice angle beta value not found.") + self.assertDelta( ol.gamma(), 90, 0.4, "Correct lattice angle gamma value not found.") + + # Go to HKL + ConvertToDiffractionMDWorkspace(InputWorkspace='TOPAZ_3132',OutputWorkspace='TOPAZ_3132_HKL',OutputDimensions='HKL',LorentzCorrection='1',SplitInto='2',SplitThreshold='150') + + + # Bin to a line (H=0 to 6, L=3, K=3) + BinMD(InputWorkspace='TOPAZ_3132_HKL',AxisAligned='0', + BasisVector0='X,units,1,0,0',BasisVector1='Y,units,6.12323e-17,1,0',BasisVector2='2,units,-0,0,1', + Translation='-0,3,6',OutputExtents='0,6, -0.1,0.1, -0.1,0.1',OutputBins='60,1,1', + OutputWorkspace='TOPAZ_3132_HKL_line') + + # Now check the integrated bin and the peaks + w = mtd["TOPAZ_3132_HKL_line"] + self.assertLessThan( w.signalAt(1), 1e4, "Limited background signal" ) + self.assertDelta( w.signalAt(10), 140.824, 1, "Peak 1") #self.assertDelta( w.signalAt(10), 1110.86, 10, "Peak 1") + self.assertDelta( w.signalAt(20), 36.25, 1, "Peak 2") #self.assertDelta( w.signalAt(20), 337.71, 10, "Peak 2") + self.assertDelta( w.signalAt(30), 26.53, 1, "Peak 3") #self.assertDelta( w.signalAt(30), 195.548, 10, "Peak 3") + + # Now do the same peak finding with Q in the sample frame + + + ConvertToDiffractionMDWorkspace(InputWorkspace='TOPAZ_3132',OutputWorkspace='TOPAZ_3132_QSample',OutputDimensions='Q (sample frame)',LorentzCorrection='1',SplitInto='2',SplitThreshold='150') + FindPeaksMD(InputWorkspace='TOPAZ_3132_QSample',PeakDistanceThreshold='0.12',MaxPeaks='200',OutputWorkspace='peaks_QSample') + FindUBUsingFFT(PeaksWorkspace='peaks_QSample',MinD='2',MaxD='16') + CopySample(InputWorkspace='peaks_QSample',OutputWorkspace='TOPAZ_3132',CopyName='0',CopyMaterial='0',CopyEnvironment='0',CopyShape='0') + + # Index the peaks and check + results = IndexPeaks(PeaksWorkspace='peaks_QSample') + indexed = results[0] + if indexed < 100: + raise Exception("Expected at least 100 of 100 peaks to be indexed. Only indexed %d!" % indexed) + + # Check the UB matrix + w = mtd["TOPAZ_3132"] + s = w.sample() + ol = s.getOrientedLattice() + self.assertDelta( ol.a(), 4.714, 0.01, "Correct lattice a value not found.") + self.assertDelta( ol.b(), 6.06, 0.01, "Correct lattice b value not found.") + self.assertDelta( ol.c(), 10.42, 0.01, "Correct lattice c value not found.") + self.assertDelta( ol.alpha(), 90, 0.4, "Correct lattice angle alpha value not found.") + self.assertDelta( ol.beta(), 90, 0.4, "Correct lattice angle beta value not found.") + self.assertDelta( ol.gamma(), 90, 0.4, "Correct lattice angle gamma value not found.") + + # Compare new and old UBs + newUB = numpy.array(mtd["TOPAZ_3132"].sample().getOrientedLattice().getUB()) + # UB Matrices are not necessarily the same, some of the H,K and/or L sign can be reversed + diff = abs(newUB) - abs(originalUB) < 0.001 + for c in xrange(3): + # This compares each column, allowing old == new OR old == -new + if not (numpy.all(diff[:,c]) ): + raise Exception("More than 0.001 difference between UB matrices: Q (lab frame):\n%s\nQ (sample frame):\n%s" % (originalUB, newUB) ) + + # load output hkl file and the golden one + LoadHKL(Filename="TOPAZ_3132.hkl", OutputWorkspace="TOPAZ_3132") + LoadHKL(Filename='TOPAZ_3132_reference.hkl', OutputWorkspace="TOPAZ_3132_golden") + + def validateMethod(self): + return "ValidateWorkspaceToWorkspace" + + def validate(self): + return ('TOPAZ_3132','TOPAZ_3132_golden') diff --git a/Code/Mantid/Testing/SystemTests/tests/analysis/DirectInelasticDiagnostic.py b/Code/Mantid/Testing/SystemTests/tests/analysis/DirectInelasticDiagnostic.py new file mode 100644 index 000000000000..f491e3bedfba --- /dev/null +++ b/Code/Mantid/Testing/SystemTests/tests/analysis/DirectInelasticDiagnostic.py @@ -0,0 +1,66 @@ +from stresstesting import MantidStressTest +from mantid.simpleapi import MaskDetectors, mtd, config +import Direct.DirectEnergyConversion as reduction +import os + +class DirectInelasticDiagnostic(MantidStressTest): + + def requiredMemoryMB(self): + """Requires 4Gb""" + return 4000 + + def runTest(self): + white = 'MAP17186.raw' + sample = 'MAP17269.raw' + + # Libisis values to check against + tiny=1e-10 + huge=1e10 + + v_out_lo = 0.01 + v_out_hi = 100. + + vv_lo = 0.1 + vv_hi = 2.0 + vv_sig = 0.0 + + sv_sig = 3.3 + sv_hi = 1.5 + sv_lo = 0.0 + s_zero = True + + reducer = reduction.setup_reducer('MAPS') + # parameters which explicitly affect diagnostics + # + reducer.prop_man.wb_integr_range = [20,300] + reducer.prop_man.bkgd_range=[12000,18000] + diag_mask = reducer.diagnose(white, sample, tiny=tiny, huge=huge, + van_out_lo=v_out_lo, van_out_hi=v_out_hi, + van_lo=vv_lo, van_hi=vv_hi, van_sig=vv_sig, + samp_lo=sv_lo, samp_hi=sv_hi, samp_sig=sv_sig, samp_zero=s_zero,hard_mask_file=None) + + sample = reducer.get_run_descriptor(sample) + sample_ws = sample.get_workspace() + MaskDetectors(Workspace=sample_ws, MaskedWorkspace=diag_mask) + + # Save the masked spectra nmubers to a simple ASCII file for comparison + self.saved_diag_file = os.path.join(config['defaultsave.directory'], 'CurrentDirectInelasticDiag.txt') + handle = file(self.saved_diag_file, 'w') + for index in range(sample_ws.getNumberHistograms()): + if sample_ws.getDetector(index).isMasked(): + spec_no = sample_ws.getSpectrum(index).getSpectrumNo() + handle.write(str(spec_no) + '\n') + handle.close + + def cleanup(self): + if os.path.exists(self.saved_diag_file): + if self.succeeded(): + os.remove(self.saved_diag_file) + else: + os.rename(self.saved_diag_file, os.path.join(config['defaultsave.directory'], 'DirectInelasticDiag-Mismatch.txt')) + + def validateMethod(self): + return 'validateASCII' + + def validate(self): + return (self.saved_diag_file,'DirectInelasticDiagnostic.txt') diff --git a/Code/Mantid/Testing/SystemTests/tests/analysis/DirectInelasticDiagnostic2.py b/Code/Mantid/Testing/SystemTests/tests/analysis/DirectInelasticDiagnostic2.py new file mode 100644 index 000000000000..38ff1f6958f4 --- /dev/null +++ b/Code/Mantid/Testing/SystemTests/tests/analysis/DirectInelasticDiagnostic2.py @@ -0,0 +1,89 @@ +from stresstesting import MantidStressTest +from mantid.simpleapi import * +from mantid.kernel import PropertyManager +from mantid import config +import os + +def MAX_DBL(): + import sys + return sys.float_info[0]/2 + +def getNamedParameter(ws, name): + return ws.getInstrument().getNumberParameter(name)[0] + +class DirectInelasticDiagnostic2(MantidStressTest): + + def requiredMemoryMB(self): + """Requires 4Gb""" + return 4000 + + + def runTest(self): + red_man = PropertyManager() + red_man_name = "__dgs_reduction_properties" + pmds[red_man_name] = red_man + + if 'detvan' in mtd: + detvan = mtd['detvan'] + else: + detvan = Load('MAP17186.raw') + if 'sample' in mtd: + sample = mtd['sample'] + else: + sample = Load('MAP17269.raw') + + # Libisis values to check against + # All PropertyManager properties need to be set + red_man["LowCounts"] = 1e-10 + red_man["HighCounts"] = 1e10 + red_man["LowOutlier"] = 0.01 + red_man["HighOutlier"] = 100. + red_man["ErrorBarCriterion"] = 0.0 + red_man["MedianTestLow"] = 0.1 + red_man["MedianTestHigh"] = 2.0 + red_man["SamBkgMedianTestLow"] = 0.0 + red_man["SamBkgMedianTestHigh"] = 1.5 + red_man["SamBkgErrorbarCriterion"] = 3.3 + red_man["RejectZeroBackground"] = True + # Things needed to run vanadium reduction + red_man["IncidentBeamNormalisation"] = "ToMonitor" + red_man["DetVanIntRangeUnits"] = "Energy" + # properties affecting diagnostics: + + #reducer.wb_integr_range = [20,300] + red_man["DetVanIntRangeLow"] = 20. + red_man["DetVanIntRangeHigh"] = 300. + red_man["BackgroundCheck"] = True + red_man["BackgroundTofStart"]=12000. + red_man["BackgroundTofEnd"]=18000. + #reducer.bkgd_range=[12000,18000] + + + diag_mask = DgsDiagnose(DetVanWorkspace=detvan, SampleWorkspace=sample, + ReductionProperties=red_man_name) + + MaskDetectors(sample, MaskedWorkspace=diag_mask) + # Save the masked spectra numbers to a simple ASCII file for comparison + self.saved_diag_file = os.path.join(config['defaultsave.directory'], + 'CurrentDirectInelasticDiag2.txt') + handle = file(self.saved_diag_file, 'w') + for index in range(sample.getNumberHistograms()): + if sample.getDetector(index).isMasked(): + spec_no = sample.getSpectrum(index).getSpectrumNo() + handle.write(str(spec_no) + '\n') + handle.close + + def cleanup(self): + if os.path.exists(self.saved_diag_file): + if self.succeeded(): + os.remove(self.saved_diag_file) + else: + os.rename(self.saved_diag_file, + os.path.join(config['defaultsave.directory'], + 'DirectInelasticDiag2-Mismatch.txt')) + + def validateMethod(self): + return 'validateASCII' + + def validate(self): + return (self.saved_diag_file, 'DirectInelasticDiagnostic.txt') diff --git a/Code/Mantid/Testing/SystemTests/tests/analysis/EQSANSBeamCenterAPIv2.py b/Code/Mantid/Testing/SystemTests/tests/analysis/EQSANSBeamCenterAPIv2.py new file mode 100644 index 000000000000..11b5526b5048 --- /dev/null +++ b/Code/Mantid/Testing/SystemTests/tests/analysis/EQSANSBeamCenterAPIv2.py @@ -0,0 +1,75 @@ +import stresstesting +import mantid +from mantid.simpleapi import * +from reduction_workflow.instruments.sans.sns_command_interface import * +from mantid.api import * + +import os + +def do_cleanup(): + absfile = FileFinder.getFullPath("EQSANS_4061_event_reduction.log") + if os.path.exists(absfile): + os.remove(absfile) + return True + +class EQSANSBeamCenter(stresstesting.MantidStressTest): + + def cleanup(self): + do_cleanup() + return True + + def runTest(self): + config = ConfigService.Instance() + config["facilityName"]='SNS' + EQSANS(False) + AppendDataFile("EQSANS_4061_event.nxs") + NoSolidAngle() + IndependentBinning(False) + UseConfig(False) + UseConfigTOFTailsCutoff(False) + UseConfigMask(False) + SetTransmission(1.0, 0.0) + TotalChargeNormalization(normalize_to_beam=False) + DirectBeamCenter("EQSANS_1466_event.nxs") + Reduce() + # Scale up to match correct scaling. The reference data is off by a factor 10.0 + Scale(InputWorkspace="EQSANS_4061_event_frame2_Iq", Factor=10.0, + Operation='Multiply', OutputWorkspace="EQSANS_4061_event_frame2_Iq") + Scale(InputWorkspace="EQSANS_4061_event_frame2_Iq", Factor=277.781, + Operation='Multiply', OutputWorkspace="EQSANS_4061_event_frame2_Iq") + + def validate(self): + # Be more tolerant with the output, mainly because of the errors. + # The following tolerance check the errors up to the third digit. + self.tolerance = 0.1 + self.disableChecking.append('Instrument') + self.disableChecking.append('Sample') + self.disableChecking.append('SpectraMap') + self.disableChecking.append('Axes') + return "EQSANS_4061_event_frame2_Iq", 'EQSANSBeamCenter.nxs' + +class EQSANSBeamCenterEvent(EQSANSBeamCenter): + + def cleanup(self): + do_cleanup() + return True + + def runTest(self): + config = ConfigService.Instance() + config["facilityName"]='SNS' + EQSANS(True) + AppendDataFile("EQSANS_4061_event.nxs") + NoSolidAngle() + IndependentBinning(False) + UseConfig(False) + UseConfigTOFTailsCutoff(False) + UseConfigMask(False) + SetTransmission(1.0, 0.0) + TotalChargeNormalization(normalize_to_beam=False) + DirectBeamCenter("EQSANS_1466_event.nxs") + Reduce() + # Scale up to match correct scaling. The reference data is off by a factor 10.0 + Scale(InputWorkspace="EQSANS_4061_event_frame2_Iq", Factor=10.0, + Operation='Multiply', OutputWorkspace="EQSANS_4061_event_frame2_Iq") + Scale(InputWorkspace="EQSANS_4061_event_frame2_Iq", Factor=277.781, + Operation='Multiply', OutputWorkspace="EQSANS_4061_event_frame2_Iq") diff --git a/Code/Mantid/Testing/SystemTests/tests/analysis/EQSANSDarkCurrentAPIv2.py b/Code/Mantid/Testing/SystemTests/tests/analysis/EQSANSDarkCurrentAPIv2.py new file mode 100644 index 000000000000..daa6d4bb8c91 --- /dev/null +++ b/Code/Mantid/Testing/SystemTests/tests/analysis/EQSANSDarkCurrentAPIv2.py @@ -0,0 +1,50 @@ +import stresstesting +import mantid +from mantid.simpleapi import * +from reduction_workflow.instruments.sans.sns_command_interface import * +from mantid.api import * + +import os + +class EQSANSDarkCurrent(stresstesting.MantidStressTest): + + def cleanup(self): + absfile = FileFinder.getFullPath("EQSANS_1466_event_reduction.log") + if os.path.exists(absfile): + os.remove(absfile) + return True + + """ + Analysis Tests for EQSANS + Testing that the I(Q) output of is correct + """ + + def runTest(self): + config = ConfigService.Instance() + config["facilityName"]='SNS' + EQSANS(True) + SolidAngle() + SetBeamCenter(96.29, 126.15) + PerformFlightPathCorrection(False) + UseConfig(False) + UseConfigTOFTailsCutoff(False) + SetTOFTailsCutoff(low_cut=0.00, high_cut=0.00) + UseConfigMask(False) + TotalChargeNormalization(normalize_to_beam=False) + SetTransmission(1.0,0.0, False) + DarkCurrent("EQSANS_4061_event.nxs") + AppendDataFile("EQSANS_1466_event.nxs") + Reduce1D() + # Scale up to match correct scaling. + Scale(InputWorkspace="EQSANS_1466_event_Iq", Factor=2777.81, + Operation='Multiply', OutputWorkspace="EQSANS_1466_event_Iq") + + def validate(self): + self.tolerance = 1.0 + self.disableChecking.append('Instrument') + self.disableChecking.append('Sample') + self.disableChecking.append('SpectraMap') + self.disableChecking.append('Axes') + + return "EQSANS_1466_event_Iq", 'EQSANSDarkCurrent.nxs' + \ No newline at end of file diff --git a/Code/Mantid/Testing/SystemTests/tests/analysis/EQSANSEffAPIv2.py b/Code/Mantid/Testing/SystemTests/tests/analysis/EQSANSEffAPIv2.py new file mode 100644 index 000000000000..60c2f0b67a7f --- /dev/null +++ b/Code/Mantid/Testing/SystemTests/tests/analysis/EQSANSEffAPIv2.py @@ -0,0 +1,47 @@ +import stresstesting +import mantid +from mantid.simpleapi import * +from reduction_workflow.instruments.sans.sns_command_interface import * +from mantid.api import FileFinder + +import os + +class EQSANSEff(stresstesting.MantidStressTest): + + def cleanup(self): + absfile = FileFinder.getFullPath("EQSANS_1466_event_reduction.log") + if os.path.exists(absfile): + os.remove(absfile) + return True + + def runTest(self): + """ + System test for sensitivity correction + """ + config = ConfigService.Instance() + config["facilityName"]='SNS' + EQSANS(False) + AppendDataFile("EQSANS_1466_event.nxs") + SolidAngle() + UseConfig(False) + UseConfigTOFTailsCutoff(False) + UseConfigMask(False) + SetBeamCenter(96.29, 126.15) + SetTransmission(1.0, 0.0) + TotalChargeNormalization(normalize_to_beam=False) + SensitivityCorrection("EQSANS_4061_event.nxs", min_sensitivity=0.5, max_sensitivity=1.5, dark_current=None, use_sample_dc=False) + Reduce1D() + Scale(InputWorkspace="EQSANS_1466_event_Iq", Factor=277.781, + Operation='Multiply', OutputWorkspace="EQSANS_1466_event_Iq") + + def validate(self): + # Be more tolerant with the output, mainly because of the errors. + # The following tolerance check the errors up to the third digit. + mtd["EQSANS_1466_event_Iq"].dataE(0)[0]=8.13907 + self.tolerance = 0.1 + self.disableChecking.append('Instrument') + self.disableChecking.append('Sample') + self.disableChecking.append('SpectraMap') + self.disableChecking.append('Axes') + return "EQSANS_1466_event_Iq", 'EQSANSEff.nxs' + diff --git a/Code/Mantid/Testing/SystemTests/tests/analysis/EQSANSFlatTestAPIv2.py b/Code/Mantid/Testing/SystemTests/tests/analysis/EQSANSFlatTestAPIv2.py new file mode 100644 index 000000000000..fe4ac6a3f4ca --- /dev/null +++ b/Code/Mantid/Testing/SystemTests/tests/analysis/EQSANSFlatTestAPIv2.py @@ -0,0 +1,65 @@ +import stresstesting +import mantid +from mantid.simpleapi import * +from reduction_workflow.instruments.sans.sns_command_interface import * + +FILE_LOCATION = "/SNS/EQSANS/IPTS-5636/data/" + +class EQSANSFlatTest(stresstesting.MantidStressTest): + def requiredFiles(self): + files = [] + files.append(FILE_LOCATION+"EQSANS_5704_event.nxs") + files.append(FILE_LOCATION+"EQSANS_5734_event.nxs") + files.append(FILE_LOCATION+"EQSANS_5732_event.nxs") + files.append(FILE_LOCATION+"EQSANS_5738_event.nxs") + files.append(FILE_LOCATION+"EQSANS_5729_event.nxs") + files.append(FILE_LOCATION+"EQSANS_5737_event.nxs") + files.append(FILE_LOCATION+"EQSANS_5703_event.nxs") + files.append("bl6_flux_at_sample") + return files + + def runTest(self): + """ + System test for EQSANS. + This test is meant to be run at SNS and takes a long time. + It is used to verify that the complete reduction chain works + and reproduces reference results. + """ + config = ConfigService.Instance() + config["facilityName"]='SNS' + EQSANS(True) + SolidAngle() + DarkCurrent(FILE_LOCATION+"EQSANS_5704_event.nxs") + TotalChargeNormalization(beam_file="bl6_flux_at_sample") + AzimuthalAverage(n_bins=100, n_subpix=1, log_binning=False) + IQxQy(nbins=100) + UseConfigTOFTailsCutoff(True) + PerformFlightPathCorrection(True) + UseConfigMask(True) + SetBeamCenter(89.6749, 129.693) + SensitivityCorrection(FILE_LOCATION+'EQSANS_5703_event.nxs', + min_sensitivity=0.5, + max_sensitivity=1.5, use_sample_dc=True) + DirectBeamTransmission(FILE_LOCATION+"EQSANS_5734_event.nxs", + FILE_LOCATION+"EQSANS_5738_event.nxs", beam_radius=3) + ThetaDependentTransmission(False) + AppendDataFile([FILE_LOCATION+"EQSANS_5729_event.nxs"]) + CombineTransmissionFits(True) + + Background(FILE_LOCATION+"EQSANS_5732_event.nxs") + BckDirectBeamTransmission(FILE_LOCATION+"EQSANS_5737_event.nxs", + FILE_LOCATION+"EQSANS_5738_event.nxs", beam_radius=3) + BckThetaDependentTransmission(False) + BckCombineTransmissionFits(True) + SaveIqAscii(process='None') + SetAbsoluteScale(277.781) + Reduce1D() + + def validate(self): + self.tolerance = 0.3 + self.disableChecking.append('Instrument') + self.disableChecking.append('Sample') + self.disableChecking.append('SpectraMap') + self.disableChecking.append('Axes') + return "EQSANS_5729_event_frame1_Iq", 'EQSANSFlatTest.nxs' + diff --git a/Code/Mantid/Testing/SystemTests/tests/analysis/EQSANSIQOutputAPIv2.py b/Code/Mantid/Testing/SystemTests/tests/analysis/EQSANSIQOutputAPIv2.py new file mode 100644 index 000000000000..69da2f6824d5 --- /dev/null +++ b/Code/Mantid/Testing/SystemTests/tests/analysis/EQSANSIQOutputAPIv2.py @@ -0,0 +1,275 @@ +import stresstesting +import math +import mantid +from mantid.simpleapi import * +from reduction_workflow.instruments.sans.sns_command_interface import * +from mantid.api import * + +import os + +def do_cleanup(): + Files = ["EQSANS_4061_event_reduction.log", + "EQSANS_1466_event_reduction.log"] + for file in Files: + absfile = FileFinder.getFullPath(file) + if os.path.exists(absfile): + os.remove(absfile) + return True + +class EQSANSIQOutput(stresstesting.MantidStressTest): + + def cleanup(self): + do_cleanup() + return True + """ + Analysis Tests for EQSANS + Testing that the I(Q) output of is correct + """ + + def runTest(self): + """ + Check that EQSANSTofStructure returns the correct workspace + """ + config = ConfigService.Instance() + config["facilityName"]='SNS' + EQSANS() + SetBeamCenter(96.29, 126.15) + AppendDataFile("EQSANS_1466_event.nxs") + NoSolidAngle() + UseConfig(False) + UseConfigTOFTailsCutoff(False) + UseConfigMask(False) + TotalChargeNormalization(normalize_to_beam=False) + Reduce1D() + # Scale up to match correct scaling. + Scale(InputWorkspace="EQSANS_1466_event_Iq", Factor=2777.81, + Operation='Multiply', OutputWorkspace="EQSANS_1466_event_Iq") + + def validate(self): + self.tolerance = 0.2 + mtd["EQSANS_1466_event_Iq"].dataY(0)[0] = 269.687 + mtd["EQSANS_1466_event_Iq"].dataE(0)[0] = 16.4977 + mtd["EQSANS_1466_event_Iq"].dataE(0)[1] = 6.78 + mtd["EQSANS_1466_event_Iq"].dataY(0)[2] = 11.3157 + mtd["EQSANS_1466_event_Iq"].dataE(0)[2] = 1.23419 + self.disableChecking.append('Instrument') + self.disableChecking.append('Sample') + self.disableChecking.append('SpectraMap') + self.disableChecking.append('Axes') + return "EQSANS_1466_event_Iq", 'EQSANSIQOutput.nxs' + +class EQSANSBeamMonitor(stresstesting.MantidStressTest): + + def cleanup(self): + do_cleanup() + return True + """ + Analysis Tests for EQSANS + Testing that the I(Q) output of is correct + """ + + def runTest(self): + config = ConfigService.Instance() + config["facilityName"]='SNS' + EQSANS() + SetBeamCenter(96.29, 126.15) + AppendDataFile("EQSANS_1466_event.nxs") + NoSolidAngle() + UseConfig(False) + UseConfigTOFTailsCutoff(False) + UseConfigMask(False) + BeamMonitorNormalization('SANSBeamFluxCorrectionMonitor.nxs') + Reduce1D() + + def validate(self): + self.disableChecking.append('Instrument') + self.disableChecking.append('Sample') + self.disableChecking.append('SpectraMap') + self.disableChecking.append('Axes') + return "EQSANS_1466_event_Iq", 'EQSANSBeamMonitor.nxs' + +class EQSANSDQPositiveOutput(stresstesting.MantidStressTest): + + def cleanup(self): + do_cleanup() + return True + """ + Analysis Tests for EQSANS + Testing that the Q resolution output of is correct + """ + + def runTest(self): + """ + Check that the Q resolution calculation returns positive values + even when background is larger than signal and I(q) is negative. + (Non-physical value that's an experimental edge case) + """ + config = ConfigService.Instance() + config["facilityName"]='SNS' + EQSANS() + SetBeamCenter(96.29, 126.15) + AppendDataFile("EQSANS_1466_event.nxs") + UseConfig(False) + UseConfigTOFTailsCutoff(False) + UseConfigMask(False) + TotalChargeNormalization(normalize_to_beam=False) + SetTransmission(1.0,0.0, False) + Background("EQSANS_4061_event.nxs") + Resolution() + Reduce1D() + + def validate(self): + dq = mtd['EQSANS_1466_event_Iq'].dataDx(0) + for x in dq: + if x<0: + return False + return True + +class EQSANSDQOutput(stresstesting.MantidStressTest): + + def cleanup(self): + do_cleanup() + return True + """ + Analysis Tests for EQSANS + Testing that the Q resolution output of is correct + """ + + def runTest(self): + """ + Check that the Q resolution calculation returns positive values + even when background is larger than signal and I(q) is negative. + (Non-physical value that's an experimental edge case) + """ + config = ConfigService.Instance() + config["facilityName"]='SNS' + EQSANS() + SetBeamCenter(96.29, 126.15) + AppendDataFile("EQSANS_1466_event.nxs") + UseConfig(False) + UseConfigTOFTailsCutoff(False) + UseConfigMask(False) + TotalChargeNormalization(normalize_to_beam=False) + SetTransmission(1.0, 0.0, False) + Background("EQSANS_4061_event.nxs") + Resolution(10) + Reduce1D() + + def validate(self): + """ + Reference values were generate using the event-by-event method + and are slightly different than the ones generated using + the histogram method. + The event-by-event method processes each event one-by-one, + computes dQ for each of them, and averages those dQ for each + Q bin of the I(Q) distribution. + """ + dq_ref = [0.00178823,0.0014458,0.00144805,0.00155836,0.00150908, + 0.00163262,0.00158216,0.00160879,0.00165932,0.00164304, + 0.00165549,0.00163676,0.00167581,0.0016957,0.00167898, + 0.00172297,0.00169375,0.00174938,0.00173394,0.00180498, + 0.00188825,0.00184747,0.00181396,0.00185052,0.00191187, + 0.00192331,0.00196536,0.00196182,0.00202844,0.00205516, + 0.00208013,0.00210195,0.00212621,0.00217228,0.00217713, + 0.002243,0.00225329,0.00229956,0.00234733,0.00234773, + 0.00239551,0.00243152,0.0024392,0.00248026,0.00249286, + 0.00252012,0.00253674,0.00257043,0.00257755,0.00261695, + 0.00263961,0.00268499,0.0026836,0.00273043,0.00272828, + 0.00279073,0.00279924,0.00284322,0.00283794,0.00288332, + 0.00289423,0.00291934,0.00294244,0.00295239,0.00297587, + 0.00300671,0.00299071,0.00307836,0.00304013,0.00307726, + 0.00312929,0.00314636,0.00315895,0.00312642,0.00322729, + 0.00325368,0.00326916,0.00328936,0.00331894,0.00328319, + 0.00337098,0.00335638,0.00335586,0.00340926,0.00343972, + 0.00349148,0.003528,0.00352863,0.0035665,0.0036791, + 0.00360243,0.00364245,0.003671,0,0,0,0.00375495,0,0,0,0] + dq = mtd['EQSANS_1466_event_Iq'].readDx(0) + diff = [math.fabs(dq_ref[i]-dq[i])<0.0001 for i in range(7,100)] + output = reduce(lambda x,y:x and y, diff) + if not output: + for i in range(len(dq)): + print i, dq[i], dq_ref[i], math.fabs(dq_ref[i]-dq[i])<0.0001 + return output + +class EQSANSDQOutput_FS(stresstesting.MantidStressTest): + + def cleanup(self): + do_cleanup() + return True + """ + Analysis Tests for EQSANS + Testing that the Q resolution output of is correct + """ + + def runTest(self): + """ + Check that the Q resolution calculation returns positive values + even when background is larger than signal and I(q) is negative. + (Non-physical value that's an experimental edge case) + """ + config = ConfigService.Instance() + config["facilityName"]='SNS' + EQSANS() + SetBeamCenter(96.29, 126.15) + AppendDataFile("EQSANS_4061_event.nxs") + UseConfig(False) + UseConfigTOFTailsCutoff(False) + UseConfigMask(False) + TotalChargeNormalization(normalize_to_beam=False) + SetTransmission(1.0,0.0, False) + Resolution(12) + Reduce1D() + + def validate(self): + """ + Reference values were generate using the event-by-event method + and are slightly different than the ones generated using + the histogram method. + The event-by-event method processes each event one-by-one, + computes dQ for each of them, and averages those dQ for each + Q bin of the I(Q) distribution. + """ + dq_ref = [0.00255107356133, 0.00215833578128, 0.00208718785908, + 0.00258510271064, 0.00293816108702, 0.00247205866985, + 0.00243935430286, 0.00239444669495, 0.00222146661565, + 0.00218605712485, 0.00219528175558, 0.0022064529384, + 0.00222261319274, 0.00224172877526, 0.00225796674563, + 0.00228220728003, 0.00230427122347, 0.00232713464119, + 0.00235408216185, 0.00238474827119, 0.00240595507163, + 0.00243366105712, 0.00246093985138, 0.00248828126962, + 0.00251992966389, 0.00255373215231, 0.00259127844171, + 0.00263727405994, 0.00268617120932, 0.00273367187508, + 0.00277746568962, 0.00282377112768, 0.00287707862012, + 0.00292488071673, 0.00297083402995, 0.00302034443396, + 0.00306791149356, 0.00311128530472, 0.00315886049123, + 0.0032012867282, 0.00324181579199, 0.00328255488894, + 0.00332106647848, 0.00336006110389, 0.00339953376057, + 0.00343507183824, 0.00347168225631, 0.00350947714109, + 0.00354374653283, 0.00357867641742, 0.00361759403268, + 0.00365056833748, 0.00368612178547, 0.00372126622111, + 0.00375568496126, 0.00378827338665, 0.00382102059653, + 0.00386208119997, 0.00389527759712, 0.00392382196507, + 0.00395898855656, 0.00399254216973, 0.00402263239642, + 0.00405571908096, 0.0040850426166, 0.004115066991, + 0.00414251925121, 0.00417373849783, 0.00420187672507, + 0.00422580041865, 0.00425450461041, 0.00428409252891, + 0.0043057691751, 0.00434121835718, 0.00437168838538, + 0.00439831287327, 0.00443009051949, 0.00446383617502, + 0.00448646538796, 0.00452524116438, 0.00455891945975, + 0.00458584606578, 0.00461675547089, 0.00465411973842, + 0.00468084439834, 0.00470294856029, 0.0047424262336, + 0.00478414058644, 0.00481411031777, 0.00482401661572, + 0.00486137558128, 0.0049171158478, 0.00494417232844, + 0.00496567444129, 0.0049866092171, 0.00500861857974, + 0.00503217184255, 0.0, 0.0, 0.0, 0.0] + + + + dq = mtd['EQSANS_4061_event_frame1_Iq'].readDx(0) + diff = [math.fabs(dq_ref[i]-dq[i])<0.0001 for i in range(7,100)] + output = reduce(lambda x,y:x and y, diff) + + if not output: + for i in range(len(dq)): + print i, dq[i], dq_ref[i], math.fabs(dq_ref[i]-dq[i])<0.0001 + return output \ No newline at end of file diff --git a/Code/Mantid/Testing/SystemTests/tests/analysis/EQSANSNormalisationAPIv2.py b/Code/Mantid/Testing/SystemTests/tests/analysis/EQSANSNormalisationAPIv2.py new file mode 100644 index 000000000000..f11e20d9589b --- /dev/null +++ b/Code/Mantid/Testing/SystemTests/tests/analysis/EQSANSNormalisationAPIv2.py @@ -0,0 +1,150 @@ +import stresstesting +from mantid.simpleapi import * +from reduction_workflow.instruments.sans.sns_command_interface import * +from mantid.api import * +import os + +class EQSANSNormalisationNoFlux(stresstesting.MantidStressTest): + """ + Analysis Tests for EQSANS + Testing that the I(Q) output of is correct + """ + + def runTest(self): + """ + Check that EQSANSTofStructure returns the correct workspace + """ + config = ConfigService.Instance() + config["facilityName"]='SNS' + ws = "__eqsans_normalisation_test" + + EQSANSLoad(Filename="EQSANS_1466_event.nxs", OutputWorkspace=ws, + PreserveEvents=False, LoadMonitors=False) + EQSANSNormalise(InputWorkspace=ws, NormaliseToBeam=False, + OutputWorkspace=ws) + SumSpectra(InputWorkspace=ws, OutputWorkspace="eqsans_no_flux") + + def validate(self): + self.disableChecking.append('Instrument') + self.disableChecking.append('Sample') + self.disableChecking.append('SpectraMap') + self.disableChecking.append('Axes') + + return "eqsans_no_flux", 'EQSANSNormalisation_NoFlux.nxs' + +class EQSANSNormalisationDefault(stresstesting.MantidStressTest): + """ + Analysis Tests for EQSANS + Testing that the I(Q) output of is correct + """ + + def runTest(self): + """ + Check that EQSANSTofStructure returns the correct workspace + """ + config = ConfigService.Instance() + config["facilityName"]='SNS' + ws = "__eqsans_normalisation_test" + + EQSANSLoad(Filename="EQSANS_1466_event.nxs", OutputWorkspace=ws, + PreserveEvents=False, LoadMonitors=False) + EQSANSNormalise(InputWorkspace=ws,NormaliseToBeam=True, + OutputWorkspace=ws) + SumSpectra(InputWorkspace=ws, OutputWorkspace="eqsans_default_flux") + + def validate(self): + # This test only makes sense if /SNS is not available, + # otherwise we will end up using the actual beam file, + # which may not produce the same output. This test + # is meant to exercise the functionality to find the + # beam profile and will only produce the correct results + # on a system that is not hooked up to real instrument files. + if os.path.isdir('/SNS/EQSANS'): + return True + self.disableChecking.append('Instrument') + self.disableChecking.append('Sample') + self.disableChecking.append('SpectraMap') + self.disableChecking.append('Axes') + + return "eqsans_default_flux", 'EQSANSNormalisation_DefaultFlux.nxs' + +class EQSANSNormalisationInputFlux(stresstesting.MantidStressTest): + """ + Analysis Tests for EQSANS + Testing that the I(Q) output of is correct + """ + + def runTest(self): + """ + Check that EQSANSTofStructure returns the correct workspace + """ + config = ConfigService.Instance() + config["facilityName"]='SNS' + ws = "__eqsans_normalisation_test" + spectrum_file = "eqsans_beam_flux.txt" + + EQSANSLoad(Filename="EQSANS_1466_event.nxs", OutputWorkspace=ws, + PreserveEvents=False, LoadMonitors=False) + EQSANSNormalise(InputWorkspace=ws,NormaliseToBeam=True, + BeamSpectrumFile=spectrum_file, + OutputWorkspace=ws) + SumSpectra(InputWorkspace=ws, OutputWorkspace="eqsans_input_flux") + + def validate(self): + self.disableChecking.append('Instrument') + self.disableChecking.append('Sample') + self.disableChecking.append('SpectraMap') + self.disableChecking.append('Axes') + + return "eqsans_input_flux", 'EQSANSNormalisation_InputFlux.nxs' + +class EQSANSNormalisationBeamFlux(stresstesting.MantidStressTest): + """ + Analysis Tests for EQSANS + """ + + def runTest(self): + """ + Check that EQSANSTofStructure returns the correct workspace + """ + config = ConfigService.Instance() + config["facilityName"]='SNS' + self.prop_mng = "eqsans_normalise_options" + self.data_ws = "eqsans_normalise_data_ws" + + EQSANSLoad(Filename="EQSANS_3293_event.nxs", + NoBeamCenter=True, + ReductionProperties=self.prop_mng, + OutputWorkspace=self.data_ws) + + EQSANSNormalise(InputWorkspace=self.data_ws, + BeamSpectrumFile='SANSBeamFluxCorrectionMonitor.nxs', + NormaliseToMonitor=True, + ReductionProperties=self.prop_mng, + OutputWorkspace=self.data_ws) + + def validate(self): + ref_values = [9.66631788e-08, 1.99540011e-08, 0.00000000e+00, 2.84897084e-08, + 2.58802935e-08, 0.00000000e+00, 3.43023370e-08, 1.11017160e-08, + 3.22199520e-08, 8.31598470e-08, 3.05866692e-08, 3.00540473e-08, + 2.97218143e-08, 5.92981344e-08, 2.92735276e-08, 1.91616696e-08, + 4.63637972e-08, 8.94602703e-09, 4.34305480e-08, 1.71487695e-08, + 2.51816301e-08, 3.24283000e-08, 2.40811371e-08, 3.20081242e-08, + 8.03994116e-09, 3.23002602e-08, 2.43204630e-08, 7.99166600e-09, + 2.40009985e-08, 8.04082934e-09, 1.61818559e-08, 2.44975746e-08, + 0.00000000e+00, 2.49096583e-08, 0.00000000e+00, 8.48764614e-09, + 8.59073435e-09, 0.00000000e+00, 8.77853612e-09, 0.00000000e+00, + 3.69158961e-08, 2.16789982e-08, 1.41834793e-08] + + output_y = mtd[self.data_ws].readY(0) + if output_y[0]-ref_values[0] > 0.000006: + return False + if output_y[5]-ref_values[5] > 0.000006: + return False + if output_y[10]-ref_values[10] > 0.000006: + return False + if output_y[25]-ref_values[25] > 0.000006: + return False + + return True + diff --git a/Code/Mantid/Testing/SystemTests/tests/analysis/EQSANSProcessedEffAPIv2.py b/Code/Mantid/Testing/SystemTests/tests/analysis/EQSANSProcessedEffAPIv2.py new file mode 100644 index 000000000000..eb9ec24a140e --- /dev/null +++ b/Code/Mantid/Testing/SystemTests/tests/analysis/EQSANSProcessedEffAPIv2.py @@ -0,0 +1,45 @@ +import stresstesting +import mantid +from mantid.simpleapi import * +from reduction_workflow.instruments.sans.sns_command_interface import * +from mantid.api import FileFinder + +import os + +class EQSANSProcessedEff(stresstesting.MantidStressTest): + + def cleanup(self): + absfile = FileFinder.getFullPath("EQSANS_1466_event_reduction.log") + if os.path.exists(absfile): + os.remove(absfile) + return True + + def runTest(self): + """ + System test for sensitivity correction + """ + config = ConfigService.Instance() + config["facilityName"]='SNS' + EQSANS(False) + AppendDataFile("EQSANS_1466_event.nxs") + SolidAngle() + UseConfig(False) + UseConfigTOFTailsCutoff(False) + UseConfigMask(False) + SetBeamCenter(96.29, 126.15) + SetTransmission(1.0, 0.0) + TotalChargeNormalization(normalize_to_beam=False) + SensitivityCorrection("EQSANS_sensitivity.nxs") + Reduce1D() + Scale(InputWorkspace="EQSANS_1466_event_Iq", Factor=277.781, + Operation='Multiply', OutputWorkspace="EQSANS_1466_event_Iq") + + def validate(self): + # Be more tolerant with the output, mainly because of the errors. + # The following tolerance check the errors up to the third digit. + self.tolerance = 0.1 + self.disableChecking.append('Instrument') + self.disableChecking.append('Sample') + self.disableChecking.append('SpectraMap') + self.disableChecking.append('Axes') + return "EQSANS_1466_event_Iq", 'EQSANSProcessedEff.nxs' diff --git a/Code/Mantid/Testing/SystemTests/tests/analysis/EQSANSSolidAPIv2.py b/Code/Mantid/Testing/SystemTests/tests/analysis/EQSANSSolidAPIv2.py new file mode 100644 index 000000000000..429bfe2cd110 --- /dev/null +++ b/Code/Mantid/Testing/SystemTests/tests/analysis/EQSANSSolidAPIv2.py @@ -0,0 +1,85 @@ +import stresstesting +from mantid.simpleapi import * +from reduction_workflow.instruments.sans.sns_command_interface import * +from mantid.api import * + +import os + +def do_cleanup(): + absfile = FileFinder.getFullPath("EQSANS_1466_event_reduction.log") + if os.path.exists(absfile): + os.remove(absfile) + print "cleaned" + return True + +class EQSANSSolid(stresstesting.MantidStressTest): + + def cleanup(self): + do_cleanup() + return True + """ + Analysis Tests for EQSANS + Testing that the I(Q) output of is correct + """ + + def runTest(self): + """ + Check that EQSANSTofStructure returns the correct workspace + """ + config = ConfigService.Instance() + config["facilityName"]='SNS' + EQSANS(False) + AppendDataFile("EQSANS_1466_event.nxs") + SolidAngle() + UseConfig(False) + UseConfigTOFTailsCutoff(False) + UseConfigMask(False) + TotalChargeNormalization(normalize_to_beam=False) + SetBeamCenter(96.29, 126.15) + SetTransmission(1.0,0.0, False) + Reduce1D() + # Scale up to match correct scaling. + Scale(InputWorkspace="EQSANS_1466_event_Iq", Factor=2777.81, + Operation='Multiply', OutputWorkspace="EQSANS_1466_event_Iq") + + def validate(self): + self.tolerance = 0.2 + mtd["EQSANS_1466_event_Iq"].dataY(0)[0] = 269.688 + mtd["EQSANS_1466_event_Iq"].dataE(0)[0] = 13.8013 + mtd["EQSANS_1466_event_Iq"].dataY(0)[2] = 11.3167 + + self.disableChecking.append('Instrument') + self.disableChecking.append('Sample') + self.disableChecking.append('SpectraMap') + self.disableChecking.append('Axes') + + return "EQSANS_1466_event_Iq", 'EQSANSSolid.nxs' + +class EQSANSSolidEvent(EQSANSSolid): + + def cleanup(self): + do_cleanup() + return True + """ + Analysis Tests for EQSANS + Testing that the I(Q) output of is correct + """ + def runTest(self): + """ + Check that EQSANSTofStructure returns the correct workspace + """ + config = ConfigService.Instance() + config["facilityName"]='SNS' + EQSANS(True) + AppendDataFile("EQSANS_1466_event.nxs") + SolidAngle() + UseConfig(False) + UseConfigTOFTailsCutoff(False) + UseConfigMask(False) + TotalChargeNormalization(normalize_to_beam=False) + SetBeamCenter(96.29, 126.15) + SetTransmission(1.0,0.0, False) + Reduce1D() + # Scale up to match correct scaling. + Scale(InputWorkspace="EQSANS_1466_event_Iq", Factor=2777.81, + Operation='Multiply', OutputWorkspace="EQSANS_1466_event_Iq") diff --git a/Code/Mantid/Testing/SystemTests/tests/analysis/EQSANSTransAPIv2.py b/Code/Mantid/Testing/SystemTests/tests/analysis/EQSANSTransAPIv2.py new file mode 100644 index 000000000000..b6bc10883c35 --- /dev/null +++ b/Code/Mantid/Testing/SystemTests/tests/analysis/EQSANSTransAPIv2.py @@ -0,0 +1,233 @@ +import stresstesting +import mantid +from mantid.simpleapi import * +from reduction_workflow.instruments.sans.sns_command_interface import * +from mantid.api import * + +import os + +def do_cleanup(): + Files = ["EQSANS_4061_event_reduction.log", + "EQSANS_1466_event_reduction.log"] + for file in Files: + absfile = FileFinder.getFullPath(file) + if os.path.exists(absfile): + os.remove(absfile) + return True + +class EQSANSTransmission(stresstesting.MantidStressTest): + + def cleanup(self): + do_cleanup() + return True + + def runTest(self): + config = ConfigService.Instance() + config["facilityName"]='SNS' + EQSANS(False) + AppendDataFile("EQSANS_1466_event.nxs") + SolidAngle() + UseConfig(False) + UseConfigTOFTailsCutoff(False) + CombineTransmissionFits(True) + UseConfigMask(False) + SetBeamCenter(96.29, 126.15) + TotalChargeNormalization(normalize_to_beam=False) + DirectBeamTransmission("EQSANS_1466_event.nxs", "EQSANS_4061_event.nxs", beam_radius=3) + ThetaDependentTransmission(True) + Reduce1D() + # Scale up to match correct scaling. + Scale(InputWorkspace="EQSANS_1466_event_Iq", Factor=2777.81, + Operation='Multiply', OutputWorkspace="EQSANS_1466_event_Iq") + + def validate(self): + # Be more tolerant with the output, mainly because of the errors. + # The following tolerance check the errors up to the third digit. + self.tolerance = 0.1 + self.disableChecking.append('Instrument') + self.disableChecking.append('Sample') + self.disableChecking.append('SpectraMap') + self.disableChecking.append('Axes') + return "EQSANS_1466_event_Iq", 'EQSANSTrans.nxs' + +class EQSANSTransmissionEvent(EQSANSTransmission): + + def cleanup(self): + do_cleanup() + return True + + def runTest(self): + config = ConfigService.Instance() + config["facilityName"]='SNS' + EQSANS(True) + AppendDataFile("EQSANS_1466_event.nxs") + SolidAngle() + UseConfig(False) + UseConfigTOFTailsCutoff(False) + UseConfigMask(False) + SetBeamCenter(96.29, 126.15) + TotalChargeNormalization(normalize_to_beam=False) + DirectBeamTransmission("EQSANS_1466_event.nxs", "EQSANS_4061_event.nxs", beam_radius=3) + ThetaDependentTransmission(True) + Reduce1D() + # Scale up to match correct scaling. + Scale(InputWorkspace="EQSANS_1466_event_Iq", Factor=2777.81, + Operation='Multiply', OutputWorkspace="EQSANS_1466_event_Iq") + + def validate(self): + # Be more tolerant with the output, mainly because of the errors. + # The following tolerance check the errors up to the third digit. + self.tolerance = 0.1 + self.disableChecking.append('Instrument') + self.disableChecking.append('Sample') + self.disableChecking.append('SpectraMap') + self.disableChecking.append('Axes') + return "EQSANS_1466_event_Iq", 'EQSANSTransEvent.nxs' + + +class EQSANSTransmissionDC(stresstesting.MantidStressTest): + + def cleanup(self): + do_cleanup() + return True + + def runTest(self): + """ + Check that EQSANSTofStructure returns the correct workspace + """ + config = ConfigService.Instance() + config["facilityName"]='SNS' + EQSANS(False) + AppendDataFile("EQSANS_1466_event.nxs") + SolidAngle() + UseConfig(False) + UseConfigTOFTailsCutoff(False) + UseConfigMask(False) + SetBeamCenter(96.29, 126.15) + DarkCurrent("EQSANS_4061_event.nxs") + TotalChargeNormalization(normalize_to_beam=False) + DirectBeamTransmission("EQSANS_1466_event.nxs", "EQSANS_1466_event.nxs", beam_radius=3) + ThetaDependentTransmission(True) + Reduce1D() + # Scale up to match correct scaling. + Scale(InputWorkspace="EQSANS_1466_event_Iq", Factor=2777.81, + Operation='Multiply', OutputWorkspace="EQSANS_1466_event_Iq") + + def validate(self): + # Be more tolerant with the output, mainly because of the errors. + # The following tolerance check the errors up to the third digit. + self.tolerance = 0.1 + self.disableChecking.append('Instrument') + self.disableChecking.append('Sample') + self.disableChecking.append('SpectraMap') + self.disableChecking.append('Axes') + return "EQSANS_1466_event_Iq", 'EQSANSTransmissionDC.nxs' + +class EQSANSTransmissionCompatibility(EQSANSTransmission): + + def cleanup(self): + do_cleanup() + return True + + """ + Analysis Tests for EQSANS + Check that the transmission correction can be applied if the + sample run and transmission runs don't have the same binning + """ + + def runTest(self): + config = ConfigService.Instance() + config["facilityName"]='SNS' + EQSANS(True) + AppendDataFile("EQSANS_1466_event.nxs") + SolidAngle() + UseConfig(False) + UseConfigTOFTailsCutoff(False) + UseConfigMask(False) + SetBeamCenter(96.29, 126.15) + TotalChargeNormalization(normalize_to_beam=False) + DirectBeamTransmission("EQSANS_4061_event.nxs", "EQSANS_4061_event.nxs", beam_radius=3) + ThetaDependentTransmission(True) + Reduce1D() + # Scale up to match correct scaling. + Scale(InputWorkspace="EQSANS_1466_event_Iq", Factor=2777.81, + Operation='Multiply', OutputWorkspace="EQSANS_1466_event_Iq") + + def validate(self): + # Be more tolerant with the output, mainly because of the errors. + # The following tolerance check the errors up to the third digit. + self.tolerance = 0.1 + self.disableChecking.append('Instrument') + self.disableChecking.append('Sample') + self.disableChecking.append('SpectraMap') + self.disableChecking.append('Axes') + return "EQSANS_1466_event_Iq", 'EQSANSTransmissionCompatibility.nxs' + +class EQSANSTransmissionFS(stresstesting.MantidStressTest): + + def cleanup(self): + do_cleanup() + return True + + def runTest(self): + """ + Check that EQSANSTofStructure returns the correct workspace + """ + config = ConfigService.Instance() + config["facilityName"]='SNS' + EQSANS(False) + SetBeamCenter(96.29, 126.15) + AppendDataFile("EQSANS_4061_event.nxs") + SolidAngle() + UseConfig(False) + UseConfigTOFTailsCutoff(False) + UseConfigMask(False) + TotalChargeNormalization(normalize_to_beam=False) + SetTransmission(0.5, 0.1) + ThetaDependentTransmission(False) + Reduce1D() + + def validate(self): + self.tolerance = 0.000001 + self.disableChecking.append('Instrument') + self.disableChecking.append('Sample') + self.disableChecking.append('SpectraMap') + self.disableChecking.append('Axes') + return "EQSANS_4061_event_frame1_Iq", 'EQSANSTransmissionFS.nxs' + +class EQSANSDirectTransFS(stresstesting.MantidStressTest): + + def cleanup(self): + do_cleanup() + return True + + def runTest(self): + """ + Check that EQSANSTofStructure returns the correct workspace + """ + config = ConfigService.Instance() + config["facilityName"]='SNS' + EQSANS(False) + SetBeamCenter(96.29, 126.15) + AppendDataFile("EQSANS_4061_event.nxs") + UseConfig(False) + SetTOFTailsCutoff(500, 500) + UseConfigMask(False) + TotalChargeNormalization(normalize_to_beam=False) + DirectBeamTransmission("EQSANS_4061_event.nxs", "EQSANS_4061_event.nxs", beam_radius=3) + ThetaDependentTransmission(False) + NoIQxQy() + Reduce1D() + Scale(InputWorkspace="EQSANS_4061_event_frame1_Iq", Factor=2.0, + Operation='Multiply', OutputWorkspace="EQSANS_4061_event_frame1_Iq") + + def validate(self): + # Relax the tolerance since the reference data is not for that exact + # scenario but for one that's very close to it. + self.tolerance = 0.00001 + self.disableChecking.append('Instrument') + self.disableChecking.append('Sample') + self.disableChecking.append('SpectraMap') + self.disableChecking.append('Axes') + return "EQSANS_4061_event_frame1_Iq", 'EQSANSDirectTransFS.nxs' + diff --git a/Code/Mantid/Testing/SystemTests/tests/analysis/EllipsoidIntegr.py b/Code/Mantid/Testing/SystemTests/tests/analysis/EllipsoidIntegr.py new file mode 100644 index 000000000000..30bc5c2ce893 --- /dev/null +++ b/Code/Mantid/Testing/SystemTests/tests/analysis/EllipsoidIntegr.py @@ -0,0 +1,72 @@ +# File: EllipsoidIntegr.py +# +# Integrates a run using the ellipsoid technique + +import os +import sys +import shutil +import time + +import stresstesting +import numpy + + +from mantid.api import * +#sys.path.append("/home/ruth/GIT_MantidBuild/bin/") +from mantid.simpleapi import * + +class EllipsoidIntegr( stresstesting.MantidStressTest): + + def requiredMemoryMB(self): + """ Require about 12GB free """ + return 2000 + + def runTest(self): + # expected results with size determined + # automatically from projected event sigmas + inti_auto = [ 88, 99, 23, 33, 8, 8, 4 ] + sigi_auto = [ 13.784, 18.1384, 13.1529, 9.94987, 5.83095, 10.2956, 10.2956] + # expected results with fixed size + # ellipsoids + inti_fixed = [ 87.541, 95.3934, 21.3607, 33.4262, 7.36066, 9.68852, 3.54098 ] + sigi_fixed = [ 13.9656, 18.4523, 13.4335, 10.1106, 5.94223, 10.5231, 10.5375 ] + + # first, load peaks into a peaks workspace + + + peaks_file = "TOPAZ_3007.peaks" + peaks_ws_name="TOPAZ_3007_peaks" + LoadIsawPeaks( Filename=peaks_file,OutputWorkspace = peaks_ws_name) + + + # next, load events into an event workspace + event_file="TOPAZ_3007_bank_37_20_sec.nxs" + event_ws_name="TOPAZ_3007_events" + + LoadNexus(Filename=event_file, OutputWorkspace=event_ws_name) + # configure and test the algorithm + # using automatically determined + # ellipsoid sizes + IntegrateEllipsoids(event_ws_name, peaks_ws_name,".25","0",".2",".2",".25",OutputWorkspace=peaks_ws_name) + + peaks_ws = mtd[peaks_ws_name] + for i in range( 13, 20) : + + self.assertDelta( peaks_ws.getPeak(i).getIntensity(), inti_auto[i-13], 0.1 ) + self.assertDelta( peaks_ws.getPeak(i).getSigmaIntensity(), sigi_auto[i-13], 0.1 ) + + # configure and test the algorithm + # using fixed ellipsoid sizes + peaks_ws=IntegrateEllipsoids( event_ws_name,peaks_ws_name,.25,1,.2,.2,.25,OutputWorkspace=peaks_ws_name) + peaks_ws = mtd[peaks_ws_name] + + for i in range( 13,20 ): + self.assertDelta(peaks_ws.getPeak(i).getIntensity(), inti_fixed[i-13], 0.1 ) + self.assertDelta( peaks_ws.getPeak(i).getSigmaIntensity(), sigi_fixed[i-13], 0.1 ) + + def validate(self): + return True + + def requiredFiles(self): + + return ["TOPAZ_3007_bank_37_20_sec.nxs","TOPAZ_3007.peaks"] \ No newline at end of file diff --git a/Code/Mantid/Testing/SystemTests/tests/analysis/EnginXCalibrateTest.py b/Code/Mantid/Testing/SystemTests/tests/analysis/EnginXCalibrateTest.py new file mode 100644 index 000000000000..ac53f59b55c3 --- /dev/null +++ b/Code/Mantid/Testing/SystemTests/tests/analysis/EnginXCalibrateTest.py @@ -0,0 +1,28 @@ +import platform +import stresstesting +from mantid.simpleapi import * + +class EnginXCalibrateTest(stresstesting.MantidStressTest): + + def runTest(self): + positions = EnginXCalibrateFull(Filename = 'ENGINX00193749.nxs', + Bank = 1, + ExpectedPeaks = '1.3529, 1.6316, 1.9132') + + (self.difc, self.zero) = EnginXCalibrate(Filename = 'ENGINX00193749.nxs', + Bank = 1, + ExpectedPeaks = '2.7057,1.9132,1.6316,1.5621,1.3528,0.9566', + DetectorPositions = positions) + + def validate(self): + import sys + if sys.platform == "darwin": + # Mac fitting tests produce differences for some reason. + self.assertDelta(self.difc, 18405.4, 0.1) + self.assertDelta(self.zero, 3.53, 0.05) + else: + self.assertDelta(self.difc, 18404.522, 0.001) + self.assertDelta(self.zero, 4.426, 0.001) + + def cleanup(self): + mtd.remove('positions') diff --git a/Code/Mantid/Testing/SystemTests/tests/analysis/FilteredLoadvsLoadThenFilter.py b/Code/Mantid/Testing/SystemTests/tests/analysis/FilteredLoadvsLoadThenFilter.py new file mode 100644 index 000000000000..23b8dbeedd39 --- /dev/null +++ b/Code/Mantid/Testing/SystemTests/tests/analysis/FilteredLoadvsLoadThenFilter.py @@ -0,0 +1,18 @@ +import stresstesting +from mantid.simpleapi import * + +'''Tests that filtering with LoadEventNexus gives the same answer as loading the whole file and then filtering''' +class FilteredLoadvsLoadThenFilter(stresstesting.MantidStressTest): + + def runTest(self): + filteredLoad = LoadEventNexus("CNCS_7860_event.nxs",FilterByTimeStart=60.0,FilterByTimeStop=120.0,FilterByTofMin=-1e10,FilterByTofMax=1e10) + loadAll = LoadEventNexus("CNCS_7860_event.nxs",FilterByTimeStart=-1e10,FilterByTimeStop=1e10,FilterByTofMin=-1e10,FilterByTofMax=1e10) + loadAndFilter = FilterByTime(loadAll,StartTime=60.0,StopTime=120.0) + # This next step is needed otherwise the X boundaries are different causing CheckWorkspacesMatch to fail + loadAndFilter = RebinToWorkspace(WorkspaceToRebin=loadAndFilter,WorkspaceToMatch=filteredLoad) + + def validateMethod(self): + return "ValidateWorkspaceToWorkspace" + + def validate(self): + return 'filteredLoad','loadAndFilter' diff --git a/Code/Mantid/Testing/SystemTests/tests/analysis/GEMTests.py b/Code/Mantid/Testing/SystemTests/tests/analysis/GEMTests.py new file mode 100644 index 000000000000..8f7bb3ec9c03 --- /dev/null +++ b/Code/Mantid/Testing/SystemTests/tests/analysis/GEMTests.py @@ -0,0 +1,185 @@ +import stresstesting +import os +from mantid.simpleapi import * + +class GEMTest(stresstesting.MantidStressTest): + + def __init__(self): + stresstesting.MantidStressTest.__init__(self) + self.gss_file = '' + self.ref_gss_file = 'GEM58654.gss' + self.xye_tof_files = [] + self.ref_xye_tof_files = ['GEM58654_b1_TOF.dat','GEM58654_b2_TOF.dat','GEM58654_b3_TOF.dat','GEM58654_b4_TOF.dat','GEM58654_b5_TOF.dat','GEM58654_b6_TOF.dat'] + self.xye_d_files = [] + self.ref_xye_d_files = ['GEM58654_b1_D.dat','GEM58654_b2_D.dat','GEM58654_b3_D.dat','GEM58654_b4_D.dat','GEM58654_b5_D.dat','GEM58654_b6_D.dat'] + self.file_index = 0 + self.new_cal_file = '' + + def runTest(self): + # do something + LoadRaw(Filename=r'GEM59378.raw',OutputWorkspace='Vanadium',LoadLogFiles='0') + CreateSingleValuedWorkspace(OutputWorkspace='totuamps',DataValue='450.02215576200001') + Divide(LHSWorkspace='Vanadium',RHSWorkspace='totuamps',OutputWorkspace='Vanadium') + SolidAngle(InputWorkspace='Vanadium',OutputWorkspace='Corr') + CreateSingleValuedWorkspace(OutputWorkspace='Sc',DataValue='100') + Multiply(LHSWorkspace='Corr',RHSWorkspace='Sc',OutputWorkspace='Corr') + Divide(LHSWorkspace='Vanadium',RHSWorkspace='Corr',OutputWorkspace='Vanadium') + ConvertUnits(InputWorkspace='Vanadium',OutputWorkspace='Vanadium',Target='Wavelength') + Integration(InputWorkspace='Vanadium',OutputWorkspace='Vanadium',RangeLower='1.3999999999999999',RangeUpper='3') + Multiply(LHSWorkspace='Corr',RHSWorkspace='Vanadium',OutputWorkspace='Corr') + DeleteWorkspace('Vanadium') + CreateSingleValuedWorkspace(OutputWorkspace='Sc',DataValue='100000') + Divide(LHSWorkspace='Corr',RHSWorkspace='Sc',OutputWorkspace='Corr') + + self.new_cal_file = os.path.join(config['defaultsave.directory'],'offsets_2011_cycle111b_new.cal') + MaskDetectorsIf(InputWorkspace='Corr',Mode='DeselectIf',InputCalFile=r'offsets_2011_cycle111b.cal',OutputCalFile=self.new_cal_file) + # load precompiled vanadium files + LoadNexusProcessed(Filename=r'van_gem59378_benchmark-0.nxs',OutputWorkspace='Vanadium-1') + LoadNexusProcessed(Filename=r'van_gem59378_benchmark-1.nxs',OutputWorkspace='Vanadium-2') + LoadNexusProcessed(Filename=r'van_gem59378_benchmark-2.nxs',OutputWorkspace='Vanadium-3') + LoadNexusProcessed(Filename=r'van_gem59378_benchmark-3.nxs',OutputWorkspace='Vanadium-4') + LoadNexusProcessed(Filename=r'van_gem59378_benchmark-4.nxs',OutputWorkspace='Vanadium-5') + LoadNexusProcessed(Filename=r'van_gem59378_benchmark-5.nxs',OutputWorkspace='Vanadium-6') + # load data + LoadRaw(Filename=r'GEM58654.raw',OutputWorkspace='sample',LoadLogFiles='0') + LoadRaw(Filename=r'GEM58654.raw',OutputWorkspace='sampleadd',LoadLogFiles='0') + Plus(LHSWorkspace='sampleadd',RHSWorkspace='sample',OutputWorkspace='sample') + DeleteWorkspace('sampleadd') + CreateSingleValuedWorkspace(OutputWorkspace='totuamps',DataValue='600.05676269499997') + Divide(LHSWorkspace='sample',RHSWorkspace='totuamps',OutputWorkspace='sample') + + LoadRaw(Filename=r'GEM59381.raw',OutputWorkspace='Sempty',LoadLogFiles='0') + CreateSingleValuedWorkspace(OutputWorkspace='totuamps',DataValue='400.04138183600003') + Divide(LHSWorkspace='Sempty',RHSWorkspace='totuamps',OutputWorkspace='Sempty') + Minus(LHSWorkspace='sample',RHSWorkspace='Sempty',OutputWorkspace='sample') + DeleteWorkspace('Sempty') + AlignDetectors(InputWorkspace='sample',OutputWorkspace='sample',CalibrationFile=r'offsets_2011_cycle111b.cal') + Divide(LHSWorkspace='sample',RHSWorkspace='Corr',OutputWorkspace='sample') + DeleteWorkspace('Corr') + CreateSingleValuedWorkspace(OutputWorkspace='scale',DataValue='1') + Multiply(LHSWorkspace='sample',RHSWorkspace='scale',OutputWorkspace='sample') + ConvertUnits(InputWorkspace='sample',OutputWorkspace='sample',Target='Wavelength') + CylinderAbsorption(InputWorkspace='sample',OutputWorkspace='SampleTrans',AttenuationXSection='0.5',ScatteringXSection='1',SampleNumberDensity='1',NumberOfWavelengthPoints='100',CylinderSampleHeight='4',CylinderSampleRadius='0.40000000000000002',NumberOfSlices='10',NumberOfAnnuli='10') + Divide(LHSWorkspace='sample',RHSWorkspace='SampleTrans',OutputWorkspace='sample') + ConvertUnits(InputWorkspace='sample',OutputWorkspace='sample',Target='dSpacing') + DiffractionFocussing(InputWorkspace='sample',OutputWorkspace='sample',GroupingFileName=self.new_cal_file) + + CropWorkspace(InputWorkspace='sample',OutputWorkspace='sample-1',EndWorkspaceIndex='0') + CropWorkspace(InputWorkspace='sample',OutputWorkspace='sample-2',StartWorkspaceIndex='1',EndWorkspaceIndex='1') + CropWorkspace(InputWorkspace='sample',OutputWorkspace='sample-3',StartWorkspaceIndex='2',EndWorkspaceIndex='2') + CropWorkspace(InputWorkspace='sample',OutputWorkspace='sample-4',StartWorkspaceIndex='3',EndWorkspaceIndex='3') + CropWorkspace(InputWorkspace='sample',OutputWorkspace='sample-5',StartWorkspaceIndex='4',EndWorkspaceIndex='4') + CropWorkspace(InputWorkspace='sample',OutputWorkspace='sample-6',StartWorkspaceIndex='5',EndWorkspaceIndex='5') + DeleteWorkspace('sample') + Divide(LHSWorkspace='sample-1',RHSWorkspace='Vanadium-1',OutputWorkspace='ResultD-1') + Divide(LHSWorkspace='sample-2',RHSWorkspace='Vanadium-2',OutputWorkspace='ResultD-2') + Divide(LHSWorkspace='sample-3',RHSWorkspace='Vanadium-3',OutputWorkspace='ResultD-3') + Divide(LHSWorkspace='sample-4',RHSWorkspace='Vanadium-4',OutputWorkspace='ResultD-4') + Divide(LHSWorkspace='sample-5',RHSWorkspace='Vanadium-5',OutputWorkspace='ResultD-5') + Divide(LHSWorkspace='sample-6',RHSWorkspace='Vanadium-6',OutputWorkspace='ResultD-6') + Rebin(InputWorkspace='ResultD-1',OutputWorkspace='ResultD-1',Params='0.559211,-0.004,37.6844') + Rebin(InputWorkspace='ResultD-2',OutputWorkspace='ResultD-2',Params='0.348675,-0.002,14.5631') + Rebin(InputWorkspace='ResultD-3',OutputWorkspace='ResultD-3',Params='0.169661,-0.0011546,8.06311') + Rebin(InputWorkspace='ResultD-4',OutputWorkspace='ResultD-4',Params='0.108284,-0.00111682,4.25328') + Rebin(InputWorkspace='ResultD-5',OutputWorkspace='ResultD-5',Params='0.0818697,-0.00109142,2.82906') + Rebin(InputWorkspace='ResultD-6',OutputWorkspace='ResultD-6',Params='0.0661098,-0.00105175,1.87008') + ConvertUnits(InputWorkspace='ResultD-1',OutputWorkspace='ResultTOF-1',Target='TOF') + ReplaceSpecialValues(InputWorkspace='ResultD-1',OutputWorkspace='ResultD-1',NaNValue='0',InfinityValue='0',BigNumberThreshold='99999999.999999985') + ReplaceSpecialValues(InputWorkspace='ResultTOF-1',OutputWorkspace='ResultTOF-1',NaNValue='0',InfinityValue='0',BigNumberThreshold='99999999.999999985') + ConvertUnits(InputWorkspace='ResultD-2',OutputWorkspace='ResultTOF-2',Target='TOF') + ReplaceSpecialValues(InputWorkspace='ResultD-2',OutputWorkspace='ResultD-2',NaNValue='0',InfinityValue='0',BigNumberThreshold='99999999.999999985') + ReplaceSpecialValues(InputWorkspace='ResultTOF-2',OutputWorkspace='ResultTOF-2',NaNValue='0',InfinityValue='0',BigNumberThreshold='99999999.999999985') + ConvertUnits(InputWorkspace='ResultD-3',OutputWorkspace='ResultTOF-3',Target='TOF') + ReplaceSpecialValues(InputWorkspace='ResultD-3',OutputWorkspace='ResultD-3',NaNValue='0',InfinityValue='0',BigNumberThreshold='99999999.999999985') + ReplaceSpecialValues(InputWorkspace='ResultTOF-3',OutputWorkspace='ResultTOF-3',NaNValue='0',InfinityValue='0',BigNumberThreshold='99999999.999999985') + ConvertUnits(InputWorkspace='ResultD-4',OutputWorkspace='ResultTOF-4',Target='TOF') + ReplaceSpecialValues(InputWorkspace='ResultD-4',OutputWorkspace='ResultD-4',NaNValue='0',InfinityValue='0',BigNumberThreshold='99999999.999999985') + ReplaceSpecialValues(InputWorkspace='ResultTOF-4',OutputWorkspace='ResultTOF-4',NaNValue='0',InfinityValue='0',BigNumberThreshold='99999999.999999985') + ConvertUnits(InputWorkspace='ResultD-5',OutputWorkspace='ResultTOF-5',Target='TOF') + ReplaceSpecialValues(InputWorkspace='ResultD-5',OutputWorkspace='ResultD-5',NaNValue='0',InfinityValue='0',BigNumberThreshold='99999999.999999985') + ReplaceSpecialValues(InputWorkspace='ResultTOF-5',OutputWorkspace='ResultTOF-5',NaNValue='0',InfinityValue='0',BigNumberThreshold='99999999.999999985') + ConvertUnits(InputWorkspace='ResultD-6',OutputWorkspace='ResultTOF-6',Target='TOF') + ReplaceSpecialValues(InputWorkspace='ResultD-6',OutputWorkspace='ResultD-6',NaNValue='0',InfinityValue='0',BigNumberThreshold='99999999.999999985') + ReplaceSpecialValues(InputWorkspace='ResultTOF-6',OutputWorkspace='ResultTOF-6',NaNValue='0',InfinityValue='0',BigNumberThreshold='99999999.999999985') + + # group and save + GroupWorkspaces(InputWorkspaces='ResultTOF-1,ResultTOF-2,ResultTOF-3,ResultTOF-4,ResultTOF-5,ResultTOF-6',OutputWorkspace='ResultTOFgrp') + + self.gss_file = os.path.join(config['defaultsave.directory'],'GEM58654_new.gss') + append=False + for i in range(1,7): + if i > 1: + append=True + SaveGSS(InputWorkspace='ResultTOF-%d' % i,Filename=self.gss_file,SplitFiles=False,Append=append,Bank=i) + + filename= os.path.join(config['defaultsave.directory'],r'GEM58654_b%d_TOF.dat' % i) + SaveFocusedXYE(InputWorkspace='ResultTOF-%d' % i,Filename=filename,SplitFiles=False,IncludeHeader='0') + self.xye_tof_files.append(filename) + + filename= os.path.join(config['defaultsave.directory'],r'GEM58654_b%d_D.dat' % i) + SaveFocusedXYE(InputWorkspace='ResultD-%d' % i,Filename=filename,SplitFiles=False,IncludeHeader='0') + self.xye_d_files.append(filename) + + def cleanup(self): + '''Remove temporary files''' + if os.path.exists(self.gss_file): + os.remove(self.gss_file) + if os.path.exists(self.new_cal_file): + os.remove(self.new_cal_file) + for file in self.xye_tof_files: + if os.path.exists(file): + os.remove(file) + for file in self.xye_d_files: + if os.path.exists(file): + os.remove(file) + + def doValidation(self): + '''Override doValidation to vaildate two things at the same time''' + self.disableChecking.append('Instrument') + # reset validate() method to call validateNexus() instead + self.validate = self.validateNexus + res = self.validateWorkspaceToNeXus() + if not res: + return False + # reset validate() method to call validateGSS() + self.validate = self.validateGSS + res = self.validateASCII() + if not res: + return False + # reset validate() method to call validateTOFXYE() + self.validate = self.validateTOFXYE + self.file_index = 0 + # file_index is incremented after each call to validateASCII() + res = self.validateASCII() and self.validateASCII() and self.validateASCII() and self.validateASCII() and self.validateASCII() and self.validateASCII() + if not res: + return False + # reset validate() method to call validateTOFXYE() + self.validate = self.validateDXYE + self.file_index = 0 + # file_index is incremented after each call to validateASCII() + res = self.validateASCII() and self.validateASCII() and self.validateASCII() and self.validateASCII() and self.validateASCII() and self.validateASCII() + return res + + def validateNexus(self): + '''Compare the result of reduction with the reference nexus file''' + return 'ResultTOFgrp','GEM58654.nxs' + + def validateGSS(self): + '''Validate the created gss file''' + from mantid.api import FileFinder + return self.gss_file, FileFinder.getFullPath(self.ref_gss_file) + + def validateTOFXYE(self): + '''Validate the created gss file''' + from mantid.api import FileFinder + i = self.file_index + self.file_index += 1 + return self.xye_tof_files[i], FileFinder.getFullPath(self.ref_xye_tof_files[i]) + + def validateDXYE(self): + '''Validate the created gss file''' + from mantid.api import FileFinder + i = self.file_index + self.file_index += 1 + return self.xye_d_files[i], FileFinder.getFullPath(self.ref_xye_d_files[i]) + diff --git a/Code/Mantid/Testing/SystemTests/tests/analysis/HFIRBackgroundAPIv2.py b/Code/Mantid/Testing/SystemTests/tests/analysis/HFIRBackgroundAPIv2.py new file mode 100644 index 000000000000..f047afcd211e --- /dev/null +++ b/Code/Mantid/Testing/SystemTests/tests/analysis/HFIRBackgroundAPIv2.py @@ -0,0 +1,176 @@ +import stresstesting +import mantid +from mantid.api import FileFinder +from mantid.simpleapi import * +from reduction_workflow.instruments.sans.hfir_command_interface import * + +import os + +def do_cleanup(): + Files = ["BioSANS_test_data_reduction.log", + "BioSANS_test_data_Iq.xml", + "BioSANS_test_data_Iq.txt", + "BioSANS_test_data_Iqxy.dat"] + for file in Files: + absfile = FileFinder.getFullPath(file) + if os.path.exists(absfile): + os.remove(absfile) + return True + +class HFIRBackground(stresstesting.MantidStressTest): + + def cleanup(self): + do_cleanup() + return True + + def runTest(self): + config = ConfigService.Instance() + config["facilityName"]='HFIR' + GPSANS() + SetBeamCenter(16, 95) + AppendDataFile("BioSANS_test_data.xml") + Background("BioSANS_test_data.xml") + AzimuthalAverage(binning="0.01,0.001,0.11", error_weighting=True) + Reduce1D() + + def validate(self): + self.tolerance = 0.00001 + self.disableChecking.append('Instrument') + self.disableChecking.append('Sample') + self.disableChecking.append('SpectraMap') + self.disableChecking.append('Axes') + return "BioSANS_test_data_Iq", 'HFIRBackground.nxs' + +class HFIRBackgroundTransmission(stresstesting.MantidStressTest): + + def cleanup(self): + do_cleanup() + return True + + def runTest(self): + config = ConfigService.Instance() + config["facilityName"]='HFIR' + GPSANS() + AppendDataFile("BioSANS_test_data.xml") + Background("BioSANS_test_data.xml") + SetBckTransmission(0.55, 0.1) + AzimuthalAverage(binning="0.01,0.001,0.11", error_weighting=True) + Reduce1D() + + def validate(self): + self.tolerance = 0.00001 + self.disableChecking.append('Instrument') + self.disableChecking.append('Sample') + self.disableChecking.append('SpectraMap') + self.disableChecking.append('Axes') + return "BioSANS_test_data_Iq", 'HFIRBackgroundTransmission.nxs' + +class HFIRBackgroundDirectBeamTrans(stresstesting.MantidStressTest): + + def cleanup(self): + do_cleanup() + return True + + def runTest(self): + config = ConfigService.Instance() + config["facilityName"]='HFIR' + GPSANS() + AppendDataFile("BioSANS_test_data.xml") + Background("BioSANS_test_data.xml") + BckDirectBeamTransmission(sample_file="BioSANS_sample_trans.xml", + empty_file="BioSANS_empty_trans.xml", + beam_radius=10.0) + AzimuthalAverage(binning="0.01,0.001,0.11", error_weighting=True) + Reduce1D() + + def validate(self): + self.tolerance = 0.00001 + self.disableChecking.append('Instrument') + self.disableChecking.append('Sample') + self.disableChecking.append('SpectraMap') + self.disableChecking.append('Axes') + return "BioSANS_test_data_Iq", 'HFIRBackgroundDirectBeamTrans.nxs' + +class HFIRBackgroundBeamSpreaderTrans(stresstesting.MantidStressTest): + + def cleanup(self): + do_cleanup() + return True + + def runTest(self): + config = ConfigService.Instance() + config["facilityName"]='HFIR' + GPSANS() + AppendDataFile("BioSANS_test_data.xml") + Background("BioSANS_test_data.xml") + BckBeamSpreaderTransmission(sample_spreader="BioSANS_test_data.xml", + direct_spreader="BioSANS_empty_cell.xml", + sample_scattering="BioSANS_test_data.xml", + direct_scattering="BioSANS_empty_cell.xml", + spreader_transmission=0.5, + spreader_transmission_err=0.1) + AzimuthalAverage(binning="0.01,0.001,0.11") + Reduce1D() + + def validate(self): + self.tolerance = 0.00001 + self.disableChecking.append('Instrument') + self.disableChecking.append('Sample') + self.disableChecking.append('SpectraMap') + self.disableChecking.append('Axes') + return "BioSANS_test_data_Iq", 'HFIRBackgroundBeamSpreaderTrans.nxs' + +class HFIRBackgroundTransDarkCurrent(stresstesting.MantidStressTest): + + def cleanup(self): + do_cleanup() + return True + + def runTest(self): + config = ConfigService.Instance() + config["facilityName"]='HFIR' + GPSANS() + AppendDataFile("BioSANS_test_data.xml") + Background("BioSANS_test_data.xml") + BckDirectBeamTransmission(sample_file="BioSANS_sample_trans.xml", + empty_file="BioSANS_empty_trans.xml", + beam_radius=10.0) + BckTransmissionDarkCurrent("BioSANS_dark_current.xml") + AzimuthalAverage(binning="0.01,0.001,0.11", error_weighting=True) + Reduce1D() + + def validate(self): + self.tolerance = 0.00001 + self.disableChecking.append('Instrument') + self.disableChecking.append('Sample') + self.disableChecking.append('SpectraMap') + self.disableChecking.append('Axes') + return "BioSANS_test_data_Iq", 'HFIRBackgroundTransDarkCurrent.nxs' + +class HFIRBackgroundDirectBeamTransDC(stresstesting.MantidStressTest): + + def cleanup(self): + do_cleanup() + return True + + def runTest(self): + config = ConfigService.Instance() + config["facilityName"]='HFIR' + GPSANS() + AppendDataFile("BioSANS_test_data.xml") + Background("BioSANS_test_data.xml") + BckDirectBeamTransmission(sample_file="BioSANS_sample_trans.xml", + empty_file="BioSANS_empty_trans.xml", + beam_radius=10.0) + BckTransmissionDarkCurrent("BioSANS_dark_current.xml") + AzimuthalAverage(binning="0.01,0.001,0.11", error_weighting=True) + Reduce1D() + + def validate(self): + self.tolerance = 0.00001 + self.disableChecking.append('Instrument') + self.disableChecking.append('Sample') + self.disableChecking.append('SpectraMap') + self.disableChecking.append('Axes') + return "BioSANS_test_data_Iq", 'HFIRBackgroundDirectBeamTransDC.nxs' + diff --git a/Code/Mantid/Testing/SystemTests/tests/analysis/HFIREffAPIv2.py b/Code/Mantid/Testing/SystemTests/tests/analysis/HFIREffAPIv2.py new file mode 100644 index 000000000000..f8a80cfcea51 --- /dev/null +++ b/Code/Mantid/Testing/SystemTests/tests/analysis/HFIREffAPIv2.py @@ -0,0 +1,109 @@ +import stresstesting +import mantid +from mantid.api import FileFinder +from mantid.simpleapi import * +from reduction_workflow.instruments.sans.hfir_command_interface import * + +import os + +def do_cleanup(): + Files = ["BioSANS_test_data_reduction.log", + "BioSANS_test_data_Iq.xml", + "BioSANS_test_data_Iq.txt", + "BioSANS_test_data_Iqxy.dat"] + for file in Files: + absfile = FileFinder.getFullPath(file) + if os.path.exists(absfile): + os.remove(absfile) + return True + +class HFIREffAPIv2(stresstesting.MantidStressTest): + + def cleanup(self): + do_cleanup() + return True + + def runTest(self): + """ + System test for sensitivity correction + """ + config = ConfigService.Instance() + config["facilityName"]='HFIR' + GPSANS() + DirectBeamCenter("BioSANS_empty_cell.xml") + AppendDataFile("BioSANS_test_data.xml") + SetTransmission(0.51944, 0.011078) + SensitivityCorrection("BioSANS_flood_data.xml", dark_current="BioSANS_dark_current.xml") + AzimuthalAverage(binning="0.01,0.001,0.11", error_weighting=True) + Reduce1D() + + def validate(self): + self.tolerance = 0.00001 + self.disableChecking.append('Instrument') + self.disableChecking.append('Sample') + self.disableChecking.append('SpectraMap') + self.disableChecking.append('Axes') + return "BioSANS_test_data_Iq", 'HFIREff.nxs' + +class HFIRSensitivityDirectBeamCenter(stresstesting.MantidStressTest): + + def cleanup(self): + do_cleanup() + return True + + def runTest(self): + """ + System test for sensitivity correction + """ + config = ConfigService.Instance() + config["facilityName"]='HFIR' + GPSANS() + DirectBeamCenter("BioSANS_empty_cell.xml") + AppendDataFile("BioSANS_test_data.xml") + SetTransmission(0.51944, 0.011078) + SensitivityCorrection("BioSANS_flood_data.xml", + dark_current="BioSANS_dark_current.xml") + SensitivityDirectBeamCenter("BioSANS_empty_trans.xml") + AzimuthalAverage(binning="0.01,0.001,0.11", error_weighting=True) + Reduce1D() + + def validate(self): + self.tolerance = 0.00001 + self.disableChecking.append('Instrument') + self.disableChecking.append('Sample') + self.disableChecking.append('SpectraMap') + self.disableChecking.append('Axes') + return "BioSANS_test_data_Iq", 'HFIRSensitivityDirectBeamCenter.nxs' + +class HFIRSensitivityScatteringBeamCenter(stresstesting.MantidStressTest): + + def cleanup(self): + do_cleanup() + return True + + def runTest(self): + """ + System test for sensitivity correction + """ + config = ConfigService.Instance() + config["facilityName"]='HFIR' + GPSANS() + DirectBeamCenter("BioSANS_empty_cell.xml") + AppendDataFile("BioSANS_test_data.xml") + SetTransmission(0.51944, 0.011078) + SensitivityCorrection("BioSANS_flood_data.xml", + dark_current="BioSANS_dark_current.xml") + SensitivityScatteringBeamCenter("BioSANS_test_data.xml") + AzimuthalAverage(binning="0.01,0.001,0.11", error_weighting=True) + Reduce1D() + + def validate(self): + self.tolerance = 0.00001 + self.disableChecking.append('Instrument') + self.disableChecking.append('Sample') + self.disableChecking.append('SpectraMap') + self.disableChecking.append('Axes') + return "BioSANS_test_data_Iq", 'HFIRSensitivityScatteringBeamCenter.nxs' + + + diff --git a/Code/Mantid/Testing/SystemTests/tests/analysis/HFIRReductionAPIv2.py b/Code/Mantid/Testing/SystemTests/tests/analysis/HFIRReductionAPIv2.py new file mode 100644 index 000000000000..17a7a32a2a92 --- /dev/null +++ b/Code/Mantid/Testing/SystemTests/tests/analysis/HFIRReductionAPIv2.py @@ -0,0 +1,106 @@ +import stresstesting +import mantid +from mantid.api import FileFinder +from mantid.simpleapi import * +from reduction_workflow.instruments.sans.hfir_command_interface import * + +import os + +def do_cleanup(): + Files = ["BioSANS_test_data_reduction.log", + "BioSANS_test_data_Iq.xml", + "BioSANS_test_data_Iq.txt", + "BioSANS_test_data_Iqxy.dat"] + for file in Files: + absfile = FileFinder.getFullPath(file) + if os.path.exists(absfile): + os.remove(absfile) + return True + +class HFIRReductionAPIv2(stresstesting.MantidStressTest): + + def cleanup(self): + do_cleanup() + return True + + """ + Simple reduction example + """ + + def runTest(self): + + config = ConfigService.Instance() + config["facilityName"]='HFIR' + GPSANS() + DirectBeamCenter("BioSANS_empty_cell.xml") + AppendDataFile("BioSANS_test_data.xml") + SetTransmission(0.51944, 0.011078) + SensitivityCorrection("BioSANS_flood_data.xml") + AzimuthalAverage(binning="0.01,0.001,0.11", error_weighting=True) + Reduce() + + def validate(self): + self.disableChecking.append('Instrument') + self.disableChecking.append('Sample') + self.disableChecking.append('SpectraMap') + self.disableChecking.append('Axes') + return "BioSANS_test_data_Iq", "HFIRReduction.nxs" + +class HFIRAbsoluteScalingReference(stresstesting.MantidStressTest): + + def cleanup(self): + do_cleanup() + return True + + """ + Test absolute scaling using a reference data set + """ + + def runTest(self): + config = ConfigService.Instance() + config["facilityName"]='HFIR' + GPSANS() + SolidAngle(detector_tubes=True) + MonitorNormalization() + AzimuthalAverage(binning="0.01,0.001,0.2") + SetBeamCenter(16.39, 95.53) + SetDirectBeamAbsoluteScale('BioSANS_empty_trans.xml') + AppendDataFile(["BioSANS_test_data.xml"]) + Reduce() + + def validate(self): + self.disableChecking.append('Instrument') + self.disableChecking.append('Sample') + self.disableChecking.append('SpectraMap') + self.disableChecking.append('Axes') + return "BioSANS_test_data_Iq", "HFIRAbsoluteScalingReference.nxs" + +class HFIRAbsoluteScalingValue(stresstesting.MantidStressTest): + + def cleanup(self): + do_cleanup() + return True + + """ + Test absolute scaling using a reference data set + """ + + def runTest(self): + config = ConfigService.Instance() + config["facilityName"]='HFIR' + GPSANS() + SolidAngle(detector_tubes=True) + MonitorNormalization() + AzimuthalAverage(binning="0.01,0.001,0.2") + SetBeamCenter(16.39, 95.53) + SetAbsoluteScale(1.680537663117948) + AppendDataFile(["BioSANS_test_data.xml"]) + Reduce() + + def validate(self): + self.disableChecking.append('Instrument') + self.disableChecking.append('Sample') + self.disableChecking.append('SpectraMap') + self.disableChecking.append('Axes') + return "BioSANS_test_data_Iq", "HFIRAbsoluteScalingReference.nxs" + diff --git a/Code/Mantid/Testing/SystemTests/tests/analysis/HFIRTestsAPIv2.py b/Code/Mantid/Testing/SystemTests/tests/analysis/HFIRTestsAPIv2.py new file mode 100644 index 000000000000..05e25ea38f73 --- /dev/null +++ b/Code/Mantid/Testing/SystemTests/tests/analysis/HFIRTestsAPIv2.py @@ -0,0 +1,732 @@ +""" + System tests for HFIR SANS reduction. + + The following tests were converted from the unittest framework + that is part of python to the stresstesting framework used in Mantid. +""" +import stresstesting +from mantid.api import * +from mantid.simpleapi import * +from reduction_workflow.instruments.sans.hfir_command_interface import * +import types +import traceback +import math +import os + +# Set directory containing the test data, relative to the Mantid release directory. +TEST_DIR = "." +data_search_dirs = ConfigService.Instance()["datasearch.directories"].split(';') +for item in data_search_dirs: + if item.endswith("SANS2D/"): + TEST_DIR = item +if len(TEST_DIR)==0: + raise RuntimeError, "Could not locate test data directory: [...]/Data/SANS2D" + +def _diff_iq(x,y): return x-y +def _add(x,y): return x+y + +def _read_IGOR(filepath): + """ + Read in an HFIR IGOR output file with reduced data + @param filepath: path of the file to be read + """ + data = [] + with open(filepath) as f: + # Skip first header line + f.readline() + for line in f: + toks = line.split() + try: + q = float(toks[0]) + iq = float(toks[1]) + diq = float(toks[2]) + data.append([q, iq, diq]) + except: + print "_read_IGOR:", sys.exc_value + return data + +def _check_result(ws, test_file, tolerance=1e-6): + """ + Compare the data in two reduced data files. + @param reduced_file: path of the Mantid-reduced file + @param test_file: path of the IGOR-reduced file + """ + passed = True + + # Read mantid data + x = ws.dataX(0)[:len(ws.dataX(0))] + y = ws.dataY(0) + e = ws.dataE(0) + data_mantid = zip(x,y,e) + + # Read the test data to compare with + data_igor = _read_IGOR(test_file) + + # Check length + if not len(data_mantid)==len(data_igor): + print "Incompatible data lengths" + return False + + # Utility methods for manipulating the lists + def _diff_chi2(x,y): return (x[1]-y[1])*(x[1]-y[1])/(x[2]*x[2]) + def _diff_iq(x,y): return x[1]-y[1] + def _diff_err(x,y): return x[2]-y[2] + def _add(x,y): return x+y + + # Check that I(q) is the same for both data sets + deltas = map(_diff_iq, data_mantid, data_igor) + delta = reduce(_add, deltas)/len(deltas) + if math.fabs(delta)>tolerance or math.isnan(delta): + passed = False + print "Sum of I(q) deltas is outside tolerance: %g > %g" % (math.fabs(delta), tolerance) + + # Then compare the errors + deltas = map(_diff_err, data_mantid, data_igor) + delta_err = reduce(_add, deltas)/len(deltas) + if math.fabs(delta_err)>tolerance or math.isnan(delta): + passed = False + print "Sum of dI(q) deltas is outside tolerance: %g > %g" % (math.fabs(delta_err), tolerance) + + # Compute chi2 of our result relative to IGOR + deltas = map(_diff_chi2, data_mantid, data_igor) + chi2 = reduce(_add, deltas)/len(data_igor) + if chi2>10.0*tolerance or math.isnan(delta): + passed= False + print "Chi2 is outside tolerance: %g > %g" % (chi2, 10.0*tolerance) + + return passed + +def do_cleanup(): + Files = ["GPSANS_reduction.log", + "BioSANS_exp61_scan0004_0001_Iq.txt", + "BioSANS_exp61_scan0004_0001_Iq.xml", + "BioSANS_exp61_scan0004_0001_Iqxy.dat", + "BioSANS_exp61_scan0004_0001_reduction.log", + "BioSANS_test_data_Iq.txt", + "BioSANS_test_data_Iq.xml", + "BioSANS_test_data_Iqxy.dat", + "BioSANS_test_data_reduction.log", + "test_data_Iq.txt", + "test_data_Iq.xml", + "test_data_Iqxy.dat", + "test_data_reduction.log"] + for file in Files: + absfile = FileFinder.getFullPath(file) + if os.path.exists(absfile): + os.remove(absfile) + return True + +class HFIRTestsAPIv2(stresstesting.MantidStressTest): + + def cleanup(self): + do_cleanup() + return True + + def assertTrue(self, condition): + if not condition: + raise RuntimeError, "Condition failed" + + def assertEqual(self, a, b): + if not a == b: + raise RuntimeError, "%s != %s" % (a, b) + + def _assertAlmostEqual(self, first, second, places=None, msg=None, delta=None, rel_delta=None): + return self.assertAlmostEqual(first, second, places, msg, delta, rel_delta) + + def assertAlmostEqual(self, first, second, places=None, msg=None, delta=None, rel_delta=None): + if not assertAlmostEqual(first, second, places, msg, delta, rel_delta): + if msg is None: + msg = "Failed condition" + raise RuntimeError, msg + + def _cleanup(self): + ws_list = AnalysisDataService.getObjectNames() + for ws in ws_list: + AnalysisDataService.remove(ws) + + def runTest(self): + + class TestStub(object): + def __init__(self, test_method): + self._test_method = test_method + self._passed = True + + def run_test(self): + # Set up the test + ReductionSingleton.clean() + # Execute the test + try: + print self._test_method.__name__ + return self._test_method() + except: + print traceback.format_exc() + return False + + self.all_passed = True + self.n_tests = 0 + self.n_passed = 0 + self.failed_tests = [] + for item in dir(self): + m = getattr(self, item) + if item.startswith("test_") and type(m)==types.MethodType: + self.n_tests += 1 + t = TestStub(m) + result = t.run_test() + self._cleanup() + if result is None or result==True: + self.n_passed += 1 + else: + self.failed_tests.append(item) + self.all_passed = False + + def test_data_path(self): + self.assertEqual(ReductionSingleton()._data_path, '.') + #any path that definitely exists on a computer with Mantid installed + test_path = os.path.normcase(ConfigService.Instance()['instrumentDefinition.directory']) + DataPath(test_path) + self.assertEqual(ReductionSingleton()._data_path, test_path) + + def test_set_detector_distance(self): + GPSANS() + DataPath(TEST_DIR) + AppendDataFile("BioSANS_test_data.xml") + SetSampleDetectorDistance(2500.0) + Reduce1D() + + ws = AnalysisDataService.retrieve("BioSANS_test_data") + sdd = ws.getRun().getProperty("sample_detector_distance").value + self.assertEqual(sdd, 2500.0) + + def test_set_detector_offset(self): + GPSANS() + DataPath(TEST_DIR) + AppendDataFile("BioSANS_test_data.xml") + SetSampleDetectorOffset(500.0) + Reduce1D() + + ws = AnalysisDataService.retrieve("BioSANS_test_data") + sdd = ws.getRun().getProperty("sample_detector_distance").value + self.assertEqual(sdd, 6500.0) + + def test_set_distance_and_detector_offset(self): + """ + If both detector distance and offset are set, use only the distance + """ + GPSANS() + DataPath(TEST_DIR) + AppendDataFile("BioSANS_test_data.xml") + SetSampleDetectorDistance(2500.0) + SetSampleDetectorOffset(500.0) + Reduce1D() + + ws = AnalysisDataService.retrieve("BioSANS_test_data") + sdd = ws.getRun().getProperty("sample_detector_distance").value + self.assertEqual(sdd, 2500.0) + + def test_set_wavelength(self): + GPSANS() + DataPath(TEST_DIR) + AppendDataFile("BioSANS_test_data.xml") + SetWavelength(5.0, 1.2) + Reduce1D() + + ws = AnalysisDataService.retrieve("BioSANS_test_data") + v_x = ws.dataX(0) + self.assertEqual(v_x[0], 4.4) + self.assertEqual(v_x[1], 5.6) + + def test_direct_beam_center(self): + GPSANS() + DataPath(TEST_DIR) + DirectBeamCenter("BioSANS_empty_cell.xml") + AppendDataFile("BioSANS_test_data.xml") + Reduce() + + ws = AnalysisDataService.retrieve("BioSANS_test_data") + center_x = ws.getRun().getProperty("beam_center_x").value + center_y = ws.getRun().getProperty("beam_center_y").value + self.assertAlmostEqual(center_x, 16.6038, delta=0.0001) + self.assertAlmostEqual(center_y, 96.771, delta=0.0001) + + propmng_name = ReductionSingleton().get_reduction_table_name() + p = PropertyManagerDataService.retrieve(propmng_name) + center_x = p.getProperty("LatestBeamCenterX").value + center_y = p.getProperty("LatestBeamCenterY").value + self.assertAlmostEqual(center_x, 16.6038, delta=0.0001) + self.assertAlmostEqual(center_y, 96.771, delta=0.0001) + + def test_hand_beam_center(self): + GPSANS() + SetBeamCenter(1.1, 2.2) + Reduce() + + propmng_name = ReductionSingleton().get_reduction_table_name() + p = PropertyManagerDataService.retrieve(propmng_name) + + center_x = p.getProperty("LatestBeamCenterX").value + center_y = p.getProperty("LatestBeamCenterY").value + + self.assertAlmostEqual(center_x, 1.1, delta=0.0001) + self.assertAlmostEqual(center_y, 2.2, delta=0.0001) + + def test_load_run(self): + GPSANS() + DataPath(TEST_DIR) + self.assertEqual(len(ReductionSingleton()._data_files), 0) + AppendDataFile("BioSANS_test_data.xml") + self.assertEqual(len(ReductionSingleton()._data_files), 1) + + def test_to_steps(self): + GPSANS() + DataPath(TEST_DIR) + DirectBeamCenter("BioSANS_empty_cell.xml") + AppendDataFile("BioSANS_test_data.xml") + DarkCurrent("BioSANS_dark_current.xml") + SensitivityCorrection("BioSANS_flood_data.xml", dark_current="BioSANS_dark_current.xml") + AzimuthalAverage(binning="0.01,0.001,0.11", error_weighting=True) + Reduce1D() + + ws = AnalysisDataService.retrieve("BioSANS_test_data") + sdd = ws.getRun().getProperty("sample_detector_distance").value + self.assertEqual(sdd, 6000.0) + + ws = AnalysisDataService.retrieve("BioSANS_test_data_Iq") + self.assertTrue(_check_result(ws, TEST_DIR+"reduced_center_calculated.txt", tolerance=1e-4)) + + def test_reduction_1(self): + GPSANS() + DataPath(TEST_DIR) + DirectBeamCenter("BioSANS_empty_cell.xml") + AppendDataFile("BioSANS_test_data.xml") + SensitivityCorrection("BioSANS_flood_data.xml") + AzimuthalAverage(binning="0.01,0.001,0.11", error_weighting=True) + Reduce1D() + + ws = AnalysisDataService.retrieve("BioSANS_test_data_Iq") + data = ws.dataY(0) + check = [0.19472,0.204269,0.215354,0.230114,0.238961,0.237201,0.247843,0.248424,0.253676,0.254327,0.254366,0.252931,0.258339,0.259297,0.257155,0.254059,0.252383,0.252826,0.256604,0.256754,0.255592,0.256813,0.248569,0.25331,0.251032,0.246424,0.249477,0.250939,0.251959,0.24925,0.250372,0.246148,0.250478,0.244621,0.247428,0.246431,0.245041,0.241647,0.24307,0.240096,0.242797,0.238182,0.237548,0.239789,0.241477,0.23456,0.237372,0.233715,0.233789,0.232262,0.231589,0.230986,0.231646,0.231331,0.230484,0.2277,0.226819,0.224341,0.227239,0.223228,0.221232,0.222011,0.224747,0.219533,0.216973,0.218734,0.21668,0.218366,0.214926,0.213985,0.214469,0.210473,0.209867,0.209066,0.208965,0.207498,0.204505,0.205786,0.202186,0.200442,0.200485,0.200554,0.200499,0.198152,0.193945,0.192082,0.193783,0.193787,0.190557,0.190471,0.186827,0.190088,0.188204,0.187547,0.182206,0.181384,0.180358,0.182663,0.178844,0.176556] + + deltas = map(_diff_iq, data, check) + delta = reduce(_add, deltas)/len(deltas) + self.assertTrue(math.fabs(delta)<0.00001) + + def test_no_solid_angle(self): + GPSANS() + DataPath(TEST_DIR) + DirectBeamCenter("BioSANS_empty_cell.xml") + AppendDataFile("BioSANS_test_data.xml") + NoSolidAngle() + SensitivityCorrection("BioSANS_flood_data.xml") + AzimuthalAverage(binning="0.01,0.001,0.11", error_weighting=True) + Reduce1D() + + ws = AnalysisDataService.retrieve("BioSANS_test_data_Iq") + data = ws.dataY(0) + self.assertAlmostEqual(data[0], 0.1948464330517794, delta=0.00001) + self.assertAlmostEqual(data[10], 0.25088976280978281, delta=0.00001) + self.assertAlmostEqual(data[20], 0.252098592791137, delta=0.00001) + + def test_reduction_2(self): + GPSANS() + DataPath(TEST_DIR) + DirectBeamCenter("BioSANS_empty_cell.xml") + AppendDataFile("BioSANS_test_data.xml") + DarkCurrent("BioSANS_dark_current.xml") + AzimuthalAverage(binning="0.01,0.001,0.11", error_weighting=True) + Reduce1D() + + ws = AnalysisDataService.retrieve("BioSANS_test_data_Iq") + data = ws.dataY(0) + check = [0.268942,0.272052,0.269806,0.27129,0.273852,0.271301,0.271732,0.271103,0.270996,0.269677,0.27098,0.266802,0.26789,0.268222,0.266125,0.262736,0.262752,0.263827,0.26315,0.262775,0.261541,0.260818,0.258955,0.257675,0.255908,0.254088,0.256778,0.256883,0.253568,0.25636,0.252323,0.251833,0.251914,0.252298,0.249375,0.247718,0.247768,0.244636,0.245604,0.243996,0.244332,0.244363,0.242985,0.242234,0.241118,0.241411,0.24084,0.239293,0.2392,0.236565,0.234557,0.233974,0.232905,0.231898,0.231085,0.229586,0.22862,0.227001,0.226783,0.225837,0.224835,0.223807,0.222296,0.221557,0.220464,0.219139,0.217611,0.217049,0.21606,0.215739,0.216233,0.213467,0.213141,0.213275,0.219695,0.216121,0.215502,0.21792,0.209364,0.209368,0.2064,0.205844,0.20431,0.203443,0.202442,0.200195,0.199408,0.19853,0.195654,0.195514,0.193086,0.193388,0.19137,0.190122,0.189119,0.18864,0.185473,0.184958,0.183981,0.182581] + + deltas = map(_diff_iq, data, check) + delta = reduce(_add, deltas)/len(deltas) + self.assertTrue(math.fabs(delta)<0.00001) + + def test_straight_Q1D(self): + GPSANS() + DataPath(TEST_DIR) + DirectBeamCenter("BioSANS_empty_cell.xml") + AppendDataFile("BioSANS_test_data.xml") + AzimuthalAverage(binning="0.01,0.001,0.11", error_weighting=True) + Reduce1D() + + ws = AnalysisDataService.retrieve("BioSANS_test_data_Iq") + data = ws.dataY(0) + check = [0.269037,0.272176,0.269917,0.271416,0.273988,0.271432,0.271857,0.271232,0.271118,0.269797,0.271095,0.266912,0.268015,0.268356,0.266256,0.26287,0.262888,0.263964,0.263281,0.262905,0.261669,0.26094,0.259081,0.257802,0.256029,0.254228,0.256913,0.257021,0.253692,0.256491,0.252454,0.251969,0.25204,0.252423,0.249516,0.247844,0.247895,0.24476,0.245734,0.244125,0.244474,0.244491,0.243126,0.242359,0.241239,0.24154,0.240976,0.239421,0.23933,0.236688,0.234685,0.234105,0.233034,0.232036,0.231208,0.229714,0.228749,0.227122,0.226918,0.225969,0.22497,0.223933,0.222426,0.221684,0.2206,0.219277,0.217739,0.217173,0.216193,0.215869,0.216354,0.213597,0.213271,0.213407,0.219829,0.216259,0.215635,0.218058,0.209499,0.209503,0.206529,0.205981,0.20445,0.203577,0.202577,0.200334,0.199544,0.198663,0.195786,0.195653,0.19322,0.193537,0.191503,0.190253,0.189253,0.188771,0.1856,0.185099,0.184111,0.182717] + + deltas = map(_diff_iq, data, check) + delta = reduce(_add, deltas)/len(deltas) + self.assertTrue(math.fabs(delta)<0.00001) + + def test_transmission(self): + GPSANS() + DataPath(TEST_DIR) + DirectBeamCenter("BioSANS_empty_cell.xml") + TimeNormalization() + DirectBeamTransmission(sample_file="BioSANS_sample_trans.xml", + empty_file="BioSANS_empty_trans.xml") + AzimuthalAverage(binning="0.01,0.001,0.11", error_weighting=True) + AppendDataFile("BioSANS_test_data.xml") + Reduce1D() + + ws = AnalysisDataService.retrieve("BioSANS_test_data_Iq") + data = ws.dataY(0) + check = [0.514758,0.520759,0.516451,0.51932,0.524206,0.519275,0.520125,0.518997,0.518729,0.516198,0.518718,0.51072,0.512816,0.513449,0.509453,0.502968,0.503003,0.505098,0.503835,0.503088,0.500716,0.499304,0.495777,0.49332,0.489926,0.486497,0.491656,0.491858,0.48546,0.490808,0.483111,0.482176,0.482359,0.483098,0.477528,0.474279,0.474485,0.468472,0.470305,0.467228,0.467934,0.467971,0.465358,0.463885,0.461762,0.462352,0.461285,0.458322,0.458118,0.453064,0.44927,0.448151,0.446129,0.444207,0.442629,0.439792,0.437958,0.434826,0.434443,0.432655,0.430731,0.428771,0.425893,0.424477,0.422421,0.419886,0.416942,0.415876,0.414037,0.41339,0.414353,0.409062,0.408431,0.408712,0.419282,0.412833,0.41062,0.414427,0.400056,0.400141,0.394724,0.393821,0.390721,0.38932,0.387497,0.383062,0.381603,0.380016,0.374635,0.374214,0.369733,0.370353,0.366464,0.364109,0.362184,0.361299,0.355246,0.354339,0.352412,0.349748] + + deltas = map(_diff_iq, data, check) + delta = reduce(_add, deltas)/len(deltas) + self.assertTrue(math.fabs(delta)<0.001) + + def test_spreader_transmission(self): + GPSANS() + DataPath(TEST_DIR) + DirectBeamCenter("BioSANS_empty_cell.xml") + AzimuthalAverage(binning="0.01,0.001,0.11", error_weighting=True) + BeamSpreaderTransmission(sample_spreader="BioSANS_test_data.xml", + direct_spreader="BioSANS_empty_cell.xml", + sample_scattering="BioSANS_test_data.xml", + direct_scattering="BioSANS_empty_cell.xml", + spreader_transmission=0.5, + spreader_transmission_err=0.1) + + AppendDataFile("BioSANS_test_data.xml") + Reduce1D() + + data = mtd["BioSANS_test_data_Iq"].dataY(0) + self.assertAlmostEqual(data[0], 0.00418831, delta=0.00001) + self.assertAlmostEqual(data[10], 0.0042193, delta=0.00001) + + def test_transmission_by_hand(self): + GPSANS() + DataPath(TEST_DIR) + DirectBeamCenter("BioSANS_empty_cell.xml") + AppendDataFile("BioSANS_test_data.xml") + SetTransmission(0.51944, 0.011078) + AzimuthalAverage(binning="0.01,0.001,0.11", error_weighting=True) + Reduce1D() + + property_manager = PropertyManagerDataService.retrieve(ReductionSingleton().get_reduction_table_name()) + p=property_manager.getProperty("TransmissionAlgorithm") + + ws = AnalysisDataService.retrieve("BioSANS_test_data_Iq") + self.assertTrue(_check_result(ws, TEST_DIR+"reduced_transmission.txt", 0.0001)) + + def test_center_by_hand(self): + GPSANS() + DataPath(TEST_DIR) + SetBeamCenter(16, 95) + AppendDataFile("BioSANS_test_data.xml") + SensitivityCorrection("BioSANS_flood_data.xml", dark_current="BioSANS_dark_current.xml") + DarkCurrent("BioSANS_dark_current.xml") + AzimuthalAverage(binning="0.01,0.001,0.11", error_weighting=True) + Reduce1D() + + ws = AnalysisDataService.retrieve("BioSANS_test_data_Iq") + self.assertTrue(_check_result(ws, TEST_DIR+"reduced_center_by_hand.txt", 0.0001)) + + def test_background(self): + GPSANS() + DataPath(TEST_DIR) + SetBeamCenter(16, 95) + AppendDataFile("BioSANS_test_data.xml") + SensitivityCorrection("BioSANS_flood_data.xml", dark_current="BioSANS_dark_current.xml") + DarkCurrent("BioSANS_dark_current.xml") + Background("BioSANS_test_data.xml") + AzimuthalAverage(binning="0.01,0.001,0.11", error_weighting=True) + Reduce1D() + + ws = AnalysisDataService.retrieve("BioSANS_test_data_Iq") + data = ws.dataY(0) + self.assertAlmostEqual(data[0], 0.0,10) + self.assertAlmostEqual(data[10], 0.0,10) + self.assertAlmostEqual(data[20], 0.0,10) + + def test_background_multiple_files(self): + """ + Subtracting background using multiple files should properly take + into account the normalization. + """ + GPSANS() + DataPath(TEST_DIR) + SetBeamCenter(16, 95) + AppendDataFile("BioSANS_test_data.xml") + SensitivityCorrection("BioSANS_flood_data.xml", dark_current="BioSANS_dark_current.xml") + DarkCurrent("BioSANS_dark_current.xml") + Background("BioSANS_test_data.xml") + Background("BioSANS_test_data.xml,BioSANS_test_data.xml") + AzimuthalAverage(binning="0.01,0.001,0.11", error_weighting=True) + Reduce1D() + + ws = AnalysisDataService.retrieve("BioSANS_test_data_Iq") + data = ws.dataY(0) + self.assertAlmostEqual(data[0], 0.0,10) + self.assertAlmostEqual(data[10], 0.0,10) + self.assertAlmostEqual(data[20], 0.0,10) + + def test_bck_w_transmission(self): + GPSANS() + DataPath(TEST_DIR) + SetBeamCenter(16, 95) + AppendDataFile("BioSANS_test_data.xml", "test_data") + SensitivityCorrection("BioSANS_flood_data.xml", dark_current="BioSANS_dark_current.xml") + DarkCurrent("BioSANS_dark_current.xml") + Background("BioSANS_test_data.xml") + SetTransmission(0.6,0.1) + SetBckTransmission(0.6,0.1) + AzimuthalAverage(binning="0.01,0.001,0.11", error_weighting=True) + Reduce1D() + + ws = AnalysisDataService.retrieve("test_data_Iq") + data = ws.dataY(0) + self.assertAlmostEqual(data[0], 0.0,10) + self.assertAlmostEqual(data[10], 0.0,10) + self.assertAlmostEqual(data[20], 0.0,10) + + def test_transmission_by_hand_w_sensitivity(self): + GPSANS() + DataPath(TEST_DIR) + DirectBeamCenter("BioSANS_empty_cell.xml") + AppendDataFile("BioSANS_test_data.xml") + SetTransmission(0.51944, 0.011078) + SensitivityCorrection("BioSANS_flood_data.xml") + AzimuthalAverage(binning="0.01,0.001,0.11", error_weighting=True) + Reduce1D() + + ws = AnalysisDataService.retrieve("BioSANS_test_data_Iq") + data = ws.dataY(0) + check = [0.374914,0.393394,0.414756,0.443152,0.460175,0.456802,0.477264,0.478456,0.488523,0.489758,0.489871,0.487127,0.497585,0.499346,0.49526,0.489273,0.486082,0.486923,0.494208,0.494531,0.492264,0.494608,0.478766,0.487872,0.48357,0.474654,0.48052,0.483367,0.485269,0.480079,0.482254,0.47413,0.48245,0.471207,0.476589,0.474701,0.472014,0.465479,0.468236,0.462524,0.46773,0.458851,0.457653,0.461929,0.465216,0.451887,0.45733,0.450281,0.45045,0.447508,0.446209,0.445063,0.446328,0.445735,0.444096,0.438758,0.43707,0.432302,0.437903,0.430176,0.426317,0.427858,0.433131,0.423087,0.418146,0.421584,0.417606,0.420891,0.414255,0.412448,0.413393,0.405706,0.404541,0.403016,0.402806,0.400023,0.394248,0.396725,0.389808,0.386475,0.386525,0.386674,0.386575,0.382081,0.373986,0.370391,0.37367,0.373686,0.367479,0.36732,0.36031,0.366588,0.362994,0.361712,0.351433,0.349867,0.3479,0.352355,0.344987,0.340605] + + # Check that I(q) is the same for both data sets + deltas = map(_diff_iq, data, check) + delta = reduce(_add, deltas)/len(deltas) + self.assertTrue(math.fabs(delta)<0.00001) + + def test_SampleGeometry_functions(self): + print "SKIPPING test_SampleGeometry_functions()" + return + GPSANS() + DataPath(TEST_DIR) + AppendDataFile("BioSANS_test_data.xml") + SampleGeometry('cuboid') + SampleThickness(2.0) + SampleHeight(3.0) + SampleWidth(5.0) + + # we don't need to do a full reduction for this test, do a partial reduction + ReductionSingleton().pre_process() + ReductionSingleton()._reduction_steps[0].execute(ReductionSingleton(), "BioSANS_test_data") + ReductionSingleton().geometry_correcter.execute(ReductionSingleton(), "BioSANS_test_data") + + ws = AnalysisDataService.retrieve("BioSANS_test_data") + data = [ws.dataY(0)[0], ws.dataY(1)[0], ws.dataY(2)[0], ws.dataY(3)[0], ws.dataY(4)[0], ws.dataY(5)[0]] + + check = [500091.0,60.0,40.8333,13.6333, 13.4667,13.6667] + # Check that I(q) is the same for both data sets + deltas = map(_diff_iq, data, check) + delta = reduce(_add, deltas)/len(deltas) + self.assertTrue(math.fabs(delta)<0.1) + + def test_noDC_eff_with_DC(self): + ref = [28.06525, 136.94662, -16.20412, 0.00000, 147.79915, 146.42713, 302.00869, 0.00000, 0.00000,-1869.20724,-2190.89681,-1892.14939,-2140.79608,-1980.60037,-2096.75974,-2221.30118,-2263.51541,-2264.89989,-2364.83528,-2420.58152,-2444.51906,-2418.28886,-2606.16991,-2556.93660,-2623.71380,-2547.79671,-2670.60962,-2714.35237,-2717.01692,-2730.84974,-2768.92925,-2753.96396,-2732.66316,-2795.89687,-2780.37320,-2755.38910,-2814.88120,-2830.74081,-2803.42030,-2815.33244,-2754.70444,-2718.55136,-2740.03811,-2754.60415,-2815.96387,-2754.62039,-2781.54596,-2765.26282,-2676.04665,-2762.33751,-2722.94832,-2707.74990,-2730.50371,-2721.71272,-2682.02439,-2703.36446,-2679.47677,-2658.57573,-2669.41871,-2618.90655,-2638.41601,-2614.69128,-2583.29713,-2589.39730,-2567.19209,-2535.09328,-2539.43296,-2489.60117,-2500.76844,-2456.22248,-2444.13734,-2392.68589,-2410.98591,-2348.68064,-2334.84651,-2310.41426,-2250.24085,-2220.02192,-2184.65990,-2154.19638,-2099.56797,-2058.51585,-2004.05601,-1966.52356,-1910.47283,-1876.72098,-1817.69045,-1768.62167,-1721.56444,-1666.47199,-1608.86707,-1544.26178,-1492.78389,-1438.69256,-1358.60437,-1299.34476,-1221.57010,-1080.69421,-609.77891, -77.72765] + BIOSANS() + SetSampleDetectorOffset(837.9) + #SolidAngle() # name clash with SolidAngle algorithm + MonitorNormalization() + AzimuthalAverage(n_bins=100, n_subpix=1, log_binning=True) + #IQxQy(nbins=100) + DirectBeamCenter("BioSANS_empty_cell.xml") + SensitivityCorrection('BioSANS_flood_data.xml', min_sensitivity=0.5, max_sensitivity=1.5, dark_current='BioSANS_empty_trans.xml', use_sample_dc=False) + DivideByThickness(1) + SetTransmission(1, 0) + ThetaDependentTransmission(True) + DataPath(TEST_DIR) + AppendDataFile(["BioSANS_exp61_scan0004_0001.xml"]) + Background("BioSANS_test_data.xml") + SetBckTransmission(1, 0) + BckThetaDependentTransmission(True) + Reduce1D() + + ws = AnalysisDataService.retrieve("BioSANS_exp61_scan0004_0001_Iq") + res = ws.dataY(0) + for i in range(len(res)): + self._assertAlmostEqual(res[i], ref[i], delta=0.01, + rel_delta=0.001, + msg="result point %d: %g, found %g" % (i, ref[i], res[i])) + + def test_DC_eff_with_DC(self): + #ref = [8328.70241,8506.01586,5118.44441, 0.00000,7774.69442,8455.91783,14509.24224, 0.00000, 0.00000,-27551.42890,-34835.52157,-28076.35417,-32645.28731,-29923.90302,-32544.89749,-34519.58590,-35354.19282,-35242.21670,-37201.40137,-38547.80168,-38708.50152,-38339.04967,-41672.21115,-40898.80246,-41881.33026,-40789.34624,-43124.60460,-43846.74602,-43608.61731,-44050.49270,-44607.80184,-44662.71286,-44125.45576,-45197.75580,-45086.38543,-44502.49049,-45552.66509,-45678.42736,-45347.87980,-45613.96643,-44424.82296,-43888.62587,-44292.95665,-44465.13383,-45647.14865,-44450.82619,-44951.69404,-44597.94666,-43277.63573,-44605.52402,-44004.61793,-43774.86031,-44169.38692,-43970.30050,-43316.88231,-43786.96873,-43355.97746,-42952.99756,-43062.07976,-42184.58157,-42578.47214,-42199.41403,-41700.43004,-41780.97621,-41386.94893,-40865.71000,-40932.98886,-40036.67895,-40214.90469,-39471.74497,-39278.21830,-38383.80488,-38728.91704,-37705.78298,-37327.89414,-36943.11807,-35906.89550,-35399.21901,-34751.80556,-34209.49716,-33271.20006,-32530.08744,-31561.29164,-30906.03234,-29895.47664,-29278.16621,-28248.29021,-27341.79392,-26549.84441,-25476.57298,-24453.63444,-23305.85255,-22332.01538,-21306.01200,-19867.21655,-18795.14216,-17317.28374,-14745.54556,-6037.28367,4125.05228] + ref = [28.0476,136.906,-16.3079,0,147.757,146.403,301.982,0,0,-1869.21,-2190.93,-1892.16,-2140.81,-1980.62,-2096.79,-2221.34,-2263.55,-2264.93,-2364.87,-2420.61,-2444.56,-2418.32,-2606.21,-2556.98,-2623.75,-2547.84,-2670.66,-2714.39,-2717.06,-2730.89,-2768.96,-2754.01,-2732.7,-2795.93,-2780.41,-2755.42,-2814.92,-2830.79,-2803.46,-2815.38,-2754.75,-2718.6,-2740.08,-2754.65,-2816.01,-2754.66,-2781.59,-2765.3,-2676.09,-2762.38,-2722.99,-2707.8,-2730.55,-2721.76,-2682.07,-2703.41,-2679.52,-2658.62,-2669.46,-2618.95,-2638.46,-2614.74,-2583.34,-2589.44,-2567.23,-2535.14,-2539.48,-2489.64,-2500.81,-2456.26,-2444.18,-2392.73,-2411.03,-2348.73,-2334.89,-2310.46,-2250.28,-2220.07,-2184.7,-2154.24,-2099.61,-2058.56,-2004.1,-1966.57,-1910.52,-1876.76,-1817.73,-1768.67,-1721.61,-1666.51,-1608.91,-1544.31,-1492.83,-1438.74,-1358.65,-1299.39,-1221.61,-1080.73,-609.821,-77.7712] + BIOSANS() + SetSampleDetectorOffset(837.9) + #SolidAngle() + DarkCurrent("BioSANS_dark_current.xml") + MonitorNormalization() + AzimuthalAverage(n_bins=100, n_subpix=1, log_binning=True) + #IQxQy(nbins=100) + DirectBeamCenter("BioSANS_empty_cell.xml") + SensitivityCorrection('BioSANS_flood_data.xml', min_sensitivity=0.5, max_sensitivity=1.5, dark_current='BioSANS_empty_trans.xml', use_sample_dc=False) + DivideByThickness(1) + SetTransmission(1, 0) + ThetaDependentTransmission(True) + DataPath(TEST_DIR) + AppendDataFile(["BioSANS_exp61_scan0004_0001.xml"]) + Background("BioSANS_test_data.xml") + SetBckTransmission(1, 0) + BckThetaDependentTransmission(True) + Reduce1D() + + ws = AnalysisDataService.retrieve("BioSANS_exp61_scan0004_0001_Iq") + res = ws.dataY(0) + for i in range(len(res)): + self._assertAlmostEqual(res[i], ref[i], delta=0.01, + rel_delta=0.001, + msg="result point %d: %g, found %g" % (i, ref[i], res[i])) + + def test_DC_eff_noDC(self): + #ref = [7164.60565,7752.68818,5711.05627, 0.00000,5900.87667,8062.67404, 0.00000, 0.00000,-24761.10043,-23989.79632,-27228.05671,-27520.90826,-28702.43297,-30016.08164,-31857.27731,-32831.96025,-33274.36135,-33765.95318,-35208.90831,-37330.42544,-38283.00967,-38157.84654,-40398.13178,-40807.56861,-40981.56490,-40010.58202,-42502.81591,-43001.82289,-42582.26700,-43857.23377,-44163.99857,-44732.14970,-43799.50312,-44791.12989,-44777.68791,-43985.74941,-45468.56174,-45452.90859,-45309.47499,-45759.04142,-43969.71697,-43854.45515,-44260.09016,-44420.83533,-45370.71500,-44500.35745,-45047.70688,-44404.89711,-43526.84357,-44566.97107,-43693.66349,-43741.61517,-44045.48712,-43860.53110,-43371.59488,-43623.05598,-43456.87922,-42905.84855,-42947.82849,-42114.29792,-42493.59647,-41998.37587,-41635.60470,-41808.27092,-41359.04234,-40774.21357,-40842.43155,-40073.84107,-40151.59039,-39504.86741,-39166.91772,-38472.64978,-38668.95577,-37731.30203,-37416.76227,-36798.92809,-35971.80065,-35477.59413,-34782.44503,-34089.54104,-33225.67613,-32520.31544,-31591.39201,-30937.42531,-29962.72283,-29241.95009,-28269.99833,-27317.23101,-26561.76975,-25533.91747,-24418.32912,-23309.34592,-22383.49546,-21298.00468,-19889.28546,-18800.07365,-17315.89420,-14744.66783,-6047.10832,4171.62004] + ref = [10.4139,124.814,25.0443,0,38.3413,133.417,0,0,-1733.56,-1627.57,-1811.38,-1851.58,-1888.38,-1957.07,-2056.47,-2117.52,-2139.32,-2176.94,-2239.91,-2350.65,-2417.75,-2406.99,-2525.48,-2551.45,-2566.83,-2499.38,-2632.35,-2662.17,-2653.14,-2718.65,-2740.78,-2758.94,-2712,-2771.35,-2761.38,-2724.05,-2809.97,-2815.92,-2801.25,-2824.54,-2726.76,-2716.63,-2737.83,-2752.06,-2798.95,-2757.7,-2787.58,-2753.12,-2691.47,-2759.93,-2703.94,-2705.55,-2722.64,-2714.75,-2685.28,-2693.49,-2685.75,-2655.65,-2662.42,-2614.47,-2633.12,-2602.29,-2579.4,-2591.17,-2565.28,-2529.61,-2533.85,-2491.87,-2496.78,-2458.25,-2437.25,-2398.16,-2407.29,-2350.32,-2340.43,-2301.5,-2254.37,-2224.97,-2186.64,-2146.73,-2096.71,-2058.12,-2006.2,-1968.6,-1914.93,-1874.31,-1819.05,-1767.14,-1722.35,-1670.38,-1606.61,-1544.51,-1496.24,-1438.21,-1360.12,-1299.68,-1221.61,-1080.91,-610.638,-71.9557] + BIOSANS() + SetSampleDetectorOffset(837.9) + #SolidAngle() + DarkCurrent("BioSANS_dark_current.xml") + MonitorNormalization() + AzimuthalAverage(n_bins=100, n_subpix=1, log_binning=True) + #IQxQy(nbins=100) + DirectBeamCenter("BioSANS_empty_cell.xml") + SensitivityCorrection('BioSANS_flood_data.xml', min_sensitivity=0.5, max_sensitivity=1.5, use_sample_dc=False) + DivideByThickness(1) + SetTransmission(1, 0) + ThetaDependentTransmission(True) + DataPath(TEST_DIR) + AppendDataFile(["BioSANS_exp61_scan0004_0001.xml"]) + Background("BioSANS_test_data.xml") + SetBckTransmission(1, 0) + BckThetaDependentTransmission(True) + Reduce1D() + + ws = AnalysisDataService.retrieve("BioSANS_exp61_scan0004_0001_Iq") + res = ws.dataY(0) + for i in range(len(res)): + self._assertAlmostEqual(res[i], ref[i], delta=0.01, + rel_delta=0.001, + msg="result point %d: %g, found %g" % (i, ref[i], res[i])) + + def test_transmission_beam_center(self): + GPSANS() + DataPath(TEST_DIR) + DirectBeamCenter("BioSANS_empty_cell.xml") + AppendDataFile("BioSANS_test_data.xml", "test_data") + SensitivityCorrection("BioSANS_flood_data.xml", dark_current="BioSANS_dark_current.xml") + DarkCurrent("BioSANS_dark_current.xml") + DirectBeamTransmission(sample_file="BioSANS_sample_trans.xml", + empty_file="BioSANS_empty_trans.xml", + beam_radius=10.0) + SetTransmissionBeamCenter(100,15) + AzimuthalAverage(binning="0.01,0.001,0.11", error_weighting=True) + Reduce1D() + + ws = AnalysisDataService.retrieve("test_data_Iq") + data = ws.dataY(0) + self.assertAlmostEqual(data[0], 0.195821, delta=0.00001) + self.assertAlmostEqual(data[10], 0.256210, delta=0.00001) + self.assertAlmostEqual(data[20], 0.257666, delta=0.00001) + + def test_bck_transmission_default_beam_center(self): + GPSANS() + DataPath(TEST_DIR) + DirectBeamCenter("BioSANS_empty_cell.xml") + AppendDataFile("BioSANS_test_data.xml", "test_data") + DarkCurrent("BioSANS_dark_current.xml") + Background("BioSANS_test_data.xml") + SetTransmission(0.6,0.1) + BckDirectBeamTransmission(sample_file="BioSANS_sample_trans.xml", empty_file="BioSANS_empty_trans.xml", beam_radius=10.0) + AzimuthalAverage(binning="0.01,0.001,0.11", error_weighting=True) + Reduce1D() + + ws = AnalysisDataService.retrieve("test_data_Iq") + data = ws.dataY(0) + self.assertAlmostEqual(data[0], -0.0682723, delta=0.00001) + self.assertAlmostEqual(data[10], -0.068800, delta=0.00001) + self.assertAlmostEqual(data[20], -0.066403, delta=0.00001) + + def test_bck_transmission_set_beam_center(self): + GPSANS() + DataPath(TEST_DIR) + DirectBeamCenter("BioSANS_empty_cell.xml") + AppendDataFile("BioSANS_test_data.xml", "test_data") + DarkCurrent("BioSANS_dark_current.xml") + Background("BioSANS_test_data.xml") + SetTransmission(0.6,0.1) + BckDirectBeamTransmission(sample_file="BioSANS_sample_trans.xml", empty_file="BioSANS_empty_trans.xml", beam_radius=10.0) + SetBckTransmissionBeamCenter(100,15) + AzimuthalAverage(binning="0.01,0.001,0.11", error_weighting=True) + Reduce1D() + + data = mtd["test_data_Iq"].dataY(0) + self.assertAlmostEqual(data[0], 0.1787709, delta=0.00001) + self.assertAlmostEqual(data[10], 0.1801518, delta=0.00001) + self.assertAlmostEqual(data[20], 0.1738586, delta=0.00001) + + def test_bck_transmission_direct_beam_center(self): + GPSANS() + DataPath(TEST_DIR) + #DirectBeamCenter("BioSANS_empty_cell.xml") + SetBeamCenter(100,15) + AppendDataFile("BioSANS_test_data.xml", "test_data") + DarkCurrent("BioSANS_dark_current.xml") + Background("BioSANS_test_data.xml") + SetTransmission(0.6,0.1) + BckDirectBeamTransmission(sample_file="BioSANS_sample_trans.xml", empty_file="BioSANS_empty_trans.xml", beam_radius=10.0) + BckTransmissionDirectBeamCenter("BioSANS_empty_cell.xml") + AzimuthalAverage(binning="0.01,0.001,0.11", error_weighting=True) + Reduce1D() + + data = mtd["test_data_Iq"].dataY(0) + self.assertAlmostEqual(data[0], -0.046791, delta=0.00001) + self.assertAlmostEqual(data[10], -0.047874, delta=0.00001) + self.assertAlmostEqual(data[20], -0.047785, delta=0.00001) + + def validate(self): + print "HFIRTests: %d / %d tests passed" % (self.n_passed, self.n_tests) + for item in self.failed_tests: + print item + return self.all_passed + +def assertAlmostEqual(first, second, places=None, msg=None, delta=None, rel_delta=None): + """ + Simple test to compare two numbers + @return: True of the two numbers agree within tolerance + """ + if first == second: + # shortcut + return True + + if delta is not None and places is not None: + raise TypeError("specify delta or places not both") + + if delta is not None: + if abs(first - second) <= delta: + return True + elif abs(first - second)/abs(second) %s != %s but within %s percent' % (str(first), + str(second), + str(rel_delta*100.0)) + return True + + standardMsg = '%s != %s within %s delta' % (str(first), + str(second), + str(delta)) + else: + if places is None: + places = 7 + + if round(abs(second-first), places) == 0: + return True + + standardMsg = '%s != %s within %r places' % (str(first), + str(second), + places) + print standardMsg + return False + diff --git a/Code/Mantid/Testing/SystemTests/tests/analysis/HFIRTransAPIv2.py b/Code/Mantid/Testing/SystemTests/tests/analysis/HFIRTransAPIv2.py new file mode 100644 index 000000000000..dd7e3aedb779 --- /dev/null +++ b/Code/Mantid/Testing/SystemTests/tests/analysis/HFIRTransAPIv2.py @@ -0,0 +1,277 @@ +import stresstesting +import mantid +from mantid.api import FileFinder +from mantid.simpleapi import * +from reduction_workflow.instruments.sans.hfir_command_interface import * + +import os + +def do_cleanup(): + Files = ["BioSANS_test_data_reduction.log", + "BioSANS_test_data_Iq.xml", + "BioSANS_test_data_Iq.txt", + "BioSANS_test_data_Iqxy.dat"] + for file in Files: + absfile = FileFinder.getFullPath(file) + if os.path.exists(absfile): + os.remove(absfile) + return True + +class HFIRTrans(stresstesting.MantidStressTest): + + def cleanup(self): + do_cleanup() + return True + + def runTest(self): + config = ConfigService.Instance() + config["facilityName"]='HFIR' + GPSANS() + DirectBeamCenter("BioSANS_empty_cell.xml") + TimeNormalization() + DirectBeamTransmission(sample_file="BioSANS_sample_trans.xml", + empty_file="BioSANS_empty_trans.xml") + AzimuthalAverage(binning="0.01,0.001,0.11") + AppendDataFile("BioSANS_test_data.xml") + Reduce1D() + + def validate(self): + self.tolerance = 0.00001 + self.disableChecking.append('Instrument') + self.disableChecking.append('Sample') + self.disableChecking.append('SpectraMap') + self.disableChecking.append('Axes') + return "BioSANS_test_data_Iq", 'HFIRTrans.nxs' + +class HFIRTrans(stresstesting.MantidStressTest): + + def cleanup(self): + do_cleanup() + return True + + def runTest(self): + config = ConfigService.Instance() + config["facilityName"]='HFIR' + GPSANS() + DirectBeamCenter("BioSANS_empty_cell.xml") + TimeNormalization() + SetTransmission(0.522296, 0.009134) + AzimuthalAverage(binning="0.01,0.001,0.11") + AppendDataFile("BioSANS_test_data.xml") + Reduce1D() + + def validate(self): + self.tolerance = 0.00001 + self.disableChecking.append('Instrument') + self.disableChecking.append('Sample') + self.disableChecking.append('SpectraMap') + self.disableChecking.append('Axes') + return "BioSANS_test_data_Iq", 'HFIRTrans.nxs' + +class HFIRTransmissionDarkCurrent(stresstesting.MantidStressTest): + + def cleanup(self): + do_cleanup() + return True + + def runTest(self): + config = ConfigService.Instance() + config["facilityName"]='HFIR' + GPSANS() + DirectBeamCenter("BioSANS_empty_cell.xml") + TimeNormalization() + DirectBeamTransmission(sample_file="BioSANS_sample_trans.xml", + empty_file="BioSANS_empty_trans.xml") + TransmissionDarkCurrent("BioSANS_dark_current.xml") + AzimuthalAverage(binning="0.01,0.001,0.11") + AppendDataFile("BioSANS_test_data.xml") + Reduce1D() + + def validate(self): + self.tolerance = 0.00001 + self.disableChecking.append('Instrument') + self.disableChecking.append('Sample') + self.disableChecking.append('SpectraMap') + self.disableChecking.append('Axes') + return "BioSANS_test_data_Iq", 'HFIRTransmissionDarkCurrent.nxs' + +class HFIRTransmissionDirectBeamCenter(stresstesting.MantidStressTest): + + def cleanup(self): + do_cleanup() + return True + + def runTest(self): + config = ConfigService.Instance() + config["facilityName"]='HFIR' + GPSANS() + DirectBeamCenter("BioSANS_empty_cell.xml") + TimeNormalization() + DirectBeamTransmission(sample_file="BioSANS_sample_trans.xml", + empty_file="BioSANS_empty_trans.xml") + TransmissionDirectBeamCenter("BioSANS_empty_trans.xml") + AzimuthalAverage(binning="0.01,0.001,0.11") + AppendDataFile("BioSANS_test_data.xml") + Reduce1D() + + def validate(self): + self.tolerance = 0.00001 + self.disableChecking.append('Instrument') + self.disableChecking.append('Sample') + self.disableChecking.append('SpectraMap') + self.disableChecking.append('Axes') + return "BioSANS_test_data_Iq", 'HFIRTransmissionDirectBeamCenter.nxs' + +class HFIRTransmissionBeamCenter(stresstesting.MantidStressTest): + + def cleanup(self): + do_cleanup() + return True + + def runTest(self): + config = ConfigService.Instance() + config["facilityName"]='HFIR' + GPSANS() + DirectBeamCenter("BioSANS_empty_cell.xml") + TimeNormalization() + DirectBeamTransmission(sample_file="BioSANS_sample_trans.xml", + empty_file="BioSANS_empty_trans.xml") + SetTransmissionBeamCenter(16.389123399465063, + 95.530251864359087) + AzimuthalAverage(binning="0.01,0.001,0.11") + AppendDataFile("BioSANS_test_data.xml") + Reduce1D() + + def validate(self): + self.tolerance = 0.00001 + self.disableChecking.append('Instrument') + self.disableChecking.append('Sample') + self.disableChecking.append('SpectraMap') + self.disableChecking.append('Axes') + return "BioSANS_test_data_Iq", 'HFIRTransmissionDirectBeamCenter.nxs' + +class HFIRTransmissionBeamSpreader(stresstesting.MantidStressTest): + + def cleanup(self): + do_cleanup() + return True + + def runTest(self): + config = ConfigService.Instance() + config["facilityName"]='HFIR' + GPSANS() + DirectBeamCenter("BioSANS_empty_cell.xml") + TimeNormalization() + BeamSpreaderTransmission(sample_spreader="BioSANS_test_data.xml", + direct_spreader="BioSANS_empty_cell.xml", + sample_scattering="BioSANS_test_data.xml", + direct_scattering="BioSANS_empty_cell.xml", + spreader_transmission=0.5, + spreader_transmission_err=0.1) + AzimuthalAverage(binning="0.01,0.001,0.11") + AppendDataFile("BioSANS_test_data.xml") + Reduce1D() + + def validate(self): + self.tolerance = 0.00001 + self.disableChecking.append('Instrument') + self.disableChecking.append('Sample') + self.disableChecking.append('SpectraMap') + self.disableChecking.append('Axes') + return "BioSANS_test_data_Iq", 'HFIRTransmissionBeamSpreader.nxs' + +class HFIRTransmissionBeamSpreaderDC(stresstesting.MantidStressTest): + + def cleanup(self): + do_cleanup() + return True + + def runTest(self): + config = ConfigService.Instance() + config["facilityName"]='HFIR' + GPSANS() + DirectBeamCenter("BioSANS_empty_cell.xml") + TimeNormalization() + BeamSpreaderTransmission(sample_spreader="BioSANS_test_data.xml", + direct_spreader="BioSANS_empty_cell.xml", + sample_scattering="BioSANS_test_data.xml", + direct_scattering="BioSANS_empty_cell.xml", + spreader_transmission=0.5, + spreader_transmission_err=0.1) + TransmissionDarkCurrent("BioSANS_dark_current.xml") + AzimuthalAverage(binning="0.01,0.001,0.11") + AppendDataFile("BioSANS_test_data.xml") + Reduce1D() + + def validate(self): + self.tolerance = 0.00001 + self.disableChecking.append('Instrument') + self.disableChecking.append('Sample') + self.disableChecking.append('SpectraMap') + self.disableChecking.append('Axes') + return "BioSANS_test_data_Iq", 'HFIRTransmissionBeamSpreaderDC.nxs' + +class HFIRTransmissionBeamSpreaderDBC(stresstesting.MantidStressTest): + + def cleanup(self): + do_cleanup() + return True + + def runTest(self): + config = ConfigService.Instance() + config["facilityName"]='HFIR' + GPSANS() + DirectBeamCenter("BioSANS_empty_cell.xml") + TimeNormalization() + BeamSpreaderTransmission(sample_spreader="BioSANS_test_data.xml", + direct_spreader="BioSANS_empty_cell.xml", + sample_scattering="BioSANS_test_data.xml", + direct_scattering="BioSANS_empty_cell.xml", + spreader_transmission=0.5, + spreader_transmission_err=0.1) + TransmissionDirectBeamCenter("BioSANS_empty_trans.xml") + AzimuthalAverage(binning="0.01,0.001,0.11") + AppendDataFile("BioSANS_test_data.xml") + Reduce1D() + + def validate(self): + self.tolerance = 0.00001 + self.disableChecking.append('Instrument') + self.disableChecking.append('Sample') + self.disableChecking.append('SpectraMap') + self.disableChecking.append('Axes') + return "BioSANS_test_data_Iq", 'HFIRTransmissionBeamSpreaderDBC.nxs' + +class HFIRTransmissionBeamSpreaderBC(stresstesting.MantidStressTest): + + def cleanup(self): + do_cleanup() + return True + + def runTest(self): + config = ConfigService.Instance() + config["facilityName"]='HFIR' + GPSANS() + DirectBeamCenter("BioSANS_empty_cell.xml") + TimeNormalization() + BeamSpreaderTransmission(sample_spreader="BioSANS_test_data.xml", + direct_spreader="BioSANS_empty_cell.xml", + sample_scattering="BioSANS_test_data.xml", + direct_scattering="BioSANS_empty_cell.xml", + spreader_transmission=0.5, + spreader_transmission_err=0.1) + SetTransmissionBeamCenter(16.389123399465063, + 95.530251864359087) + AzimuthalAverage(binning="0.01,0.001,0.11") + AppendDataFile("BioSANS_test_data.xml") + Reduce1D() + + def validate(self): + self.tolerance = 0.00001 + self.disableChecking.append('Instrument') + self.disableChecking.append('Sample') + self.disableChecking.append('SpectraMap') + self.disableChecking.append('Axes') + return "BioSANS_test_data_Iq", 'HFIRTransmissionBeamSpreaderDBC.nxs' + + diff --git a/Code/Mantid/Testing/SystemTests/tests/analysis/HYSPECReductionTest.py b/Code/Mantid/Testing/SystemTests/tests/analysis/HYSPECReductionTest.py new file mode 100644 index 000000000000..697b16639a5f --- /dev/null +++ b/Code/Mantid/Testing/SystemTests/tests/analysis/HYSPECReductionTest.py @@ -0,0 +1,52 @@ +""" +System test for HYSPEC reduction +""" + +from mantid.simpleapi import * +import os +import stresstesting + +class HYSPECReductionTest(stresstesting.MantidStressTest): + + def requiredMemoryMB(self): + return 5000 + + def requiredFiles(self): + return ['HYS_13656_event.nxs','HYS_13657_event.nxs','HYS_13658_event.nxs'] + + def cleanup(self): + if os.path.exists(self.groupingFile): + os.remove(self.groupingFile) + return True + + def runTest(self): + Load(Filename='HYS_13656-13658',OutputWorkspace='sum') + FilterByLogValue(InputWorkspace='sum',OutputWorkspace='sum1',LogName='s1',MinimumValue='0',MaximumValue='24.5',LogBoundary='Left') + DeleteWorkspace('sum') + GenerateEventsFilter(InputWorkspace='sum1',OutputWorkspace='splboth',InformationWorkspace='info',UnitOfTime='Nanoseconds',LogName='s1',MaximumLogValue='24.5',LogValueInterval='3') + FilterEvents(InputWorkspace='sum1',OutputWorkspaceBaseName='split',InformationWorkspace='info',SplitterWorkspace='splboth',FilterByPulseTime='1',GroupWorkspaces='1') + DeleteWorkspace('split_unfiltered') + DeleteWorkspace("splboth") + DeleteWorkspace("info") + DeleteWorkspace('sum1') + CompressEvents('split',0.1,OutputWorkspace='splitc') + DeleteWorkspace('split') + self.groupingFile=os.path.join(config.getString('defaultsave.directory'),'group4x2.xml') + GenerateGroupingSNSInelastic(AlongTubes="4",AcrossTubes="2",Instrument="HYSPEC",Filename=self.groupingFile) + config['default.facility']="SNS" + DgsReduction(SampleInputWorkspace='splitc',IncidentBeamNormalisation='ByCurrent',OutputWorkspace='reduced',GroupingFile=self.groupingFile,TimeIndepBackgroundSub ='1',TibTofRangeStart =10400,TibTofRangeEnd =12400,IncidentEnergyGuess=50) + DeleteWorkspace('splitc') + SetGoniometer('reduced',Axis0="s1,0,1,0,1") + SetUB('reduced',5.823,6.475,3.186,90,90,90,'0,1,0','0,0,1') + ConvertToMD(InputWorkspace='reduced',OutputWorkspace='md',QDimensions='Q3D',QConversionScales='HKL',MinValues='-0.5,-3,-5,-10',MaxValues='0.5,6,2,45') + DeleteWorkspace('reduced') + MergeMD(InputWorkspaces='md',OutputWorkspace='merged') + DeleteWorkspace("md") + BinMD(InputWorkspace='merged',AxisAligned='0',BasisVector0='[H,0,0],in 1.079 A^-1,1,0,0,0',BasisVector1='[0,K,0],in 0.97 A^-1,0,1,0,0',BasisVector2='[0,0,L],in 1.972 A^-1,0,0,1,0',BasisVector3='DeltaE,DeltaE,0,0,0,1',OutputExtents='-3,3,-2,6,-4,-1.5,-3,3',OutputBins='1,100,100,1',Parallel='1',OutputWorkspace='slice') + DeleteWorkspace("merged") + DeleteWorkspace("PreprocessedDetectorsWS") + + def validate(self): + self.tolerance = 1e-8 + return 'slice','HYSPECReduction_TIBasEvents.nxs' + diff --git a/Code/Mantid/Testing/SystemTests/tests/analysis/ILLD2BTest.py b/Code/Mantid/Testing/SystemTests/tests/analysis/ILLD2BTest.py new file mode 100644 index 000000000000..12c63c0b86cf --- /dev/null +++ b/Code/Mantid/Testing/SystemTests/tests/analysis/ILLD2BTest.py @@ -0,0 +1,64 @@ +import stresstesting + +from mantid.api import mtd, IMDEventWorkspace +from mantid.simpleapi import LoadILLAscii + +import unittest + +class ILLD2BLoadTest(unittest.TestCase): + + ws_name = "d2b_ws" + prefix = "D2B" + dataFile = "ILL/ILL_D2B_121459.txt" + + def tearDown(self): + for wsName in mtd.getObjectNames(): + if wsName.startswith(self.prefix): + mtd.remove(wsName) + + #================== Success cases ================================ + def test_load_single_file(self): + self._run_load(self.dataFile) + + # Check some data + wsOut = mtd[self.ws_name] + self.assertEqual(wsOut.getNEvents(), 409600) + + + + def _run_load(self, dataFile): + """ + ILL Loader + """ + LoadILLAscii(Filename=dataFile,OutputWorkspace=self.ws_name) + self._do_ads_check(self.ws_name) + + def _do_ads_check(self, name): + self.assertTrue(name in mtd) + self.assertTrue(type(mtd[name]) == IMDEventWorkspace) + + + +#==================================================================================== + +class ILLD2BTest(stresstesting.MantidStressTest): + + def requiredMemoryMB(self): + """Set a limit of 2.5Gb to avoid 32-bit environment""" + return 2500 + + def runTest(self): + self._success = False + # Custom code to create and run this single test suite + suite = unittest.TestSuite() + suite.addTest( unittest.makeSuite(ILLD2BLoadTest, "test") ) + runner = unittest.TextTestRunner() + # Run using either runner + res = runner.run(suite) + if res.wasSuccessful(): + self._success = True + else: + self._success = False + + def validate(self): + return self._success diff --git a/Code/Mantid/Testing/SystemTests/tests/analysis/ILLD33Test.py b/Code/Mantid/Testing/SystemTests/tests/analysis/ILLD33Test.py new file mode 100644 index 000000000000..24531122016b --- /dev/null +++ b/Code/Mantid/Testing/SystemTests/tests/analysis/ILLD33Test.py @@ -0,0 +1,115 @@ +import stresstesting + +from mantid.api import mtd +from mantid.simpleapi import SetupILLD33Reduction, SANSReduction,Rebin,SANSAzimuthalAverage1D + +import unittest + +class ILLD33SANSTest(unittest.TestCase): + + prefix = "D33" + + def tearDown(self): + for wsName in mtd.getObjectNames(): + if wsName.startswith(self.prefix): + mtd.remove(wsName) + + def test_all(self): + + SetupILLD33Reduction( + # Beam center shouldn't work + #BeamCenterMethod="None", + MaskedDetectorList=[14709,14710,14711,14712,14713,14714,14715,14716,14717,14718,14719, + 14720,14721,14722,14723,14724,14725,14726,14727,14728,14729,14730, + 14731,14732,14733,14734,14735,14965,14966,14967,14968,14969,14970, + 14971,14972,14973,14974,14975,14976,14977,14978,14979,14980,14981, + 14982,14983,14984,14985,14986,14987,14988,14989,14990,14991,15221, + 15222,15223,15224,15225,15226,15227,15228,15229,15230,15231,15232, + 15233,15234,15235,15236,15237,15238,15239,15240,15241,15242,15243, + 15244,15245,15246,15247,15477,15478,15479,15480,15481,15482,15483, + 15484,15485,15486,15487,15488,15489,15490,15491,15492,15493,15494, + 15495,15496,15497,15498,15499,15500,15501,15502,15503,15733,15734, + 15735,15736,15737,15738,15739,15740,15741,15742,15743,15744,15745, + 15746,15747,15748,15749,15750,15751,15752,15753,15754,15755,15756, + 15757,15758,15759,15989,15990,15991,15992,15993,15994,15995,15996, + 15997,15998,15999,16000,16001,16002,16003,16004,16005,16006,16007, + 16008,16009,16010,16011,16012,16013,16014,16015,16245,16246,16247, + 16248,16249,16250,16251,16252,16253,16254,16255,16256,16257,16258, + 16259,16260,16261,16262,16263,16264,16265,16266,16267,16268,16269, + 16270,16271,16501,16502,16503,16504,16505,16506,16507,16508,16509, + 16510,16511,16512,16513,16514,16515,16516,16517,16518,16519,16520, + 16521,16522,16523,16524,16525,16526,16527,16757,16758,16759,16760, + 16761,16762,16763,16764,16765,16766,16767,16768,16769,16770,16771, + 16772,16773,16774,16775,16776,16777,16778,16779,16780,16781,16782, + 16783,17013,17014,17015,17016,17017,17018,17019,17020,17021,17022, + 17023,17024,17025,17026,17027,17028,17029,17030,17031,17032,17033, + 17034,17035,17036,17037,17038,17039,17269,17270,17271,17272,17273, + 17274,17275,17276,17277,17278,17279,17280,17281,17282,17283,17284, + 17285,17286,17287,17288,17289,17290,17291,17292,17293,17294,17295, + 17525,17526,17527,17528,17529,17530,17531,17532,17533,17534,17535, + 17536,17537,17538,17539,17540,17541,17542,17543,17544,17545,17546, + 17547,17548,17549,17550,17551], + BeamCenterMethod="DirectBeam", + BeamCenterFile='ILL/001427.nxs', + Normalisation="Timer", + DarkCurrentFile= 'ILL/001420.nxs', + TransmissionMethod="DirectBeam", + TransmissionSampleDataFile= 'ILL/001431.nxs', + TransmissionEmptyDataFile= 'ILL/001427.nxs', + BckTransmissionEmptyDataFile= 'ILL/001427.nxs', + TransmissionBeamRadius = 3, + TransmissionUseSampleDC=False, + BackgroundFiles='ILL/001422.nxs', + BckTransmissionSampleDataFile='ILL/001428.nxs', + DoAzimuthalAverage=False, + Do2DReduction=False, + ComputeResolution=True, + ReductionProperties=self.prefix + "props") + + output=SANSReduction(Filename='ILL/001425.nxs', ReductionProperties=self.prefix + "props", + OutputWorkspace=self.prefix + "out") + Rebin(InputWorkspace=self.prefix + 'out',OutputWorkspace=self.prefix + 'out_rebin', + Params='4,0.1,15') + SANSAzimuthalAverage1D(InputWorkspace=self.prefix + 'out_rebin',Binning='0.001,0.0002,0.03', + OutputWorkspace=self.prefix + 'final') + + # Check some data + wsOut = mtd[self.prefix + 'out'] + self.assertEqual(wsOut.getNumberHistograms(), 65538) + wsOut = mtd[self.prefix + 'out_rebin'] + self.assertEqual(wsOut.getNumberHistograms(), 65538) + wsOut = mtd[self.prefix + 'final'] + self.assertEqual(wsOut.getNumberHistograms(), 1) + + + + #================== Failure cases ================================ + + # TODO + + + + +#==================================================================================== + +class ILLD33Test(stresstesting.MantidStressTest): + + def requiredMemoryMB(self): + """Set a limit of 2.5Gb to avoid 32-bit environment""" + return 2500 + + def runTest(self): + self._success = False + # Custom code to create and run this single test suite + suite = unittest.TestSuite() + suite.addTest( unittest.makeSuite(ILLD33SANSTest, "test") ) + runner = unittest.TextTestRunner() + # Run using either runner + res = runner.run(suite) + if res.wasSuccessful(): + self._success = True + else: + self._success = False + + def validate(self): + return self._success diff --git a/Code/Mantid/Testing/SystemTests/tests/analysis/ILLIN4Test.py b/Code/Mantid/Testing/SystemTests/tests/analysis/ILLIN4Test.py new file mode 100644 index 000000000000..d64e9ec7c2fd --- /dev/null +++ b/Code/Mantid/Testing/SystemTests/tests/analysis/ILLIN4Test.py @@ -0,0 +1,75 @@ +import stresstesting + +from mantid.api import MatrixWorkspace, mtd +from mantid.simpleapi import LoadILL +from mantid.kernel import V3D + +import unittest + +DIFF_PLACES = 12 + +class ILLIN4Tests(unittest.TestCase): + + ws_name = "in4_ws" + dataFile = "ILL/ILLIN4_074252.nxs" + + def tearDown(self): + if self.ws_name in mtd: + mtd.remove(self.ws_name) + + #================== Success cases ================================ + def test_load_file(self): + self._run_load(self.dataFile) + + # Check some data + wsOut = mtd[self.ws_name] + self.assertEqual(wsOut.getNumberHistograms(), 397) + + # Check is the two detectors have the same theta + samplePos = wsOut.getInstrument().getSample().getPos() + beamDirection = V3D(0,0,1) + det9 = wsOut.getDetector(9) + det209 = wsOut.getDetector(209) + self.assertEqual(det9.getTwoTheta(samplePos, beamDirection), + det209.getTwoTheta(samplePos, beamDirection)) + + # Same mirror position + self.assertEqual(det9.getPos().getX(),det209.getPos().getX()) + self.assertEqual(det9.getPos().getZ(),det209.getPos().getZ()) + self.assertEqual(det9.getPos().getY(),-det209.getPos().getY()) + + #================== Failure cases ================================ + + # TODO + + + def _run_load(self, dataFile): + """ + ILL Loader + """ + LoadILL(Filename=dataFile,OutputWorkspace=self.ws_name) + self._do_ads_check(self.ws_name) + + def _do_ads_check(self, name): + self.assertTrue(name in mtd) + self.assertTrue(type(mtd[name]) == MatrixWorkspace) + +#==================================================================================== + +class LoadILLIN4Test(stresstesting.MantidStressTest): + + def runTest(self): + self._success = False + # Custom code to create and run this single test suite + suite = unittest.TestSuite() + suite.addTest( unittest.makeSuite(ILLIN4Tests, "test") ) + runner = unittest.TextTestRunner() + # Run using either runner + res = runner.run(suite) + if res.wasSuccessful(): + self._success = True + else: + self._success = False + + def validate(self): + return self._success diff --git a/Code/Mantid/Testing/SystemTests/tests/analysis/ILLIN5Test.py b/Code/Mantid/Testing/SystemTests/tests/analysis/ILLIN5Test.py new file mode 100644 index 000000000000..9255b1eedb92 --- /dev/null +++ b/Code/Mantid/Testing/SystemTests/tests/analysis/ILLIN5Test.py @@ -0,0 +1,89 @@ +import stresstesting + +from mantid.api import MatrixWorkspace, mtd +from mantid.simpleapi import LoadILL + +import unittest + +DIFF_PLACES = 12 + +class ILLIN5Tests(unittest.TestCase): + + wsData_name = "in5_ws_data" + wsVana_name = "in5_ws_vana" + dataDispersionFile = "ILL/ILLIN5_Sample_096003.nxs" + vanadiumFile = "ILL/ILLIN5_Vana_095893.nxs" + + + def tearDown(self): + if self.wsData_name in mtd: + mtd.remove(self.wsData_name) + if self.wsVana_name in mtd: + mtd.remove(self.wsVana_name) + + #================== Success cases ================================ + def test_load_single_file(self): + self._run_load(self.dataDispersionFile) + + # Check some data + wsOut = mtd[self.wsData_name] + self.assertEqual(wsOut.getNumberHistograms(), 98305) + + def test_load_dispersion_file_and_vanadium_file(self): + self._run_load(self.dataDispersionFile,self.vanadiumFile) + + # Check some data + wsOut = mtd[self.wsData_name] + self.assertEqual(wsOut.getNumberHistograms(), 98305) + + def test_load_dispersion_file_and_vanadium_workspace(self): + + self._run_load(self.vanadiumFile,outWSName=self.wsVana_name) + # Check some data + wsVana = mtd[self.wsVana_name] + self.assertEqual(wsVana.getNumberHistograms(), 98305) + + + self._run_load(self.dataDispersionFile,vanaFile=None,vanaWS=self.wsVana_name,outWSName=self.wsData_name) + + # Check some data + wsData = mtd[self.wsData_name] + self.assertEqual(wsData.getNumberHistograms(), 98305) + + #================== Failure cases ================================ + + # TODO + + #================== Private methods ================================ + + + def _run_load(self, dataFile, vanaFile=None,vanaWS=None,outWSName=wsData_name): + """ + ILL Loader + """ + LoadILL(Filename=dataFile,FilenameVanadium=None,WorkspaceVanadium=None,OutputWorkspace=outWSName) + self._do_ads_check(outWSName) + + def _do_ads_check(self, name): + self.assertTrue(name in mtd) + self.assertTrue(type(mtd[name]) == MatrixWorkspace) + +#==================================================================================== + +class LoadILLIN5Test(stresstesting.MantidStressTest): + + def runTest(self): + self._success = False + # Custom code to create and run this single test suite + suite = unittest.TestSuite() + suite.addTest( unittest.makeSuite(ILLIN5Tests, "test") ) + runner = unittest.TextTestRunner() + # Run using either runner + res = runner.run(suite) + if res.wasSuccessful(): + self._success = True + else: + self._success = False + + def validate(self): + return self._success diff --git a/Code/Mantid/Testing/SystemTests/tests/analysis/INTERLoadingTest.py b/Code/Mantid/Testing/SystemTests/tests/analysis/INTERLoadingTest.py new file mode 100644 index 000000000000..8cc5a9c7feed --- /dev/null +++ b/Code/Mantid/Testing/SystemTests/tests/analysis/INTERLoadingTest.py @@ -0,0 +1,17 @@ +from LoadAndCheckBase import * + +''' +Test File loading and basic data integrity checks of INTER data in Mantid. +''' +class INTERLoadingTest(LoadAndCheckBase): + def get_raw_workspace_filename(self): + return "INTER00007709.raw" + + def get_nexus_workspace_filename(self): + return "INTER00007709.nxs" + + def get_integrated_reference_workspace_filename(self): + return "INTER00007709Integrated.nxs" + + def get_expected_instrument_name(self): + return "INTER" \ No newline at end of file diff --git a/Code/Mantid/Testing/SystemTests/tests/analysis/ISISDirectInelastic.py b/Code/Mantid/Testing/SystemTests/tests/analysis/ISISDirectInelastic.py new file mode 100644 index 000000000000..af683d96b1d9 --- /dev/null +++ b/Code/Mantid/Testing/SystemTests/tests/analysis/ISISDirectInelastic.py @@ -0,0 +1,514 @@ +import stresstesting +from mantid.simpleapi import * +from mantid.api import Workspace +import os,shutil + +from abc import ABCMeta, abstractmethod +from Direct.PropertyManager import PropertyManager + + +#---------------------------------------------------------------------- +class ISISDirectInelasticReduction(stresstesting.MantidStressTest): + """A base class for the ISIS direct inelastic tests + + The workflow is defined in the runTest() method, simply + define an __init__ method and set the following properties + on the object + - instr_name: A string giving the instrument name for the test + - sample_run: An integer run number of the sample or a a workspace + - incident_energy: A float value for the Ei guess + - bins: A list of rebin parameters + - white_beam: An integer giving a white_beam_file or a workspace + - mono_van: An integer giving a mono-vanadium run or a workspace or None + - map_file: An optional string pointing to a map file + - sample_mass: A float value for the sample mass or None + - sample_rmm: A float value for the sample rmm or None + - hard_mask: An hard mask file or None + """ + __metaclass__ = ABCMeta # Mark as an abstract class + + @abstractmethod + def get_reference_file(self): + """Returns the name of the reference file to compare against""" + raise NotImplementedError("Implement get_reference_file to return " + "the name of the file to compare against.") + + @abstractmethod + def get_result_workspace(self): + """Returns the result workspace to be checked""" + + @abstractmethod + def runTest(self): + """Defines the workflow for the test""" + # rename workspace to the name expected by unit test framework + + + + def validate(self): + """Returns the name of the workspace & file to compare""" + self.tolerance = 1e-6 + self.tolerance_is_reller=True + self.disableChecking.append('SpectraMap') + self.disableChecking.append('Instrument') + self.disableChecking.append('Sample') + result = self.get_result_workspace() + reference = self.get_reference_file() + return result, reference + + def _is_numeric(self, obj): + """Returns true if the object is an int or float, false otherwise""" + if type(obj) != float or type(obj) != int: + return True + else: + return False + + def _is_workspace(self, obj): + """ Returns True if the object is a workspace""" + return isinstance(obj, Workspace) + def __init__(self): + stresstesting.MantidStressTest.__init__(self) + # this is temporary parameter + self.scale_to_fix_abf=1 + +#------------------------- MARI tests ------------------------------------------------- + +class MARIReductionFromFile(ISISDirectInelasticReduction): + + def __init__(self): + ISISDirectInelasticReduction.__init__(self) + + from ISIS_MariReduction import ReduceMARIFromFile + + self.red = ReduceMARIFromFile() + self.red.def_advanced_properties() + self.red.def_main_properties() + # temporary fix to account for different monovan integral + self.scale_to_fix_abf = 0.997979227566217 + + def runTest(self): + outWS = self.red.reduce() + outWS*=self.scale_to_fix_abf + + + + def get_result_workspace(self): + """Returns the result workspace to be checked""" + return "outWS" + def get_reference_file(self): + return "MARIReduction.nxs" + +class MARIReductionFromFileCache(ISISDirectInelasticReduction): + + def __init__(self): + ISISDirectInelasticReduction.__init__(self) + self.tolerance = 1e-9 + from ISIS_MariReduction import ReduceMARIFromFile + + self.red = ReduceMARIFromFile() + self.red.def_advanced_properties() + self.red.def_main_properties() + + def prepare_test_file(self): + """ This method will run instead of pause and + would copy run file 11001 into 11002 emulating + appearance of this file from instrument + """ + self._counter+=1 + if self._counter>= 3: + source = FileFinder.findRuns('11001')[0] + targ_path = config['defaultsave.directory'] + targ_file = os.path.join(targ_path,'MAR11002.raw') + shutil.copy2(source ,targ_file ) + + self._file_to_clear = targ_file + self._counter = 0 + + + + def runTest(self): + self.red.wait_for_file = 10 + self.red._debug_wait_for_files_operation = self.prepare_test_file + self._counter=0 + + self.red.reducer.prop_man.sample_run = [11001,11002] + MARreducedRuns = self.red.run_reduction() + + RenameWorkspace(InputWorkspace=MARreducedRuns[0],OutputWorkspace='MARreducedFromFile') + RenameWorkspace(InputWorkspace=MARreducedRuns[1],OutputWorkspace='MARreducedWithCach') + + self.red.wait_for_file =0 + self.red._debug_wait_for_files_operation = None + os.remove(self._file_to_clear) + + def validate(self): + """Returns the name of the workspace & file to compare""" + super(MARIReductionFromFileCache,self).validate() + self.tolerance = 1e-9 + return 'MARreducedFromFile', 'MARreducedWithCach' + + def validateMethod(self): + return "validateWorkspaceToWorkspace" + + + def get_result_workspace(self): + """Returns the result workspace to be checked""" + return "outWS" + def get_reference_file(self): + return "MARIReduction.nxs" + + +class MARIReductionFromWorkspace(ISISDirectInelasticReduction): + + def __init__(self): + ISISDirectInelasticReduction.__init__(self) + + from ISIS_MariReduction import ReduceMARIFromWorkspace + + self.red = ReduceMARIFromWorkspace() + self.red.def_advanced_properties() + self.red.def_main_properties() + + self.scale_to_fix_abf = 0.997979227566217 + + + def runTest(self): + """Defines the workflow for the test""" + + outWS=self.red.reduce() + # temporary fix to account for different monovan integral + outWS*=self.scale_to_fix_abf + + + def get_result_workspace(self): + """Returns the result workspace to be checked""" + return "outWS" + + def get_reference_file(self): + return "MARIReduction.nxs" + +class MARIReductionMon2Norm(ISISDirectInelasticReduction): + + def __init__(self): + ISISDirectInelasticReduction.__init__(self) + + from ISIS_MariReduction import ReduceMARIMon2Norm + + self.red = ReduceMARIMon2Norm() + self.red.def_advanced_properties() + self.red.def_main_properties() + + def runTest(self): + """Defines the workflow for the test""" + + outWS=self.red.reduce() + # temporary fix to account for different monovan integral + outWS*=0.989834962505304 + + def get_result_workspace(self): + """Returns the result workspace to be checked""" + return "outWS" + + def get_reference_file(self): + return "MARIReduction.nxs" + + def validate(self): + result,reference = super(MARIReductionMon2Norm,self).validate() + self.tolerance = 1e-3 + return result,reference + + +class MARIReductionMonSeparate(ISISDirectInelasticReduction): + + def __init__(self): + ISISDirectInelasticReduction.__init__(self) + # This test has not been run properly so reference file is kind-of + # arbitrary. It just checks that this reduction works. + # Mari reduction masks are not correct for monitors loaded separately, + # This explains all the difference encountered. + from ISIS_MariReduction import ReduceMARIMonitorsSeparate + + self.red = ReduceMARIMonitorsSeparate() + self.red.def_advanced_properties() + self.red.def_main_properties() + + def runTest(self): + """Defines the workflow for the test""" + # temporary fix cross-influence of tests for MARI. changes to nex ticket make this unnecessary + PropertyManager.mono_correction_factor.set_cash_mono_run_number(None) + outWS=self.red.reduce() + # temporary fix to account for different monovan integral + outWS*=0.997966051169129 + + + def get_result_workspace(self): + """Returns the result workspace to be checked""" + return "outWS" + + def get_reference_file(self): + # monitor separate for MARI needs new maps and masks so, it is easier to redefine + # reference file for the time being + return "MARIReductionMonSeparate.nxs" + +class MARIReductionSum(ISISDirectInelasticReduction): + + def __init__(self): + + ISISDirectInelasticReduction.__init__(self) + from ISIS_MariReduction import MARIReductionSum + + self.red = MARIReductionSum() + self.red.def_advanced_properties() + self.red.def_main_properties() + + def runTest(self): + """Defines the workflow for the test + It verifies operation on summing two files on demand. No absolute units + """ + outWS=self.red.reduce() + #outWS*=1.00001556766686 + + def get_result_workspace(self): + """Returns the result workspace to be checked""" + return "outWS" + + def get_reference_file(self): + return "MARIReductionSum.nxs" + +class MARIReductionWaitAndSum(ISISDirectInelasticReduction): + + def __init__(self): + + ISISDirectInelasticReduction.__init__(self) + from ISIS_MariReduction import MARIReductionSum + + self.red = MARIReductionSum() + self.red.def_advanced_properties() + self.red.def_main_properties() + + def prepare_test_file(self): + """ This method will run instead of pause and + would copy run file 11015 into 11002 emulating + appearance of this file from instrument + """ + self._counter+=1 + if self._counter>= 3: + source = FileFinder.findRuns('11015')[0] + targ_path = config['defaultsave.directory'] + targ_file = os.path.join(targ_path,'MAR11002.raw') + shutil.copy2(source ,targ_file ) + + self._file_to_clear = targ_file + self._counter = 0 + + def runTest(self): + """Defines the workflow for the test + It verifies operation on summing two files on demand. with wait for + files appearing on data search path + """ + self.red.wait_for_file = 100 + self.red._debug_wait_for_files_operation = self.prepare_test_file + self._counter=0 + + self.red.reducer.prop_man.sample_run=[11001,11002] + outWS = self.red.run_reduction() + + self.red.wait_for_file =0 + self.red._debug_wait_for_files_operation = None + os.remove(self._file_to_clear) + + + def get_result_workspace(self): + """Returns the result workspace to be checked""" + return "outWS" + + def get_reference_file(self): + return "MARIReductionSum.nxs" + +#------------------------- MAPS tests ------------------------------------------------- + +class MAPSDgreduceReduction(ISISDirectInelasticReduction): + + def requiredMemoryMB(self): + """Far too slow for managed workspaces. They're tested in other places. Requires 10Gb""" + return 10000 + + def __init__(self): + ISISDirectInelasticReduction.__init__(self) + + from ISIS_MAPS_DGSReduction import ReduceMAPS + + self.red = ReduceMAPS() + self.red.def_advanced_properties() + self.red.def_main_properties() + + def runTest(self): + + outWS=self.red.reduce() + #New WBI value 0.02720959162181584 + #Old WBI Value 0.027209867107187088 + # fix old system test. + #outWS*=0.02720959162181584/0.027209867107187088 + + # rename workspace to the name expected by unit test framework + #RenameWorkspace(InputWorkspace=outWS,OutputWorkspace=wsName) + self.ws_name = 'outWS' + + + def get_reference_file(self): + return "MAPSDgreduceReduction.nxs" + def get_result_workspace(self): + """Returns the result workspace to be checked""" + return self.ws_name + + +#------------------------- MERLIN tests ------------------------------------------------- + +class MERLINReduction(ISISDirectInelasticReduction): + + def requiredMemoryMB(self): + """Far too slow for managed workspaces. They're tested in other places. Requires 16Gb""" + return 16000 + + def __init__(self): + ''' Test relies on MERLIN_Parameters.xml file introduced in July 2014 + ''' + ISISDirectInelasticReduction.__init__(self) + + from ISIS_MERLINReduction import ReduceMERLIN + + self.red = ReduceMERLIN() + self.red.def_advanced_properties() + self.red.def_main_properties() + + def runTest(self): + outWS = self.red.reduce() + + def get_reference_file(self): + return "MERLINReduction.nxs" + def get_result_workspace(self): + """Returns the result workspace to be checked""" + return "outWS" + + def validate(self): + self.tolerance = 1e-6 + self.tolerance_is_reller=True + self.disableChecking.append('SpectraMap') + self.disableChecking.append('Instrument') + result = self.get_result_workspace() + reference = self.get_reference_file() + return result, reference + +#------------------------- LET tests ------------------------------------------------- +# + +class LETReduction(stresstesting.MantidStressTest): + + def requiredMemoryMB(self): + """Far too slow for managed workspaces. They're tested in other places. Requires 2Gb""" + return 2000 + + def runTest(self): + """ + Run the LET reduction with event NeXus files + + Relies on LET_Parameters.xml file from June 2013 + """ + from ISIS_LETReduction import ReduceLET_OneRep + red = ReduceLET_OneRep() + red.def_main_properties() + red.def_advanced_properties() + + outWS=red.reduce() + + + def validate(self): + self.tolerance = 1e-6 + self.tolerance_is_reller=True + self.disableChecking.append('SpectraMap') + self.disableChecking.append('Instrument') + + return "outWS", "LETReduction.nxs" + +class LETReductionEvent2014Multirep(stresstesting.MantidStressTest): + """ + written in a hope that most of the stuff find here will eventually find its way into main reduction routines + """ + + def requiredMemoryMB(self): + """Far too slow for managed workspaces. They're tested in other places. Requires 20Gb""" + return 20000 + + def runTest(self): + """ + Run the LET reduction with event NeXus files + + Relies on LET_Parameters.xml file from June 2013 + """ + from ISIS_LETReduction import ReduceLET_MultiRep2014 + red = ReduceLET_MultiRep2014() + + red.def_advanced_properties() + red.def_main_properties() + + + out_ws_list=red.reduce() + + #mults =[41.178539329370217/41.178300987983413,72.235863046309746/72.231475173892022] + #New normalization for 3.4 meV: 41.178539329370217 + #Old normalization for 3.4 meV: 41.178300987983413 + #New normalization for 8 meV: 72.235863046309746 + #Old normalization for 8 meV: 72.231475173892022 + #for ind,ws in enumerate(out_ws_list): + # ws *=mults[ind] + + + + + + def validate(self): + self.tolerance = 1e-6 + self.tolerance_is_reller=False + self.disableChecking.append('SpectraMap') + self.disableChecking.append('Instrument') + + return "LETreducedEi3.4","LET14305_3_4mev.nxs","LETreducedEi8.0", "LET14305_8_0mev.nxs" + +class LETReductionEvent2015Multirep(stresstesting.MantidStressTest): + """ + written in a hope that most of the stuff find here will eventually find its way into main reduction routines + """ + + def requiredMemoryMB(self): + """Far too slow for managed workspaces. They're tested in other places. Requires 20Gb""" + return 20000 + + def runTest(self): + """ + Run the LET reduction with event NeXus files + + Relies on LET_Parameters.xml file from June 2013 + """ + from ISIS_LETReduction import ReduceLET_MultiRep2015 + red = ReduceLET_MultiRep2015() + + red.def_advanced_properties() + red.def_main_properties() + + + out_ws_list=red.reduce() + + #for ind,ws in enumerate(out_ws_list): + # ws *=mults[ind] + + + + + + def validate(self): + self.tolerance = 1e-6 + self.tolerance_is_reller=False + self.disableChecking.append('SpectraMap') + self.disableChecking.append('Instrument') + + return "LETreducedEi3.4","LET14305_3_4meV2015.nxs","LETreducedEi8.0", "LET14305_8_0meV2015.nxs" + diff --git a/Code/Mantid/Testing/SystemTests/tests/analysis/ISISDirectReductionComponents.py b/Code/Mantid/Testing/SystemTests/tests/analysis/ISISDirectReductionComponents.py new file mode 100644 index 000000000000..071bfef28164 --- /dev/null +++ b/Code/Mantid/Testing/SystemTests/tests/analysis/ISISDirectReductionComponents.py @@ -0,0 +1,255 @@ +import os,sys +import stresstesting +from mantid.simpleapi import * +from mantid.api import Workspace,IEventWorkspace + +from Direct.PropertyManager import PropertyManager +from Direct.RunDescriptor import RunDescriptor +import ISIS_MariReduction as mr + +#---------------------------------------------------------------------- +class ISIS_ReductionWebLike(stresstesting.MantidStressTest): + def __init__(self): + stresstesting.MantidStressTest.__init__(self) + + # prepare reduction variable + self.rd = mr.ReduceMARIFromFile() + self.rd.def_main_properties() + self.rd.def_advanced_properties() + + save_folder = config['defaultsave.directory'] + + self.rd.save_web_variables(os.path.join(save_folder,'reduce_vars.py')) + + + def runTest(self): + # run reduction using saved variables like web variables + web_var_folder = config['defaultsave.directory'] + sys.path.insert(0,web_var_folder) + reload(mr) + + # change these variables to save result as nxs workspace + mr.web_var.advanced_vars['save_format']='nxs' + # web services currently needs input file to be defined + input_file = 'MAR11001.RAW' + rez = mr.main(input_file,web_var_folder) + + # verify if result was indeed written + self.rd.reducer.sample_run = input_file + saveFileName = self.rd.reducer.save_file_name + oputputFile = os.path.join(web_var_folder,saveFileName+'.nxs') + + self.assertTrue(os.path.exists(oputputFile)) + + web_var_file = os.path.join(web_var_folder,'reduce_vars') + if os.path.exists(web_var_file+'.py'): + os.remove(web_var_file+'.py') + if os.path.exists(web_var_file+'.pyc'): + os.remove(web_var_file+'.pyc') + + + def get_result_workspace(self): + """Returns the result workspace to be checked""" + if 'outWS' in mtd: + return 'outWS' + saveFileName = self.rd.reducer.save_file_name + outWS = Load(Filename=saveFileName+'.nxs') + outWS *= 0.997979227566217 + fullRezPath =FileFinder.getFullPath(saveFileName+'.nxs') + os.remove(fullRezPath) + return 'outWS' + def get_reference_file(self): + return "MARIReduction.nxs" + + def validate(self): + """Returns the name of the workspace & file to compare""" + self.tolerance = 1e-6 + self.tolerance_is_reller=True + self.disableChecking.append('SpectraMap') + self.disableChecking.append('Instrument') + self.disableChecking.append('Sample') + result = self.get_result_workspace() + reference = self.get_reference_file() + return result, reference + +class ISIS_ReductionWrapperValidate(stresstesting.MantidStressTest): + def __init__(self): + stresstesting.MantidStressTest.__init__(self) + self.result = False + + + def runTest(self): + # prepare reduction variable + rd = mr.ReduceMARIFromFile() + rd.def_main_properties() + rd.def_advanced_properties() + + self.result,message = rd.validate_result() + if not self.result: + print "*** Validation failed: {0}".format(message) + + + + def validate(self): + """Returns the name of the workspace & file to compare""" + return self.result + + +#---------------------------------------------------------------------- +class ISISLoadFilesRAW(stresstesting.MantidStressTest): + + + def __init__(self): + stresstesting.MantidStressTest.__init__(self) + self.valid = False + + def runTest(self): + propman = PropertyManager('MAR') + + propman.sample_run = 11001 + propman.load_monitors_with_workspace = True + + mon_ws = PropertyManager.sample_run.get_monitors_ws() + ws = PropertyManager.sample_run.get_workspace() + + self.assertTrue(isinstance(ws,Workspace)) + self.assertEqual(ws.getNumberHistograms(),922) + + DeleteWorkspace(ws) + + propman.load_monitors_with_workspace = False + propman.sample_run = 11001 + ws = PropertyManager.sample_run.get_workspace() + mon_ws = PropertyManager.sample_run.get_monitors_ws() + + self.assertEqual(ws.getNumberHistograms(),919) + self.assertEqual(mon_ws.getNumberHistograms(),3) + + # + propman = PropertyManager('MAPS') + propman.sample_run = 17186 + propman.load_monitors_with_workspace = False + + mon_ws = PropertyManager.sample_run.get_monitors_ws() + ws = PropertyManager.sample_run.get_workspace() + self.assertTrue(isinstance(ws,Workspace)) + self.assertEqual(ws.getNumberHistograms(),41472) + self.assertEqual(mon_ws.getNumberHistograms(),4) + # + self.valid = True + + def validate(self): + return self.valid + +class ISISLoadFilesMER(stresstesting.MantidStressTest): + + + def __init__(self): + stresstesting.MantidStressTest.__init__(self) + self.valid = False + + def runTest(self): + # + propman = PropertyManager('MER') + propman.sample_run = 6398 # (raw file) + propman.det_cal_file = 6399 + propman.load_monitors_with_workspace = False + + mon_ws = PropertyManager.sample_run.get_monitors_ws() + self.assertTrue(not(mon_ws is None)) + + ws = PropertyManager.sample_run.get_workspace() + self.assertTrue(isinstance(ws,Workspace)) + self.assertEqual(ws.getNumberHistograms(),69632) + self.assertEqual(mon_ws.getNumberHistograms(),9) + + # test load together + propman.sample_run = None # (clean things up) + propman.load_monitors_with_workspace = True + propman.sample_run = 6398 + + mon_ws = PropertyManager.sample_run.get_monitors_ws() + self.assertTrue(not(mon_ws is None)) + ws = PropertyManager.sample_run.get_workspace() + self.assertTrue(isinstance(ws,Workspace)) + self.assertEqual(ws.getNumberHistograms(),69641) + self.assertEqual(mon_ws.getNumberHistograms(),69641) + + + propman.sample_run = 18492 # (histogram nxs file ) + propman.det_cal_file = None + mon_ws = PropertyManager.sample_run.get_monitors_ws() + self.assertTrue(not(mon_ws is None)) + ws = PropertyManager.sample_run.get_workspace() + self.assertTrue(isinstance(ws,Workspace)) + self.assertEqual(ws.getNumberHistograms(),69641) + self.assertEqual(mon_ws.getNumberHistograms(),69641) + + + self.valid = True + return + # enable when bug #10980 is fixed + propman.sample_run = 18492 # (histogram nxs file ) + propman.det_cal_file = None + mon_ws = PropertyManager.sample_run.get_monitors_ws() + self.assertTrue(not(mon_ws is None)) + + ws = PropertyManager.sample_run.get_workspace() + self.assertTrue(isinstance(ws,Workspace)) + self.assertEqual(ws.getNumberHistograms(),69632) + self.assertEqual(mon_ws.getNumberHistograms(),9) + + + self.valid = True + + + def validate(self): + return self.valid + +class ISISLoadFilesLET(stresstesting.MantidStressTest): + + + def __init__(self): + stresstesting.MantidStressTest.__init__(self) + self.valid = False + + def runTest(self): + + # + propman = PropertyManager('LET') + + + propman.sample_run = 6278 #event nexus file + propman.load_monitors_with_workspace = False + + # Here we have known problem of propman loading new IDF, and + # workspace is written using old IDF. New IDF has mon1_norm_spec =73729 + # and ei_mon1_spec=73734 (on January 2015) and old + # IDF -- mon1_norm_spec =40961 and 40966 (forever) + # Normalized by monitor-1. -- need monitor1 and ei needs ei_mon1_spec + # This problem is hopefully fixed in reduction now, but here + # we have to specify these values manually to guard against + # changes in a future + propman.normalise_method='monitor-1' + propman.mon1_norm_spec=40961 + propman.ei_mon1_spec =40966 + + mon_ws = PropertyManager.sample_run.get_monitors_ws() + self.assertTrue(not(mon_ws is None)) + ws = PropertyManager.sample_run.get_workspace() + + self.assertTrue(isinstance(ws,IEventWorkspace)) + self.assertEqual(ws.getNumberHistograms(),40960) + self.assertTrue(isinstance(mon_ws,Workspace)) + # + self.assertEqual(mon_ws.getNumberHistograms(),9) + + + self.valid = True + + + def validate(self): + return self.valid + +if __name__=="__main__": + ISISLoadFilesMER.runTest() diff --git a/Code/Mantid/Testing/SystemTests/tests/analysis/ISISIndirectAbsCorTest.py b/Code/Mantid/Testing/SystemTests/tests/analysis/ISISIndirectAbsCorTest.py new file mode 100644 index 000000000000..2d3e85724613 --- /dev/null +++ b/Code/Mantid/Testing/SystemTests/tests/analysis/ISISIndirectAbsCorTest.py @@ -0,0 +1,237 @@ +import stresstesting +from mantid.simpleapi import * +from IndirectImport import is_supported_f2py_platform +import os + +#==================================================================================================== + + +class CylAbsTest(stresstesting.MantidStressTest): + + def skipTests(self): + return not is_supported_f2py_platform() + + def runTest(self): + import IndirectAbsCor as Main + + sname = 'irs26176_graphite002_red' + LoadNexusProcessed(Filename=sname, OutputWorkspace=sname) + + beam = [3.0, 1.0, -1.0, 2.0, -2.0, 0.0, 3.0, 0.0, 3.0] + size = [0.2, 0.25, 0.26, 0.0] + density = [0.1, 0.1, 0.1] + sigs = [5.0, 0.1, 0.1] + siga = [0.0, 5.0, 5.0] + avar = 0.002 + saveOp = False + Main.AbsRun(sname, 'cyl', beam, 2, size, density, + sigs, siga, avar, saveOp) + + def validate(self): + self.tolerance = 1e-3 + return 'irs26176_graphite002_cyl_Abs', 'ISISIndirectAbsCor_CylAbsTest.nxs' + +#==================================================================================================== + + +class FltAbsTest(stresstesting.MantidStressTest): + + def skipTests(self): + return not is_supported_f2py_platform() + + def runTest(self): + import IndirectAbsCor as Main + + sname = 'irs26176_graphite002_red' + LoadNexusProcessed(Filename=sname, OutputWorkspace=sname) + + beam = '' + size = [0.1, 0.01, 0.01] + density = [0.1, 0.1, 0.1] + sigs = [5.0, 0.1, 0.1] + siga = [0.0, 5.0, 5.0] + avar = 45.0 + saveOp = False + Main.AbsRun(sname, 'flt', beam, 2, size, density, + sigs, siga, avar, saveOp) + + def validate(self): + self.tolerance = 1e-3 + return 'irs26176_graphite002_flt_Abs', 'ISISIndirectAbsCor_FltAbsTest.nxs' + + +#==================================================================================================== + + +class FltAbsTSecCloseTo90Test(stresstesting.MantidStressTest): + + def skipTests(self): + return not is_supported_f2py_platform() + + def runTest(self): + import IndirectAbsCor as Main + + sname = 'irs59330_graphite002_red' + LoadNexusProcessed(Filename=sname, OutputWorkspace=sname) + + beam = '' + size = [0.1, 0.01, 0.01] + density = [0.05, 0.5, 0.5] + sigs = [5.0, 0.1, 0.1] + siga = [0.0, 5.0, 5.0] + avar = 45.0 + saveOp = False + Main.AbsRun(sname, 'flt', beam, 2, size, density, + sigs, siga, avar, saveOp) + + def validate(self): + self.tolerance = 1e-3 + return 'iris59330_graphite002_flt_Abs', 'ISISIndirectAbsCor_FltAbsTSecCloseTo90Test.nxs' + +#==================================================================================================== + + +class AbsRunFeederTest(stresstesting.MantidStressTest): + """ + Test AbsRunFeeder with given values for scattering and absorption cross sections + for both sample and can. + """ + + def skipTests(self): + return not is_supported_f2py_platform() + + def runTest(self): + from IndirectAbsCor import AbsRunFeeder + + # H20 sample + inputWS = 'irs26176_graphite002_red' + # cylindrical Vanadium can + canWS = 'irs26173_graphite002_red' + + Load(inputWS + '.nxs', OutputWorkspace=inputWS) + Load(canWS + '.nxs', OutputWorkspace=canWS) + + geom = 'cyl' + ncan = 2 + size = [0.2, 0.25, 0.26, 0.0] + sigs = [5.0, 0.1, 0.1] + siga = [0.0, 5.0, 5.0] + avar = 0.002 + density = [0.1, 0.1, 0.1] + beam_width = 4.0 + AbsRunFeeder(inputWS, canWS, geom, ncan, size, avar, density, beam_width=beam_width, sigs=sigs, siga=siga) + + def validate(self): + self.tolerance = 1e-3 + return 'irs26176_graphite002_cyl_Abs', 'ISISIndirectAbsCor_AbsRunFeederTest.nxs' + +#==================================================================================================== + + +class AbsRunFeederChemicalFormulaTest(stresstesting.MantidStressTest): + """ + Test AbsRunFeeder with chemical formula input for scattering and absorption cross sections + for both sample and can. + """ + + def skipTests(self): + return not is_supported_f2py_platform() + + def runTest(self): + from IndirectAbsCor import AbsRunFeeder + + # H20 sample + inputWS = 'irs26176_graphite002_red' + # cylindrical Vanadium can + canWS = 'irs26173_graphite002_red' + + Load(inputWS + '.nxs', OutputWorkspace=inputWS) + Load(canWS + '.nxs', OutputWorkspace=canWS) + + geom = 'cyl' + ncan = 2 + size = [0.2, 0.25, 0.26, 0.0] + avar = 0.002 + density = [0.1, 0.1, 0.1] + beam_width = 4.0 + sampleFormula = 'H2-O' + canFormula = 'V' + AbsRunFeeder(inputWS, canWS, geom, ncan, size, avar, density, beam_width=beam_width, sample_formula=sampleFormula, can_formula=canFormula, sigs=[0,0,0], siga=[0,0,0]) + + def validate(self): + self.tolerance = 1e-3 + return 'irs26176_graphite002_cyl_Abs', 'ISISIndirectAbsCor_ChemicalFormulaTest.nxs' + +#==================================================================================================== + + +class AbsRunFeederDefaultBeamWidthTest(stresstesting.MantidStressTest): + """ + Test AbsRunFeeder with given values for scattering and absorption cross sections + for both sample and can and the beam width taken from the IPF. + """ + + def skipTests(self): + return not is_supported_f2py_platform() + + def runTest(self): + from IndirectAbsCor import AbsRunFeeder + + # H20 sample + inputWS = 'irs26176_graphite002_red' + # cylindrical Vanadium can + canWS = 'irs26173_graphite002_red' + + Load(inputWS + '.nxs', OutputWorkspace=inputWS) + path = os.path.join(config['instrumentDefinition.directory'], 'IRIS_Parameters.xml') + LoadParameterFile(inputWS, Filename=path) + Load(canWS + '.nxs', OutputWorkspace=canWS) + + geom = 'cyl' + ncan = 2 + size = [0.2, 0.25, 0.26, 0.0] + sigs = [5.0, 0.1, 0.1] + siga = [0.0, 5.0, 5.0] + avar = 0.002 + density = [0.1, 0.1, 0.1] + AbsRunFeeder(inputWS, canWS, geom, ncan, size, avar, density, sigs=sigs, siga=siga) + + def validate(self): + self.tolerance = 1e-3 + return 'irs26176_graphite002_cyl_Abs', 'ISISIndirectAbsCor_DefaultBeamWidthTest.nxs' + +#==================================================================================================== + + +class AbsRunFeederDiffractionTest(stresstesting.MantidStressTest): + """ + Test AbsRunFeeder with sample and can material formulas for a diffraction run. + """ + + def skipTests(self): + return not is_supported_f2py_platform() + + def runTest(self): + from IndirectAbsCor import AbsRunFeeder + + # H20 sample + inputWS = 'irs26176_diffspec_red' + # cylindrical Vanadium can + canWS = 'irs26173_diffspec_red' + + Load(inputWS + '.nxs', OutputWorkspace=inputWS) + Load(canWS + '.nxs', OutputWorkspace=canWS) + + geom = 'cyl' + ncan = 2 + size = [0.2, 0.25, 0.26, 0.0] + avar = 0.002 + density = [0.1, 0.1, 0.1] + beam_width = 4.0 + sampleFormula = 'H2-O' + canFormula = 'V' + AbsRunFeeder(inputWS, canWS, geom, ncan, size, avar, density, beam_width=beam_width, sample_formula=sampleFormula, can_formula=canFormula, sigs=[0,0,0], siga=[0,0,0]) + + def validate(self): + self.tolerance = 1e-3 + return 'irs26176_diffspec_cyl_Abs', 'ISISIndirectAbsCor_AbsRunFeederDiffractionTest.nxs' diff --git a/Code/Mantid/Testing/SystemTests/tests/analysis/ISISIndirectAnalysisTest.py b/Code/Mantid/Testing/SystemTests/tests/analysis/ISISIndirectAnalysisTest.py new file mode 100644 index 000000000000..c5410ba8b05f --- /dev/null +++ b/Code/Mantid/Testing/SystemTests/tests/analysis/ISISIndirectAnalysisTest.py @@ -0,0 +1,31 @@ +import stresstesting +import os +from mantid.simpleapi import * +from IndirectImport import is_supported_f2py_platform + + +class ElasticWindowMultipleTest(stresstesting.MantidStressTest): + + def runTest(self): + Load(Filename='osi92762_graphite002_red.nxs,osi92763_graphite002_red.nxs', + OutputWorkspace='__ElWinMulti_InputWS') + + ElasticWindowMultiple( + InputWorkspaces='__ElWinMulti_InputWS', + Range1Start=-0.2, + Range1End=0.2, + Range2Start='-0.24', + Range2End='-0.22', + OutputInQ='eq', + OutputInQSquared='eq2', + OutputELF='elf', + OutputELT='elt') + + GroupWorkspaces(InputWorkspaces=['elf', 'elt'], + OutputWorkspace='__ElWinMulti_OutputWS') + + SaveNexus(Filename='__ElWinMulti_OutputWS', InputWorkspace='__ElWinMulti_OutputWS') + + def validate(self): + self.tolerance = 1e-10 + return '__ElWinMulti_OutputWS', 'II.AnalysisElwinMulti.nxs' diff --git a/Code/Mantid/Testing/SystemTests/tests/analysis/ISISIndirectBayesTest.py b/Code/Mantid/Testing/SystemTests/tests/analysis/ISISIndirectBayesTest.py new file mode 100644 index 000000000000..437cc801abbd --- /dev/null +++ b/Code/Mantid/Testing/SystemTests/tests/analysis/ISISIndirectBayesTest.py @@ -0,0 +1,388 @@ +import stresstesting +import os +from mantid.simpleapi import * +from IndirectImport import is_supported_f2py_platform + +def _cleanup_files(dirname, filenames): + """ + Attempts to remove each filename from + the given directory + """ + for filename in filenames: + path = os.path.join(dirname, filename) + try: + os.remove(path) + except OSError: + pass + +class QLresTest(stresstesting.MantidStressTest): + + def skipTests(self): + if is_supported_f2py_platform(): + return False + else: + return True + + def runTest(self): + import IndirectBayes as Main + nbins = ['1', '1'] + sname = 'irs26176_graphite002_red' + rname = 'irs26173_graphite002_res' + rsname = '' + wfile = '' + erange = [-0.5, 0.5] + fitOp = [True, 'Sloping', False, False] #elastic, background, width, resnorm + loopOp = False + plotOp = False + saveOp = False + + spath = sname+'.nxs' # path name for sample nxs file + LoadNexusProcessed(Filename=spath, OutputWorkspace=sname) + rpath = rname+'.nxs' # path name for res nxs file + LoadNexusProcessed(Filename=rpath, OutputWorkspace=rname) + Main.QLRun('QL',sname,rname,rsname,erange,nbins,fitOp,wfile,loopOp,plotOp,saveOp) + + def validate(self): + self.tolerance = 1e-4 + return 'irs26176_graphite002_QLr_Workspace_0','ISISIndirectBayes_QlresTest.nxs' + + def cleanup(self): + filenames = ['irs26176_graphite002_QLr.lpt','irs26176_graphite002_QLr.ql1', + 'irs26176_graphite002_QLr.ql2','irs26176_graphite002_QLr.ql3', + 'irs26176_graphite002_QLr_Parameters.nxs'] + _cleanup_files(config['defaultsave.directory'], filenames) + +#======================================================================== +class ResNormTest(stresstesting.MantidStressTest): + + def skipTests(self): + if is_supported_f2py_platform(): + return False + else: + return True + + def runTest(self): + import IndirectBayes as Main + nbin = '1' + vname = 'irs26173_graphite002_red' + rname = 'irs26173_graphite002_res' + erange = [-0.2, 0.2] + plotOp = False + saveOp = False + + vpath = vname+'.nxs' # path name for van nxs file + LoadNexusProcessed(Filename=vpath, OutputWorkspace=vname) + rpath = rname+'.nxs' # path name for res nxs file + LoadNexusProcessed(Filename=rpath, OutputWorkspace=rname) + Main.ResNormRun(vname,rname,erange,nbin,plotOp,saveOp) + + def validate(self): + self.tolerance = 1e-4 + self.disableChecking.append("SpectraMap") + return 'irs26173_graphite002_ResNorm_Fit','ISISIndirectBayes_ResNormTest.nxs' + + def cleanup(self): + filenames = ['irs26173_graphite002_resnrm.lpt'] + _cleanup_files(config['defaultsave.directory'], filenames) + +#========================================================================= +class QuestTest(stresstesting.MantidStressTest): + + def skipTests(self): + if is_supported_f2py_platform(): + return False + else: + return True + + def runTest(self): + import IndirectBayes as Main + nbins = [1, 1] + nbs = [50, 30] + sname = 'irs26176_graphite002_red' + rname = 'irs26173_graphite002_res' + erange = [-0.5, 0.5] + fitOp = [True, 'Sloping', False, False] #elastic, background, width, resnorm + loopOp = False + plotOp = 'None' + saveOp = False + + spath = sname+'.nxs' # path name for sample nxs file + LoadNexusProcessed(Filename=spath, OutputWorkspace=sname) + rpath = rname+'.nxs' # path name for res nxs file + LoadNexusProcessed(Filename=rpath, OutputWorkspace=rname) + Main.QuestRun(sname,rname,nbs,erange,nbins,fitOp,loopOp,plotOp,saveOp) + + def validate(self): + self.tolerance = 1e-1 + return 'irs26176_graphite002_Qst_Fit','ISISIndirectBayes_QuestTest.nxs' + + def cleanup(self): + filenames = ['irs26176_graphite002_Qst.lpt','irs26176_graphite002_Qss.ql2', + 'irs26176_graphite002_Qsb.ql1'] + _cleanup_files(config['defaultsave.directory'], filenames) + +#============================================================================= +class QSeTest(stresstesting.MantidStressTest): + + def skipTests(self): + if is_supported_f2py_platform(): + return False + else: + return True + + def runTest(self): + import IndirectBayes as Main + nbins = ['1', '1'] + sname = 'irs26176_graphite002_red' + rname = 'irs26173_graphite002_res' + rsname = '' + wfile = '' + erange = [-0.5, 0.5] + fitOp = [True, 'Sloping', False, False] #elastic, background, width, resnorm + loopOp = False + plotOp = False + saveOp = False + + spath = sname+'.nxs' # path name for sample nxs file + LoadNexusProcessed(Filename=spath, OutputWorkspace=sname) + rpath = rname+'.nxs' # path name for res nxs file + LoadNexusProcessed(Filename=rpath, OutputWorkspace=rname) + Main.QLRun('QSe',sname,rname,rsname,erange,nbins,fitOp,wfile,loopOp,plotOp,saveOp) + + def validate(self): + self.tolerance = 1e-1 + return 'irs26176_graphite002_QSe_Workspace_0','ISISIndirectBayes_QSeTest.nxs' + + def cleanup(self): + filenames = ['irs26176_graphite002_QSe_Parameters.nxs', 'irs26176_graphite002_Qse.qse', + 'irs26176_graphite002_Qse.lpt'] + _cleanup_files(config['defaultsave.directory'], filenames) + +#============================================================================= +class QLDataTest(stresstesting.MantidStressTest): + + def skipTests(self): + if is_supported_f2py_platform(): + return False + else: + return True + + def runTest(self): + import IndirectBayes as Main + nbins = ['1', '1'] + sname = 'irs26176_graphite002_red' + rname = 'irs26173_graphite002_red' + rsname = '' + wfile = '' + erange = [-0.5, 0.5] + fitOp = [True, 'Sloping', False, False] #elastic, background, width, resnorm + loopOp = False + plotOp = False + saveOp = False + + spath = sname+'.nxs' # path name for sample nxs file + LoadNexusProcessed(Filename=spath, OutputWorkspace=sname) + rpath = rname+'.nxs' # path name for res nxs file + LoadNexusProcessed(Filename=rpath, OutputWorkspace=rname) + Main.QLRun('QL',sname,rname,rsname,erange,nbins,fitOp,wfile,loopOp,plotOp,saveOp) + + def validate(self): + self.tolerance = 1e-4 + return 'irs26176_graphite002_QLd_Workspace_0','ISISIndirectBayes_QLDataTest.nxs' + + def cleanup(self): + filenames = ['irs26176_graphite002_QLd.lpt','irs26176_graphite002_QLd.ql1', + 'irs26176_graphite002_QLd.ql2','irs26176_graphite002_QLd.ql3', + 'irs26176_graphite002_QLd_Parameters.nxs'] + _cleanup_files(config['defaultsave.directory'], filenames) + +#============================================================================= +class QLResNormTest(stresstesting.MantidStressTest): + + def skipTests(self): + if is_supported_f2py_platform(): + return False + else: + return True + + def runTest(self): + import IndirectBayes as Main + + nbins = ['1', '1'] + sname = 'irs26176_graphite002_red' + rname = 'irs26173_graphite002_res' + rsname = 'irs26173_graphite002_ResNorm' + wfile = '' + erange = [-0.5, 0.5] + fitOp = [True, 'Sloping', False, True] #elastic, background, width, resnorm + loopOp = True + plotOp = False + saveOp = False + + spath = sname+'.nxs' # path name for sample nxs file + LoadNexusProcessed(Filename=spath, OutputWorkspace=sname) + rpath = rname+'.nxs' # path name for res nxs file + LoadNexusProcessed(Filename=rpath, OutputWorkspace=rname) + rspath = rsname+'_Paras.nxs' # path name for resNorm nxs file + LoadNexusProcessed(Filename=rspath, OutputWorkspace=rsname) + Main.QLRun('QL',sname,rname,rsname,erange,nbins,fitOp,wfile,loopOp,plotOp,saveOp) + + def validate(self): + self.tolerance = 1e-1 + return 'irs26176_graphite002_QLr_Workspaces','ISISIndirectBayes_QLr_ResNorm_Test.nxs' + + def cleanup(self): + filenames = ['irs26176_graphite002_QLd.lpt','irs26176_graphite002_QLd.ql1', + 'irs26176_graphite002_QLd.ql2','irs26176_graphite002_QLd.ql3', + 'irs26176_graphite002_QLd_Parameters.nxs'] + _cleanup_files(config['defaultsave.directory'], filenames) + +#============================================================================= +class QLWidthTest(stresstesting.MantidStressTest): + + def skipTests(self): + if is_supported_f2py_platform(): + return False + else: + return True + + def runTest(self): + import IndirectBayes as Main + + nbins = ['1', '1'] + sname = 'irs26176_graphite002_red' + rname = 'irs26173_graphite002_res' + rsname = '' + wfile = 'irs26176_graphite002_width_water.dat' + erange = [-0.5, 0.5] + fitOp = [True, 'Sloping', True, False] #elastic, background, width, resnorm + loopOp = False + plotOp = False + saveOp = False + + spath = sname+'.nxs' # path name for sample nxs file + LoadNexusProcessed(Filename=spath, OutputWorkspace=sname) + rpath = rname+'.nxs' # path name for res nxs file + LoadNexusProcessed(Filename=rpath, OutputWorkspace=rname) + Main.QLRun('QL',sname,rname,rsname,erange,nbins,fitOp,wfile,loopOp,plotOp,saveOp) + + def validate(self): + self.tolerance = 1e-1 + return 'irs26176_graphite002_QLr_Workspace_0','ISISIndirectBayes_QLr_width_Test.nxs' + + def cleanup(self): + filenames = ['irs26176_graphite002_QLd.lpt','irs26176_graphite002_QLd.ql1', + 'irs26176_graphite002_QLd.ql2','irs26176_graphite002_QLd.ql3', + 'irs26176_graphite002_QLd_Parameters.nxs'] + _cleanup_files(config['defaultsave.directory'], filenames) + +#============================================================================= + +class JumpCETest(stresstesting.MantidStressTest): + + def runTest(self): + sname = 'irs26176_graphite002_QLr_Workspace' + qrange = [0.6, 1.705600] + plotOp = False + saveOp = False + + filename = sname + '.nxs' # path name for nxs file + LoadNexusProcessed(Filename=filename, OutputWorkspace=sname) + + # Data must be in HWHM + Scale(InputWorkspace=sname, Factor=0.5, OutputWorkspace=sname) + + JumpFit(InputWorkspace=sname, + Function='ChudleyElliot', + Width=2, + QMin=qrange[0], + QMax=qrange[1], + Plot=plotOp, + Save=saveOp) + + def validate(self): + self.tolerance = 1e-5 + return 'irs26176_graphite002_QLr_ChudleyElliot_fit_Workspace','ISISIndirectBayes_JumpCETest.nxs' + +#============================================================================= +class JumpHallRossTest(stresstesting.MantidStressTest): + + def runTest(self): + sname = 'irs26176_graphite002_QLr_Workspace' + qrange = [0.6, 1.705600] + plotOp = False + saveOp = False + + path = sname+'.nxs' # path name for nxs file + LoadNexusProcessed(Filename=path, OutputWorkspace=sname) + + # Data must be in HWHM + Scale(InputWorkspace=sname, Factor=0.5, OutputWorkspace=sname) + + JumpFit(InputWorkspace=sname, + Function='HallRoss', + Width=2, + QMin=qrange[0], + QMax=qrange[1], + Plot=plotOp, + Save=saveOp) + + def validate(self): + self.tolerance = 1e-5 + return 'irs26176_graphite002_QLr_HallRoss_fit_Workspace','ISISIndirectBayes_JumpHallRossTest.nxs' + +#============================================================================= +class JumpFickTest(stresstesting.MantidStressTest): + + def runTest(self): + sname = 'irs26176_graphite002_QLr_Workspace' + qrange = [0.6, 1.705600] + plotOp = False + saveOp = False + + path = sname+'.nxs' # path name for nxs file + LoadNexusProcessed(Filename=path, OutputWorkspace=sname) + + # Data must be in HWHM + Scale(InputWorkspace=sname, Factor=0.5, OutputWorkspace=sname) + + JumpFit(InputWorkspace=sname, + Function='FickDiffusion', + Width=2, + QMin=qrange[0], + QMax=qrange[1], + Plot=plotOp, + Save=saveOp) + + def validate(self): + self.tolerance = 5e-4 + return 'irs26176_graphite002_QLr_FickDiffusion_fit_Workspace','ISISIndirectBayes_JumpFickTest.nxs' + +#============================================================================= +class JumpTeixeiraTest(stresstesting.MantidStressTest): + + def runTest(self): + sname = 'irs26176_graphite002_QLr_Workspace' + qrange = [0.6, 1.705600] + plotOp = False + saveOp = False + + path = sname+'.nxs' # path name for nxs file + LoadNexusProcessed(Filename=path, OutputWorkspace=sname) + + # Data must be in HWHM + Scale(InputWorkspace=sname, Factor=0.5, OutputWorkspace=sname) + + JumpFit(InputWorkspace=sname, + Function='TeixeiraWater', + Width=2, + QMin=qrange[0], + QMax=qrange[1], + Plot=plotOp, + Save=saveOp) + + def validate(self): + self.tolerance = 1e-2 + return 'irs26176_graphite002_QLr_TeixeiraWater_fit_Workspace','ISISIndirectBayes_JumpTeixeiraTest.nxs' + +#============================================================================= diff --git a/Code/Mantid/Testing/SystemTests/tests/analysis/ISISIndirectInelastic.py b/Code/Mantid/Testing/SystemTests/tests/analysis/ISISIndirectInelastic.py new file mode 100644 index 000000000000..30a6b8ac06ec --- /dev/null +++ b/Code/Mantid/Testing/SystemTests/tests/analysis/ISISIndirectInelastic.py @@ -0,0 +1,1366 @@ +import stresstesting +import os +import platform +from abc import ABCMeta, abstractmethod + +from mantid.simpleapi import * + +# For debugging only. +from mantid.api import FileFinder + +# Import our workflows. +from inelastic_indirect_reducer import IndirectReducer +from inelastic_indirect_reduction_steps import CreateCalibrationWorkspace +from IndirectDataAnalysis import msdfit, furyfitSeq, furyfitMult, confitSeq, abscorFeeder + +''' +- TOSCA only supported by "Reduction" (the Energy Transfer tab of C2E). +- OSIRIS/IRIS supported by all tabs / interfaces. +- VESUVIO is not supported by any interface as of yet. + +For diagrams on the intended work flow of the IDA and Indirect parts of the +C2E interface, please see: + +- http://www.mantidproject.org/IDA +- http://www.mantidproject.org/Indirect + +System test class hierarchy as shown below: + +stresstesting.MantidStressTest + | + +--ISISIndirectInelasticBase + | + +--ISISIndirectInelasticReduction + | | + | +--TOSCAReduction + | +--IRISReduction + | +--OSIRISReduction + | + +--ISISIndirectInelasticCalibratrion + | | + | +--IRISCalibratrion + | +--OSIRISCalibratrion + | + +--ISISIndirectInelasticResolution + | | + | +--IRISResolution + | +--OSIRISResolution + | + +--ISISIndirectInelasticDiagnostics + | | + | +--IRISDiagnostics + | +--OSIRISDiagnostics + | + +--ISISIndirectInelasticMoments + | | + | +--IRISMoments + | +--OSIRISMoments + | + +--ISISIndirectInelasticElwinAndMSDFit + | | + | +--IRISElwinAndMSDFit + | +--OSIRISElwinAndMSDFit + | + +--ISISIndirectInelasticFuryAndFuryFit + | | + | +--IRISFuryAndFuryFit + | +--OSIRISFuryAndFuryFit + | + +--ISISIndirectInelasticFuryAndFuryFitMulti + | | + | +--IRISFuryAndFuryFitMulti + | +--OSIRISFuryAndFuryFitMulti + | + +--ISISIndirectInelasticConvFit + | | + | +--IRISConvFit + | +--OSIRISConvFit + | +''' + + +class ISISIndirectInelasticBase(stresstesting.MantidStressTest): + '''A common base class for the ISISIndirectInelastic* base classes. + ''' + + __metaclass__ = ABCMeta # Mark as an abstract class + + @abstractmethod + def get_reference_files(self): + '''Returns the name of the reference files to compare against.''' + raise NotImplementedError("Implmenent get_reference_files to return " + "the names of the files to compare against.") + + @abstractmethod + def _run(self): + raise NotImplementedError("Implement _run.") + + def validate_results_and_references(self): + if type(self.get_reference_files()) != list: + raise RuntimeError("The reference file(s) should be in a list") + if type(self.result_names) != list: + raise RuntimeError("The result workspace(s) should be in a list") + if len(self.get_reference_files()) !=\ + len(self.result_names): + raise RuntimeError("The number of result workspaces does not match" + " the number of reference files.") + if len(self.get_reference_files()) < 1: + raise RuntimeError("There needs to be a least one result and " + "reference.") + + @abstractmethod + def _validate_properties(self): + '''Check the object properties are in an expected state to continue''' + raise NotImplementedError("Implmenent _validate_properties.") + + def runTest(self): + self._validate_properties() + self._run() + self.validate_results_and_references() + + def validate(self): + '''Performs the validation for the generalised case of multiple results + and multiple reference files. + ''' + + self.disableChecking.append('SpectraMap') + self.disableChecking.append('Instrument') + self.disableChecking.append('Axes') + + for reference_file, result in zip(self.get_reference_files(), + self.result_names): + wsName = "RefFile" + if reference_file.endswith('.nxs'): + LoadNexus(Filename=reference_file, OutputWorkspace=wsName) + else: + raise RuntimeError("Should supply a NeXus file: %s" % + reference_file) + + if not self.validateWorkspaces([result, wsName]): + print str([reference_file, result]) + " do not match." + return False + + return True + + def get_temp_dir_path(self, filename): + '''Given a filename, prepends the system test temporary directory + and returns the full path.''' + return os.path.join(config['defaultsave.directory'], filename) + + +#============================================================================== +class ISISIndirectInelasticReduction(ISISIndirectInelasticBase): + '''A base class for the ISIS indirect inelastic reduction tests + + The workflow is defined in the _run() method, simply + define an __init__ method and set the following properties + on the object + - instr_name: A string giving the instrument name for the test + - detector_range: A list containing the lower and upper bounds of the + range of detectors to use + - data_file: A string giving the data file to use + - rebin_string: A comma separated string giving the rebin params + - save_formats: A list containing the file extensions of the formats + to save to. + ''' + + __metaclass__ = ABCMeta # Mark as an abstract class + sum_files = False + + def _run(self): + self.tolerance = 1e-7 + '''Defines the workflow for the test''' + reducer = IndirectReducer() + reducer.set_instrument_name(self.instr_name) + reducer.set_detector_range(self.detector_range[0], + self.detector_range[1]) + reducer.set_sum_files(self.sum_files) + self.parameter_file = self.instr_name + '_graphite_002_Parameters.xml' + reducer.set_parameter_file(self.parameter_file) + + for name in self.data_files: + reducer.append_data_file(name) + + if self.rebin_string is not None: + reducer.set_rebin_string(self.rebin_string) + + # Do the reduction and rename the result. + reducer.reduce() + self.result_names = sorted(reducer.get_result_workspaces()) + + def _validate_properties(self): + '''Check the object properties are in an expected state to continue''' + if type(self.instr_name) != str: + raise RuntimeError("instr_name property should be a string") + if type(self.detector_range) != list and len(self.detector_range) != 2: + raise RuntimeError("detector_range should be a list of exactly 2 " + "values") + if type(self.data_files) != list: + raise RuntimeError("data_file property should be a string") + if self.rebin_string is not None and type(self.rebin_string) != str: + raise RuntimeError("rebin_string property should be a string") + if self.sum_files is not None and type(self.sum_files) != bool: + raise RuntimeError("sum_files property should be a bool") + +#------------------------- TOSCA tests ---------------------------------------- + + +class TOSCAReduction(ISISIndirectInelasticReduction): + + def __init__(self): + ISISIndirectInelasticReduction.__init__(self) + self.instr_name = 'TOSCA' + self.detector_range = [0, 139] + self.data_files = ['TSC15352.raw'] + self.rebin_string = '-2.5,0.015,3,-0.005,1000' + + def get_reference_files(self): + return ["II.TOSCAReductionFromFile.nxs"] + +class TOSCAMultiFileReduction(ISISIndirectInelasticReduction): + + def __init__(self): + ISISIndirectInelasticReduction.__init__(self) + self.instr_name = 'TOSCA' + self.detector_range = [0, 139] + self.data_files = ['TSC15352.raw', 'TSC15353.raw','TSC15354.raw'] + self.rebin_string = '-2.5,0.015,3,-0.005,1000' + + def get_reference_files(self): + #note that the same run for single reduction is used. + #as they should be the same + return ['II.TOSCAReductionFromFile.nxs', 'II.TOSCAMultiFileReduction1.nxs', 'II.TOSCAMultiFileReduction2.nxs'] + +class TOSCAMultiFileSummedReduction(ISISIndirectInelasticReduction): + + def __init__(self): + ISISIndirectInelasticReduction.__init__(self) + self.instr_name = 'TOSCA' + self.detector_range = [0, 139] + self.data_files = ['TSC15352.raw', 'TSC15353.raw','TSC15354.raw'] + self.rebin_string = '-2.5,0.015,3,-0.005,1000' + self.sum_files = True + + def get_reference_files(self): + return ['II.TOSCAMultiFileSummedReduction.nxs'] + + +#------------------------- OSIRIS tests --------------------------------------- + + +class OSIRISReduction(ISISIndirectInelasticReduction): + + def __init__(self): + ISISIndirectInelasticReduction.__init__(self) + self.instr_name = 'OSIRIS' + self.detector_range = [962, 1003] + self.data_files = ['OSIRIS00106550.raw'] + self.rebin_string = None + + def get_reference_files(self): + return ["II.OSIRISReductionFromFile.nxs"] + +class OSIRISMultiFileReduction(ISISIndirectInelasticReduction): + + def __init__(self): + ISISIndirectInelasticReduction.__init__(self) + self.instr_name = 'OSIRIS' + self.detector_range = [962, 1003] + self.data_files = ['OSIRIS00106550.raw',' OSIRIS00106551.raw'] + self.rebin_string = None + + def get_reference_files(self): + #note that the same run for single reduction is used. + #as they should be the same + return ['II.OSIRISReductionFromFile.nxs','II.OSIRISMultiFileReduction1.nxs'] + +class OSIRISMultiFileSummedReduction(ISISIndirectInelasticReduction): + + def __init__(self): + ISISIndirectInelasticReduction.__init__(self) + self.instr_name = 'OSIRIS' + self.detector_range = [962, 1003] + self.data_files = ['OSIRIS00106550.raw', 'OSIRIS00106551.raw'] + self.rebin_string = None + self.sum_files = True + + def get_reference_files(self): + return ['II.OSIRISMultiFileSummedReduction.nxs'] + +#------------------------- IRIS tests ----------------------------------------- + +class IRISReduction(ISISIndirectInelasticReduction): + + def __init__(self): + ISISIndirectInelasticReduction.__init__(self) + self.instr_name = 'IRIS' + self.detector_range = [2, 52] + self.data_files = ['IRS21360.raw'] + self.rebin_string = None + + def get_reference_files(self): + return ["II.IRISReductionFromFile.nxs"] + + +class IRISMultiFileReduction(ISISIndirectInelasticReduction): + + def __init__(self): + ISISIndirectInelasticReduction.__init__(self) + self.instr_name = 'IRIS' + self.detector_range = [2, 52] + self.data_files = ['IRS21360.raw', 'IRS53664.raw'] + self.rebin_string = None + + def get_reference_files(self): + return ['II.IRISReductionFromFile.nxs', 'II.IRISMultiFileReduction1.nxs'] + + +class IRISMultiFileSummedReduction(ISISIndirectInelasticReduction): + + def __init__(self): + ISISIndirectInelasticReduction.__init__(self) + self.instr_name = 'IRIS' + self.detector_range = [2, 52] + self.data_files = ['IRS21360.raw', 'IRS53664.raw'] + self.sum_files = True + self.rebin_string = None + + def get_reference_files(self): + #note that the same run for single reduction is used. + #as they should be the same + return ['II.IRISMultiFileSummedReduction.nxs'] + +#--------------------- Generic Reduction tests ----------------------------- + +class ISISIndirectInelasticReductionOutput(stresstesting.MantidStressTest): + + def runTest(self): + reducer = self._setup_reducer() + reducer.reduce() + self.result_names = sorted(reducer.get_result_workspaces()) + + def validate(self): + self.assertEqual(len(self.result_names), 1) + self.result_name = self.result_names[0] + + self.output_file_names = self._get_file_names() + self.assert_reduction_output_exists(self.output_file_names) + self.assert_ascii_file_matches() + self.assert_aclimax_file_matches() + self.assert_spe_file_matches() + + def cleanup(self): + mtd.clear() + + for file_path in self.output_file_names.itervalues(): + if os.path.isfile(file_path): + os.remove(file_path) + + def assert_ascii_file_matches(self): + expected_result = [ + 'X , Y0 , E0 , Y1 , E1 , Y2 , E2', + '-2.4925,0,0,0.617579,0.362534,0.270868,0.159006', + '-2.4775,0.375037,0.273017,0,0,0.210547,0.153272' + ] + self.assert_file_format_matches_expected(expected_result, self.output_file_names['ascii'], + "Output of ASCII format did not match expected result.") + + def assert_aclimax_file_matches(self): + expected_result = [ + '# X \t Y \t E', + '0', + '3.0075\t0.175435\t0.115017' + ] + self.assert_file_format_matches_expected(expected_result, self.output_file_names['aclimax'], + "Output of aclimax format did not match expected result.") + + def assert_spe_file_matches(self): + #Old SPE format: + # ' 3 1532', + # '### Phi Grid', + # ' 5.000E-01 1.500E+00 2.500E+00 3.500E+00', + # '### Energy Grid', + # '-2.500E+00-2.485E+00-2.470E+00-2.455E+00-2.440E+00-2.425E+00-2.410E+00-2.395E+00' + # + # New SPE format: + expected_result = [ + ' 3 1532', + '### Phi Grid', + '0.5 1.5 2.5 3.5', + '### Energy Grid', + '-2.5 -2.485 -2.47 -2.455 -2.44 -2.425 -2.41 -2.395' + ] + self.assert_file_format_matches_expected(expected_result, self.output_file_names['spe'], + "Output of SPE format did not match expected result.") + + def assert_reduction_output_exists(self, output_file_names): + for file_path in output_file_names.itervalues(): + self.assertTrue(os.path.exists(file_path), "File does not exist in the default save directory") + self.assertTrue(os.path.isfile(file_path), "Output file of reduction output is not a file.") + + def assert_file_format_matches_expected(self, expected_result, file_path, msg=""): + num_lines = len(expected_result) + actual_result = self._read_ascii_file(file_path, num_lines) + self.assertTrue(actual_result == expected_result, msg + " (%s != %s)" % (actual_result, expected_result)) + + def _setup_reducer(self): + self.file_formats = ['nxs', 'spe', 'nxspe', 'ascii', 'aclimax'] + self.file_extensions = ['.nxs', '.spe', '.nxspe', '.dat', '_aclimax.dat'] + self.instr_name = 'TOSCA' + self.detector_range = [0, 139] + self.data_files = ['TSC15352.raw'] + self.rebin_string = '-2.5,0.015,3,-0.005,1000' + self.parameter_file = self.instr_name + '_graphite_002_Parameters.xml' + + reducer = IndirectReducer() + reducer.set_instrument_name(self.instr_name) + reducer.set_detector_range(self.detector_range[0], + self.detector_range[1]) + reducer.set_sum_files(False) + reducer.set_parameter_file(self.parameter_file) + reducer.set_save_formats(self.file_formats) + + for name in self.data_files: + reducer.append_data_file(name) + + if self.rebin_string is not None: + reducer.set_rebin_string(self.rebin_string) + + return reducer + + def _read_ascii_file(self, path, num_lines): + with open(path,'rb') as file_handle: + lines = [file_handle.readline().rstrip() for _ in xrange(num_lines)] + return lines + + def _get_file_names(self): + working_directory = config['defaultsave.directory'] + + output_names = {} + for format, ext in zip(self.file_formats, self.file_extensions): + output_file_name = self.result_name + ext + output_file_name = os.path.join(working_directory, output_file_name) + output_names[format] = output_file_name + + return output_names + +#============================================================================== +class ISISIndirectInelasticCalibration(ISISIndirectInelasticBase): + '''A base class for the ISIS indirect inelastic calibration tests + + The workflow is defined in the _run() method, simply + define an __init__ method and set the following properties + on the object + - self.data_file: a string giving the name of the data file + - self.detector_range: a list of two ints, giving the lower and + upper bounds of the detector range + - self.parameters: a list containing four doubles, each a parameter. + - self.analyser: a string giving the name of the analyser to use + - self.reflection: a string giving the reflection to use + ''' + + __metaclass__ = ABCMeta # Mark as an abstract class + + def _run(self): + '''Defines the workflow for the test''' + self.tolerance = 1e-7 + + self.result_names = ['IndirectCalibration_Output'] + + CreateCalibrationWorkspace(InputFiles=self.data_file, + OutputWorkspace='IndirectCalibration_Output', + DetectorRange=self.detector_range, + PeakRange=self.peak, + BackgroundRange=self.back) + + def _validate_properties(self): + '''Check the object properties are in an expected state to continue''' + + if type(self.data_file) != str: + raise RuntimeError("data_file property should be a string") + if type(self.detector_range) != list and len(self.detector_range) != 2: + raise RuntimeError("detector_range should be a list of exactly 2 values") + if type(self.peak) != list and len(self.peak) != 2: + raise RuntimeError("peak should be a list of exactly 2 values") + if type(self.back) != list and len(self.back) != 2: + raise RuntimeError("back should be a list of exactly 2 values") + +#------------------------- OSIRIS tests --------------------------------------- + + +class OSIRISCalibration(ISISIndirectInelasticCalibration): + + def __init__(self): + ISISIndirectInelasticCalibration.__init__(self) + self.data_file = 'OSI97935.raw' + self.detector_range = [963, 1004] + self.back = [68000.00, 70000.00] + self.peak = [59000.00, 61000.00] + + def get_reference_files(self): + return ["II.OSIRISCalibration.nxs"] + +#------------------------- IRIS tests --------------------------------------- + + +class IRISCalibration(ISISIndirectInelasticCalibration): + + def __init__(self): + ISISIndirectInelasticCalibration.__init__(self) + self.data_file = 'IRS53664.raw' + self.detector_range = [3, 53] + self.back = [59000.00, 61500.00] + self.peak = [62500.00, 65000.00] + + def get_reference_files(self): + return ["II.IRISCalibration.nxs"] + + +#============================================================================== +class ISISIndirectInelasticResolution(ISISIndirectInelasticBase): + '''A base class for the ISIS indirect inelastic resolution tests + + The workflow is defined in the _run() method, simply + define an __init__ method and set the following properties + on the object + - self.instrument: a string giving the intrument name + - self.analyser: a string giving the name of the analyser + - self.reflection: a string giving the name of the reflection + - self.detector_range: a list of two integers, giving the range of detectors + - self.background: a list of two doubles, giving the background params + - self.rebin_params: a comma separated string containing the rebin params + - self.files: a list of strings containing filenames + ''' + + __metaclass__ = ABCMeta # Mark as an abstract class + + def _run(self): + self.tolerance = 1e-7 + '''Defines the workflow for the test''' + + IndirectResolution(InputFiles=self.files, + OutputWorkspace='__IndirectResolution_Test', + Instrument=self.instrument, + Analyser=self.analyser, + Reflection=self.reflection, + DetectorRange=self.detector_range, + BackgroundRange=self.background, + RebinParam=self.rebin_params, + Plot=False) + + self.result_names = ['__IndirectResolution_Test'] + + def _validate_properties(self): + '''Check the object properties are in an expected state to continue''' + + if type(self.instrument) != str: + raise RuntimeError("instrument property should be a string") + if type(self.analyser) != str: + raise RuntimeError("analyser property should be a string") + if type(self.reflection) != str: + raise RuntimeError("reflection property should be a string") + if type(self.detector_range) != list and len(self.detector_range) != 2: + raise RuntimeError("detector_range should be a list of exactly 2 values") + if type(self.background) != list and len(self.background) != 2: + raise RuntimeError("background should be a list of exactly 2 values") + if type(self.rebin_params) != str: + raise RuntimeError("rebin_params property should be a string") + # Have this as just one file for now. + if type(self.files) != list and len(self.files) != 1: + raise RuntimeError("files should be a list of exactly 1 value") + +#------------------------- OSIRIS tests --------------------------------------- + + +class OSIRISResolution(ISISIndirectInelasticResolution): + + def __init__(self): + ISISIndirectInelasticResolution.__init__(self) + self.instrument = 'OSIRIS' + self.analyser = 'graphite' + self.reflection = '002' + self.detector_range = [963, 1004] + self.background = [-0.563032, 0.605636] + self.rebin_params = '-0.2,0.002,0.2' + self.files = ['OSI97935.raw'] + + def get_reference_files(self): + return ["II.OSIRISResolution.nxs"] + +#------------------------- IRIS tests ----------------------------------------- + + +class IRISResolution(ISISIndirectInelasticResolution): + + def __init__(self): + ISISIndirectInelasticResolution.__init__(self) + self.instrument = 'IRIS' + self.analyser = 'graphite' + self.reflection = '002' + self.detector_range = [3, 53] + self.background = [-0.54, 0.65] + self.rebin_params = '-0.2,0.002,0.2' + self.files = ['IRS53664.raw'] + + def get_reference_files(self): + return ["II.IRISResolution.nxs"] + + +#============================================================================== +class ISISIndirectInelasticDiagnostics(ISISIndirectInelasticBase): + '''A base class for the ISIS indirect inelastic diagnostic tests + + The workflow is defined in the _run() method, simply + define an __init__ method and set the following properties + on the object + ''' + + __metaclass__ = ABCMeta # Mark as an abstract class + + def _run(self): + '''Defines the workflow for the test''' + + self.tolerance = 1e-7 + + TimeSlice(InputFiles=self.rawfiles, + OutputNameSuffix=self.suffix, + OutputWorkspace='__IndirectInelasticDiagnostics_out_group', + PeakRange=self.peak, + SpectraRange=self.spectra, + Plot=False, + Save=False) + + # Construct the result ws name. + self.result_names = [os.path.splitext(self.rawfiles[0])[0] + self.suffix] + + def _validate_properties(self): + '''Check the object properties are in an expected state to continue''' + + if type(self.rawfiles) != list and len(self.rawfiles) != 1: + raise RuntimeError("rawfiles should be a list of exactly 1 value") + if type(self.peak) != list and len(self.peak) != 2: + raise RuntimeError("peak should be a list of exactly 2 values") + if type(self.spectra) != list and len(self.spectra) != 2: + raise RuntimeError("spectra should be a list of exactly 2 values") + if type(self.suffix) != str: + raise RuntimeError("suffix property should be a string") + + +#------------------------- IRIS tests ----------------------------------------- + + +class IRISDiagnostics(ISISIndirectInelasticDiagnostics): + + def __init__(self): + ISISIndirectInelasticDiagnostics.__init__(self) + + self.peak = [62500, 65000] + self.rawfiles = ['IRS53664.raw'] + self.spectra = [3, 53] + self.suffix = '_graphite002_slice' + + def get_reference_files(self): + return ["II.IRISDiagnostics.nxs"] + + +#------------------------- OSIRIS tests --------------------------------------- + + +class OSIRISDiagnostics(ISISIndirectInelasticDiagnostics): + + def __init__(self): + ISISIndirectInelasticDiagnostics.__init__(self) + + self.peak = [59000, 61000] + self.rawfiles = ['OSI97935.raw'] + self.spectra = [963, 1004] + self.suffix = '_graphite002_slice' + + def get_reference_files(self): + return ["II.OSIRISDiagnostics.nxs"] + + +#============================================================================== +class ISISIndirectInelasticMoments(ISISIndirectInelasticBase): + '''A base class for the ISIS indirect inelastic Fury/FuryFit tests + + The output of Elwin is usually used with MSDFit and so we plug one into + the other in this test. + ''' + # Mark as an abstract class + __metaclass__ = ABCMeta + + def _run(self): + '''Defines the workflow for the test''' + + LoadNexus(self.input_workspace, + OutputWorkspace=self.input_workspace) + + SofQWMoments(Sample=self.input_workspace, EnergyMin=self.e_min, + EnergyMax=self.e_max, Scale=self.scale, + Plot=False, Save=False, OutputWorkspace=self.input_workspace + '_Moments') + + self.result_names = [self.input_workspace + '_Moments'] + + def _validate_properties(self): + '''Check the object properties are in an expected state to continue''' + + if type(self.input_workspace) != str: + raise RuntimeError("Input workspace should be a string.") + if type(self.e_min) != float: + raise RuntimeError("Energy min should be a float") + if type(self.e_max) != float: + raise RuntimeError("Energy max should be a float") + if type(self.scale) != float: + raise RuntimeError("Scale should be a float") + + +#------------------------- OSIRIS tests --------------------------------------- +class OSIRISMoments(ISISIndirectInelasticMoments): + + def __init__(self): + ISISIndirectInelasticMoments.__init__(self) + self.input_workspace = 'osi97935_graphite002_sqw.nxs' + self.e_min = -0.4 + self.e_max = 0.4 + self.scale = 1.0 + + def get_reference_files(self): + return ['II.OSIRISMoments.nxs'] + + +#------------------------- IRIS tests ----------------------------------------- +class IRISMoments(ISISIndirectInelasticMoments): + + def __init__(self): + ISISIndirectInelasticMoments.__init__(self) + self.input_workspace = 'irs53664_graphite002_sqw.nxs' + self.e_min = -0.4 + self.e_max = 0.4 + self.scale = 1.0 + + def get_reference_files(self): + return ['II.IRISMoments.nxs'] + + +#============================================================================== +class ISISIndirectInelasticElwinAndMSDFit(ISISIndirectInelasticBase): + '''A base class for the ISIS indirect inelastic Elwin/MSD Fit tests + + The output of Elwin is usually used with MSDFit and so we plug one into + the other in this test. + ''' + + __metaclass__ = ABCMeta # Mark as an abstract class + + def _run(self): + '''Defines the workflow for the test''' + self.tolerance = 1e-7 + + elwin_input = '__ElWinMult_in' + elwin_results = ['__ElWinMult_q', '__ElWinMult_q2', '__ElWinMult_elf'] + + # Load files and create workspace group + for filename in self.files: + Load(Filename=filename, OutputWorkspace=filename) + GroupWorkspaces(InputWorkspaces=self.files, OutputWorkspace=elwin_input) + + ElasticWindowMultiple(InputWorkspaces=elwin_input, Plot=False, + Range1Start=self.eRange[0], Range1End=self.eRange[1], + OutputInQ=elwin_results[0], OutputInQSquared=elwin_results[1], + OutputELF=elwin_results[2]) + + int_files = [self.get_temp_dir_path(filename) + ".nxs" + for filename in elwin_results] + + # Save the EQ1 & EQ2 results from Elwin to put into MSDFit. + for ws, filename in zip(elwin_results, int_files): + SaveNexusProcessed(Filename=filename, + InputWorkspace=ws) + + eq2_file = elwin_results[1] + msdfit_result = msdfit(eq2_file, + startX=self.startX, + endX=self.endX, + Save=False, + Plot=False) + + # @TODO: MSDFit has some other, as yet unfinalised, workspaces as its + # output. We need to test these too, eventually. + + # Annoyingly, MSDFit eats the EQ2 workspaces we feed it, so let's + # reload them for checking against the reference files later. + for ws, filename in zip(elwin_results, int_files): + LoadNexusProcessed(Filename=filename, + OutputWorkspace=ws) + + # Clean up the intermediate files. + for filename in int_files: + os.remove(filename) + + # We're interested in the intermediate Elwin results as well as the + # final MSDFit result. + self.result_names = [elwin_results[0], # EQ1 + elwin_results[1], # EQ2 + msdfit_result] + + def _validate_properties(self): + """Check the object properties are in an expected state to continue""" + + if type(self.files) != list or len(self.files) != 2: + raise RuntimeError("files should be a list of exactly 2 " + "strings") + if type(self.eRange) != list or len(self.eRange) != 2: + raise RuntimeError("eRange should be a list of exactly 2 " + "values") + if type(self.startX) != float: + raise RuntimeError("startX should be a float") + if type(self.endX) != float: + raise RuntimeError("endX should be a float") + +#------------------------- OSIRIS tests --------------------------------------- + + +class OSIRISElwinAndMSDFit(ISISIndirectInelasticElwinAndMSDFit): + + def __init__(self): + ISISIndirectInelasticElwinAndMSDFit.__init__(self) + self.files = ['osi97935_graphite002_red.nxs', + 'osi97936_graphite002_red.nxs'] + self.eRange = [-0.02, 0.02] + self.startX = 0.195082 + self.endX = 3.202128 + + def get_reference_files(self): + return ['II.OSIRISElwinEQ1.nxs', + 'II.OSIRISElwinEQ2.nxs', + 'II.OSIRISMSDFit.nxs'] + +#------------------------- IRIS tests ----------------------------------------- + + +class IRISElwinAndMSDFit(ISISIndirectInelasticElwinAndMSDFit): + + def __init__(self): + ISISIndirectInelasticElwinAndMSDFit.__init__(self) + self.files = ['irs53664_graphite002_red.nxs', + 'irs53665_graphite002_red.nxs'] + self.eRange = [-0.02, 0.02] + self.startX = 0.313679 + self.endX = 3.285377 + + def get_reference_files(self): + return ['II.IRISElwinEQ1.nxs', + 'II.IRISElwinEQ2.nxs', + 'II.IRISMSDFit.nxs'] + + +#============================================================================== +class ISISIndirectInelasticFuryAndFuryFit(ISISIndirectInelasticBase): + ''' + A base class for the ISIS indirect inelastic Fury/FuryFit tests + + The output of Fury is usually used with FuryFit and so we plug one into + the other in this test. + ''' + + __metaclass__ = ABCMeta # Mark as an abstract class + + def _run(self): + '''Defines the workflow for the test''' + self.tolerance = 1e-7 + self.samples = [sample[:-4] for sample in self.samples] + + # Load files into Mantid + for sample in self.samples: + LoadNexus(sample, OutputWorkspace=sample) + LoadNexus(self.resolution, OutputWorkspace=self.resolution) + + fury_props, fury_ws = Fury(Sample=self.samples[0], + Resolution=self.resolution, + EnergyMin=self.e_min, + EnergyMax=self.e_max, + NumBins=self.num_bins, + DryRun=False, + Save=False, + Plot=False) + + # Test FuryFit Sequential + furyfitSeq_ws = furyfitSeq(fury_ws.getName(), + self.func, + self.ftype, + self.startx, + self.endx, + Save=False, + Plot='None') + + self.result_names = [fury_ws.getName(), + furyfitSeq_ws] + + # Remove workspaces from Mantid + for sample in self.samples: + DeleteWorkspace(sample) + + DeleteWorkspace(self.resolution) + + def _validate_properties(self): + """Check the object properties are in an expected state to continue""" + + if type(self.samples) != list: + raise RuntimeError("Samples should be a list of strings.") + if type(self.resolution) != str: + raise RuntimeError("Resolution should be a string.") + if type(self.e_min) != float: + raise RuntimeError("e_min should be a float") + if type(self.e_max) != float: + raise RuntimeError("e_max should be a float") + if type(self.num_bins) != int: + raise RuntimeError("num_bins should be an int") + if type(self.func) != str: + raise RuntimeError("Function should be a string.") + if type(self.ftype) != str: + raise RuntimeError("Function type should be a string.") + if type(self.startx) != float: + raise RuntimeError("startx should be a float") + if type(self.endx) != float: + raise RuntimeError("endx should be a float") + +#------------------------- OSIRIS tests --------------------------------------- + + +class OSIRISFuryAndFuryFit(ISISIndirectInelasticFuryAndFuryFit): + + def __init__(self): + ISISIndirectInelasticFuryAndFuryFit.__init__(self) + + # Fury + self.samples = ['osi97935_graphite002_red.nxs'] + self.resolution = 'osi97935_graphite002_res.nxs' + self.e_min = -0.4 + self.e_max = 0.4 + self.num_bins = 4 + + # Fury Seq Fit + self.func = r'name=LinearBackground,A0=0,A1=0,ties=(A1=0);name=UserFunction,Formula=Intensity*exp(-(x/Tau)),Intensity=0.304185,Tau=100;ties=(f1.Intensity=1-f0.A0)' + self.ftype = '1E_s' + self.startx = 0.022861 + self.endx = 0.118877 + + def get_reference_files(self): + return ['II.OSIRISFury.nxs', + 'II.OSIRISFuryFitSeq.nxs'] + +#------------------------- IRIS tests ----------------------------------------- + + +class IRISFuryAndFuryFit(ISISIndirectInelasticFuryAndFuryFit): + + def __init__(self): + ISISIndirectInelasticFuryAndFuryFit.__init__(self) + + # Fury + self.samples = ['irs53664_graphite002_red.nxs'] + self.resolution = 'irs53664_graphite002_res.nxs' + self.e_min = -0.4 + self.e_max = 0.4 + self.num_bins = 4 + + # Fury Seq Fit + self.func = r'name=LinearBackground,A0=0,A1=0,ties=(A1=0);name=UserFunction,Formula=Intensity*exp(-(x/Tau)),Intensity=0.355286,Tau=100;ties=(f1.Intensity=1-f0.A0)' + self.ftype = '1E_s' + self.startx = 0.013717 + self.endx = 0.169171 + + def get_reference_files(self): + return ['II.IRISFury.nxs', + 'II.IRISFuryFitSeq.nxs'] + +#============================================================================== + + +class ISISIndirectInelasticFuryAndFuryFitMulti(ISISIndirectInelasticBase): + '''A base class for the ISIS indirect inelastic Fury/FuryFit tests + + The output of Elwin is usually used with MSDFit and so we plug one into + the other in this test. + ''' + + __metaclass__ = ABCMeta # Mark as an abstract class + + def _run(self): + '''Defines the workflow for the test''' + self.tolerance = 1e-6 + self.samples = [sample[:-4] for sample in self.samples] + + #load files into mantid + for sample in self.samples: + LoadNexus(sample, OutputWorkspace=sample) + LoadNexus(self.resolution, OutputWorkspace=self.resolution) + + fury_props, fury_ws = Fury(Sample=self.samples[0], + Resolution=self.resolution, + EnergyMin=self.e_min, + EnergyMax=self.e_max, + NumBins=self.num_bins, + DryRun=False, + Save=False, + Plot=False) + + # Test FuryFit Sequential + furyfitSeq_ws = furyfitMult(fury_ws.getName(), + self.func, + self.ftype, + self.startx, + self.endx, + Save=False, + Plot='None') + + self.result_names = [fury_ws.getName(), + furyfitSeq_ws] + + #remove workspaces from mantid + for sample in self.samples: + DeleteWorkspace(sample) + DeleteWorkspace(self.resolution) + + def _validate_properties(self): + """Check the object properties are in an expected state to continue""" + + if type(self.samples) != list: + raise RuntimeError("Samples should be a list of strings.") + if type(self.resolution) != str: + raise RuntimeError("Resolution should be a string.") + if type(self.e_min) != float: + raise RuntimeError("e_min should be a float") + if type(self.e_max) != float: + raise RuntimeError("e_max should be a float") + if type(self.num_bins) != int: + raise RuntimeError("num_bins should be an int") + if type(self.func) != str: + raise RuntimeError("Function should be a string.") + if type(self.ftype) != str: + raise RuntimeError("Function type should be a string.") + if type(self.startx) != float: + raise RuntimeError("startx should be a float") + if type(self.endx) != float: + raise RuntimeError("endx should be a float") + +#------------------------- OSIRIS tests --------------------------------------- + + +class OSIRISFuryAndFuryFitMulti(ISISIndirectInelasticFuryAndFuryFitMulti): + + def skipTests(self): + return (platform.system() == "Darwin") + + def __init__(self): + ISISIndirectInelasticFuryAndFuryFitMulti.__init__(self) + + # Fury + self.samples = ['osi97935_graphite002_red.nxs'] + self.resolution = 'osi97935_graphite002_res.nxs' + self.e_min = -0.4 + self.e_max = 0.4 + self.num_bins = 4 + + # Fury Seq Fit + self.func = r'name=LinearBackground,A0=0.510595,A1=0,ties=(A1=0);name=UserFunction,Formula=Intensity*exp( -(x/Tau)^Beta),Intensity=0.489405,Tau=0.105559,Beta=1.61112e-14;ties=(f1.Intensity=1-f0.A0)' + self.ftype = '1E_s' + self.startx = 0.0 + self.endx = 0.119681 + + def get_reference_files(self): + return ['II.OSIRISFury.nxs', + 'II.OSIRISFuryFitMulti.nxs'] + +#------------------------- IRIS tests ----------------------------------------- + + +class IRISFuryAndFuryFitMulti(ISISIndirectInelasticFuryAndFuryFitMulti): + + def __init__(self): + ISISIndirectInelasticFuryAndFuryFitMulti.__init__(self) + + # Fury + self.samples = ['irs53664_graphite002_red.nxs'] + self.resolution = 'irs53664_graphite002_res.nxs' + self.e_min = -0.4 + self.e_max = 0.4 + self.num_bins = 4 + + # Fury Seq Fit + self.func = r'name=LinearBackground,A0=0.584488,A1=0,ties=(A1=0);name=UserFunction,Formula=Intensity*exp( -(x/Tau)^Beta),Intensity=0.415512,Tau=4.848013e-14,Beta=0.022653;ties=(f1.Intensity=1-f0.A0)' + self.ftype = '1S_s' + self.startx = 0.0 + self.endx = 0.156250 + + def get_reference_files(self): + return ['II.IRISFury.nxs', + 'II.IRISFuryFitMulti.nxs'] + +#============================================================================== + + +class ISISIndirectInelasticConvFit(ISISIndirectInelasticBase): + '''A base class for the ISIS indirect inelastic ConvFit tests + + The workflow is defined in the _run() method, simply + define an __init__ method and set the following properties + on the object + ''' + # Mark as an abstract class + __metaclass__ = ABCMeta + + def _run(self): + '''Defines the workflow for the test''' + self.tolerance = 1e-4 + LoadNexus(self.sample, OutputWorkspace=self.sample) + + confitSeq( + self.sample, + self.func, + self.startx, + self.endx, + self.ftype, + self.bg, + specMin=self.spectra_min, + specMax=self.spectra_max, + Plot='None', + Save=False) + + def _validate_properties(self): + '''Check the object properties are in an expected state to continue''' + + if type(self.sample) != str: + raise RuntimeError("Sample should be a string.") + if type(self.resolution) != str: + raise RuntimeError("Resolution should be a string.") + if not os.path.isfile(self.resolution): + raise RuntimeError("Resolution must be a file that exists.") + if type(self.func) != str: + raise RuntimeError("Function should be a string.") + if type(self.bg) != str: + raise RuntimeError("Background type should be a string.") + if type(self.ftype) != str: + raise RuntimeError("Function type should be a string.") + if type(self.startx) != float: + raise RuntimeError("startx should be a float") + if type(self.endx) != float: + raise RuntimeError("endx should be a float") + if type(self.spectra_min) != int: + raise RuntimeError("Min spectrum should be a int") + if type(self.spectra_max) != int: + raise RuntimeError("Max spectrum should be a int") + if type(self.ties) != bool: + raise RuntimeError("ties should be a boolean.") + +#------------------------- OSIRIS tests --------------------------------------- + + +class OSIRISConvFit(ISISIndirectInelasticConvFit): + + def __init__(self): + ISISIndirectInelasticConvFit.__init__(self) + self.sample = 'osi97935_graphite002_red.nxs' + self.resolution = FileFinder.getFullPath('osi97935_graphite002_res.nxs') + #ConvFit fit function + self.func = 'name=LinearBackground,A0=0,A1=0;(composite=Convolution,FixResolution=true,NumDeriv=true;name=Resolution,FileName=\"%s\";name=Lorentzian,Amplitude=2,PeakCentre=0,FWHM=0.05)' % self.resolution + self.ftype = '1L' + self.startx = -0.2 + self.endx = 0.2 + self.bg = 'FitL_s' + self.spectra_min = 0 + self.spectra_max = 41 + self.ties = False + + self.result_names = ['osi97935_graphite002_conv_1LFitL_s0_to_41_Result'] + + def get_reference_files(self): + return ['II.OSIRISConvFitSeq.nxs'] + + +#------------------------- IRIS tests ----------------------------------------- +class IRISConvFit(ISISIndirectInelasticConvFit): + + def __init__(self): + ISISIndirectInelasticConvFit.__init__(self) + self.sample = 'irs53664_graphite002_red.nxs' + self.resolution = FileFinder.getFullPath('irs53664_graphite002_res.nxs') + #ConvFit fit function + self.func = 'name=LinearBackground,A0=0.060623,A1=0.001343;(composite=Convolution,FixResolution=true,NumDeriv=true;name=Resolution,FileName=\"%s\";name=Lorentzian,Amplitude=1.033150,PeakCentre=-0.000841,FWHM=0.001576)' % self.resolution + self.ftype = '1L' + self.startx = -0.2 + self.endx = 0.2 + self.bg = 'FitL_s' + self.spectra_min = 0 + self.spectra_max = 50 + self.ties = False + + self.result_names = ['irs53664_graphite002_conv_1LFitL_s0_to_50_Result'] + + def get_reference_files(self): + return ['II.IRISConvFitSeq.nxs'] + +#============================================================================== + + +class ISISIndirectInelasticApplyCorrections(ISISIndirectInelasticBase): + '''A base class for the ISIS indirect inelastic Apply Corrections tests + + The workflow is defined in the _run() method, simply + define an __init__ method and set the following properties + on the object + ''' + # Mark as an abstract class + __metaclass__ = ABCMeta + + def _run(self): + '''Defines the workflow for the test''' + self.tolerance = 1e-4 + + LoadNexus(self._sample_workspace + '.nxs', OutputWorkspace=self._sample_workspace) + if self._corrections_workspace != '': + LoadNexus(self._corrections_workspace + '.nxs', OutputWorkspace=self._corrections_workspace) + if self._can_workspace != '': + LoadNexus(self._can_workspace + '.nxs', OutputWorkspace=self._can_workspace) + + output_workspaces = self._run_apply_corrections() + self.result_names = [output_workspaces['reduced_workspace']] + + 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: + ___ + """ + + if self._can_workspace != '': + can_run = mtd[self._can_workspace].getRun() + can_run_number = can_run.getProperty('run_number').value + + mode = '' + if self._corrections_workspace != '' and self._can_workspace != '': + mode = 'Correct_%s' % can_run_number + elif self._corrections_workspace != '': + mode = 'Corrected' + else: + mode = 'Subtract_%s' % can_run_number + + workspace_name_stem = self._sample_workspace[:-3] + 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 _validate_properties(self): + '''Check the object properties are in an expected state to continue''' + +#------------------------- IRIS tests ----------------------------------------- + +class IRISApplyCorrectionsWithCan(ISISIndirectInelasticApplyCorrections): + """ Test applying corrections with just a can workspace """ + + def __init__(self): + ISISIndirectInelasticApplyCorrections.__init__(self) + + self._sample_workspace = 'irs26176_graphite002_red' + self._can_workspace = 'irs26173_graphite002_red' + self._corrections_workspace = '' + self._can_geometry = 'cyl' + self._using_corrections = False + + self._kwargs = {'RebinCan':False, 'ScaleOrNotToScale':False, + 'factor':1, 'Save':False, 'PlotResult':'None', 'PlotContrib':False} + + def get_reference_files(self): + return ['II.IRISApplyCorrectionsWithCan.nxs'] + + +class IRISApplyCorrectionsWithCorrectionsWS(ISISIndirectInelasticApplyCorrections): + """ Test applying corrections with a corrections workspace """ + + def __init__(self): + ISISIndirectInelasticApplyCorrections.__init__(self) + + self._sample_workspace = 'irs26176_graphite002_red' + self._can_workspace = '' + self._corrections_workspace = 'irs26176_graphite002_cyl_Abs' + self._can_geometry = 'cyl' + self._using_corrections = True + + self._kwargs = {'RebinCan':False, 'ScaleOrNotToScale':False, + 'factor':1, 'Save':False, 'PlotResult':'None', 'PlotContrib':False} + + def get_reference_files(self): + return ['II.IRISApplyCorrectionsWithCorrectionsWS.nxs'] + +class IRISApplyCorrectionsWithBoth(ISISIndirectInelasticApplyCorrections): + """ Test applying corrections with both a can and a corrections workspace """ + + def __init__(self): + ISISIndirectInelasticApplyCorrections.__init__(self) + + self._sample_workspace = 'irs26176_graphite002_red' + self._can_workspace = 'irs26173_graphite002_red' + self._corrections_workspace = 'irs26176_graphite002_cyl_Abs' + self._can_geometry = 'cyl' + self._using_corrections = True + + self._kwargs = {'RebinCan':False, 'ScaleOrNotToScale':False, + 'factor':1, 'Save':False, 'PlotResult':'None', 'PlotContrib':False} + + def get_reference_files(self): + return ['II.IRISApplyCorrections.nxs'] + +#============================================================================== +# Transmission Monitor Test + +class ISISIndirectInelasticTransmissionMonitor(ISISIndirectInelasticBase): + ''' + ''' + + # Mark as an abstract class + __metaclass__ = ABCMeta + + def _run(self): + '''Defines the workflow for the test''' + + self.tolerance = 1e-4 + Load(self.sample, OutputWorkspace=self.sample) + Load(self.can, OutputWorkspace=self.can) + + IndirectTransmissionMonitor(SampleWorkspace=self.sample, CanWorkspace=self.can, + OutputWorkspace='IRISTransmissionMonitorTest') + + def _validate_properties(self): + '''Check the object properties are in an expected state to continue''' + + if type(self.sample) != str: + raise RuntimeError("Sample should be a string.") + if type(self.can) != str: + raise RuntimeError("Can should be a string.") + + +#------------------------- IRIS tests ----------------------------------------- +class IRISTransmissionMonitor(ISISIndirectInelasticTransmissionMonitor): + + def __init__(self): + ISISIndirectInelasticTransmissionMonitor.__init__(self) + self.sample = 'IRS26176.RAW' + self.can = 'IRS26173.RAW' + + self.result_names = ['IRISTransmissionMonitorTest'] + + def get_reference_files(self): + return ['II.IRISTransmissionMonitor.nxs'] diff --git a/Code/Mantid/Testing/SystemTests/tests/analysis/ISISIndirectLoadAsciiTest.py b/Code/Mantid/Testing/SystemTests/tests/analysis/ISISIndirectLoadAsciiTest.py new file mode 100644 index 000000000000..bbd945bfa153 --- /dev/null +++ b/Code/Mantid/Testing/SystemTests/tests/analysis/ISISIndirectLoadAsciiTest.py @@ -0,0 +1,98 @@ +import stresstesting +import os +from mantid.simpleapi import * + +#==================================================================================================== +class IN10SiliconTest(stresstesting.MantidStressTest): + + def runTest(self): + import IndirectNeutron as Main + + instr = 'IN10' + ana = 'silicon' + refl = '111' + run = 'P3OT_350K' + rejectZ = False + useM = False + saveOp = False + plotOp = False + Main.InxStart(instr,run,ana,refl,rejectZ,useM,'',plotOp,saveOp) + + def validate(self): + self.tolerance = 1e-2 + self.disableChecking.append("Instrument") + return 'IN10_P3OT_350K_silicon111_red', 'ISISIndirectLoadAscii_IN10SiliconTest.nxs' + +#==================================================================================================== +class IN13CaFTest(stresstesting.MantidStressTest): + + def runTest(self): + import IndirectNeutron as Main + + instr = 'IN13' + ana = 'CaF' + refl = '422' + run = '16347' + rejectZ = False + useM = False + saveOp = False + plotOp = False + Main.IN13Start(instr,run,ana,refl,rejectZ,useM,'',plotOp,saveOp) + + def validate(self): + self.tolerance = 1e-2 + + from mantid.simpleapi import Load + + Load(Filename='ISISIndirectLoadAscii_IN13CaFTest.nxs',OutputWorkspace='ISISIndirectLoadAscii_IN13CaFTest') + Load(Filename='ISISIndirectLoadAscii_IN13CaFTest2.nxs',OutputWorkspace='ISISIndirectLoadAscii_IN13CaFTest2') + + # check each of the resulting workspaces match + ws1Match = self.checkWorkspacesMatch('IN13_16347_CaF422_q', 'ISISIndirectLoadAscii_IN13CaFTest2') + ws2Match = self.checkWorkspacesMatch('IN13_16347_CaF422_ang', 'ISISIndirectLoadAscii_IN13CaFTest') + + return ( ws1Match and ws2Match ) + + # function to check two workspaces match + # Used when the result of a test produces more than a single workspace + def checkWorkspacesMatch(self, ws1, ws2): + from mantid.simpleapi import SaveNexus, AlgorithmManager + checker = AlgorithmManager.create("CheckWorkspacesMatch") + checker.setLogging(True) + checker.setPropertyValue("Workspace1", ws1) + checker.setPropertyValue("Workspace2", ws2) + checker.setPropertyValue("Tolerance", str(self.tolerance)) + checker.setPropertyValue("CheckInstrument","0") + + checker.execute() + + if checker.getPropertyValue("Result") != 'Success!': + print self.__class__.__name__ + SaveNexus(InputWorkspace=ws2,Filename=self.__class__.__name__+'-mismatch.nxs') + return False + + return True + + +#==================================================================================================== +class IN16SiliconTest(stresstesting.MantidStressTest): + + def runTest(self): + import IndirectNeutron as Main + + instr = 'IN16' + ana = 'silicon' + refl = '111' + run = '65722' + rejectZ = True + useM = False + saveOp = False + plotOp = False + Main.IbackStart(instr,run,ana,refl,rejectZ,useM,'',plotOp,saveOp) + + def validate(self): + self.tolerance = 1e-2 + self.disableChecking.append("SpectraMap") + self.disableChecking.append("Instrument") + return 'IN16_65722_silicon111_red', 'ISISIndirectLoadAscii_IN16SiliconTest.nxs' + diff --git a/Code/Mantid/Testing/SystemTests/tests/analysis/ISISIndirectSimulationTest.py b/Code/Mantid/Testing/SystemTests/tests/analysis/ISISIndirectSimulationTest.py new file mode 100644 index 000000000000..a83e389b4397 --- /dev/null +++ b/Code/Mantid/Testing/SystemTests/tests/analysis/ISISIndirectSimulationTest.py @@ -0,0 +1,76 @@ +import stresstesting +import os +from mantid.simpleapi import * + +#==================================================================================================== +class MolDynCdlTest(stresstesting.MantidStressTest): + + def runTest(self): + from mantid.simpleapi import MolDyn + + MolDyn(Filename='DISF_NaF.cdl', + Functions=['Fqt-total', 'Sqw-total'], + Plot='None', + Save=False, + OutputWorkspace='ISISIndirectSimulationTest_MolDynCdl') + + + def validate(self): + self.tolerance = 1e-2 + self.disableChecking.append("Instrument") + + from mantid.simpleapi import Load + + Load(Filename='ISISIndirectSimulation_MolDynCDL.nxs',OutputWorkspace='ISISIndirectSimulation_MolDynCDL') + Load(Filename='ISISIndirectSimulation_MolDynCDL_SQW.nxs',OutputWorkspace='ISISIndirectSimulation_MolDynCDL_SQW') + + # check each of the resulting workspaces match + ws1Match = self.checkWorkspacesMatch('DISF_NaF_Fqt-total', 'ISISIndirectSimulation_MolDynCDL') + ws2Match = self.checkWorkspacesMatch('DISF_NaF_Sqw-total', 'ISISIndirectSimulation_MolDynCDL_SQW') + + return ( ws1Match and ws2Match ) + + + def checkWorkspacesMatch(self, ws1, ws2): + """ + Function to check two workspaces match + Used when the result of a test produces more than a single workspace + """ + + from mantid.simpleapi import SaveNexus, AlgorithmManager + + checker = AlgorithmManager.create("CheckWorkspacesMatch") + checker.setLogging(True) + checker.setPropertyValue("Workspace1", ws1) + checker.setPropertyValue("Workspace2", ws2) + checker.setPropertyValue("Tolerance", str(self.tolerance)) + checker.setPropertyValue("CheckInstrument","0") + + checker.execute() + + if checker.getPropertyValue("Result") != 'Success!': + print self.__class__.__name__ + SaveNexus(InputWorkspace=ws2,Filename=self.__class__.__name__+'-mismatch.nxs') + return False + + return True + + +#==================================================================================================== +class MolDynDatTest(stresstesting.MantidStressTest): + + def runTest(self): + from mantid.simpleapi import MolDyn + + MolDyn(Filename='WSH_test.dat', + Plot='None', + Save=False, + OutputWorkspace='WSH_test_iqt') + + + def validate(self): + self.tolerance = 1e-2 + self.disableChecking.append("Instrument") + + return 'WSH_test_iqt', 'ISISIndirectSimulation_MolDynDAT.nxs' + diff --git a/Code/Mantid/Testing/SystemTests/tests/analysis/ISISLoadingEventData.py b/Code/Mantid/Testing/SystemTests/tests/analysis/ISISLoadingEventData.py new file mode 100644 index 000000000000..1e15aebe9e2a --- /dev/null +++ b/Code/Mantid/Testing/SystemTests/tests/analysis/ISISLoadingEventData.py @@ -0,0 +1,16 @@ +import stresstesting +from mantid.simpleapi import * + +class ISISLoadingEventData(stresstesting.MantidStressTest): + """ There is no event data inside mantid/Test directory. + Hence, all the units test that are specific to ISIS + when loading EventData should go to here. + """ + def runTest(self): + ev_ws = LoadEventNexus('LET00006278.nxs') + # isis_vms_compat/SPB[2] + self.assertEqual(ev_ws.sample().getGeometryFlag(), 1, "It does not read correctly the vms compat (check ") + # Isis correct the tof using loadTimeOfFlight method. + self.assertDelta(ev_ws.getEventList(10).getTofs()[1], 1041.89,0.01, "The ISIS event correction is incorrect (check LoadEventNexus::loadTimeOfFlight") + def validate(self): + return True diff --git a/Code/Mantid/Testing/SystemTests/tests/analysis/ISISMuonAnalysis.py b/Code/Mantid/Testing/SystemTests/tests/analysis/ISISMuonAnalysis.py new file mode 100644 index 000000000000..2232f4953ce2 --- /dev/null +++ b/Code/Mantid/Testing/SystemTests/tests/analysis/ISISMuonAnalysis.py @@ -0,0 +1,189 @@ +import math +import stresstesting +from mantid.simpleapi import * + +from abc import ABCMeta, abstractmethod + +#---------------------------------------------------------------------- +class ISISMuonAnalysis(stresstesting.MantidStressTest): + """A base class for the ISIS Muon Analysis tests + + The workflow is defined in the runTest() method, simply + define an __init__ method and set the following properties + on the object + - file_name: String pointing to nexus file to be used. + - map_name: String pointing to xml grouping file. + - instr_name: A string giving the instrument name. + - sample_run: An integer run number of the sample + - period_data: A boolean denoting whether the file has period data. + - asym: A boolean to tell whether the plot type is assymetry or not. + - x_min: Float value of the minimum x. + - x_max: Float value of the maximum x. + - rebin: Boolean to tell whether rebinning is to be done. + - rebin_fixed: Optional boolean to tell if the rebinning is in fixed steps. + - rebin_params: A string containing the rebin parameters. See wiki rebin for more info. + """ + __metaclass__ = ABCMeta # Mark as an abstract class + + @abstractmethod + def get_reference_file(self): + """Returns the name of the reference file to compare against""" + raise NotImplementedError("Implmenent get_reference_file to return " + "the name of the file to compare against.") + + def get_result_workspace(self): + """Returns the result workspace to be checked""" + return (self.instr_name + str(self.sample_run) ) + + def runTest(self): + """Defines the workflow for the test""" + + self._validate_properties() + + outputWS = (self.instr_name + str(self.sample_run) ) + + # Load + LoadMuonNexus(Filename=self.file_name, OutputWorkspace='MuonAnalysis' ) + + # Group, Crop, Clone + if(self.period_data): + GroupDetectors(InputWorkspace='MuonAnalysis_1', OutputWorkspace=outputWS, MapFile=self.map_name) + else: + GroupDetectors(InputWorkspace='MuonAnalysis', OutputWorkspace=outputWS, MapFile=self.map_name) + CropWorkspace(InputWorkspace=outputWS, OutputWorkspace=outputWS, XMin=self.x_min, XMax=self.x_max) + CloneWorkspace(InputWorkspace=outputWS, OutputWorkspace=(outputWS + '_Raw') ) + + # Rebin then... + if (self.rebin ): + + ws = mtd[outputWS] + binSize = ws.dataX(0)[1]-ws.dataX(0)[0] + firstX = ws.dataX(0)[0] + lastX = ws.dataX(0)[ws.blocksize()] + + if (self.rebin_fixed): + Rebin(InputWorkspace=outputWS, OutputWorkspace=outputWS, Params=str(binSize*float(self.rebin_params) ) ) + else: + Rebin(InputWorkspace=outputWS, OutputWorkspace=outputWS, Params=self.rebin_params) + + numberOfFullBunchedBins = math.floor((lastX - firstX) / binSize ) + + # ...Crop + if(numberOfFullBunchedBins > 0): + lastX = firstX + numberOfFullBunchedBins*binSize + lastX_str = '%.15f' % lastX + CropWorkspace(InputWorkspace=outputWS, OutputWorkspace=outputWS, XMax=lastX_str ) + + GroupWorkspaces(InputWorkspaces=outputWS + ',' + outputWS + '_Raw', OutputWorkspace='MuonGroup') + + if(self.asym): + AsymmetryCalc(InputWorkspace=outputWS, OutputWorkspace=outputWS, ForwardSpectra='0', BackwardSpectra='1') + + def validate(self): + """Returns the name of the workspace & file to compare""" + self.tolerance = 1e-7 + self.disableChecking.append('SpectraMap') + self.disableChecking.append('Instrument') + result = self.get_result_workspace() + reference = self.get_reference_file() + return result, reference + + def _validate_properties(self): + """Check the object properties are + in an expected state to continue + """ + if type(self.instr_name) != str: + raise RuntimeError("instr_name property should be a string") + if type(self.file_name) != str: + raise RuntimeError("file_name property should be a string") + if type(self.period_data) != bool: + raise RuntimeError("period_data property should be a bool") + + + +#------------------------- ARGUS tests ------------------------------------------------- + +class ARGUSAnalysisFromFile(ISISMuonAnalysis): + + def __init__(self): + ISISMuonAnalysis.__init__(self) + self.file_name = 'argus0044309.nxs' + self.map_name = 'ARGUSGrouping.xml' + self.instr_name = 'ARGUS' + self.sample_run = 44309 + self.asym = True + self.period_data = False + self.x_min = 2 + self.x_max = 12 + self.rebin = True + self.rebin_fixed = True + self.rebin_params = '1' + + def get_reference_file(self): + return "ARGUSAnalysis.nxs" + + +#------------------------- EMU tests ------------------------------------------------- + +class EMUAnalysisFromFile(ISISMuonAnalysis): + + def __init__(self): + ISISMuonAnalysis.__init__(self) + self.file_name = 'emu00031895.nxs' + self.map_name = 'EMUGrouping.xml' + self.instr_name = 'EMU' + self.sample_run = 31895 + self.asym = True + self.period_data = True + self.x_min = 0.11 + self.x_max = 10 + self.rebin = False + + def get_reference_file(self): + return "EMUAnalysis.nxs" + + +#------------------------- HiFi tests ------------------------------------------------- + +class HiFiAnalysisFromFile(ISISMuonAnalysis): + + def __init__(self): + ISISMuonAnalysis.__init__(self) + self.file_name = 'hifi00038401.nxs' + self.map_name = 'HiFiGrouping.xml' + self.instr_name = 'Hifi' + self.sample_run = 38401 + self.asym = True + self.period_data = False + self.x_min = 1 + self.x_max = 5 + self.rebin = True + self.rebin_fixed = True + self.rebin_params = '1' + + def get_reference_file(self): + return "HiFiAnalysis.nxs" + + +#------------------------- MuSR tests ------------------------------------------------- + +class MuSRAnalysisFromFile(ISISMuonAnalysis): + + def __init__(self): + ISISMuonAnalysis.__init__(self) + self.file_name = 'MUSR00015192.nxs' + self.map_name = 'MuSRGrouping.xml' + self.instr_name = 'MuSR' + self.sample_run = 15192 + self.asym = True + self.period_data = True + self.x_min = 0.11 + self.x_max = 10 + self.rebin = True + self.rebin_fixed = False + self.rebin_params = '0.11,0.0159999,10' + + def get_reference_file(self): + return "MuSRAnalysis.nxs" + + \ No newline at end of file diff --git a/Code/Mantid/Testing/SystemTests/tests/analysis/ISISMuonAnalysisGrouping.py b/Code/Mantid/Testing/SystemTests/tests/analysis/ISISMuonAnalysisGrouping.py new file mode 100644 index 000000000000..2e404a5ebcf8 --- /dev/null +++ b/Code/Mantid/Testing/SystemTests/tests/analysis/ISISMuonAnalysisGrouping.py @@ -0,0 +1,170 @@ +import math +import stresstesting +from mantid.simpleapi import * + +from abc import ABCMeta, abstractmethod + +#---------------------------------------------------------------------- +class ISISMuonAnalysisGrouping(stresstesting.MantidStressTest): + """A base class for the ISIS Muon Analysis tests + + The workflow is defined in the runTest() method, simply + define an __init__ method and set the following properties + on the object + - file_name: String pointing to nexus file to be used. + - map_name: String pointing to xml grouping file. + - instr_name: A string giving the instrument name. + - sample_run: An integer run number of the sample + - period_data: A boolean denoting whether the file has period data. + - asym: A boolean to tell whether the plot type is assymetry or not. + - logs: A boolean to tell whether the plot type is logorithmic or not. + - x_min: Float value of the minimum x. + - x_max: Float value of the maximum x. + """ + __metaclass__ = ABCMeta # Mark as an abstract class + + @abstractmethod + def get_reference_file(self): + """Returns the name of the reference file to compare against""" + raise NotImplementedError("Implmenent get_reference_file to return " + "the name of the file to compare against.") + + def get_result_workspace(self): + """Returns the result workspace to be checked""" + return (self.instr_name + str(self.sample_run) ) + + def runTest(self): + """Defines the workflow for the test""" + + self._validate_properties() + + outputWS = (self.instr_name + str(self.sample_run) ) + + # Load + LoadMuonNexus(Filename=self.file_name, OutputWorkspace='MuonAnalysis' ) + + # Group, Crop, Clone + if(self.period_data): + GroupDetectors(InputWorkspace='MuonAnalysis_1', OutputWorkspace=outputWS, MapFile=self.map_name) + else: + GroupDetectors(InputWorkspace='MuonAnalysis', OutputWorkspace=outputWS, MapFile=self.map_name) + CropWorkspace(InputWorkspace=outputWS, OutputWorkspace=outputWS, XMin=self.x_min, XMax=self.x_max) + CloneWorkspace(InputWorkspace=outputWS, OutputWorkspace=(outputWS + '_Raw') ) + GroupWorkspaces(InputWorkspaces=outputWS + ',' + outputWS + '_Raw', OutputWorkspace='MuonGroup') + + if(self.logs): + Logarithm(InputWorkspace=outputWS, OutputWorkspace=outputWS) + if(self.asym): + RemoveExpDecay(InputWorkspace=outputWS, OutputWorkspace=outputWS) + + + def validate(self): + """Returns the name of the workspace & file to compare""" + self.tolerance = 1e-7 + self.disableChecking.append('SpectraMap') + self.disableChecking.append('Instrument') + result = self.get_result_workspace() + reference = self.get_reference_file() + return result, reference + + def _validate_properties(self): + """Check the object properties are + in an expected state to continue + """ + if type(self.file_name) != str: + raise RuntimeError("file_name property should be a string") + if type(self.map_name) != str: + raise RuntimeError("map_name property should be a string") + if type(self.instr_name) != str: + raise RuntimeError("instr_name property should be a string") + if type(self.period_data) != bool: + raise RuntimeError("period_data property should be a bool") + if type(self.asym) != bool: + raise RuntimeError("asym property should be a bool") + if type(self.logs) != bool: + raise RuntimeError("log property should be a bool") + + + +#------------------------- ARGUS group fwd test ------------------------------------------------- + +class ARGUSAnalysisFromFile(ISISMuonAnalysisGrouping): + + def __init__(self): + ISISMuonAnalysisGrouping.__init__(self) + self.file_name = 'argus0044309.nxs' + self.map_name = 'ARGUSFwdGrouping.xml' + self.instr_name = 'ARGUS' + self.sample_run = 44309 + self.period_data = False + self.asym = False + self.logs = True + self.x_min = 3 + self.x_max = 10 + + def get_reference_file(self): + return "ARGUSAnalysisLogFwd.nxs" + + +#------------------------- EMU group fwd test ------------------------------------------------- + +class EMUAnalysisFromFile(ISISMuonAnalysisGrouping): + + def __init__(self): + ISISMuonAnalysisGrouping.__init__(self) + self.file_name = 'emu00031895.nxs' + self.map_name = 'EMUFwdGrouping.xml' + self.instr_name = 'EMU' + self.sample_run = 31895 + self.period_data = True + self.asym = True + self.logs = False + self.x_min = 0.11 + self.x_max = 10 + + + def get_reference_file(self): + return "EMUAnalysisAsymFwd.nxs" + + +#------------------------- HiFi group 0 test ------------------------------------------------- + +class HiFiAnalysisFromFile(ISISMuonAnalysisGrouping): + + def __init__(self): + ISISMuonAnalysisGrouping.__init__(self) + self.file_name = 'hifi00038401.nxs' + self.map_name = 'HiFi0Grouping.xml' + self.instr_name = 'Hifi' + self.sample_run = 38401 + self.period_data = False + self.asym = True + self.logs = False + self.x_min = 0.1199 + self.x_max = 7.4999 + + def get_reference_file(self): + return "HiFiAnalysisAsym0.nxs" + + +#------------------------- MuSR Group 1 test ------------------------------------------------- + +class MuSRAnalysisFromFile(ISISMuonAnalysisGrouping): + + def __init__(self): + ISISMuonAnalysisGrouping.__init__(self) + self.file_name = 'MUSR00015192.nxs' + self.map_name = 'MuSR1Grouping.xml' + self.instr_name = 'MuSR' + self.sample_run = 15192 + self.period_data = True + self.asym = False + self.logs = True + self.x_min = 1.4 + self.x_max = 3.9 + + + def get_reference_file(self): + return "MuSRAnalysisLog1.nxs" + + \ No newline at end of file diff --git a/Code/Mantid/Testing/SystemTests/tests/analysis/ISISReflInstrumentIDFTest.py b/Code/Mantid/Testing/SystemTests/tests/analysis/ISISReflInstrumentIDFTest.py new file mode 100644 index 000000000000..d9d7db86066a --- /dev/null +++ b/Code/Mantid/Testing/SystemTests/tests/analysis/ISISReflInstrumentIDFTest.py @@ -0,0 +1,57 @@ +""" +These system tests are to verify that the IDF and parameter files for POLREF, CRISP, INTER and SURF are read properly +""" + +import stresstesting +from mantid.simpleapi import * +import os +from abc import ABCMeta, abstractmethod + +class ISISReflInstrumentIDFTest(stresstesting.MantidStressTest): + + __metaclass__ = ABCMeta # Mark as an abstract class + + @abstractmethod + def get_IDF_name(self): + """Returns the IDF""" + raise NotImplementedError("Implement get_IDF_name to return ") + + def runTest(self): + IDF_path = os.path.join(config['instrumentDefinition.directory'], self.get_IDF_name()) + ws = LoadEmptyInstrument(IDF_path) + inst = ws.getInstrument() + self.assertTrue(isinstance(inst.getNumberParameter('MonitorIntegralMin')[0] , float)) + self.assertTrue(isinstance(inst.getNumberParameter('MonitorIntegralMax')[0] , float)) + self.assertTrue(isinstance(inst.getNumberParameter('MonitorBackgroundMin')[0] , float)) + self.assertTrue(isinstance(inst.getNumberParameter('MonitorBackgroundMax')[0] , float)) + self.assertTrue(isinstance(inst.getNumberParameter('PointDetectorStart')[0] , float)) + self.assertTrue(isinstance(inst.getNumberParameter('PointDetectorStop')[0] , float)) + self.assertTrue(isinstance(inst.getNumberParameter('MultiDetectorStart')[0] , float)) + self.assertTrue(isinstance(inst.getNumberParameter('I0MonitorIndex')[0] , float)) + self.assertTrue(isinstance(inst.getNumberParameter('LambdaMin')[0] , float)) + self.assertTrue(isinstance(inst.getNumberParameter('LambdaMax')[0] , float)) + + return True; + + def doValidate(self): + return True; + +# Specialisation for testing POLREF +class POLREF_ISISReflInstrumentIDFTest(ISISReflInstrumentIDFTest): + def get_IDF_name(self): + return "POLREF_Definition.xml" + +# Specialisation for testing INTER +class INTER_ISISReflInstrumentIDFTest(ISISReflInstrumentIDFTest): + def get_IDF_name(self): + return "INTER_Definition.xml" + +# Specialisation for testing SURF +class SURF_ISISReflInstrumentIDFTest(ISISReflInstrumentIDFTest): + def get_IDF_name(self): + return "SURF_Definition.xml" + +# Specialisation for testing CRISP +class CRISP_ISISReflInstrumentIDFTest(ISISReflInstrumentIDFTest): + def get_IDF_name(self): + return "CRISP_Definition.xml" diff --git a/Code/Mantid/Testing/SystemTests/tests/analysis/ISIS_LETReduction.py b/Code/Mantid/Testing/SystemTests/tests/analysis/ISIS_LETReduction.py new file mode 100644 index 000000000000..df2385d75af5 --- /dev/null +++ b/Code/Mantid/Testing/SystemTests/tests/analysis/ISIS_LETReduction.py @@ -0,0 +1,420 @@ +""" Sample LET reduction scrip """ +import os +os.environ["PATH"] = r"c:/Mantid/Code/builds/br_master/bin/Release;"+os.environ["PATH"] + + +from Direct.ReductionWrapper import * +try: + import reduce_vars as rv +except: + rv = None + +# +def find_binning_range(energy,ebin): + """ function finds the binning range used in multirep mode + for merlin ls=11.8,lm2=10. mult=2.8868 dt_DAE=1 + for LET ls=25,lm2=23.5 mult=4.1 dt_DAE=1.6 + all these values have to be already present in IDF and should be taken from there + + # THIS FUNCTION SHOULD BE MADE GENERIG AND MOVED OUT OF HERE + """ + + InstrName = config['default.instrument'][0:3] + if InstrName.find('LET')>-1: + ls =25 + lm2 =23.5 + mult=4.1 + dt_DAE = 1.6 + elif InstrName.find('MER')>-1: + ls =11.8 + lm2=10 + mult=2.8868 + dt_DAE = 1 + else: + raise RuntimeError("Find_binning_range: unsupported/unknown instrument found") + + energy=float(energy) + + emin=(1.0-ebin[2])*energy #minimum energy is with 80% energy loss + lam=(81.81/energy)**0.5 + lam_max=(81.81/emin)**0.5 + tsam=252.82*lam*ls #time at sample + tmon2=252.82*lam*lm2 #time to monitor 6 on LET + tmax=tsam+(252.82*lam_max*mult) #maximum time to measure inelastic signal to + t_elastic=tsam+(252.82*lam*mult) #maximum time of elastic signal + tbin=[int(tmon2),dt_DAE,int(tmax)] + energybin=[float("{0: 6.4f}".format(elem*energy)) for elem in ebin] + + return (energybin,tbin,t_elastic) +#-------------------------------------------------------------------------------------------------------- +def find_background(ws_name,bg_range): + """ Function to find background from multirep event workspace + dt_DAE = 1 for MERLIN and 1.6 for LET + should be precalculated or taken from IDF + + # THIS FUNCTION SHOULD BE MADE GENERIC AND MOVED OUT OF HERE + """ + InstrName = config['default.instrument'][0:3] + if InstrName.find('LET')>-1: + dt_DAE = 1.6 + elif InstrName.find('MER')>-1: + dt_DAE = 1 + else: + raise RuntimeError("Find_binning_range: unsupported/unknown instrument found") + + bg_ws_name = 'bg' + delta=bg_range[1]-bg_range[0] + Rebin(InputWorkspace='w1',OutputWorkspace=bg_ws_name,Params=[bg_range[0],delta,bg_range[1]],PreserveEvents=False) + v=(delta)/dt_DAE + CreateSingleValuedWorkspace(OutputWorkspace='d',DataValue=v) + Divide(LHSWorkspace=bg_ws_name,RHSWorkspace='d',OutputWorkspace=bg_ws_name) + return bg_ws_name + + +class ReduceLET_OneRep(ReductionWrapper): + @MainProperties + def def_main_properties(self): + """ Define main properties used in reduction """ + + + prop = {} + ei = 7.0 + ebin = [-1,0.002,0.95] + + prop['sample_run'] = 'LET00006278.nxs' + prop['wb_run'] = 'LET00005545.raw' + prop['incident_energy'] = ei + prop['energy_bins'] = ebin + + + # Absolute units reduction properties. + #prop['monovan_run'] = 17589 + #prop['sample_mass'] = 10/(94.4/13) # -- this number allows to get approximately the same system test intensities for MAPS as the old test + #prop['sample_rmm'] = 435.96 # + return prop + + @AdvancedProperties + def def_advanced_properties(self): + """ separation between simple and advanced properties depends + on scientist, experiment and user. + main properties override advanced properties. + """ + + prop = {} + prop['map_file'] = 'rings_103' + prop['hard_mask_file'] ='LET_hard.msk' + prop['det_cal_file'] = 'det_corrected7.dat' + prop['save_format']='' + prop['bleed'] = False + prop['norm_method']='current' + prop['detector_van_range']=[0.5,200] + prop['load_monitors_with_workspace']=True + #TODO: this has to be loaded from the workspace and work without this + #prop['ei-mon1-spec']=40966 + + + return prop + # + @iliad + def reduce(self,input_file=None,output_directory=None): + # run reduction, write auxiliary script to add something here. + + prop = self.reducer.prop_man + # Ignore input properties for the time being + white_ws = 'wb_wksp' + LoadRaw(Filename='LET00005545.raw',OutputWorkspace=white_ws) + #prop.wb_run = white_ws + + sample_ws = 'w1' + monitors_ws = sample_ws + '_monitors' + LoadEventNexus(Filename='LET00006278.nxs',OutputWorkspace=sample_ws, + SingleBankPixelsOnly='0',LoadMonitors='1', + MonitorsAsEvents='1') + ConjoinWorkspaces(InputWorkspace1=sample_ws, InputWorkspace2=monitors_ws) + #prop.sample_run = sample_ws + + + ebin = prop.energy_bins + ei = prop.incident_energy + + (energybin,tbin,t_elastic) = find_binning_range(ei,ebin) + Rebin(InputWorkspace=sample_ws,OutputWorkspace=sample_ws, Params=tbin, PreserveEvents='1') + + prop.bkgd_range=[int(t_elastic),int(tbin[2])] + + ebinstring = str(energybin[0])+','+str(energybin[1])+','+str(energybin[2]) + self.reducer.prop_man.energy_bins = ebinstring + + red = DirectEnergyConversion() + + red.initialise(prop) + outWS = red.convert_to_energy(white_ws,sample_ws) + #SaveNexus(ws,Filename = 'MARNewReduction.nxs') + + #when run from web service, return additional path for web server to copy data to" + return outWS + + def __init__(self,rv=None): + """ sets properties defaults for the instrument with Name""" + ReductionWrapper.__init__(self,'LET',rv) +#---------------------------------------------------------------------------------------------------------------------- + +class ReduceLET_MultiRep2014(ReductionWrapper): + @MainProperties + def def_main_properties(self): + """ Define main properties used in reduction """ + + + prop = {} + ei=[3.4,8.] # multiple energies provided in the data file + ebin=[-4,0.002,0.8] #binning of the energy for the spe file. The numbers are as a fraction of ei [from ,step, to ] + + prop['sample_run'] = [14305] + prop['wb_run'] = 5545 + prop['incident_energy'] = ei + prop['energy_bins'] = ebin + + + # Absolute units reduction properties. + # Vanadium labelled Dec 2011 - flat plate of dimensions: 40.5x41x2.0# volume = 3404.025 mm**3 mass= 20.79 + prop['monovan_run'] = 14319 # vanadium run in the same configuration as your sample + prop['sample_mass'] = 20.79 # 17.25 # mass of your sample (PrAl3) + prop['sample_rmm'] = 50.9415 # 221.854 # molecular weight of your sample + + return prop + + @AdvancedProperties + def def_advanced_properties(self): + """ separation between simple and advanced properties depends + on scientist, experiment and user. + main properties override advanced properties. + """ + + prop = {} + prop['map_file'] = 'rings_103.map' + prop['det_cal_file'] = 'det_corrected7.nxs' + prop['save_format']='' + prop['bleed'] = False + prop['norm_method']='current' + prop['detector_van_range']=[2,7] + prop['background_range'] = [92000,98000] # TOF range for the calculating flat background + prop['hardmaskOnly']='LET_hard.msk' # diag does not work well on LET. At present only use a hard mask RIB has created + + # Disable internal background check TODO: fix internal background check + prop['check_background']=False + + prop['monovan_mapfile'] = 'rings_103.map' + + #TODO: Correct monitor, depending on workspace. This has to be loaded from the workspace and work without this settings + #prop['ei-mon1-spec']=40966 + + + + return prop + # + @iliad + def reduce(self,input_file=None,output_directory=None): + # run reduction, write auxiliary script to add something here. + + red_properties = self.reducer.prop_man + ####### + wb= red_properties.wb_run + run_no = red_properties.sample_run + bg_range = red_properties.background_range + ei = red_properties.incident_energy + ebin = red_properties.energy_bins + + remove_background = True #if true then will subtract a flat background in time from the time range given below otherwise put False + + red = DirectEnergyConversion() + + red.initialise(red_properties) + + energybin,tbin,t_elastic = find_binning_range(ei[0],ebin) + energybin,tbin,t_elastic = find_binning_range(ei[1],ebin) + + # loads the white-beam (or rather the long monovan ). Does it as a raw file to save time as the event mode is very large + if 'wb_wksp' in mtd: + wb_wksp=mtd['wb_wksp'] + else: #only load white-beam if not already there + wb_wksp = LoadRaw(Filename='LET0000'+str(wb)+'.raw',OutputWorkspace='wb_wksp') + #dgreduce.getReducer().det_cal_file = 'det_corrected7.nxs' + #wb_wksp = dgreduce.getReducer().load_data('LET0000'+str(wb)+'.raw','wb_wksp') + #dgreduce.getReducer().det_cal_file = wb_wksp + + for run in [run_no]: #loop around runs + fname='LET0000'+str(run)+'.nxs' + print ' processing file ', fname + #w1 = dgreduce.getReducer().load_data(run,'w1') + Load(Filename=fname,OutputWorkspace='w1',LoadMonitors='1') + + + if remove_background: + bg_ws_name=find_background('w1',bg_range) + + ############################################################################################# + # this section finds all the transmitted incident energies if you have not provided them + #if len(ei) == 0: -- not tested here -- should be unit test for that. + #ei = find_chopper_peaks('w1_monitors') + print 'Energies transmitted are:' + print (ei) + + RenameWorkspace(InputWorkspace = 'w1',OutputWorkspace='w1_storage') + RenameWorkspace(InputWorkspace = 'w1_monitors',OutputWorkspace='w1_mon_storage') + + #now loop around all energies for the run + result =[] + for ind,energy in enumerate(ei): + print float(energy) + (energybin,tbin,t_elastic) = find_binning_range(energy,ebin) + print " Rebinning will be performed in the range: ",energybin + # if we calculate more then one energy, initial workspace will be used more then once + if ind 0 the reduction wait until file appears on the data + # search path checking after time specified below. + rd.wait_for_file = 0 # waiting time interval + +###### Run reduction over all run numbers or files assigned to ###### + # sample_run variable + red_ws = rd.run_reduction() + + diff --git a/Code/Mantid/Testing/SystemTests/tests/analysis/IndirectDiffractionTests.py b/Code/Mantid/Testing/SystemTests/tests/analysis/IndirectDiffractionTests.py new file mode 100644 index 000000000000..9d14be49631d --- /dev/null +++ b/Code/Mantid/Testing/SystemTests/tests/analysis/IndirectDiffractionTests.py @@ -0,0 +1,107 @@ +from abc import ABCMeta, abstractmethod +import stresstesting + + +class MSGDiffractionReductionTest(stresstesting.MantidStressTest): + """ + Base class for tests that use the MSGDiffractionReduction algorithm. + """ + + __metaclass__ = ABCMeta + + @abstractmethod + def get_reference_file(self): + """ + Gets reference result file for workspace comparison. + """ + raise NotImplementedError() + + def runTest(self): + """ + Runs an MSGDiffractionReduction with the configured parameters. + """ + from mantid.simpleapi import MSGDiffractionReduction + from mantid import mtd + + MSGDiffractionReduction(InputFiles=self.raw_file, + OutputWorkspace=self.output_workspace_group, + Instrument=self.instrument, + Mode=self.mode, + DetectorRange=self.detector_range, + RebinParam=self.rebinning) + + self._output_workspace = mtd[self.output_workspace_group].getNames()[0] + + def validate(self): + """ + Validates the result workspace with the reference file. + """ + self.disableChecking.append('Instrument') + return self._output_workspace, self.get_reference_file() + + +#------------------------------------------------------------------------------- +class IRISDiffspecDiffractionTest(MSGDiffractionReductionTest): + + def __init__(self): + MSGDiffractionReductionTest.__init__(self) + + self.instrument = 'IRIS' + self.mode = 'diffspec' + self.raw_file = 'IRS21360.raw' + self.detector_range = [105, 112] + self.rebinning = '3.0,0.001,4.0' + self.output_workspace_group = 'IRIS_Diffraction_DiffSpec_Test' + + def get_reference_file(self): + return 'IRISDiffspecDiffractionTest.nxs' + + +#------------------------------------------------------------------------------- +class TOSCADiffractionTest(MSGDiffractionReductionTest): + + def __init__(self): + MSGDiffractionReductionTest.__init__(self) + + self.instrument = 'TOSCA' + self.mode = 'diffspec' + self.raw_file = 'TSC11453.raw' + self.detector_range = [146, 149] + self.rebinning = '0.5,0.001,2.1' + self.output_workspace_group = 'TOSCA_Diffraction_DiffSpec_Test' + + def get_reference_file(self): + return 'TOSCADiffractionTest.nxs' + + +#------------------------------------------------------------------------------- +class OSIRISDiffspecDiffractionTest(MSGDiffractionReductionTest): + + def __init__(self): + MSGDiffractionReductionTest.__init__(self) + + self.instrument = 'OSIRIS' + self.mode = 'diffspec' + self.raw_file = 'osiris00101300.raw' + self.detector_range = [3, 962] + self.rebinning = '2.0,0.001,3.0' + self.output_workspace_group = 'OSIRIS_Diffraction_DiffSpec_Test' + + def get_reference_file(self): + return 'OsirisDiffspecDiffractionTest.nxs' + + +#------------------------------------------------------------------------------- +class OsirisDiffOnlyTest(stresstesting.MantidStressTest): + + def runTest(self): + from mantid.simpleapi import OSIRISDiffractionReduction + OSIRISDiffractionReduction( + OutputWorkspace="OsirisDiffractionTest", + Sample="OSI89813.raw, OSI89814.raw, OSI89815.raw, OSI89816.raw, OSI89817.raw", + CalFile="osiris_041_RES10.cal", + Vanadium="OSI89757, OSI89758, OSI89759, OSI89760, OSI89761") + + def validate(self): + self.disableChecking.append('Instrument') + return 'OsirisDiffractionTest', 'OsirisDiffractionTest.nxs' diff --git a/Code/Mantid/Testing/SystemTests/tests/analysis/IndirectEnergyConversionTest.py b/Code/Mantid/Testing/SystemTests/tests/analysis/IndirectEnergyConversionTest.py new file mode 100644 index 000000000000..d5af6da914f2 --- /dev/null +++ b/Code/Mantid/Testing/SystemTests/tests/analysis/IndirectEnergyConversionTest.py @@ -0,0 +1,26 @@ +import stresstesting +from mantid.simpleapi import * + +class IndirectEnergyConversionTest(stresstesting.MantidStressTest): + + def runTest(self): + instrument = 'IRIS' + analyser = 'graphite' + reflection = '002' + detector_range = [3, 53] + files = 'irs21360.raw' + rebin_string = '-0.5,0.005,0.5' + + InelasticIndirectReduction(InputFiles=files, + RebiNString=rebin_string, + DetectorRange=detector_range, + Instrument=instrument, + Analyser=analyser, + Reflection=reflection, + OutputWorkspace='__IndirectEnergyCOnversionTest_out_group') + + + def validate(self): + self.disableChecking.append('Instrument') + self.disableChecking.append('SpectraMap') + return 'irs21360_graphite002_red', 'IndirectEnergyConversionTest.nxs' diff --git a/Code/Mantid/Testing/SystemTests/tests/analysis/L2QScriptTest.py b/Code/Mantid/Testing/SystemTests/tests/analysis/L2QScriptTest.py new file mode 100644 index 000000000000..aaa77adc67ff --- /dev/null +++ b/Code/Mantid/Testing/SystemTests/tests/analysis/L2QScriptTest.py @@ -0,0 +1,25 @@ + +import stresstesting +from mantid.simpleapi import * +from isis_reflectometry.l2q import * + +class L2QScriptTest(stresstesting.MantidStressTest): + + + def runTest(self): + ws = Load(Filename="INTER00013469.nxs") + ws = ConvertUnits(InputWorkspace=ws,Target="Wavelength",AlignBins=1) + Io=CropWorkspace(InputWorkspace=ws,XMin=0.8,XMax=14.5,StartWorkspaceIndex=2,EndWorkspaceIndex=2) + D=CropWorkspace(InputWorkspace=ws,XMin=0.8,XMax=14.5,StartWorkspaceIndex=3) + I= Divide(LHSWorkspace=D,RHSWorkspace=Io,AllowDifferentNumberSpectra=True) + detector_component_name = 'linear-detector' + sample_component_name = 'some-surface-holder' + theta = 0.7 + l2q(ws, detector_component_name, theta, sample_component_name) # This generates an output workspace called IvsQ + + + def validate(self): + self.disableChecking.append('Instrument') + return 'IvsQ','L2QReferenceResult.nxs' + + diff --git a/Code/Mantid/Testing/SystemTests/tests/analysis/LOQAddBatch.py b/Code/Mantid/Testing/SystemTests/tests/analysis/LOQAddBatch.py new file mode 100644 index 000000000000..ebd0638483b0 --- /dev/null +++ b/Code/Mantid/Testing/SystemTests/tests/analysis/LOQAddBatch.py @@ -0,0 +1,76 @@ +import stresstesting +from mantid.simpleapi import * +from mantid.api import FileFinder +from mantid import config +import ISISCommandInterface as ici +import SANSBatchMode as batch +import SANSadd2 as sansadd + +import os + +class SANSAddBatch(stresstesting.MantidStressTest): + output_file = '99630sannotrans' + csv_file = 'input.csv' + result = '' + + def cleanup(self): + print "Cleanup" + absfile = FileFinder.getFullPath("input.csv") + if os.path.exists(absfile): + os.remove(absfile) + return True + + def runTest(self): + #here we are testing the LOQ setup + ici.LOQ() + #rear detector + ici.Detector("main-detector-bank") + #test batch mode, although only the analysis from the last line is checked + # Find the file , this should really be in the BatchReduce reduction step + + f = open(self.csv_file,'w') + print >> f, "sample_sans,99630-add,output_as, %s"%self.output_file + f.close() + runnum = '99630' + sansadd.add_runs((runnum, runnum),'LOQ','.RAW') + + ici.Set1D() + ici.MaskFile('MASK.094AA') + batch.BatchReduce(self.csv_file, 'nxs', plotresults=False, saveAlgs={'SaveNexus':'nxs'}) + + print ' reduction without' + + ici._refresh_singleton() + + ici.LOQ() + ici.Detector("main-detector-bank") + ici.Set1D() + ici.MaskFile('MASK.094AA') + LOQ99630 = Load(runnum) + LOQ99630 += LOQ99630 + ici.AssignSample(LOQ99630, reload=False) + self.result = ici.WavRangeReduction() + + def validate(self): + # Need to disable checking of the Spectra-Detector map because it isn't + # fully saved out to the nexus file (it's limited to the spectra that + # are actually present in the saved workspace). + self.disableChecking.append('SpectraMap') + self.disableChecking.append('Axes') + self.disableChecking.append('Instrument') + self.tolerance = 1.0e-10 #almost ZERO! + print 'validating', self.result, self.output_file + return self.result,self.output_file+'.nxs' + + + + def __del__(self): + # remove all created files. + defaultsave = config['defaultsave.directory'] + for file_name in ['LOQ99630-add.nxs', self.output_file+'.nxs', self.csv_file ]: + try: + os.remove(os.path.join(defaultsave,file_name)) + except: + pass + + diff --git a/Code/Mantid/Testing/SystemTests/tests/analysis/LOQCentreNoGrav.py b/Code/Mantid/Testing/SystemTests/tests/analysis/LOQCentreNoGrav.py new file mode 100644 index 000000000000..51cca5aaae31 --- /dev/null +++ b/Code/Mantid/Testing/SystemTests/tests/analysis/LOQCentreNoGrav.py @@ -0,0 +1,56 @@ +import stresstesting +from mantid.simpleapi import * +from ISISCommandInterface import * + +class LOQCentreNoGrav(stresstesting.MantidStressTest): + + def runTest(self): + + LOQ() + + Set1D() + Detector("rear-detector") + MaskFile('MASK.094AA') + Gravity(False) + + AssignSample('54431.raw') + TransmissionSample('54435.raw', '54433.raw') + AssignCan('54432.raw') + TransmissionCan('54434.raw', '54433.raw') + + FindBeamCentre(60,200, 9) + + WavRangeReduction(3, 9, DefaultTrans) + + def validate(self): + + return '54431main_1D_3.0_9.0','LOQCentreNoGravSearchCentreFixed.nxs' + +class LOQCentreNoGravDefineCentre(stresstesting.MantidStressTest): + def runTest(self): + + LOQ() + + Set1D() + Detector("rear-detector") + MaskFile('MASK.094AA') + Gravity(False) + SetCentre(324.765, 327.670) + + AssignSample('54431.raw') + TransmissionSample('54435.raw', '54433.raw') + AssignCan('54432.raw') + TransmissionCan('54434.raw', '54433.raw') + + WavRangeReduction(3, 9, DefaultTrans) + + def validate(self): + # Need to disable checking of the Spectra-Detector map becauseit isn't + # fully saved out to the nexus file (it's limited to the spectra that + # are actually present in the saved workspace). + self.disableChecking.append('SpectraMap') + self.disableChecking.append('Axes') + self.disableChecking.append('Instrument') + + return '54431main_1D_3.0_9.0','LOQCentreNoGrav.nxs' + diff --git a/Code/Mantid/Testing/SystemTests/tests/analysis/LOQReductionGUI.py b/Code/Mantid/Testing/SystemTests/tests/analysis/LOQReductionGUI.py new file mode 100644 index 000000000000..a8ec0d38e701 --- /dev/null +++ b/Code/Mantid/Testing/SystemTests/tests/analysis/LOQReductionGUI.py @@ -0,0 +1,27 @@ +import stresstesting +from mantid.simpleapi import * +import isis_reducer +import ISISCommandInterface as i +import isis_instrument +import isis_reduction_steps + +MASKFILE = FileFinder.getFullPath('MaskLOQData.txt') +BATCHFILE = FileFinder.getFullPath('loq_batch_mode_reduction.csv') + +class LOQMinimalBatchReduction(stresstesting.MantidStressTest): + def __init__(self): + super(LOQMinimalBatchReduction, self).__init__() + config['default.instrument'] = 'LOQ' + + def runTest(self): + import SANSBatchMode as batch + i.LOQ() + i.MaskFile(MASKFILE) + fit_settings = batch.BatchReduce(BATCHFILE, '.nxs', combineDet='merged', saveAlgs={}) + + def validate(self): + # note increased tolerance to something which quite high + # this is partly a temperary measure, but also justified by + # when overlaying the two options they overlap very well + self.tolerance = 1.0e+1 + return 'first_time_merged', 'LOQReductionMergedData.nxs' diff --git a/Code/Mantid/Testing/SystemTests/tests/analysis/LOQSANSUtilityTest.py b/Code/Mantid/Testing/SystemTests/tests/analysis/LOQSANSUtilityTest.py new file mode 100644 index 000000000000..ecaa625a5e5c --- /dev/null +++ b/Code/Mantid/Testing/SystemTests/tests/analysis/LOQSANSUtilityTest.py @@ -0,0 +1,28 @@ +import stresstesting +from mantid.simpleapi import * +from mantid import config +import SANSUtility as su +import SANSadd2 as add + +import os + +def unixLikePathFromWorkspace(ws): + return su.getFilePathFromWorkspace(ws).replace('\\','/') + + +class SANSUtilityTest(stresstesting.MantidStressTest): + + def runTest(self): + # created after issue reported in #8156 + ws = Load('LOQ54432') + self.assertTrue('Data/SystemTest/LOQ/LOQ54432.raw' in unixLikePathFromWorkspace(ws)) + ws = Load('LOQ99618.RAW') + self.assertTrue('Data/SystemTest/LOQ/LOQ99618.RAW' in unixLikePathFromWorkspace(ws)) + add.add_runs(('LOQ54432','LOQ54432'),'LOQ','.raw') + ws = Load('LOQ54432-add') + file_path = unixLikePathFromWorkspace(ws) + logger.information("File Path from -add: "+str(file_path)) + file_path = file_path.replace('-ADD','-add') # MAC seems to report that the file is LOQ54432-ADD.nxs + self.assertTrue('LOQ54432-add' in file_path) + os.remove(file_path) + diff --git a/Code/Mantid/Testing/SystemTests/tests/analysis/LOQTransFitWorkspace2D.py b/Code/Mantid/Testing/SystemTests/tests/analysis/LOQTransFitWorkspace2D.py new file mode 100644 index 000000000000..2bb5558ba175 --- /dev/null +++ b/Code/Mantid/Testing/SystemTests/tests/analysis/LOQTransFitWorkspace2D.py @@ -0,0 +1,53 @@ +import stresstesting +from mantid.simpleapi import * +from ISISCommandInterface import * + +class LOQTransFitWorkspace2D(stresstesting.MantidStressTest): + """ + Tests the SANS interface commands TransFit() and TransWorkspace(). Also tests + a LOQ reduction in 2D with can and transmission files + """ + + def runTest(self): + self.setup() + + #test TransFit() + TransFit('LOG',3.0,8.0) + TransmissionSample('54435.raw', '54433.raw') + TransmissionCan('54434.raw', '54433.raw') + + #run the reduction + WavRangeReduction(3, 4, False, '_suff') + + #save the results, we'll use them later, remove the other tempory workspaces + RenameWorkspace(InputWorkspace='54435_trans_sample_3.0_8.0',OutputWorkspace= 'samp') + RenameWorkspace(InputWorkspace='54434_trans_can_3.0_8.0',OutputWorkspace= 'can') + DeleteWorkspace(Workspace='54435_trans_sample_3.0_8.0_unfitted') + DeleteWorkspace(Workspace='54434_trans_can_3.0_8.0_unfitted') + DeleteWorkspace(Workspace='54431main_2D_3.0_4.0_suff') + + #now test TransWorkspace() + self.setup() + #use the results we calculated above + TransWorkspace('samp', 'can') + + WavRangeReduction(3, 4, False, '_suff') + + def setup(self): + #DataPath("../Data/LOQ/") + #UserPath("../Data/LOQ/") + LOQ() + MaskFile('MASK.094AA') + Gravity(False) + Set2D() + Detector("main-detector-bank") + AssignSample('54431.raw') + AssignCan('54432.raw') + LimitsWav(3,4, 0.2, 'LIN') + + def validate(self): + self.disableChecking.append('SpectraMap') + #when comparing LOQ files you seem to need the following + self.disableChecking.append('Axes') + self.disableChecking.append('Instrument') + return '54431main_2D_3.0_4.0_suff','LOQTransFitWorkspace2D.nxs' diff --git a/Code/Mantid/Testing/SystemTests/tests/analysis/LoadAndCheckBase.py b/Code/Mantid/Testing/SystemTests/tests/analysis/LoadAndCheckBase.py new file mode 100644 index 000000000000..28256b4f5867 --- /dev/null +++ b/Code/Mantid/Testing/SystemTests/tests/analysis/LoadAndCheckBase.py @@ -0,0 +1,94 @@ +""" +These system tests are to verify the behaviour of the ISIS reflectometry reduction scripts +""" + +import stresstesting +from mantid.simpleapi import * +import mantid.api._api + +from abc import ABCMeta, abstractmethod + +class LoadAndCheckBase(stresstesting.MantidStressTest): + + __metaclass__ = ABCMeta # Mark as an abstract class + + __comparison_out_workspace_name = 'a_integrated' + + @abstractmethod + def get_raw_workspace_filename(self): + """Returns the name of the raw workspace file""" + raise NotImplementedError("Implement get_raw_workspace_filename") + + @abstractmethod + def get_nexus_workspace_filename(self): + """Returns the name of the nexus workspace file""" + raise NotImplementedError("Implement get_nexus_workspace_filename") + + @abstractmethod + def get_expected_instrument_name(self): + """Returns the name of the instrument""" + raise NotImplementedError("Implement get_expected_instrument_name") + + def get_expected_number_of_periods(self): + return 1 + + def get_integrated_reference_workspace_filename(self): + """Returns the name of the benchmark file used for end-of-test comparison.""" + if self.enable_reference_result_checking(): + # Must have a reference result file if reference result checking is required + raise NotImplementedError("Implement get_nexus_workspace_filename") + + def enable_reference_result_checking(self): + return True + + def enable_instrument_checking(self): + return True + + + def do_check_workspace_shape(self, ws1, ws2): + self.assertTrue(ws1.getNumberHistograms(), ws2.getNumberHistograms()) + self.assertTrue(len(ws1.readX(0)) == len(ws2.readX(0))) + self.assertTrue(len(ws1.readY(0)) == len(ws2.readY(0))) + + def do_check_instrument_applied(self, ws1, ws2): + instrument_name = self.get_expected_instrument_name() + self.assertTrue(ws1.getInstrument().getName() == instrument_name) + self.assertTrue(ws2.getInstrument().getName() == instrument_name) + + def runTest(self): + Load(Filename=self.get_nexus_workspace_filename(), OutputWorkspace='nexus') + Load(Filename=self.get_raw_workspace_filename(), OutputWorkspace='raw') + + a = mtd['nexus'] + b = mtd['raw'] + n_periods = self.get_expected_number_of_periods() + + self.assertTrue(type(a) == type(b)) + + #raise NotImplementedError() + if(isinstance(a,mantid.api._api.WorkspaceGroup)): + self.assertEqual(a.size(), b.size()) + self.assertEqual(a.size(), n_periods) + # Loop through each workspace in the group and apply some simple comaprison checks. + for i in range(0, a.size()): + self.do_check_workspace_shape(a[i], b[i]) + if self.enable_instrument_checking(): + self.do_check_instrument_applied(a[i], b[i]) + if self.enable_reference_result_checking(): + Integration(InputWorkspace=a[0], OutputWorkspace=self.__comparison_out_workspace_name) + else: + self.do_check_workspace_shape(a, b) + if self.enable_instrument_checking(): + self.do_check_instrument_applied(a, b) + if self.enable_reference_result_checking(): + Integration(InputWorkspace=a, OutputWorkspace=self.__comparison_out_workspace_name) + + def validate(self): + self.disableChecking.append('Instrument') + if self.enable_reference_result_checking(): + return self.__comparison_out_workspace_name, self.get_integrated_reference_workspace_filename() + else: + return True + + + diff --git a/Code/Mantid/Testing/SystemTests/tests/analysis/LoadEmbeddedInstrumentInfo.py b/Code/Mantid/Testing/SystemTests/tests/analysis/LoadEmbeddedInstrumentInfo.py new file mode 100644 index 000000000000..ab56356edd2d --- /dev/null +++ b/Code/Mantid/Testing/SystemTests/tests/analysis/LoadEmbeddedInstrumentInfo.py @@ -0,0 +1,31 @@ +import stresstesting +from mantid.simpleapi import * + +""" +Here testing against embedded instrument info in different raw file formats + +This include to test that embedded information in raw ISIS Nexus file formats +get loaded correctly. + +""" + +# here test against a custom made ISIS raw hist nexus file created by Freddie +# where the A1_window has be, for the purpose of testing, been put at a +# completely wrong location of (0,3,0) +class ISISRawHistNexus(stresstesting.MantidStressTest): + + def runTest(self): + + # ISIS raw hist nexus file with A1_window at location (0,3,0) + MAPS00018314_raw_ISIS_hist = Load('MAPS00018314.nxs') + + def validate(self): + + MAPS00018314_raw_ISIS_hist = mtd['MAPS00018314_raw_ISIS_hist'] + inst = MAPS00018314_raw_ISIS_hist.getInstrument() + A1window = inst.getComponentByName('MAPS/A1_window') + + if str(A1window.getPos()) != '[0,3,0]' : + return False + + return True \ No newline at end of file diff --git a/Code/Mantid/Testing/SystemTests/tests/analysis/LoadLotsOfFiles.py b/Code/Mantid/Testing/SystemTests/tests/analysis/LoadLotsOfFiles.py new file mode 100644 index 000000000000..f3934442d959 --- /dev/null +++ b/Code/Mantid/Testing/SystemTests/tests/analysis/LoadLotsOfFiles.py @@ -0,0 +1,283 @@ +from mantid.simpleapi import * +from mantid.api import FrameworkManager +import copy +import os +import re +import stresstesting + +BANNED_FILES = ['992 Descriptions.txt', + 'BASIS_AutoReduction_Mask.xml', + 'BioSANS_dark_current.xml', + 'BioSANS_empty_cell.xml', + 'BioSANS_empty_trans.xml', + 'BioSANS_exp61_scan0004_0001.xml', + 'BioSANS_flood_data.xml', + 'BioSANS_sample_trans.xml', + 'CNCS_TS_2008_08_18.dat', + 'DISF_NaF.cdl', + 'det_corrected7.dat', + 'det_LET_cycle12-3.dat', + 'eqsans_configuration.1463', + 'FLAT_CELL.061', + 'HYSA_mask.xml', + 'IN10_P3OT_350K.inx', + 'IN13_16347.asc', + 'IN16_65722.asc', + 'IP0005.dat', + 'batch_input.csv', + 'mar11015.msk', + 'LET_hard.msk', #It seems loade does not understand it? + 'MASK.094AA', + 'MASKSANS2D_094i_RKH.txt', + 'MASKSANS2D.091A', + 'MASKSANS2Doptions.091A', + 'MaskSANS2DReductionGUI.txt', + 'MaskSANS2DReductionGUI_MaskFiles.txt', + 'MaskSANS2DReductionGUI_LimitEventsTime.txt', + 'MAP17269.raw', # Don't need to check multiple MAPS files + 'MAP17589.raw', + 'MER06399.raw', # Don't need to check multiple MERLIN files + 'PG3_11485-1.dat', # Generic load doesn't do very well with ASCII files + 'PG3_2538_event.nxs', # Don't need to check all of the PG3 files + 'PG3_9829_event.nxs', + 'REF_M_9684_event.nxs', + 'REF_M_9709_event.nxs', + 'SANS2D_periodTests.csv', + 'SANS2D_992_91A.csv', + 'SANS2D_mask_batch.csv', + 'sans2d_reduction_gui_batch.csv', + 'squaricn.phonon', + 'squaricn.castep', + 'target_circles_mask.xml', + 'linked_circles_mask.xml', + 'testCansas1DMultiEntry.xml', + 'Wish_Diffuse_Scattering_ISAW_UB.mat', + 'WSH_test.dat', + 'SANS2D_multiPeriodTests.csv', + 'SANS2D_periodTests.csv', + 'DIRECTM1_15785_12m_31Oct12_v12.dat', + 'MaskSANS2DReductionGUI.txt', + 'sans2d_reduction_gui_batch.csv' + 'MANTID_FLAT_CELL.115', + 'MaskLOQData.txt', + 'DIRECTHAB.983', + 'loq_batch_mode_reduction.csv', + 'det_corrected7.nxs', # this file can be loaded by LoadDetectorInfo but I am not sure if generic loader should ever deal with it + 'poldi2013n006903.hdf', + 'poldi2013n006904.hdf', + 'poldi2014n019874.hdf', + 'poldi2014n019881.hdf' + ] + +EXPECTED_EXT = '.expected' + +BANNED_REGEXP = [r'SANS2D\d+.log$', + r'SANS2D00000808_.+.txt$', + r'.*_reduction.log$', + r'.+_characterization_\d+_\d+_\d+.*\.txt', + r'.*\.cal', + r'.*\.detcal', + r'.*Grouping\.xml', + r'.*\.map', + r'.*\.irf', + r'.*\.hkl', + r'EVS.*\.raw', + r'.*_pulseid\.dat'] + +# This list stores files that will be loaded first. +# Implemented as simple solution to avoid failures on +# WinXP where small files have trouble allocating larger +# amounts of contiguous memory. +# Usage of XP is getting lower so we don't want to compromise the +# performance of the code elsewhere just to pass here +PRIORITY_FILES = ['HYS_13658_event.nxs', + 'ILLIN5_Sample_096003.nxs', + 'ILLIN5_Vana_095893.nxs'] + +def useDir(direc): + """Only allow directories that aren't test output or + reference results.""" + if "reference" in direc: + return False + if config["defaultsave.directory"] == direc: + return False + return ("Data" in direc) + +def useFile(direc, filename): + """Returns (useFile, abspath)""" + # if it is an -stamp file then assume these are cmake created files + if filename.endswith("-stamp"): + return (False, filename) + + # list of explicitly banned files at the top of this script + if filename in BANNED_FILES: + return (False, filename) + + # is an 'expected' file + if filename.endswith(EXPECTED_EXT): + return (False, filename) + + # list of banned files by regexp + for regexp in BANNED_REGEXP: + if re.match(regexp, filename, re.I) is not None: + return (False, filename) + + filename = os.path.join(direc, filename) + if os.path.isdir(filename): + return (False, filename) + return (True, filename) + +class LoadLotsOfFiles(stresstesting.MantidStressTest): + def __getDataFileList__(self): + # get a list of directories to look in + dirs = config['datasearch.directories'].split(';') + dirs = [item for item in dirs if useDir(item)] + print "Looking for data files in:", ', '.join(dirs) + + # Files and their corresponding sizes. the low-memory win machines + # fair better loading the big files first + files = {} + priority_abspaths = copy.deepcopy(PRIORITY_FILES) + for direc in dirs: + myFiles = os.listdir(direc) + for filename in myFiles: + (good, fullpath) = useFile(direc, filename) + #print "***", good, filename + if good: + files[fullpath] = os.path.getsize(fullpath) + try: + cur_index = PRIORITY_FILES.index(filename) + priority_abspaths[cur_index] = fullpath + except ValueError: + pass + + datafiles = sorted(files, key=lambda key: files[key], reverse=True) + + # Put the priority ones first + for insertion_index, fname in enumerate(priority_abspaths): + try: + cur_index = datafiles.index(fname) + except ValueError: + continue + value = datafiles.pop(cur_index) + datafiles.insert(insertion_index, fname) + + return datafiles + + def __runExtraTests__(self, wksp, filename): + """Runs extra tests that are specified in '.expected' files + next to the data files""" + expected = filename + EXPECTED_EXT + if not os.path.exists(expected): #file exists + return True + if os.path.getsize(expected) <= 0: #non-zero length + return True + + # Eval statement will use current scope. Allow access to + # mantid module + import mantid + + print "Found an expected file '%s' file" % expected + expectedfile = open(expected) + tests = expectedfile.readlines() + failed = [] # still run all of the tests + for test in tests: + test = test.strip() + result = eval(test) + if not (result == True): + failed.append((test, result)) + if len(failed) > 0: + for item in failed: + print " Failed test '%s' returned '%s' instead of 'True'" % (item[0], item[1]) + return False + return True + + + def __loadAndTest__(self, filename): + """Do all of the real work of loading and testing the file""" + print "----------------------------------------" + print "Loading '%s'" % filename + from mantid.api import Workspace + from mantid.api import IMDEventWorkspace + # Output can be a tuple if the Load algorithm has extra output properties + # but the output workspace should always be the first argument + outputs = Load(filename) + if type(outputs) == tuple: + wksp = outputs[0] + else: + wksp = outputs + + if not isinstance(wksp, Workspace): + print "Unexpected output type from Load algorithm: Type found=%s" % str(type(outputs)) + return False + + if wksp is None: + print 'Load returned None' + return False + + # generic checks + if wksp.getName() is None or len(wksp.getName()) <= 0: + print "Workspace does not have a name" + del wksp + return False + + id = wksp.id() + if id is None or len(id) <= 0: + print "Workspace does not have an id" + del wksp + return False + + # checks based on workspace type + if hasattr(wksp, "getNumberHistograms"): + if wksp.getNumberHistograms() <= 0: + print "Workspace has zero histograms" + del wksp + return False + if "managed" not in id.lower() and wksp.getMemorySize() <= 0: + print "Workspace takes no memory: Memory used=" + str(wksp.getMemorySize()) + del wksp + return False + + # checks for EventWorkspace + if hasattr(wksp, "getNumberEvents"): + if wksp.getNumberEvents() <= 0: + print "EventWorkspace does not have events" + del wksp + return False + + # do the extra checks + result = self.__runExtraTests__(wksp, filename) + + # cleanup + del wksp + return result + + def runTest(self): + """Main entry point for the test suite""" + files = self.__getDataFileList__() + + # run the tests + failed = [] + for filename in files: + try: + if not self.__loadAndTest__(filename): + print "FAILED TO LOAD '%s'" % filename + failed.append(filename) + except Exception, e: + print "FAILED TO LOAD '%s' WITH ERROR:" % filename + print e + failed.append(filename) + finally: + # Clear everything for the next test + FrameworkManager.Instance().clear() + + # final say on whether or not it 'worked' + print "----------------------------------------" + if len(failed) != 0: + print "SUMMARY OF FAILED FILES" + for filename in failed: + print filename + raise RuntimeError("Failed to load %d of %d files" \ + % (len(failed), len(files))) + else: + print "Successfully loaded %d files" % len(files) diff --git a/Code/Mantid/Testing/SystemTests/tests/analysis/LoadLotsOfInstruments.py b/Code/Mantid/Testing/SystemTests/tests/analysis/LoadLotsOfInstruments.py new file mode 100644 index 000000000000..3736d6c01576 --- /dev/null +++ b/Code/Mantid/Testing/SystemTests/tests/analysis/LoadLotsOfInstruments.py @@ -0,0 +1,78 @@ +from mantid.simpleapi import * +from mantid.api import FrameworkManager +import os +import re +import glob +import stresstesting + +EXPECTED_EXT = '.expected' + +class LoadLotsOfInstruments(stresstesting.MantidStressTest): + def __getDataFileList__(self): + # get a list of directories to look in + direc = config['instrumentDefinition.directory'] + print "Looking for instrument definition files in: %s" % direc + cwd = os.getcwd() + os.chdir(direc) + myFiles = glob.glob("*Definition*.xml") + os.chdir(cwd) + # Files and their corresponding sizes. the low-memory win machines + # fair better loading the big files first + files = [] + for filename in myFiles: + files.append(os.path.join(direc, filename)) + files.sort() + return files + + + def __loadAndTest__(self, filename): + """Do all of the real work of loading and testing the file""" + print "----------------------------------------" + print "Loading '%s'" % filename + wksp = LoadEmptyInstrument(filename) + if wksp is None: + return False + + # TODO standard tests + if wksp.getNumberHistograms() <= 0: + del wksp + return False + if wksp.getMemorySize() <= 0: + print "Workspace takes no memory: Memory used=" + str(wksp.getMemorySize()) + del wksp + return False + + # cleanup + del wksp + return True + + def runTest(self): + """Main entry point for the test suite""" + files = self.__getDataFileList__() + + # run the tests + failed = [] + for filename in files: + try: + if not self.__loadAndTest__(filename): + print "FAILED TO LOAD '%s'" % filename + failed.append(filename) + except Exception, e: + print "FAILED TO LOAD '%s' WITH ERROR:" % filename + print e + failed.append(filename) + finally: + # Clear everything for the next test + FrameworkManager.Instance().clear() + + # final say on whether or not it 'worked' + print "----------------------------------------" + if len(failed) != 0: + print "SUMMARY OF FAILED FILES" + for filename in failed: + print filename + raise RuntimeError("Failed to load %d of %d files" \ + % (len(failed), len(files))) + else: + print "Successfully loaded %d files" % len(files) + print files diff --git a/Code/Mantid/Testing/SystemTests/tests/analysis/LoadMuonNexusTest.py b/Code/Mantid/Testing/SystemTests/tests/analysis/LoadMuonNexusTest.py new file mode 100644 index 000000000000..a682f38210c1 --- /dev/null +++ b/Code/Mantid/Testing/SystemTests/tests/analysis/LoadMuonNexusTest.py @@ -0,0 +1,17 @@ +import stresstesting +from mantid.simpleapi import * + +class LoadMuonNexusTest(stresstesting.MantidStressTest): + + def runTest(self): + # EMU03087 is an old data file produced by CONVERT_NEXUS from MCS binary files. + # Checked specifically because stores resulution (used to calculate FirstGoodData) + # as NX_FLOAT32 opposed to NX_INT32 in other Muon files. + loadResult = LoadMuonNexus(Filename = "EMU03087.nxs", + OutputWorkspace = "EMU03087") + + firstGoodData = loadResult[3] + self.assertDelta(firstGoodData, 0.416, 0.0001) + + def cleanup(self): + mtd.remove("EMU03087") diff --git a/Code/Mantid/Testing/SystemTests/tests/analysis/LoadTest.py b/Code/Mantid/Testing/SystemTests/tests/analysis/LoadTest.py new file mode 100644 index 000000000000..8b7aa2141357 --- /dev/null +++ b/Code/Mantid/Testing/SystemTests/tests/analysis/LoadTest.py @@ -0,0 +1,222 @@ +""" + Extends the basic test of the Load algorithm done by the LoadLotsOfFiles + test to encompass the complex multi-file loading that the Load + algorithm is capable of. +""" +import stresstesting + +from mantid.api import AnalysisDataService, IEventWorkspace, MatrixWorkspace, WorkspaceGroup +from mantid.simpleapi import Load + +import unittest + +DIFF_PLACES = 8 + +class LoadTest(stresstesting.MantidStressTest): + + def runTest(self): + self._success = False + + # Custom code to create and run this single test suite + # and then mark as success or failure + suite = unittest.TestSuite() + suite.addTest( unittest.makeSuite(LoadTests, "test") ) + runner = unittest.TextTestRunner() + # Run using either runner + res = runner.run(suite) + if res.wasSuccessful(): + self._success = True + else: + self._success = False + + def validate(self): + return self._success + +#------------------------------------------------------------------------------ +# work horse +class LoadTests(unittest.TestCase): + + wsname = "__LoadTest" + cleanup_names = [] + + def tearDown(self): + self.cleanup_names.append(self.wsname) + for name in self.cleanup_names: + try: + AnalysisDataService.remove(name) + except KeyError: + pass + self.cleanup_names = [] + + def test_csv_list_with_same_instrument_produces_single_group(self): + data = Load("OFFSPEC10791,10792,10793.raw", OutputWorkspace = self.wsname) + + self.assertTrue(isinstance(data, WorkspaceGroup)) + self.assertEquals(6, data.getNumberOfEntries()) + ads_names = ["OFFSPEC00010791_1", "OFFSPEC00010791_2", + "OFFSPEC00010792_1", "OFFSPEC00010792_2", + "OFFSPEC00010793_1", "OFFSPEC00010793_2"] + for name in ads_names: + self.assertTrue(name in AnalysisDataService) + + deleted_names = ["OFFSPEC10791", "OFFSPEC10792", "OFFSPEC10793"] + for name in deleted_names: + self.assertTrue(name not in AnalysisDataService) + + self.cleanup_names = ads_names + + def test_csv_list_with_different_instrument_produces_single_group(self): + # Combine test of different instruments with giving the output name + # the same name as one of the members of the group + self.wsname = "LOQ99631" + data = Load("LOQ99631.RAW, CSP85423.raw", OutputWorkspace = self.wsname) + + self.assertTrue(isinstance(data, WorkspaceGroup)) + self.assertEquals(3, data.getNumberOfEntries()) + ads_names = ["LOQ99631", "CSP85423_1", "CSP85423_2"] + for name in ads_names: + self.assertTrue(name in AnalysisDataService) + + deleted_names = ["CSP85423"] + for name in deleted_names: + self.assertTrue(name not in AnalysisDataService) + + self.cleanup_names = ads_names + self.wsname = "__LoadTest" + + def test_extra_properties_passed_to_loader(self): + data = Load("CNCS_7860_event.nxs", OutputWorkspace = self.wsname, + BankName = "bank1", SingleBankPixelsOnly = False) + + self.assertTrue(isinstance(data, IEventWorkspace)) + self.assertEquals(1740, data.getNumberEvents()) + + def test_extra_properties_passed_to_loader_for_multiple_files(self): + data = Load("EQSANS_1466_event.nxs,EQSANS_3293_event.nxs", OutputWorkspace = self.wsname, + BankName = "bank1", SingleBankPixelsOnly = False) + + self.assertTrue(isinstance(data, WorkspaceGroup)) + self.assertEquals(2, data.getNumberOfEntries()) + # Test number of events in each + self.assertEquals(740, data[0].getNumberEvents()) + self.assertEquals(105666, data[1].getNumberEvents()) + + def test_range_operator_loads_correct_number_of_files(self): + data = Load("TSC15352:15354.raw", OutputWorkspace = self.wsname) + + self.assertTrue(isinstance(data, WorkspaceGroup)) + self.assertEquals(3, data.getNumberOfEntries()) + + self.assertTrue(isinstance(data[0], MatrixWorkspace)) + self.assertTrue(isinstance(data[1], MatrixWorkspace)) + self.assertTrue(isinstance(data[2], MatrixWorkspace)) + + # Cursory check that the correct ones were loaded + self.assertTrue("TO96_2" in data[0].getTitle()) + self.assertTrue("TO96_3" in data[1].getTitle()) + self.assertTrue("TO96_4" in data[2].getTitle()) + + def test_stepped_range_operator_loads_correct_number_of_files(self): + data = Load("TSC15352:15354:2.raw", OutputWorkspace = self.wsname) + + self.assertTrue(isinstance(data, WorkspaceGroup)) + self.assertEquals(2, data.getNumberOfEntries()) + + self.assertTrue(isinstance(data[0], MatrixWorkspace)) + self.assertTrue(isinstance(data[1], MatrixWorkspace)) + + # Cursory check that the correct ones were loaded + self.assertTrue("TO96_2" in data[0].getTitle()) + self.assertTrue("TO96_4" in data[1].getTitle()) + + def test_plus_operator_sums_single_set_files(self): + data = Load("TSC15352+15353.raw", OutputWorkspace = self.wsname) + + self.assertTrue(isinstance(data, MatrixWorkspace)) + self.assertEquals(149, data.getNumberHistograms()) + self.assertEquals(24974, data.blocksize()) + + self.assertAlmostEqual(9.0, data.readX(2)[1], places = DIFF_PLACES) + self.assertAlmostEqual(46352.0, data.readY(2)[1], places = DIFF_PLACES) + self.assertAlmostEqual(215.29514625276622, data.readE(2)[1], places = DIFF_PLACES) + + deleted_names = ["TSC15352", "TSC15353"] + for name in deleted_names: + self.assertTrue(name not in AnalysisDataService) + + def test_plus_operator_sums_multiple_set_files_to_give_group(self): + summed_data = Load("TSC15352+15353.raw,TSC15352+15354.raw", OutputWorkspace = self.wsname) + + self.assertTrue(isinstance(summed_data, WorkspaceGroup)) + self.assertEquals(2, summed_data.getNumberOfEntries()) + + # First group + data = summed_data[0] + self.assertEquals(149, data.getNumberHistograms()) + self.assertEquals(24974, data.blocksize()) + + self.assertAlmostEqual(9.0, data.readX(2)[1], places = DIFF_PLACES) + self.assertAlmostEqual(46352.0, data.readY(2)[1], places = DIFF_PLACES) + self.assertAlmostEqual(215.29514625276622, data.readE(2)[1], places = DIFF_PLACES) + + # Second group + data = summed_data[1] + self.assertEquals(149, data.getNumberHistograms()) + self.assertEquals(24974, data.blocksize()) + + self.assertAlmostEqual(9.0, data.readX(2)[1], places = DIFF_PLACES) + self.assertAlmostEqual(35640.0, data.readY(2)[1], places = DIFF_PLACES) + self.assertAlmostEqual(188.78559267062727, data.readE(2)[1], places = DIFF_PLACES) + + deleted_names = ["TSC15352", "TSC15353", "TSC15354"] + for name in deleted_names: + self.assertTrue(name not in AnalysisDataService,) + + def test_sum_range_operator_sums_to_single_workspace(self): + data = Load("TSC15352-15353.raw", OutputWorkspace = self.wsname) + + self.assertTrue(isinstance(data, MatrixWorkspace)) + self.assertEquals(149, data.getNumberHistograms()) + self.assertEquals(24974, data.blocksize()) + + self.assertAlmostEqual(9.0, data.readX(2)[1], places = DIFF_PLACES) + self.assertAlmostEqual(46352.0, data.readY(2)[1], places = DIFF_PLACES) + self.assertAlmostEqual(215.29514625276622, data.readE(2)[1], places = DIFF_PLACES) + + def test_sum_range_operator_with_step_sums_to_single_workspace(self): + data = Load("TSC15352-15354:2.raw", OutputWorkspace = self.wsname) + + self.assertTrue(isinstance(data, MatrixWorkspace)) + self.assertEquals(149, data.getNumberHistograms()) + self.assertEquals(24974, data.blocksize()) + + self.assertAlmostEqual(9.0, data.readX(2)[1], places = DIFF_PLACES) + self.assertAlmostEqual(35640.0, data.readY(2)[1], places = DIFF_PLACES) + self.assertAlmostEqual(188.78559267062727, data.readE(2)[1], places = DIFF_PLACES) + + + def test_plus_operator_for_input_groups(self): + summed_data = Load("OFFSPEC10791+10792.raw", OutputWorkspace = self.wsname) + + self.assertTrue(isinstance(summed_data, WorkspaceGroup)) + self.assertEquals(2, summed_data.getNumberOfEntries()) + + # First group + data = summed_data[0] + self.assertEquals(245, data.getNumberHistograms()) + self.assertEquals(5000, data.blocksize()) + + self.assertAlmostEqual(25.0, data.readX(1)[1], places = DIFF_PLACES) + self.assertAlmostEqual(4.0, data.readY(1)[1], places = DIFF_PLACES) + self.assertAlmostEqual(2.0, data.readE(1)[1], places = DIFF_PLACES) + + # Second group + data = summed_data[1] + self.assertEquals(245, data.getNumberHistograms()) + self.assertEquals(5000, data.blocksize()) + + self.assertAlmostEqual(25.0, data.readX(1)[1], places = DIFF_PLACES) + self.assertAlmostEqual(1.0, data.readY(1)[1], places = DIFF_PLACES) + self.assertAlmostEqual(1.0, data.readE(1)[1], places = DIFF_PLACES) + +#==================================================================================== diff --git a/Code/Mantid/Testing/SystemTests/tests/analysis/LoadVesuvioTest.py b/Code/Mantid/Testing/SystemTests/tests/analysis/LoadVesuvioTest.py new file mode 100644 index 000000000000..ed37fc990702 --- /dev/null +++ b/Code/Mantid/Testing/SystemTests/tests/analysis/LoadVesuvioTest.py @@ -0,0 +1,228 @@ +import stresstesting + +from mantid.api import MatrixWorkspace, mtd +from mantid.simpleapi import LoadVesuvio + +import unittest + +DIFF_PLACES = 12 + +class VesuvioTests(unittest.TestCase): + + ws_name = "evs_raw" + + + def tearDown(self): + if self.ws_name in mtd: + mtd.remove(self.ws_name) + + #================== Success cases ================================ + def test_load_with_back_scattering_spectra_produces_correct_workspace(self): + self._run_load("14188", "3-134", "DoubleDifference") + + # Check some data + evs_raw = mtd[self.ws_name] + self.assertAlmostEqual(0.078968412230231877, evs_raw.readY(0)[1], places=DIFF_PLACES) + self.assertAlmostEqual(0.12162310222873171, evs_raw.readE(0)[1], places=DIFF_PLACES) + self.assertAlmostEqual(0.018091076761311387, evs_raw.readY(131)[1188], places=DIFF_PLACES) + self.assertAlmostEqual(0.063175962622448692, evs_raw.readE(131)[1188], places=DIFF_PLACES) + + def test_consecutive_runs_with_back_scattering_spectra_gives_expected_numbers(self): + self._run_load("14188-14190", "3-134", "DoubleDifference") + + # Check some data + evs_raw = mtd[self.ws_name] + self.assertAlmostEqual(0.12812011879757312, evs_raw.readY(0)[1], places=DIFF_PLACES) + self.assertAlmostEqual(0.07005709042418834, evs_raw.readE(0)[1], places=DIFF_PLACES) + self.assertAlmostEqual(0.038491709460370394, evs_raw.readY(131)[1188], places=DIFF_PLACES) + self.assertAlmostEqual(0.036783617369284975, evs_raw.readE(131)[1188], places=DIFF_PLACES) + + def test_non_consecutive_runs_with_back_scattering_spectra_gives_expected_numbers(self): + self._run_load("14188,14190", "3-134", "DoubleDifference") + + # Check some data + evs_raw = mtd[self.ws_name] + self.assertAlmostEqual(0.17509520926405386, evs_raw.readY(0)[1], places=DIFF_PLACES) + self.assertAlmostEqual(0.085651536076367191, evs_raw.readE(0)[1], places=DIFF_PLACES) + self.assertAlmostEqual(-0.027855932189430499, evs_raw.readY(131)[1188], places=DIFF_PLACES) + self.assertAlmostEqual(0.044991428219920804, evs_raw.readE(131)[1188], places=DIFF_PLACES) + + def test_load_with_forward_scattering_spectra_produces_correct_workspace(self): + self._run_load("14188", "135-198", "SingleDifference") + + # Check some data + evs_raw = mtd[self.ws_name] + self.assertAlmostEqual(-0.4421157823659172, evs_raw.readY(0)[1], places=DIFF_PLACES) + self.assertAlmostEqual(0.23849110331150025, evs_raw.readE(0)[1], places=DIFF_PLACES) + self.assertAlmostEqual(-0.030129475930755989, evs_raw.readY(63)[1188], places=DIFF_PLACES) + self.assertAlmostEqual(0.23849110331150025, evs_raw.readE(0)[1], places=DIFF_PLACES) + + def test_consecutive_runs_with_forward_scattering_spectra_gives_expected_numbers(self): + self._run_load("14188-14190", "135-198", "SingleDifference") + + # Check some data + evs_raw = mtd[self.ws_name] + self.assertAlmostEqual(-0.33023675686822429, evs_raw.readY(0)[1], places=DIFF_PLACES) + self.assertAlmostEqual(0.13839181298987582, evs_raw.readE(0)[1], places=DIFF_PLACES) + self.assertAlmostEqual(-0.0005762703884557574, evs_raw.readY(63)[1188], places=DIFF_PLACES) + self.assertAlmostEqual(0.022314627606989094, evs_raw.readE(63)[1188], places=DIFF_PLACES) + + def test_non_consecutive_runs_with_forward_scattering_spectra_gives_expected_numbers(self): + self._run_load("14188,14190", "135-198", "SingleDifference") + + # Check some data + evs_raw = mtd[self.ws_name] + self.assertAlmostEqual(-0.31382658620745474, evs_raw.readY(0)[1], places=DIFF_PLACES) + self.assertAlmostEqual(0.16935354944452052, evs_raw.readE(0)[1], places=DIFF_PLACES) + self.assertAlmostEqual(0.0013599866184859088, evs_raw.readY(63)[1188], places=DIFF_PLACES) + self.assertAlmostEqual(0.16935354944452052, evs_raw.readE(0)[1], places=DIFF_PLACES) + + def test_load_with_spectra_mixed_from_forward_backward_gives_expected_numbers(self): + self._run_load("14188", "134,135", "DoubleDifference") + + # Check some data + evs_raw = mtd[self.ws_name] + self.assertAlmostEqual(0.43816507168120111, evs_raw.readY(0)[1], places=DIFF_PLACES) + self.assertAlmostEqual(0.23224859590051541, evs_raw.readE(0)[1], places=DIFF_PLACES) + self.assertAlmostEqual(0.013611354662030284, evs_raw.readY(1)[1188], places=DIFF_PLACES) + self.assertAlmostEqual(0.031506182465619419, evs_raw.readE(1)[1188], places=DIFF_PLACES) + + def test_foilout_mode_gives_expected_numbers(self): + self._run_load("14188", "3", "FoilOut") + + evs_raw = mtd[self.ws_name] + self.assertAlmostEqual(18753.00, evs_raw.readY(0)[1], places=DIFF_PLACES) + self.assertAlmostEqual(136.94159338929865, evs_raw.readE(0)[1], places=DIFF_PLACES) + + def test_foilin_mode_gives_expected_numbers(self): + self._run_load("14188", "3", "FoilIn") + + evs_raw = mtd[self.ws_name] + self.assertAlmostEqual(37594.0, evs_raw.readY(0)[1], places=DIFF_PLACES) + self.assertAlmostEqual(193.89172236070317, evs_raw.readE(0)[1], places=DIFF_PLACES) + + def test_using_ip_file_adjusts_instrument_and_attaches_parameters(self): + self._run_load("14188", "3", "SingleDifference","IP0005.dat") + + # Check some data + evs_raw = mtd[self.ws_name] + det0 = evs_raw.getDetector(0) + param = det0.getNumberParameter("t0") + self.assertEqual(1, len(param)) + self.assertAlmostEqual(-0.4157, param[0],places=4) + + def test_sumspectra_set_to_true_gives_single_spectra_summed_over_all_inputs(self): + self._run_load("14188", "135-142", "SingleDifference","IP0005.dat",sum=True) + evs_raw = mtd[self.ws_name] + + # Verify + self.assertEquals(1, evs_raw.getNumberHistograms()) + self.assertAlmostEqual(-1.5288171762918328, evs_raw.readY(0)[0], places=DIFF_PLACES) + self.assertAlmostEqual(-0.079412793053402098, evs_raw.readY(0)[-1], places=DIFF_PLACES) + self.assertAlmostEqual(0.52109203357613976, evs_raw.readE(0)[0], places=DIFF_PLACES) + self.assertAlmostEqual(0.10617318614513051, evs_raw.readE(0)[-1], places=DIFF_PLACES) + + def test_sumspectra_with_multiple_groups_gives_number_output_spectra_as_input_groups(self): + self._run_load("14188", "135-148;152-165", "SingleDifference","IP0005.dat",sum=True) + + evs_raw = mtd[self.ws_name] + + # Verify + self.assertEquals(2, evs_raw.getNumberHistograms()) + self.assertAlmostEqual(-0.713877795283, evs_raw.readY(0)[0], places=DIFF_PLACES) + self.assertAlmostEqual(-3.00125465604, evs_raw.readY(1)[0], places=DIFF_PLACES) + self.assertAlmostEqual(0.6219299465, evs_raw.readE(0)[0], places=DIFF_PLACES) + self.assertAlmostEqual(0.676913729914, evs_raw.readE(1)[0], places=DIFF_PLACES) + + def _run_load(self, runs, spectra, diff_opt, ip_file="", sum=False): + LoadVesuvio(Filename=runs,OutputWorkspace=self.ws_name, + SpectrumList=spectra,Mode=diff_opt,InstrumentParFile=ip_file, + SumSpectra=sum) + + self._do_ads_check(self.ws_name) + + def expected_size(): + if sum: + if ";" in spectra: + return 2 + else: + return 1 + elif "-" in spectra: + elements = spectra.split("-") + min,max=(int(elements[0]), int(elements[1])) + return max - min + 1 + elif "," in spectra: + elements = spectra.strip().split(",") + return len(elements) + else: + return 1 + + self._do_size_check(self.ws_name, expected_size()) + loaded_data = mtd[self.ws_name] + if "Difference" in diff_opt: + self.assertTrue(not loaded_data.isHistogramData()) + else: + self.assertTrue(loaded_data.isHistogramData()) + + def _do_ads_check(self, name): + self.assertTrue(name in mtd) + self.assertTrue(type(mtd[name]) == MatrixWorkspace) + + def _do_size_check(self,name, expected_nhist): + loaded_data = mtd[name] + self.assertEquals(expected_nhist, loaded_data.getNumberHistograms()) + + #================== Failure cases ================================ + + def test_missing_spectra_property_raises_error(self): + self.assertRaises(RuntimeError, LoadVesuvio, Filename="14188", + OutputWorkspace=self.ws_name) + + def test_load_with_invalid_spectra_raises_error(self): + self.assertRaises(RuntimeError, LoadVesuvio, Filename="14188", + OutputWorkspace=self.ws_name, SpectrumList="200") + + def test_load_with_spectra_that_are_just_monitors_raises_error(self): + self.assertRaises(RuntimeError, LoadVesuvio, Filename="14188", + OutputWorkspace=self.ws_name, SpectrumList="1") + self.assertRaises(RuntimeError, LoadVesuvio, Filename="14188", + OutputWorkspace=self.ws_name, SpectrumList="1-2") + + def test_load_with_invalid_difference_option_raises_error(self): + self.assertRaises(ValueError, LoadVesuvio, Filename="14188", + OutputWorkspace=self.ws_name, Mode="Unknown",SpectrumList="3-134") + + def test_load_with_difference_option_not_applicable_to_current_spectra_raises_error(self): + self.assertRaises(ValueError, LoadVesuvio, Filename="14188", + OutputWorkspace=self.ws_name, Mode="",SpectrumList="3-134") + + def test_raising_error_removes_temporary_raw_workspaces(self): + self.assertRaises(RuntimeError, LoadVesuvio, Filename="14188,14199", # Second run is invalid + OutputWorkspace=self.ws_name, Mode="SingleDifference",SpectrumList="3-134") + + self._do_test_temp_raw_workspaces_not_left_around() + + def _do_test_temp_raw_workspaces_not_left_around(self): + self.assertTrue("__loadraw_evs" not in mtd) + self.assertTrue("__loadraw_evs_monitors" not in mtd) + + +#==================================================================================== + +class LoadVesuvioTest(stresstesting.MantidStressTest): + + def runTest(self): + self._success = False + # Custom code to create and run this single test suite + suite = unittest.TestSuite() + suite.addTest( unittest.makeSuite(VesuvioTests, "test") ) + runner = unittest.TextTestRunner() + # Run using either runner + res = runner.run(suite) + if res.wasSuccessful(): + self._success = True + else: + self._success = False + + def validate(self): + return self._success diff --git a/Code/Mantid/Testing/SystemTests/tests/analysis/MDWorkspaceTests.py b/Code/Mantid/Testing/SystemTests/tests/analysis/MDWorkspaceTests.py new file mode 100644 index 000000000000..29df48e4871b --- /dev/null +++ b/Code/Mantid/Testing/SystemTests/tests/analysis/MDWorkspaceTests.py @@ -0,0 +1,184 @@ +""" +Test some features of MDWorkspaces, such as +file-backed MDWorkspaces. +""" + +import stresstesting +import os +from mantid.simpleapi import * +from mantid.api import * +from mantid.kernel import * + +############################################################################### +class PlusMDTest(stresstesting.MantidStressTest): + + _saved_filename = None + + def compare_binned(self, wsname): + """ Compare the given workspace to the previously-binned original """ + BinMD(InputWorkspace=wsname,AlignedDim0='Q_lab_x, -3, 3, 100',AlignedDim1='Q_lab_y, -3, 3, 100',AlignedDim2='Q_lab_z, -3, 3, 100',ForceOrthogonal='1',OutputWorkspace="test_binned") + ws = mtd["test_binned"] + EqualToMD(LHSWorkspace=ws, RHSWorkspace=self.original_binned, OutputWorkspace='comparison') + comparison = mtd['comparison'] + for i in xrange(comparison.getNPoints()): + if not comparison.signalAt(i): + raise Exception("Difference in workspace %s vs original_binned at index %d" % (wsname, i)) + + def runTest(self): + # Some platforms can't clean up the open file handle on cncs.nxs from the last test, so run cleanup here as well + barefilename = "cncs.nxs" + config = ConfigService.Instance() + self._saved_filename = os.path.join(config["defaultsave.directory"], barefilename) + self.cleanup() + + # Load then convert to Q in the lab frame + LoadEventNexus(Filename=r'CNCS_7860_event.nxs',OutputWorkspace='cncs_nxs') + + ConvertToDiffractionMDWorkspace(InputWorkspace='cncs_nxs', OutputWorkspace='cncs_original', SplitInto=2) + alg = SaveMD(InputWorkspace='cncs_original', Filename=barefilename) + + self.assertDelta( mtd['cncs_original'].getNPoints(), 112266, 1) + BinMD(InputWorkspace='cncs_original',AlignedDim0='Q_lab_x, -3, 3, 100',AlignedDim1='Q_lab_y, -3, 3, 100',AlignedDim2='Q_lab_z, -3, 3, 100',ForceOrthogonal='1',OutputWorkspace='cncs_original_binned') + # Scale by 2 to account for summing + self.original_binned = mtd['cncs_original_binned'] + self.original_binned *= 2 + + # Load into memory + LoadMD(Filename='cncs.nxs',FileBackEnd='0',Memory='100',OutputWorkspace='cncs_mem') + + # ======== Mem + Mem =========== + LoadMD(Filename='cncs.nxs',FileBackEnd='0',OutputWorkspace='cncs_mem2') + PlusMD(LHSWorkspace="cncs_mem2", RHSWorkspace="cncs_mem", OutputWorkspace="cncs_mem2") + self.assertDelta( mtd['cncs_mem2'].getNPoints(), 112266*2, 1) + self.compare_binned('cncs_mem2') + DeleteWorkspace('cncs_mem2') + + # ======== File + mem, with write buffer =========== + LoadMD(Filename='cncs.nxs',FileBackEnd='1',Memory='100',OutputWorkspace='cncs_file') + PlusMD(LHSWorkspace="cncs_file", RHSWorkspace="cncs_mem", OutputWorkspace="cncs_file") + self.compare_binned('cncs_file') + SaveMD("cncs_file", UpdateFileBackEnd="1") + self.assertDelta( mtd['cncs_file'].getNPoints(), 112266*2, 1) + self.compare_binned('cncs_file') + DeleteWorkspace('cncs_file') + + # Refresh the original file + SaveMD(InputWorkspace='cncs_original', Filename='cncs.nxs') + + # ======== File + mem, with a small write buffer (only 1MB) ======== + LoadMD(Filename='cncs.nxs',FileBackEnd='1',Memory='1',OutputWorkspace='cncs_file_small_buffer') + PlusMD(LHSWorkspace="cncs_file_small_buffer", RHSWorkspace="cncs_mem", OutputWorkspace="cncs_file_small_buffer") + SaveMD("cncs_file_small_buffer", UpdateFileBackEnd="1") + self.assertDelta( mtd['cncs_file_small_buffer'].getNPoints(), 112266*2, 1) + self.compare_binned('cncs_file_small_buffer') + DeleteWorkspace('cncs_file_small_buffer') + + # Refresh the original file + SaveMD(InputWorkspace='cncs_original', Filename='cncs.nxs') + + # ======== File + mem, without a write buffer ======== + LoadMD(Filename='cncs.nxs',FileBackEnd='1',Memory='0',OutputWorkspace='cncs_file_nobuffer') + PlusMD(LHSWorkspace="cncs_file_nobuffer", RHSWorkspace="cncs_mem", OutputWorkspace="cncs_file_nobuffer") + SaveMD("cncs_file_nobuffer", UpdateFileBackEnd="1") + self.assertDelta( mtd['cncs_file_nobuffer'].getNPoints(), 112266*2, 1) + self.compare_binned('cncs_file_nobuffer') + DeleteWorkspace('cncs_file_nobuffer') + + # Refresh the original file + SaveMD(InputWorkspace='cncs_original', Filename='cncs.nxs') + + # ======== File + mem to a new (cloned) file ======== + LoadMD(Filename='cncs.nxs',FileBackEnd='1',Memory='100',OutputWorkspace='cncs_file') + PlusMD(LHSWorkspace="cncs_file", RHSWorkspace="cncs_mem", OutputWorkspace="cncs_added") + SaveMD("cncs_added", UpdateFileBackEnd="1") + self.compare_binned('cncs_added') + self.assertDelta( mtd['cncs_added'].getNPoints(), 112266*2, 1) + + # Make sure we delete the workspaces so the file handles are freed + workspaces_to_delete = ["cncs_file", "cncs_mem", "cncs_added"] + for name in workspaces_to_delete: + DeleteWorkspace(name) + + def doValidation(self): + # If we reach here, no validation failed + return True + + def cleanup(self): + """ + Remove files create during test + """ + if self._saved_filename is not None: + try: + os.remove(self._saved_filename) + Logger.get("MDWorkspaceTests").notice("Removed %s" % self._saved_filename) + except OSError: + Logger.get("MDWorkspaceTests").notice("Failed to remove %s" % self._saved_filename) + + # Plus the _clone version + filename = os.path.splitext(self._saved_filename)[0] + filename += '_clone.nxs' + try: + os.remove(filename) + Logger.get("MDWorkspaceTests").notice("Removed %s " % filename) + except OSError: + Logger.get("MDWorkspaceTests").notice("Failed to remove %s" % self._saved_filename) + +############################################################################### +class MergeMDTest(stresstesting.MantidStressTest): + + _saved_filenames = [] + + def make_files_to_merge_string(self): + filenames_string = '' + + for filename in self._saved_filenames: + filenames_string += filename + ',' + + filenames_string = filenames_string[:-1] # Remove trailing comma + + return filenames_string + + def runTest(self): + config = ConfigService.Instance() + + LoadEventNexus(Filename='CNCS_7860_event.nxs', + OutputWorkspace='CNCS_7860_event_NXS',CompressTolerance=0.1) + + for omega in xrange(0, 5): + print "Starting omega %03d degrees" % omega + CreateMDWorkspace(Dimensions='3',Extents='-5,5,-5,5,-5,5',Names='Q_sample_x,Q_sample_y,Q__sample_z',Units='A,A,A',SplitInto='3',SplitThreshold='200',MaxRecursionDepth='3', + MinRecursionDepth='3', OutputWorkspace='CNCS_7860_event_MD') + + # Convert events to MD events + AddSampleLog("CNCS_7860_event_NXS", "omega", "%s.0" % omega, "Number Series") + AddSampleLog("CNCS_7860_event_NXS", "chi", "%s" % 0.0, "Number Series") + AddSampleLog("CNCS_7860_event_NXS", "phi", "%s" % 0.0, "Number Series") + # V2 of ConvertToDiffractionMD needs Goniometer to be set on workspace. + SetGoniometer(Workspace='CNCS_7860_event_NXS',Axis0='omega,0,0,1,1',Axis1='chi,1,0,0,1',Axis2='phi,0,1,0,1') + + ConvertToDiffractionMDWorkspace(InputWorkspace='CNCS_7860_event_NXS',OutputWorkspace='CNCS_7860_event_MD',OutputDimensions='Q (sample frame)',LorentzCorrection='1', Append=True) + + barefilename = "CNCS_7860_event_rotated_%03d.nxs" % omega + filename = os.path.join(config["defaultsave.directory"], barefilename) + alg = SaveMD("CNCS_7860_event_MD", Filename=filename) + self._saved_filenames.append(filename) + # End for loop + filename = os.path.join(config["defaultsave.directory"], r'merged.nxs') + alg = MergeMDFiles(Filenames=self.make_files_to_merge_string(), OutputFilename=filename, OutputWorkspace='merged') + self._saved_filenames.append(filename) + + # 5 times the number of events in the output workspace. + self.assertDelta( mtd['merged'].getNPoints(), 553035, 1) + + def doValidation(self): + # If we reach here, no validation failed + return True + + def cleanup(self): + for filename in self._saved_filenames: + try: + os.remove(filename) + Logger.get("MDWorkspaceTests").notice("Removed %s" % filename) + except OSError: + Logger.get("MDWorkspaceTests").notice("Failed to remove %s" % filename) + diff --git a/Code/Mantid/Testing/SystemTests/tests/analysis/MuonLoadTest.py b/Code/Mantid/Testing/SystemTests/tests/analysis/MuonLoadTest.py new file mode 100644 index 000000000000..fd2042b52802 --- /dev/null +++ b/Code/Mantid/Testing/SystemTests/tests/analysis/MuonLoadTest.py @@ -0,0 +1,46 @@ +import stresstesting +from mantid.simpleapi import * + +class MuonLoadTest(stresstesting.MantidStressTest): + + def runTest(self): + # Create custom grouping + grouping = WorkspaceFactory.createTable() + grouping.addColumn("vector_int", "Detectors") + grouping.addRow([range(33,65)]) + grouping.addRow([range(1,33)]) + mtd.addOrReplace("MuonLoad_Grouping", grouping) + + # Create custom dead times + deadTimes = WorkspaceFactory.createTable() + deadTimes.addColumn("int", "Index") + deadTimes.addColumn("double", "Value") + for i in range(1, 65): + deadTimes.addRow([i, i * 0.01]) + mtd.addOrReplace("MuonLoad_DeadTimes", deadTimes) + + MuonLoad(Filename = "MUSR00015192", + DetectorGroupingTable = "MuonLoad_Grouping", + ApplyDeadTimeCorrection = True, + CustomDeadTimeTable = "MuonLoad_DeadTimes", + FirstPeriod = 1, + SecondPeriod = 0, + PeriodOperation = "-", + TimeZero = 0.6, + Xmin = 0.11, + Xmax = 10.0, + RebinParams = "0.032", + OutputType = "PairAsymmetry", + PairFirstIndex = 0, + PairSecondIndex = 1, + Alpha = 0.8, + OutputWorkspace = "MuonLoad_MUSR00015192" + ) + + def validate(self): + return "MuonLoad_MUSR00015192", "MuonLoad_MUSR00015192.nxs" + + def cleanup(self): + mtd.remove("MuonLoad_MUSR00015192") + mtd.remove("MuonLoad_Grouping") + mtd.remove("MuonLoad_DeadTimes") diff --git a/Code/Mantid/Testing/SystemTests/tests/analysis/OFFSPECLoadingTest.py b/Code/Mantid/Testing/SystemTests/tests/analysis/OFFSPECLoadingTest.py new file mode 100644 index 000000000000..fc44f4bb5dad --- /dev/null +++ b/Code/Mantid/Testing/SystemTests/tests/analysis/OFFSPECLoadingTest.py @@ -0,0 +1,17 @@ +from LoadAndCheckBase import * + +''' +Test File loading and basic data integrity checks of OFFSPEC data in Mantid. +''' +class OFFSPECLoadingTest(LoadAndCheckBase): + def get_raw_workspace_filename(self): + return "OFFSPEC00010791.raw" + + def get_nexus_workspace_filename(self): + return "OFFSPEC00010791.nxs" + + def get_expected_number_of_periods(self): + return 2 + + def get_integrated_reference_workspace_filename(self): + return "OFFSPEC00010791_1Integrated.nxs" \ No newline at end of file diff --git a/Code/Mantid/Testing/SystemTests/tests/analysis/OffspecSESANS.py b/Code/Mantid/Testing/SystemTests/tests/analysis/OffspecSESANS.py new file mode 100644 index 000000000000..3c726ab0433d --- /dev/null +++ b/Code/Mantid/Testing/SystemTests/tests/analysis/OffspecSESANS.py @@ -0,0 +1,26 @@ +from stresstesting import MantidStressTest +from mantid.simpleapi import mtd, config + +class OffspecSESANS(MantidStressTest): + + def skipTests(self): + skip = False + try: + import offspec + except ImportError: + skip = True + return skip + + def requiredFiles(self): + return ["OFFSPEC00010791.raw","OFFSPEC00010792.raw","OFFSPEC00010793.raw"] + + def runTest(self): + import offspec + binning=["2.0","0.2","12.0","2"] + config["default.instrument"] = "OFFSPEC" + offspec.nrSESANSP0Fn("10792","P055","109","119","2","1",binning) + offspec.nrSESANSFn("10791+10793","dPMMA","","P055pol", + "100","130","2","1","2","3009.9",binning,"2","0") + + def validate(self): + return "dPMMASESANS","OffspecSESANS.nxs" diff --git a/Code/Mantid/Testing/SystemTests/tests/analysis/OffspecSESANSP0.py b/Code/Mantid/Testing/SystemTests/tests/analysis/OffspecSESANSP0.py new file mode 100644 index 000000000000..e5325cbe5760 --- /dev/null +++ b/Code/Mantid/Testing/SystemTests/tests/analysis/OffspecSESANSP0.py @@ -0,0 +1,27 @@ +from stresstesting import MantidStressTest +from mantid.simpleapi import config,mtd + +class OffspecSESANSP0(MantidStressTest): + + def skipTests(self): + skip = False + try: + import offspec + except ImportError: + skip = True + return skip + + def requiredFiles(self): + return ["OFFSPEC00010792.raw"] + + def runTest(self): + import offspec + binning=["2.0","0.2","12.0","2"] + config["default.instrument"] = "OFFSPEC" + offspec.nrSESANSP0Fn("10792","P055","109","119","2","1",binning) + + def cleanup(self): + pass + + def validate(self): + return "P055pol","OffspecSESANSP0.nxs" diff --git a/Code/Mantid/Testing/SystemTests/tests/analysis/PEARLPowderDiffraction.py b/Code/Mantid/Testing/SystemTests/tests/analysis/PEARLPowderDiffraction.py new file mode 100644 index 000000000000..9e076c475a25 --- /dev/null +++ b/Code/Mantid/Testing/SystemTests/tests/analysis/PEARLPowderDiffraction.py @@ -0,0 +1,44 @@ +import stresstesting +from mantid.simpleapi import * + +class PEARLPowderDiffraction(stresstesting.MantidStressTest): + + sample = "PEARL00073987.raw" + calfile = "pearl_offset_11_4.cal" + groupfile = "pearl_group_11_2_TT88.cal" + reffile = "PEARLPowderDiffraction.nxs" + + def requiredFiles(self): + return [self.sample, self.calfile, self.groupfile, self.reffile] + + def runTest(self): + LoadRaw(Filename=self.sample, OutputWorkspace='work',LoadLogFiles='0') + ConvertUnits(InputWorkspace='work',OutputWorkspace='work',Target='Wavelength') + + LoadRaw(Filename=self.sample, OutputWorkspace='monitor73987',LoadLogFiles='0',SpectrumMax='1') + ConvertUnits(InputWorkspace='monitor73987',OutputWorkspace='monitor73987',Target='Wavelength') + CropWorkspace(InputWorkspace='monitor73987',OutputWorkspace='monitor73987', + XMin=0.03,XMax=6.0) + + MaskBins(InputWorkspace='monitor73987',OutputWorkspace='monitor73987',XMin=3.45,XMax=3.7) + MaskBins(InputWorkspace='monitor73987',OutputWorkspace='monitor73987',XMin=2.96,XMax=3.2) + MaskBins(InputWorkspace='monitor73987',OutputWorkspace='monitor73987',XMin=2.1,XMax=2.26) + MaskBins(InputWorkspace='monitor73987',OutputWorkspace='monitor73987',XMin=1.73,XMax=1.98) + + SplineBackground(InputWorkspace='monitor73987',OutputWorkspace='monitor73987',NCoeff=20) + NormaliseToMonitor(InputWorkspace='work',OutputWorkspace='work',MonitorWorkspace='monitor73987', + IntegrationRangeMin=0.6,IntegrationRangeMax=5.0) + ConvertUnits(InputWorkspace='work',OutputWorkspace='work',Target='TOF') + + rb_params = [1500,-0.0006,19900] + Rebin(InputWorkspace='work',OutputWorkspace='work',Params=rb_params) + AlignDetectors(InputWorkspace='work',OutputWorkspace='work', CalibrationFile=self.calfile) + DiffractionFocussing(InputWorkspace='work',OutputWorkspace='focus', + GroupingFileName=self.groupfile) + + ConvertUnits(InputWorkspace='focus',OutputWorkspace='focus',Target='TOF') + Rebin(InputWorkspace='focus',OutputWorkspace='focus',Params=rb_params) + CropWorkspace(InputWorkspace='focus',OutputWorkspace='focus',XMin=0.1) + + def validate(self): + return 'focus','PEARLPowderDiffraction.nxs' diff --git a/Code/Mantid/Testing/SystemTests/tests/analysis/PEARLSystemTest.py b/Code/Mantid/Testing/SystemTests/tests/analysis/PEARLSystemTest.py new file mode 100644 index 000000000000..35230dba3f33 --- /dev/null +++ b/Code/Mantid/Testing/SystemTests/tests/analysis/PEARLSystemTest.py @@ -0,0 +1,384 @@ +import stresstesting +from mantid.simpleapi import * +from mantid import * +import os +import numpy as n +from abc import ABCMeta, abstractmethod + +'''Test adapted from actual script used by the scientists''' +class PEARL_Reduction(stresstesting.MantidStressTest): + __metaclass__ = ABCMeta # Mark as an abstract class + + def __init__(self): + stresstesting.MantidStressTest.__init__(self) + self.attenfile = "PRL112_DC25_10MM_FF.OUT" + self.tofbinning="1500,-0.0006,19900" + self.calfile="pearl_offset_12_1.cal" + self.groupfile="pearl_group_12_1_TT70.cal" + self.vanfile="van_spline_TT70_cycle_12_1.nxs" + self.cycle="12_1" + self.instver="new2" + self.mode="all" + self.tt_mode="TT70" + self.saved_outfile = '' + self.saved_gssfile = '' + self.reference_nexus = '' + self.reference_gss = '' + self.reference_workspace = '' + + def runTest(self): + self.do_focus() + + def doValidation(self): + '''Override doValidation to vaildate two things at the same time''' + # reset validate() method to call validateNexus() instead + self.validate = self.validateNexus + res = self.validateWorkspaceToNeXus() + if not res: + return False + # reset validate() method to call validateGSS() instead + self.validate = self.validateGSS + res = self.validateASCII() + return res + + def cleanup(self): + '''Remove temporary files''' + if os.path.exists(self.saved_outfile): + os.remove(self.saved_outfile) + if os.path.exists(self.saved_gssfile): + os.remove(self.saved_gssfile) + + @abstractmethod + def do_focus(self): + raise NotImplementedError("Implmenent do_focus to do actual test.") + + def validateNexus(self): + '''Compare the result of reduction with the reference nexus file''' + return self.reference_workspace,self.reference_nexus + + def validateGSS(self): + '''Validate the created gss file''' + from mantid.api import FileFinder + return self.saved_gssfile,FileFinder.getFullPath(self.reference_gss) + + def PEARL_getlambdarange(self): + return 0.03,6.00 + + def PEARL_getmonitorspectrum(self, runno): + return 1 + + def PEARL_getfilename(self, run_number,ext): + digit=len(str(run_number)) + + numdigits=8 + filename="PEARL" + + for i in range(0,numdigits-digit): + filename=filename+"0" + + filename+=str(run_number)+"."+ext + return filename + + def PearlLoad(self, files,ext,outname): + + if type(files) is int: + infile=self.PEARL_getfilename(files,ext) + LoadRaw(Filename=infile,OutputWorkspace=outname,LoadLogFiles="0") + else: + loop=0 + num=files.split("_") + frange=range(int(num[0]),int(num[1])+1) + for i in frange: + infile=self.PEARL_getfilename(i,ext) + outwork="run"+str(i) + LoadRaw(Filename=infile,OutputWorkspace=outwork,LoadLogFiles="0") + loop=loop+1 + if loop == 2: + firstwk="run"+str(i-1) + secondwk="run"+str(i) + Plus(LHSWorkspace=firstwk,RHSWorkspace=secondwk,OutputWorkspace=outname) + mtd.remove(firstwk) + mtd.remove(secondwk) + elif loop > 2: + secondwk="run"+str(i) + Plus(LHSWorkspace=outname,RHSWorkspace=secondwk,OutputWorkspace=outname) + mtd.remove(secondwk) + return + + def PearlLoadMon(self, files,ext,outname): + + if type(files) is int: + infile=self.PEARL_getfilename(files,ext) + mspectra=self.PEARL_getmonitorspectrum(files) + LoadRaw(Filename=infile,OutputWorkspace=outname,SpectrumMin=mspectra,SpectrumMax=mspectra,LoadLogFiles="0") + else: + loop=0 + num=files.split("_") + frange=range(int(num[0]),int(num[1])+1) + mspectra=self.PEARL_getmonitorspectrum(int(num[0])) + for i in frange: + infile=self.PEARL_getfilename(i,ext) + outwork="mon"+str(i) + LoadRaw(Filename=infile,OutputWorkspace=outwork,SpectrumMin=mspectra,SpectrumMax=mspectra,LoadLogFiles="0") + loop=loop+1 + if loop == 2: + firstwk="mon"+str(i-1) + secondwk="mon"+str(i) + Plus(LHSWorkspace=firstwk,RHSWorkspace=secondwk,OutputWorkspace=outname) + mtd.remove(firstwk) + mtd.remove(secondwk) + elif loop > 2: + secondwk="mon"+str(i) + Plus(LHSWorkspace=outname,RHSWorkspace=secondwk,OutputWorkspace=outname) + mtd.remove(secondwk) + return + + + + def PEARL_getmonitor(self, number,ext,spline_terms=20): + + works="monitor"+str(number) + self.PearlLoadMon(number,ext,works) + ConvertUnits(InputWorkspace=works,OutputWorkspace=works,Target="Wavelength") + lmin,lmax=self.PEARL_getlambdarange() + CropWorkspace(InputWorkspace=works,OutputWorkspace=works,XMin=lmin,XMax=lmax) + ex_regions=n.zeros((2,4)) + ex_regions[:,0]=[3.45,3.7] + ex_regions[:,1]=[2.96,3.2] + ex_regions[:,2]=[2.1,2.26] + ex_regions[:,3]=[1.73,1.98] + + for reg in range(0,4): + MaskBins(InputWorkspace=works,OutputWorkspace=works,XMin=ex_regions[0,reg],XMax=ex_regions[1,reg]) + + SplineBackground(InputWorkspace=works,OutputWorkspace=works,WorkspaceIndex=0,NCoeff=spline_terms) + return works + + + def PEARL_read(self, number,ext,outname): + self.PearlLoad(number,ext,outname) + ConvertUnits(InputWorkspace=outname,OutputWorkspace=outname,Target="Wavelength") + monitor=self.PEARL_getmonitor(number,ext,spline_terms=20) + NormaliseToMonitor(InputWorkspace=outname,OutputWorkspace=outname,MonitorWorkspace=monitor,IntegrationRangeMin=0.6,IntegrationRangeMax=5.0) + ConvertUnits(InputWorkspace=outname,OutputWorkspace=outname,Target="TOF") + mtd.remove(monitor) + return + + def PEARL_focus(self, number,ext="raw",fmode="trans",ttmode="TT70",atten=True,van_norm=True): + + self.tt_mode=ttmode + self.mode=fmode + + work="work" + focus="focus" + + if type(number) is int: + outfile="PRL"+str(number)+".nxs" + gssfile="PRL"+str(number)+".gss" + outwork="PRL"+str(number) + else: + outfile="PRL"+number+".nxs" + gssfile="PRL"+number+".gss" + outwork="PRL"+number + + self.PEARL_read(number,ext,work) + Rebin(InputWorkspace=work,OutputWorkspace=work,Params=self.tofbinning) + AlignDetectors(InputWorkspace=work,OutputWorkspace=work,CalibrationFile=self.calfile) + DiffractionFocussing(InputWorkspace=work,OutputWorkspace=focus,GroupingFileName=self.groupfile) + + mtd.remove(work) + + for i in range(0,14): + output="mod"+str(i+1) + van="van"+str(i+1) + rdata="rdata"+str(i+1) + if (van_norm): + LoadNexus(Filename=self.vanfile,OutputWorkspace=van,EntryNumber=i+1) + ExtractSingleSpectrum(InputWorkspace=focus,OutputWorkspace=rdata,WorkspaceIndex=i) + Rebin(InputWorkspace=van,OutputWorkspace=van,Params=self.tofbinning) + ConvertUnits(InputWorkspace=rdata,OutputWorkspace=rdata,Target="TOF") + Rebin(InputWorkspace=rdata,OutputWorkspace=rdata,Params=self.tofbinning) + Divide(LHSWorkspace=rdata,RHSWorkspace=van,OutputWorkspace=output) + CropWorkspace(InputWorkspace=output,OutputWorkspace=output,XMin=0.1) + Scale(InputWorkspace=output,OutputWorkspace=output,Factor=10) + else: + ExtractSingleSpectrum(InputWorkspace=focus,OutputWorkspace=rdata,WorkspaceIndex=i) + ConvertUnits(InputWorkspace=rdata,OutputWorkspace=rdata,Target="TOF") + Rebin(InputWorkspace=rdata,OutputWorkspace=output,Params=self.tofbinning) + CropWorkspace(InputWorkspace=output,OutputWorkspace=output,XMin=0.1) + + mtd.remove(focus) + + if (self.mode=="all"): + CloneWorkspace(InputWorkspace="mod1",OutputWorkspace="bank1") + for i in range(1,9): + toadd="mod"+str(i+1) + Plus(LHSWorkspace="bank1",RHSWorkspace=toadd,OutputWorkspace="bank1") + Scale(InputWorkspace="bank1",OutputWorkspace="bank1",Factor=0.111111111111111) + SaveGSS(InputWorkspace="bank1",Filename=gssfile,Append=False,Bank=1) + ConvertUnits(InputWorkspace="bank1",OutputWorkspace="bank1",Target="dSpacing") + SaveNexus(Filename=outfile,InputWorkspace="bank1",Append=False) + for i in range(0,5): + tosave="mod"+str(i+10) + SaveGSS(InputWorkspace=tosave,Filename=gssfile,Append=True,Bank=i+2) + ConvertUnits(InputWorkspace=tosave,OutputWorkspace=tosave,Target="dSpacing") + SaveNexus(Filename=outfile,InputWorkspace=tosave,Append=True) + + for i in range(0,14): + output="mod"+str(i+1) + van="van"+str(i+1) + rdata="rdata"+str(i+1) + mtd.remove(rdata) + mtd.remove(van) + mtd.remove(output) + mtd.remove("bank1") + + elif (self.mode=="groups"): + CloneWorkspace(InputWorkspace="mod1",OutputWorkspace="group1") + CloneWorkspace(InputWorkspace="mod4",OutputWorkspace="group2") + CloneWorkspace(InputWorkspace="mod7",OutputWorkspace="group3") + for i in range(1,3): + toadd="mod"+str(i+1) + Plus(LHSWorkspace="group1",RHSWorkspace=toadd,OutputWorkspace="group1") + Scale(InputWorkspace="group1",OutputWorkspace="group1",Factor=0.333333333333) + for i in range(1,3): + toadd="mod"+str(i+4) + Plus(LHSWorkspace="group2",RHSWorkspace=toadd,OutputWorkspace="group2") + Scale(InputWorkspace="group2",OutputWorkspace="group2",Factor=0.333333333333) + for i in range(1,3): + toadd="mod"+str(i+7) + Plus(LHSWorkspace="group3",RHSWorkspace=toadd,OutputWorkspace="group3") + Scale(InputWorkspace="group3",OutputWorkspace="group3",Factor=0.333333333333) + Plus(LHSWorkspace="group2",RHSWorkspace="group3",OutputWorkspace="group23") + Scale(InputWorkspace="group23",OutputWorkspace="group23",Factor=0.5) + SaveGSS("group1",Filename=gssfile,Append=False,Bank=1) + ConvertUnits(InputWorkspace="group1",OutputWorkspace="group1",Target="dSpacing") + SaveNexus(Filename=outfile,InputWorkspace="group1",Append=False) + SaveGSS(InputWorkspace="group2",Filename=gssfile,Append=True,Bank=2) + ConvertUnits(InputWorkspace="group2",OutputWorkspace="group2",Target="dSpacing") + SaveNexus(Filename=outfile,InputWorkspace="group2",Append=True) + SaveGSS(InputWorkspace="group3",Filename=gssfile,Append=True,Bank=3) + ConvertUnits(InputWorkspace="group3",OutputWorkspace="group3",Target="dSpacing") + SaveNexus(Filename=outfile,InputWorkspace="group3",Append=True) + SaveGSS(InputWorkspace="group23",Filename=gssfile,Append=True,Bank=4) + ConvertUnits(InputWorkspace="group23",OutputWorkspace="group23",Target="dSpacing") + SaveNexus(Filename=outfile,InputWorkspace="group23",Append=True) + for i in range(0,3): + tosave="mod"+str(i+10) + SaveGSS(InputWorkspace=tosave,Filename=gssfile,Append=True,Bank=i+5) + ConvertUnits(InputWorkspace=tosave,OutputWorkspace=tosave,Target="dSpacing") + SaveNexus(Filename=outfile,InputWorkspace=tosave,Append=True) + for i in range(0,14): + output="mod"+str(i+1) + van="van"+str(i+1) + rdata="rdata"+str(i+1) + mtd.remove(rdata) + mtd.remove(van) + mtd.remove(output) + mtd.remove("group1") + mtd.remove("group2") + mtd.remove("group3") + mtd.remove("group23") + + elif (self.mode=="trans"): + CloneWorkspace(InputWorkspace="mod1",OutputWorkspace="bank1") + for i in range(1,9): + toadd="mod"+str(i+1) + Plus(LHSWorkspace="bank1",RHSWorkspace=toadd,OutputWorkspace="bank1") + Scale(InputWorkspace="bank1",OutputWorkspace="bank1",Factor=0.111111111111111) + if (atten): + ConvertUnits(InputWorkspace="bank1",OutputWorkspace="bank1",Target="dSpacing") + CloneWorkspace(InputWorkspace="bank1",OutputWorkspace=outwork+"_noatten") + self.PEARL_atten("bank1","bank1") + ConvertUnits(InputWorkspace="bank1",OutputWorkspace="bank1",Target="TOF") + + SaveGSS(InputWorkspace="bank1",Filename=gssfile,Append=False,Bank=1) + ConvertUnits(InputWorkspace="bank1",OutputWorkspace="bank1",Target="dSpacing") + SaveNexus(Filename=outfile,InputWorkspace="bank1",Append=False) + for i in range(0,9): + tosave="mod"+str(i+1) + ConvertUnits(InputWorkspace=tosave,OutputWorkspace=tosave,Target="dSpacing") + SaveNexus(Filename=outfile,InputWorkspace=tosave,Append=True) + + for i in range(0,14): + output="mod"+str(i+1) + van="van"+str(i+1) + rdata="rdata"+str(i+1) + mtd.remove(rdata) + mtd.remove(van) + mtd.remove(output) + mtd.remove("bank1") + + elif (self.mode=="mods"): + for i in range(0,12): + output="mod"+str(i+1) + van="van"+str(i+1) + rdata="rdata"+str(i+1) + if (i==0): + SaveGSS(InputWorkspace=output,Filename=gssfile,Append=False,Bank=i+1) + ConvertUnits(InputWorkspace=output,OutputWorkspace=output,Target="dSpacing") + SaveNexus(Filename=outfile,InputWorkspace=output,Append=False) + else: + SaveGSS(InputWorkspace=output,Filename=gssfile,Append=True,Bank=i+1) + ConvertUnits(InputWorkspace=output,OutputWorkspace=output,Target="dSpacing") + SaveNexus(Filename=outfile,InputWorkspace=output,Append=True) + + mtd.remove(rdata) + mtd.remove(van) + mtd.remove(output) + + else: + print "Sorry I don't know that mode", mode + return + + LoadNexus(Filename=outfile,OutputWorkspace=outwork) + + # temporary nxs file to be deleted on cleanup + self.saved_outfile = os.path.join(config['defaultsave.directory'],outfile) + # temporary gss file to be deleted on cleanup + self.saved_gssfile = os.path.join(config['defaultsave.directory'],gssfile).replace('.gss','-0.gss') + # name of the reference nxs file which is the same as outfile + self.reference_nexus = outfile.replace('PRL','PEARL') + # name of the reference gss file + self.reference_gss = gssfile.replace('.gss','-0.gss').replace('PRL','PEARL') + # workspace to be compared with reference_nexus + self.reference_workspace = outwork + + def PEARL_atten(self, work,outwork): + PearlMCAbsorption(Filename=self.attenfile,OutputWorkspace="wc_atten") + ConvertToHistogram(InputWorkspace="wc_atten",OutputWorkspace="wc_atten") + RebinToWorkspace(WorkspaceToRebin="wc_atten",WorkspaceToMatch=work,OutputWorkspace="wc_atten") + Divide(LHSWorkspace=work,RHSWorkspace="wc_atten",OutputWorkspace=outwork) + mtd.remove("wc_atten") + return + +#================================================================================ +class PEARL_Mode_trans(PEARL_Reduction): + def do_focus(self): + #self.reference_nexus = "PRL75318_75323.nxs" + return self.PEARL_focus("75318_75323","raw",fmode="trans",ttmode="TT70",atten=True) + + def doValidation(self): + '''Validate an additional workspace''' + res = PEARL_Reduction.doValidation(self) + if not res: + return False + self.validate = self.validateNoAtten + return self.validateWorkspaceToNeXus() + + def validateNoAtten(self): + return 'PRL75318_75323_noatten','PEARL75318_75323_noatten.nxs' + +#================================================================================ +class PEARL_Mode_all_Si(PEARL_Reduction): + def do_focus(self): + #self.reference_nexus = "PRL74798_74800.nxs" + return self.PEARL_focus("74798_74800","raw",fmode="all",ttmode="TT70",atten=False) + +#================================================================================ +class PEARL_Mode_all_CeO2(PEARL_Reduction): + def do_focus(self): + #self.reference_nexus = "PRL74795_74797.nxs" + return self.PEARL_focus("74795_74797","raw",fmode="all",ttmode="TT70",atten=False) + +#================================================================================ diff --git a/Code/Mantid/Testing/SystemTests/tests/analysis/POLDIAnalyseResidualsTest.py b/Code/Mantid/Testing/SystemTests/tests/analysis/POLDIAnalyseResidualsTest.py new file mode 100644 index 000000000000..529c1e01d65e --- /dev/null +++ b/Code/Mantid/Testing/SystemTests/tests/analysis/POLDIAnalyseResidualsTest.py @@ -0,0 +1,53 @@ +import stresstesting +from mantid.simpleapi import * +import numpy as np + +'''This test checks that the residual analysis algorithm for POLDI works correctly.''' +class POLDIAnalyseResidualsTest(stresstesting.MantidStressTest): + def runTest(self): + dataFiles = ["poldi2014n019874"] + + self.loadReferenceData(dataFiles) + self.runResidualAnalysis(dataFiles) + self.analyseResults(dataFiles) + + def loadReferenceData(self, filenames): + for dataFile in filenames: + Load(Filename="%s_fortran_fit.nxs" % (dataFile), OutputWorkspace="%s_fortran_fit" % (dataFile)) + Load(Filename="%s_fortran_residuals.nxs" % (dataFile), OutputWorkspace="%s_fortran_residuals" % (dataFile)) + + def runResidualAnalysis(self, filenames): + for dataFile in filenames: + LoadSINQFile(Instrument='POLDI',Filename=dataFile + ".hdf",OutputWorkspace=dataFile) + LoadInstrument(Workspace=dataFile, InstrumentName="POLDI", RewriteSpectraMap=True) + PoldiTruncateData(InputWorkspace=dataFile,OutputWorkspace=dataFile) + PoldiAnalyseResiduals(MeasuredCountData=dataFile, FittedCountData="%s_fortran_fit" % (dataFile), MaxIterations=1, OutputWorkspace=dataFile + "Residuals") + + def analyseResults(self, filenames): + for dataFile in filenames: + workspaceNameTemplate = "Comparison_%s" % (dataFile) + + referenceData = mtd["%s_fortran_residuals" % (dataFile)].dataY(0) + calculatedData = mtd["%sResiduals" % (dataFile)].dataY(0) + + self.assertEqual(calculatedData.shape[0], referenceData.shape[0], "Number of d-values does not match for %s (is: %i, should: %i)" % (dataFile, calculatedData.shape[0], referenceData.shape[0])) + + CreateWorkspace(referenceData, calculatedData, OutputWorkspace=workspaceNameTemplate) + + fitNameTemplate = "Fit_%s" % (dataFile) + Fit("name=LinearBackground", mtd[workspaceNameTemplate], StartX=np.min(referenceData), EndX=np.max(referenceData), Output=fitNameTemplate) + + fitResult = mtd[fitNameTemplate + "_Parameters"] + + slope = fitResult.cell(1, 1) + self.assertDelta(slope, 1.0, 1e-2, "Slope is larger than 1.0 for %s (is: %d)" % (dataFile, slope)) + + relativeSlopeError = fitResult.cell(1, 2) / slope + self.assertLessThan(relativeSlopeError, 5e-3, "Relative error of slope is too large for %s (is: %d)" % (dataFile, relativeSlopeError)) + + intercept = fitResult.cell(0, 1) + self.assertDelta(intercept, 0.0, 1e-3, "Intercept deviates too far from 0 %s (is: %d)" % (dataFile, intercept)) + + residuals = mtd[fitNameTemplate + "_Workspace"].dataY(2) + maxAbsoluteResidual = np.max(np.abs(residuals)) + self.assertLessThan(maxAbsoluteResidual, 1.0, "Maximum absolute residual is too large for %s (is: %d)" % (dataFile, maxAbsoluteResidual)) diff --git a/Code/Mantid/Testing/SystemTests/tests/analysis/POLDIAutoCorrelationTest.py b/Code/Mantid/Testing/SystemTests/tests/analysis/POLDIAutoCorrelationTest.py new file mode 100644 index 000000000000..1bc1ed974b37 --- /dev/null +++ b/Code/Mantid/Testing/SystemTests/tests/analysis/POLDIAutoCorrelationTest.py @@ -0,0 +1,56 @@ +import stresstesting +from mantid.simpleapi import * +import numpy as np + +'''This test checks that the results of PoldiAutoCorrelation match the expected outcome.''' +class POLDIAutoCorrelationTest(stresstesting.MantidStressTest): + def runTest(self): + dataFiles = ["poldi2013n006903", "poldi2013n006904", "poldi2014n019874", "poldi2014n019881"] + + self.loadReferenceData(dataFiles) + self.runAutoCorrelation(dataFiles) + self.analyseResults(dataFiles) + + def loadReferenceData(self, filenames): + for dataFile in filenames: + Load(Filename="%s_reference.nxs" % (dataFile), OutputWorkspace="%s_reference" % (dataFile)) + + def runAutoCorrelation(self, filenames): + for dataFile in filenames: + LoadSINQFile(Instrument='POLDI',Filename=dataFile + ".hdf",OutputWorkspace=dataFile) + LoadInstrument(Workspace=dataFile, InstrumentName="POLDI", RewriteSpectraMap=True) + PoldiTruncateData(InputWorkspace=dataFile,OutputWorkspace=dataFile) + PoldiAutoCorrelation(InputWorkspace=dataFile, wlenmin=1.1, wlenmax=5.0, OutputWorkspace=dataFile + "Corr") + + def analyseResults(self, filenames): + for dataFile in filenames: + workspaceNameTemplate = "Comparison_%s" % (dataFile) + + referenceData = mtd["%s_reference" % (dataFile)].dataY(0) + calculatedData = mtd["%sCorr" % (dataFile)].dataY(0) + + self.assertEqual(calculatedData.shape[0], referenceData.shape[0], "Number of d-values does not match for %s (is: %i, should: %i)" % (dataFile, calculatedData.shape[0], referenceData.shape[0])) + + CreateWorkspace(referenceData, calculatedData, OutputWorkspace=workspaceNameTemplate) + + fitNameTemplate = "Fit_%s" % (dataFile) + Fit("name=LinearBackground", mtd[workspaceNameTemplate], StartX=np.min(referenceData), EndX=np.max(referenceData), Output=fitNameTemplate) + + fitResult = mtd[fitNameTemplate + "_Parameters"] + + slope = fitResult.cell(1, 1) + self.assertDelta(slope, 1.0, 1e-4, "Slope is larger than 1.0 for %s (is: %d)" % (dataFile, slope)) + + relativeSlopeError = fitResult.cell(1, 2) / slope + self.assertLessThan(relativeSlopeError, 5e-4, "Relative error of slope is too large for %s (is: %d)" % (dataFile, relativeSlopeError)) + + intercept = fitResult.cell(0, 1) + self.assertDelta(intercept, 0.0, 1.0, "Intercept deviates too far from 0 %s (is: %d)" % (dataFile, intercept)) + + relativeInterceptError = fitResult.cell(0, 2) / intercept + self.assertLessThan(relativeInterceptError, 1, "Relative error of intercept is too large for %s (is: %d)" % (dataFile, relativeInterceptError)) + + residuals = mtd[fitNameTemplate + "_Workspace"].dataY(2) + maxAbsoluteResidual = np.max(np.abs(residuals)) + self.assertLessThan(maxAbsoluteResidual, 1.0, "Maximum absolute residual is too large for %s (is: %d)" % (dataFile, maxAbsoluteResidual)) + diff --git a/Code/Mantid/Testing/SystemTests/tests/analysis/POLDIFitPeaks1DTest.py b/Code/Mantid/Testing/SystemTests/tests/analysis/POLDIFitPeaks1DTest.py new file mode 100644 index 000000000000..db35acce4e8b --- /dev/null +++ b/Code/Mantid/Testing/SystemTests/tests/analysis/POLDIFitPeaks1DTest.py @@ -0,0 +1,99 @@ +import stresstesting +from mantid.simpleapi import * +import numpy as np + +'''Checking results of PoldiFitPeaks1D.''' +class POLDIFitPeaks1DTest(stresstesting.MantidStressTest): + # The errors of fitted parameters in version 2 are a bit small + # because of the "fabricated data", so a larger margin has to be allowed. + versionDeltas = {1: 2.0e-4, 2: 1.5e-3} + errorMultiplier = {1: 1.0, 2: 4.0} + + def runTest(self): + dataFiles = ["poldi2013n006904", "poldi_2_phases_theoretical"] + versions = [1, 2] + deleteList = [[], ['12-16', '10', '9']] + + self.loadReferenceCorrelationData(dataFiles) + self.loadReferenceFitResults(dataFiles) + self.runPeakSearch(dataFiles, deleteList) + self.runPoldiFitPeaks1D(dataFiles, versions) + self.analyseResults(dataFiles, versions) + + def loadReferenceCorrelationData(self, filenames): + for dataFile in filenames: + Load(Filename="%s_reference.nxs" % (dataFile), OutputWorkspace=dataFile) + + def runPeakSearch(self, filenames, deleteList): + for dataFile,deleteRowList in zip(filenames, deleteList): + PoldiPeakSearch(InputWorkspace=dataFile, + MinimumPeakSeparation=8, + OutputWorkspace="%s_Peaks" % (dataFile)) + + for deleteRows in deleteRowList: + DeleteTableRows(TableWorkspace="%s_Peaks" % (dataFile), Rows=deleteRows) + + def loadReferenceFitResults(self, filenames): + for dataFile in filenames: + Load(Filename="%s_reference_1DFit.nxs" % (dataFile), OutputWorkspace="%s_reference_1DFit" % (dataFile)) + + def runPoldiFitPeaks1D(self, filenames, versions): + for dataFile, version in zip(filenames, versions): + args = {"InputWorkspace": dataFile, + "FwhmMultiples": 4, + "PoldiPeakTable": "%s_Peaks" % (dataFile), + "OutputWorkspace": "%s_Peaks_Refined" % (dataFile), + "FitPlotsWorkspace": "%s_FitPlots" % (dataFile), + "Version": version} + + if version == 2: + args["AllowedOverlap"] = 0.1 + + PoldiFitPeaks1D(**args) + + # This test makes sure that: + # - standard deviations of position and relative fwhm are acceptably small (indicates reasonable fit) + # - refined peak positions are within one standard deviation of reference results obtained from existing program + # - fwhms do not deviate too much from reference results + # - currently, only the first 10 peaks are compared (as in the peak search test) + def analyseResults(self, filenames, versions): + for dataFile, version in zip(filenames, versions): + calculatedPeaks = mtd["%s_Peaks_Refined" % (dataFile)] + referencePeaks = mtd["%s_reference_1DFit" % (dataFile)] + self.assertEqual(calculatedPeaks.rowCount(), referencePeaks.rowCount()) + + positions = calculatedPeaks.column(2) + referencePositions = [float(x) for x in referencePeaks.column(0)] + + fwhms = calculatedPeaks.column(4) + referenceFwhms = [float(x) for x in referencePeaks.column(1)] + + for i in range(10): + # extract position and fwhm with uncertainties + positionparts = positions[i].split() + position = [float(positionparts[0]), float(positionparts[2])] + + fwhmparts = fwhms[i].split() + fwhm = [float(fwhmparts[0]), float(fwhmparts[2])] + + self.assertTrue(self.positionAcceptable(position)) + self.assertTrue(self.fwhmAcceptable(fwhm)) + + # find closest reference peak + deltas = np.array([np.abs(position[0] - x) for x in referencePositions]) + + + self.assertDelta(deltas.min(), 0.0, self.versionDeltas[version]) + minIndex = deltas.argmin() + + self.assertTrue(self.uncertainValueEqualsReference(position, referencePositions[minIndex], self.errorMultiplier[version])) + self.assertDelta(fwhm[0], referenceFwhms[minIndex], self.versionDeltas[version]) + + def positionAcceptable(self, position): + return position[1] < 1e-3 + + def fwhmAcceptable(self, fwhm): + return fwhm[1] < 3e-3 + + def uncertainValueEqualsReference(self, value, reference, sigmas): + return np.abs(value[0] - reference) < (sigmas * value[1]) diff --git a/Code/Mantid/Testing/SystemTests/tests/analysis/POLDIFitPeaks2DTest.py b/Code/Mantid/Testing/SystemTests/tests/analysis/POLDIFitPeaks2DTest.py new file mode 100644 index 000000000000..f741019bd6bb --- /dev/null +++ b/Code/Mantid/Testing/SystemTests/tests/analysis/POLDIFitPeaks2DTest.py @@ -0,0 +1,76 @@ +import stresstesting +from mantid.simpleapi import * +import numpy as np + +'''The system test currently checks that the calculation of 2D spectra +works correctly.''' +class POLDIFitPeaks2DTest(stresstesting.MantidStressTest): + def runTest(self): + dataFiles = ["poldi2013n006904"] + + self.loadAndPrepareData(dataFiles) + self.loadReferencePeakData(dataFiles) + self.loadReferenceSpectrum(dataFiles) + self.runCalculateSpectrum2D(dataFiles) + self.analyseResults(dataFiles) + + def loadAndPrepareData(self, filenames): + for dataFile in filenames: + LoadSINQFile(Instrument='POLDI',Filename=dataFile + ".hdf",OutputWorkspace=dataFile) + LoadInstrument(Workspace=dataFile, InstrumentName="POLDI", RewriteSpectraMap=True) + PoldiTruncateData(InputWorkspace=dataFile, OutputWorkspace=dataFile) + + def loadReferencePeakData(self, filenames): + for dataFile in filenames: + Load(Filename="%s_2d_reference_Peaks.nxs" % (dataFile), OutputWorkspace="%s_reference_Peaks" % (dataFile)) + + def loadReferenceSpectrum(self, filenames): + for dataFile in filenames: + Load(Filename="%s_2d_reference_Spectrum.nxs" % (dataFile), OutputWorkspace="%s_2d_reference_Spectrum" % (dataFile)) + Load(Filename="%s_1d_reference_Spectrum.nxs" % (dataFile), OutputWorkspace="%s_1d_reference_Spectrum" % (dataFile)) + + def runCalculateSpectrum2D(self, filenames): + for dataFile in filenames: + PoldiFitPeaks2D(InputWorkspace=dataFile, + PoldiPeakWorkspace="%s_reference_Peaks" % (dataFile), + PeakProfileFunction="Gaussian", + RefinedPoldiPeakWorkspace="%s_refined_Peaks" % (dataFile), + OutputWorkspace="%s_2d_calculated_Spectrum" % (dataFile), + Calculated1DSpectrum="%s_1d_calculated_Spectrum" % (dataFile), + MaximumIterations=0) + + def analyseResults(self, filenames): + for dataFile in filenames: + calculatedSpectrum = mtd["%s_2d_calculated_Spectrum" % (dataFile)] + referenceSpectrum = mtd["%s_2d_reference_Spectrum" % (dataFile)] + + self.assertEqual(calculatedSpectrum.getNumberHistograms(), referenceSpectrum.getNumberHistograms()) + + for i in range(calculatedSpectrum.getNumberHistograms()): + calHisto = calculatedSpectrum.readY(i) + + if not referenceSpectrum.getDetector(i).isMasked(): + refHisto = referenceSpectrum.readY(i) + + absDiff = np.fabs(refHisto - calHisto) + self.assertTrue(np.all(absDiff < 7e-4)) + else: + self.assertTrue(np.all(calHisto == 0.0)) + + spectra1D = ["%s_1d_%s_Spectrum"] + + for wsName in spectra1D: + calculatedSpectrum1D = mtd[wsName % (dataFile, "calculated")] + referenceSpectrum1D = mtd[wsName % (dataFile, "reference")] + + xDataCalc = calculatedSpectrum1D.readX(0) + yDataCalc = calculatedSpectrum1D.readY(0) + + xDataRef = referenceSpectrum1D.readX(0) + yDataRef = referenceSpectrum1D.readY(0) + + indices = np.nonzero(yDataRef) + maxDifference = np.abs(np.max((yDataCalc[indices] - yDataRef[indices]) / yDataCalc[indices])) + + self.assertTrue(np.all(xDataCalc == xDataRef)) + self.assertLessThan(maxDifference, 0.0031) diff --git a/Code/Mantid/Testing/SystemTests/tests/analysis/POLDIMergeTest.py b/Code/Mantid/Testing/SystemTests/tests/analysis/POLDIMergeTest.py new file mode 100644 index 000000000000..abea1836eb2a --- /dev/null +++ b/Code/Mantid/Testing/SystemTests/tests/analysis/POLDIMergeTest.py @@ -0,0 +1,64 @@ +import stresstesting +from mantid.simpleapi import * +import numpy as np + +'''This test checks that the results of PoldiMerge match the expected outcome.''' +class POLDIMergeTest(stresstesting.MantidStressTest): + def runTest(self): + self.testHappyCase() + self.testDifferentTimings() + + + def testDifferentTimings(self): + dataFiles = ["poldi2014n019874", "poldi2014n019881"] + self.loadData(dataFiles) + + try: + self.runPoldiMerge(dataFiles, "Dummy") + self.assertTrue(False) + except RuntimeError: + self.assertTrue(True) + + + def testHappyCase(self): + dataFiles = ["poldi2013n006903", "poldi2013n006904"] + sumWorkspace = "poldi_sum_6903_6904" + + self.loadData(dataFiles) + self.runPoldiMerge(dataFiles, sumWorkspace) + + self.loadReferenceData(sumWorkspace) + self.analyseResults(sumWorkspace) + + sumWorkspaceGroup = GroupWorkspaces(dataFiles) + workspaceGroupResult = self.testGroupWorkspace(sumWorkspaceGroup) + + # compare result of workspace group merging to previously checked results + self.compareWorkspaces(workspaceGroupResult, mtd['poldi_sum_6903_6904']) + + + + def testGroupWorkspace(self, groupWorkspace): + return PoldiMerge(groupWorkspace) + + + def loadData(self, filenames): + for dataFile in filenames: + LoadSINQFile(Instrument='POLDI',Filename=dataFile + ".hdf",OutputWorkspace=dataFile) + LoadInstrument(Workspace=dataFile, InstrumentName="POLDI", RewriteSpectraMap=True) + + def runPoldiMerge(self, workspaceNames, outputWorkspaceName): + PoldiMerge(WorkspaceNames=workspaceNames, OutputWorkspace=outputWorkspaceName) + + def loadReferenceData(self, outputWorkspaceName): + Load(Filename=outputWorkspaceName + "_reference.nxs", OutputWorkspace=outputWorkspaceName + "_reference") + + def analyseResults(self, outputWorkspaceName): + for i in range(mtd[outputWorkspaceName + '_reference'].getNumberHistograms()): + # reference spectrum is still in the "original order", so for one of the workspaces, the index has to be reversed. + self.assertTrue(np.array_equal(mtd[outputWorkspaceName].dataY(i), mtd[outputWorkspaceName + '_reference'].dataY(399 - i))) + + def compareWorkspaces(self, left, right): + for i in range(left.getNumberHistograms()): + self.assertTrue(np.array_equal(left.dataY(i), right.dataY(i))) + diff --git a/Code/Mantid/Testing/SystemTests/tests/analysis/POLDIPeakSearchTest.py b/Code/Mantid/Testing/SystemTests/tests/analysis/POLDIPeakSearchTest.py new file mode 100644 index 000000000000..bd495127818f --- /dev/null +++ b/Code/Mantid/Testing/SystemTests/tests/analysis/POLDIPeakSearchTest.py @@ -0,0 +1,46 @@ +import stresstesting +from mantid.simpleapi import * +import numpy as np + +'''This test checks that the results of PoldiAutoCorrelation match the expected outcome.''' +class POLDIPeakSearchTest(stresstesting.MantidStressTest): + def runTest(self): + dataFiles = ["poldi2013n006903", "poldi2013n006904"] + + self.loadReferenceCorrelationData(dataFiles) + self.loadReferencePeakData(dataFiles) + self.runPeakSearch(dataFiles) + self.analyseResults(dataFiles) + + def loadReferenceCorrelationData(self, filenames): + for dataFile in filenames: + Load(Filename="%s_reference.nxs" % (dataFile), OutputWorkspace=dataFile) + + def loadReferencePeakData(self, filenames): + for dataFile in filenames: + Load(Filename="%s_reference_Peaks.nxs" % (dataFile), OutputWorkspace="%s_reference_Peaks" % (dataFile)) + + def runPeakSearch(self, filenames): + for dataFile in filenames: + PoldiPeakSearch(InputWorkspace=dataFile, OutputWorkspace="%s_Peaks" % (dataFile)) + + def analyseResults(self, filenames): + for dataFile in filenames: + calculatedPeaks = mtd["%s_Peaks" % (dataFile)] + referencePeaks = mtd["%s_reference_Peaks" % (dataFile)] + self.assertEqual(calculatedPeaks.rowCount(), referencePeaks.rowCount()) + + positions = calculatedPeaks.column(2) + referencePositions = referencePeaks.column(0) + + # In this test we only compare positions, because the height + # and error estimates are derived differently than in the + # original software, so the results are not exactly the same. + # + # Most important in this case are peak positions. Since the order + # depends on height, it may be different, so the comparison can not + # be done 1:1. + for position in positions[:10]: + deltas = [np.abs(float(position) - x) for x in referencePositions] + + self.assertDelta(min(deltas), 0.0, 1e-6) diff --git a/Code/Mantid/Testing/SystemTests/tests/analysis/POLDITruncateDataTest.py b/Code/Mantid/Testing/SystemTests/tests/analysis/POLDITruncateDataTest.py new file mode 100644 index 000000000000..7921bd88ec29 --- /dev/null +++ b/Code/Mantid/Testing/SystemTests/tests/analysis/POLDITruncateDataTest.py @@ -0,0 +1,81 @@ +import stresstesting +from mantid.simpleapi import * + +'''This test checks that the results of PoldiAutoCorrelation match the expected outcome.''' +class POLDITruncateDataTest(stresstesting.MantidStressTest): + def runTest(self): + self.dataFileName = "poldi2013n006903" + + self.loadDataFiles() + self.workingAnalysis() + self.workspaceAlreadyCorrect() + self.workspaceTooSmall() + + def loadDataFiles(self,): + LoadSINQFile(Instrument='POLDI',Filename=self.dataFileName + ".hdf",OutputWorkspace=self.dataFileName) + LoadInstrument(Workspace=self.dataFileName, InstrumentName="POLDI") + + def workingAnalysis(self): + # In this method the "normal behavior" is tested, if everything is + # running as expected. + currentWs = mtd[self.dataFileName] + + # Input data has 10 extra bins + self.assertEqual(len(currentWs.readX(0)), 510) + + # First without keeping the additional data + truncated = PoldiTruncateData(currentWs) + + self.assertEqual(truncated.getNumberHistograms(), currentWs.getNumberHistograms()) + self.assertEqual(len(truncated.readX(0)), 500) + + # now keeping the additional data + truncated = PoldiTruncateData(currentWs, ExtraCountsWorkspaceName="extra") + + self.assertTrue(mtd.doesExist("extra")) + + extraWs = mtd['extra'] + + self.assertEqual(extraWs.getNumberHistograms(), 1) + extraCounts = extraWs.readY(0) + self.assertEqual(len(extraCounts), 10) + + # there are 13 counts in the first bin + self.assertEqual(extraCounts[0], 13.0) + + # and none in the others + for y in extraCounts[1:]: + self.assertEqual(y, 0.0) + + def workspaceAlreadyCorrect(self): + # This method tests expected behavior if the workspace + # already has the correct size + currentWs = mtd[self.dataFileName] + + cropped = CropWorkspace(currentWs, XMax=1497.0) + self.assertEqual(len(cropped.readX(0)), 500) + + truncated = PoldiTruncateData(cropped) + self.assertEqual(len(truncated.readX(0)), len(cropped.readX(0))) + + # Now there are no extra bins. + truncated = PoldiTruncateData(cropped, ExtraCountsWorkspaceName="moreCounts") + + # "extraCounts" should not be in the analysis data service + self.assertTrue(not mtd.doesExist("moreCounts")) + + def workspaceTooSmall(self): + # When the workspace is too small, the whole analysis fails. + # This is reasonable since the timing information is then + # very likely to be incorrect, so that the data file is not usable + currentWs = mtd[self.dataFileName] + + cropped = CropWorkspace(currentWs, XMax=1197.0) + self.assertEqual(len(cropped.readX(0)), 400) + + truncated = PoldiTruncateData(cropped) + self.assertTrue(truncated is None) + + PoldiTruncateData(InputWorkspace=cropped, OutputWorkspace="NamedWorkspaceTest") + self.assertTrue(not mtd.doesExist("NamedWorkspaceTest")) + diff --git a/Code/Mantid/Testing/SystemTests/tests/analysis/POLREFLoadingTest.py b/Code/Mantid/Testing/SystemTests/tests/analysis/POLREFLoadingTest.py new file mode 100644 index 000000000000..3383084c927d --- /dev/null +++ b/Code/Mantid/Testing/SystemTests/tests/analysis/POLREFLoadingTest.py @@ -0,0 +1,20 @@ +from LoadAndCheckBase import * + +''' +Test File loading and basic data integrity checks of POLREF data in Mantid. +''' +class POLREFLoadingTest(LoadAndCheckBase): + def get_raw_workspace_filename(self): + return "POLREF00004699.raw" + + def get_nexus_workspace_filename(self): + return "POLREF00004699.nxs" + + def get_expected_number_of_periods(self): + return 2 + + def get_integrated_reference_workspace_filename(self): + return "POLREF00004699_1Integrated.nxs" + + def get_expected_instrument_name(self): + return "POLREF" \ No newline at end of file diff --git a/Code/Mantid/Testing/SystemTests/tests/analysis/Peak2ConvCell_Test.py b/Code/Mantid/Testing/SystemTests/tests/analysis/Peak2ConvCell_Test.py new file mode 100644 index 000000000000..9263716cd454 --- /dev/null +++ b/Code/Mantid/Testing/SystemTests/tests/analysis/Peak2ConvCell_Test.py @@ -0,0 +1,930 @@ +#This script creates numerous PeaksWorkspaces for different Crystal Types and Centerings. Random errors +#are also introduced into the peak's. Each PeaksWorkspace is sent through the algorithm's FindPeaksMD, +#FindUBUsingFFT, and SelectByForm to determine the corresponding Primitive and Conventional cells. These +#results are tested against the theoretical results that should have been gotten + +#NOTE; THIS TEST TAKES AN EXTREMELY LONG TIME. DELETE "XXX" IN requiredFiles method to get it to run. +#!!!!!!!!! REPLACE THE "XXX" OR else !!!!!!!!!! + + +import stresstesting +import numpy +from numpy import matrix +from numpy import linalg +import math +import random +import mantid +from mantid.simpleapi import * +#from mantid.simpleapi import * +#TODO premultiply cases, fix up.. Maybe not needed Cause Conv cell was "Nigglied" +#TODO: SWitch cases, if use approx inequality, may get error cause low level code [does Not](does) premult but when it [should](should not) +class Peak2ConvCell_Test:#(stresstesting.MantidStressTest): + conventionalUB=numpy.zeros(shape=(3,3)) + Cubic=[1,3,5] + Tetr=[6,7,11,15,18,21] + Orth=[8,13,16,19,23,26,32,36,38,40,42] + Hex = [2,4,9,12,22,24] + Tricl=[31,44] + Mon=[28,29,30,33,34,35,43] + MonI=[17,27] + MonC=[10,14,20,25,37,39,41] + CentP=[3,11,12,21,22,31,32,33,34,35,44] + CentF=[1,16,26] + CentI=[2,4,5,6,7,8,9,10,14,15,17,18,19,20,24,25,27,37,39,41,42,43] + CentC=[10,13,14,17,20,23,25,27,28,29,30,36,37,38,39,40,41] + + + def CalcConventionalUB(self,a,b,c,alpha,beta,gamma,type): + Res= matrix([[0.,0.,0.],[0.,0.,0.],[0.,0.,0.]]) + + if type=='O': + + Res[0,0]=1./a + Res[1,1]=1./b + Res[2,2]=1./c + + elif type=='H': + Res[0,0]= a*1.0 + Res[1,0]= -a/2. + Res[1,1]= a*.866 + Res[2,2]=c*1.0 + Res=Res.I + else: + if alpha <=90: + self.conventionalUB = None + return None + Res[0,0] = a*1.0 + Res[1,1] = b*1.0 + Alpha = (alpha*math.pi/180) + Res[2,0] = c*math.cos( Alpha) + Res[2,2] = c*math.sin(Alpha) + # Now Nigglify the matrix( get 3 smallest sides) + + n =0 + YY=0 + if( a <=c): + n = (int)(-Res[2,0]/a) + YY= Res[2,0] +n*a + + else: + + n= (int)(-a*Res[2,0]/(c*c)-.5) + YY=n*Res[2,0]+a + + #print ["A",YY,n] + sgn=1 + if( a <= c): + + if ( math.fabs( YY + a ) < math.fabs( YY ) and a <= c ): + + YY += a + sgn = -1 + n=n+1 + + + elif( (YY+Res[2,0])*(YY+Res[2,0])+(n+1)*(n+1)*Res[2,2]*Res[2,2] < a*a): + + YY+=Res[2,0] + n=n+1 + sgn = -1 + + #print ["B",YY,sgn,n] + + if( n>0 ): + if( a <= c): + + Res[2,0]= sgn*YY + Res[2,2] *=sgn + + else: + + if( YY*Res[2,0]+n*Res[2,2]*Res[2,2] > 0): + sgn =-1 + + else: + sgn = 1 + Res[0,0]= sgn*YY + Res[0,2] =sgn*n*Res[2,2] + + + Res=Res.I + + + self.conventionalUB = Res + + return Res + + + def Niggli( self, Res): + RUB= Res.I + X=RUB*RUB.T + done = False + + while not done: + done = True + for i in range(2): + if X[i,i]>X[i+1,i+1]: + done = False + for j in range(3): + sav= RUB[i,j] + RUB[i,j]=RUB[i+1,j] + RUB[i+1,j]=sav + X=RUB*RUB.T + + if not done: + continue + #do bc,ac,then ab + for kk in range(3): + jj=2 + if kk>1: + jj=1 + i=0 + else: + i=jj-kk-1 + if X[i,i]<2*math.fabs(X[i,jj]): + sgn=1 + if X[i,jj] >0: + sgn=-1 + for j in range(3): + RUB[jj,j]=RUB[jj,j]+sgn*RUB[i,j] + done=False + X=RUB*RUB.T + + break + + + if( numpy.linalg.det( RUB )< 0): + for cc in range(3): + RUB[0,cc] *=-1 + + + return RUB.I + + def CalcNiggliUB( self,a, b,c,alpha, beta, gamma,type, Center): + + if( Center=='P'): + X = self.CalcConventionalUB( a,b,c,alpha,beta,gamma,type) + return X + + Res= matrix([[0.,0.,0.],[0.,0.,0.],[0.,0.,0.]]) + ConvUB = self.CalcConventionalUB(a,b,c,alpha,beta,gamma,type) + if( ConvUB== None): + return None + + ResP = numpy.matrix.copy(ConvUB) + ResP =ResP.I + + if( type=='H' and Center =='I'): + Center ='R' + + if( Center == 'I'): + + s1=1 + s2=1 + for r in range(0,3): + for cc in range(3): + + + if( cc==0): + if( r>0): + + s1 = (-1)**r + s2 =-s1 + + Res[r,cc] =ResP[0,cc]/2+s1*ResP[1,cc]/2+s2*ResP[2,cc]/2 + + + Res=Res.I + + elif( Center =='F'): + + if( type =='H' or type=='M'): + return None + + ss = [0,0,0] + + for r in range(3): + for cc in range(3): + + ss=[1,1,1] + ss[r]=0 + + Res[r,cc]=ss[0]*ResP[0,cc]/2+ss[1]*ResP[1,cc]/2+ss[2]*ResP[2,cc]/2 + + + + Res=Res.I + + elif( Center =='A' or Center=='B'or Center=='C'): + + if( type =='H' ): + return None + if( type =='M' and Center== 'B'): + return None + + r=2 + if( Center =='A') : + + r=0 + if( b==c and type=='O'):# result would be orthorhombic primitive + return None + + elif( Center =='B'): + + r=1 + if( a==c and type=='O'): + return None + + elif( a==b and type=='O'): + return None + + k=0 + + Res[r,0]= ResP[r,0] + Res[r,1]= ResP[r,1] + Res[r,2]= ResP[r,2] + for i in range(1,3): + + if( k==r): + k=k+1 + for cc in range(3) : + + R = (r+1)%3 + s = (-1)**i + + Res[k,cc]= ResP[(R)%3,cc]/2+s*ResP[(R+1)%3,cc]/2 + + k=k+1 + + Res=Res.I + + + + elif( Center =='R'): + + if( type != 'H' or alpha >120):#alpha =120 planar, >120 no go or c under a-b plane. + + self.conventionalUB=NiggliUB = None + return None + + #Did not work with 0 error. FindUBUsingFFT failed + #Alpha = alpha*math.pi/180 + + #Res[0,0] = a + #Res[1,0] =(a*math.cos( Alpha )) + #Res[1,1] = (a*math.sin( Alpha )) + #Res[2,0] =(a*math.cos( Alpha )) + #Res[2,1] =(a*Res[1,0] -Res[2,0]*Res[1,0])/Res[1,1] + #Res[2,2] =math.sqrt( a*a- Res[2,1]*Res[2,1]-Res[2,0]*Res[2,0]) + Res[0,0]=.5*a + Res[0,1]=math.sqrt(3)*a/2 + Res[0,2]=.5*b + Res[1,0]=-a + Res[1,1]=0 + Res[1,2]=.5*b + Res[2,0]=.5*a + Res[2,1]=-math.sqrt(3)*a/2 + Res[2,2]=.5*b + + + Rhomb2Hex= matrix([[1. ,-1., 0.],[-1. ,0., 1.],[-1. ,-1., -1.]]) + + self.conventionalUB=Rhomb2Hex*Res + Res=Res.I + + self.conventionalUB=self.Niggli(self.conventionalUB.I) + + Res = self.Niggli(Res) + if( numpy.linalg.det( Res )< 0): + for cc in range(3): + Res[cc,0] *=-1 + + + + return Res + + def Perturb( self,val, error): + return val+random.random()*error-error/2 + + def Next( self, hkl1): + #print "Next" + hkl=matrix([[hkl1[0,0]],[hkl1[1,0]],[hkl1[2,0]]]) + S =(math.fabs( hkl[0,0])+math.fabs( hkl[1,0])+math.fabs( hkl[2,0])) + #print ["S=",S] + #The sum of abs hkl's = S until not possible. Increasing lexicographically + if( hkl[2,0] < 0): + #print "Nexta" + hkl[2,0] = -hkl[2,0] + #print hkl + return hkl + + if( math.fabs( hkl[0,0])+ math.fabs( hkl[1,0]+1 ) <= S): + + #print "Nextb" + hkl[1,0] +=1 + hkl[2,0] = -(S -math.fabs( hkl[0,0])- math.fabs( hkl[1,0] )) + elif( math.fabs( hkl[0,0]+1 ) <= S): + + #print "Nextc" + hkl[0,0]= hkl[0,0]+1.0 + hkl[1,0] = -(S - math.fabs( hkl[0,0])) + hkl[2,0] = 0 + else: + + #print "Nextd" + hkl[1,0]=0 + hkl[2,0]=0 + hkl[0,0] = -S-1 + #print hkl + return hkl + + def FixLatParams( self,List): + npos=0 + nneg=0 + if len(List)<6: + return List + has90=False + for i in range(3,6): + if math.fabs(List[i]-90)<.05: + nneg =nneg+1 + has90=True + elif List[i] <90: + npos=npos+1 + else: + nneg=nneg+1 + over90=False + if nneg ==3 or has90 or nneg==1: + over90= True + + for i in range(3,6): + if List[i]>90 and not over90: + List[i]=180-List[i] + elif List[i]<90 and over90: + List[i]=180-List[i] + + bdotc = math.cos(List[3]/180.*math.pi)*List[1]*List[2] + adotc= math.cos(List[4]/180.*math.pi)*List[0]*List[2] + adotb= math.cos(List[5]/180.*math.pi)*List[1]*List[0] + if List[0] > List[1] or (List[0] == List[1] and math.fabs(bdotc)>math.fabs(adotc)): + List = self.XchangeSides( List,0,1) + bdotc = math.cos(List[3]/180.*math.pi)*List[1]*List[2] + adotc= math.cos(List[4]/180.*math.pi)*List[0]*List[2] + adotb= math.cos(List[5]/180.*math.pi)*List[1]*List[0] + if List[1] > List[2] or (List[1] == List[2] and math.fabs(adotc)>math.fabs(adotb)): + List = self.XchangeSides(List,1,2) + bdotc = math.cos(List[3]/180.*math.pi)*List[1]*List[2] + adotc= math.cos(List[4]/180.*math.pi)*List[0]*List[2] + adotb= math.cos(List[5]/180.*math.pi)*List[1]*List[0] + + if List[0] > List[1] or (List[0] == List[1] and math.fabs(bdotc)>math.fabs(adotc)): + List = self.XchangeSides( List,0,1) + + return List + + def FixUpPlusMinus( self, UB):#TODO make increasing lengthed sides too + M= matrix([[1.0,0.0,0.0],[0.0,1.0,0.0],[0.0,0.0,1.0]]) + M1= matrix([[1.0,0.0,0.0],[0.0,1.0,0.0],[0.0,0.0,1.0]]) + G= UB.T*UB + G.I + + if G[0,1]>0: + if G[0,2]>0: + if G[1,2]>0: + return UB + else: + M[1,1]=M[2,2]=-1 + elif G[1,2]>0: + M[0,0]=M[2,2]=-1 + else: + M[1,1]=M[0,0]=-1 + else: + if G[0,2]>0: + if G[1,2]>0: + M[1,1]=M[0,0]=-1 + else: + M[0,0]=M[2,2]=-1 + elif G[1,2]>0: + M[2,2]=M[1,1]=-1 + else: + return UB + + + return UB*M + # is closeness to 90 deg( cos of ), and equal sides + def FixUB(self,UB, tolerance): + done = 1 + print "A" + while done==1: + done=0 + X = UB.T*UB + X.I + + print "B1",X + if X[0,0]> X[1,1] or (math.fabs(X[0,0]-X[1,1])math.fabs(X[0,2])+tolerance/10): + done = 1 + for i in range(0,3): + sav= UB[i,0] + UB[i,0]=UB[i,1] + UB[i,1]=sav + print "B" + continue + + print "B2" + if X[1,1]>X[2,2] or (math.fabs(X[1,1]-X[2,2])0: + odd=i + break + + + elif nneg==1 and L[i]<0: + odd=i + elif nneg==2 and L[i]>0: + odd = i + odd= 2-odd + i1=(odd+1)%3 + i2=(odd+2)%3 + print ["L=",L, odd,i1,i2, is90,tolerance] + print UB + for i in range(0,3): + UB[i,i1]=-1*UB[i,i1] + UB[i,i2]=-1*UB[i,i2] + print UB + done = 1 + return UB + + + + + + + + def getPeaks( self,Inst,UB, error,Npeaks): + + CreatePeaksWorkspace(InstrumentWorkspace="Sws",NumberOfPeaks=0,OutputWorkspace="Peaks") + Peaks=mtd["Peaks"] + + + MinAbsQ = 100000000 + UBi= matrix([[0.0,0.0,0.0],[0.0,0.0,0.0],[0.0,0.0,0.0]]) + + for ii in range(3): + for jj in range(ii,3): + + UBi = UB[ii,jj] + if( math.fabs( UBi ) < MinAbsQ and UBi !=0): + MinAbsQ = math.fabs(UBi ) + + hkl=matrix([[0.0],[0.0],[0.0]]) + + Error = error*MinAbsQ + npeaks=0 + + + a1= hkl[0,0] + a2=hkl[1,0] + a3=hkl[2,0] + done = False + while not done: + + + Qs = (UB*hkl) + Qs=Qs*(2*math.pi) + + for qs in range(3): + Qs[qs,0] = self.Perturb(Qs[qs,0],Error) + + + + if( Qs is not None and Qs[2,0] > 0): + #QQ= numpy.array([Qs[0,0],Qs[1,0],Qs[2,0]]) + QQ = mantid.kernel.V3D(Qs[0,0],Qs[1,0],Qs[2,0]) + norm = QQ.norm() + + + if norm>.3 and norm < 30: + peak =Peaks.createPeak( QQ, 1.0) + + peak.setQLabFrame(mantid.kernel.V3D(Qs[0,0],Qs[1,0],Qs[2,0]),1.0) + + Peaks.addPeak(peak) + npeaks = npeaks+1 + + + hkl = self.Next( hkl) + if npeaks>= Npeaks: + done =True + if math.fabs(hkl[0,0])>15: + done = True + if math.fabs(hkl[1,0])>15: + done = True + if math.fabs(hkl[2,0])>15: + done = True + + + + return Peaks + + + def newSetting( self, side1,side2,Xtal,Center,ang, i1,i2a): + C=Center + if Center =='A' or Center =='B' or Center=='C': + C='C' + if( Xtal=='O'): + if( ang>20 or i1>0 or i2a >1): + return False + elif (side1==0 and side2 !=0) and (C=='F' or C=='C'):#No Tetragonal "F" or C Center + return False + elif (C=='F'or C=='C') and ( side1==side2 and side1 !=0): + return False + else: + return True + + if(Xtal=='H'): + if ang > 20 or i2a>1 or not(C=='P' or C=='I'): + return False + elif side2>side1: + return False + else: + return True + + if( Xtal!='M'): + return False + return True + + def MonoClinicRearrange(self, Sides,Xtal,Center, i1,i2a): + i1q =i1 + i2q = (i1+i2a)%3 + i3q=(i2q+1)%3 + if( i1q==i3q): + i3q = (i3q+1)%3 + a = Sides[i1q] + b= Sides[ i2q] + c = Sides[i3q] + + return [a,b,c] + + def getMatrixAxis( self,v, Xtal): + ident= matrix([[1.0,0.0,0.0],[0.0,1.0,0.0],[0.0,0.0,1.0]]) + if Xtal !='H' or v>=2: + return ident + ident[v,v] =0 + ident[2,2] =0 + v1= 2 + ident[v,v1] =1 + ident[v1,v] =1 + return ident + + def getLat( self, UB): + G=UB.T*UB + G1=G.I + Res=[math.sqrt(G1[0,0]),math.sqrt(G1[1,1]),math.sqrt(G1[2,2])] + Res.append(math.acos( G1[1,2]/Res[1]/Res[2])*180.0/math.pi) + Res.append(math.acos( G1[0,2]/Res[0]/Res[2])*180.0/math.pi) + Res.append(math.acos( G1[0,1]/Res[0]/Res[1])*180.0/math.pi) + return Res + + + def AppendForms( self, condition, Center,CenterTarg, FormNums, List2Append): + L= List2Append + if condition and Center != CenterTarg: + for i in range(len(FormNums)): + L.append(FormNums[i]) + elif Center ==CenterTarg: + for i in range(len(FormNums)): + L.append(FormNums[i]) + return L + + def Xlate(self,Xtal,Center,sides,LatNiggle): #sides are sides of conventional cell + if Xtal=='O': + C=Center + if sides[0] == sides[1]: + if sides[1]==sides[2]: + X="Cubic" + Z1=list(self.Cubic) + else: + X="Tetragonal" + Z1=list(self.Tetr) + elif sides[0]==sides[2]: + X="Tetragonal" + Z1=list(self.Tetr) + elif sides[1]==sides[2]: + X="Tetragonal" + Z1=list(self.Tetr) + else: + X="Orthorhombic" + Z1=list(self.Orth) + + if C=='A' or C =='B': + C ='C' + + elif Xtal=='H': + if Center =='I': + C ='R' + X='Rhombohedral' + Z1=list(self.Hex) + else: + C='P' + X="Hexagonal" + Z1=list(self.Hex) + else:#Monoclinic + X="Monoclinic" + Z1=list(self.Mon) + C=Center + LL=[math.cos(LatNiggle[5]/180*math.pi)*LatNiggle[0]*LatNiggle[1], math.cos(LatNiggle[4]/180*math.pi)*LatNiggle[0]*LatNiggle[2],math.cos(LatNiggle[3]/180*math.pi)*LatNiggle[2]*LatNiggle[1]] + + if C=='A' or C =='B': + C ='C' + + if C=='C' or C=='I':#'I': + + Z1=self.AppendForms( LatNiggle[2]*LatNiggle[2]<4*math.fabs(LL[2])+.001, 'C',C,[10,14,39], Z1) + Z1=self.AppendForms( LatNiggle[0]*LatNiggle[0]<4*math.fabs(LL[1])+.001, 'C',C,[20,25,41], Z1) + + Z1=self.AppendForms( LatNiggle[1]*LatNiggle[1]<4*math.fabs(LL[2]+.001), 'C',C,[37], Z1) + + Z1=self.AppendForms( 3*LatNiggle[0]*LatNiggle[0] < LatNiggle[2]*LatNiggle[2]+2*math.fabs(LL[1])+.001, 'I',C,[17], Z1) + Z1=self.AppendForms( 3*LatNiggle[1]*LatNiggle[1]< LatNiggle[2]*LatNiggle[2]+2*math.fabs(LL[2]+.001), 'I',C,[27], Z1) + + if( C=='P'): + Z2=self.CentP + elif C=='F': + Z2=self.CentF + elif C=='I' or C=='R': + Z2=self.CentI + elif C=='C': + Z2=self.CentC + Z1=sorted(Z1) + return [X,C, Z1, Z2] + + + + def MatchXtlparams( self, List1a, List2, tolerance, message): + List1=List1a + + + self.assertEqual(len(List1a),6,"Not the correct number of Xtal parameters."+message) + self.assertEqual(len(List2),6,"Not the correct number of Xtal parameters."+message) + Var=["a","b","c","alpha","beta","gamma"] + self.assertDelta( List1[0],List2[0],tolerance, message +"for "+Var[0]) + self.assertDelta( List1[1],List2[1],tolerance, message +"for "+Var[1]) + self.assertDelta( List1[2],List2[2],tolerance, message +"for "+Var[2]) + angtolerance = tolerance*180/math.pi + if List1[3]<90 and List2[3]>=90: + List1[3]= 180-List1[3] + List1[4]= 180-List1[4] + List1[5]= 180-List1[5] + + + if List1[0] >List1[1]-tolerance: + if List1[1]>List1[2]-tolerance: # 3 equal sides + match = False + + i=0 + + for i in range(0,3): + match= math.fabs(List1[3]-List2[3])angtolerance: + List1 = self.XchangeSides( List1,0,1) + self.assertDelta( List1[3],List2[3],angtolerance,"Error in "+Var[3]) + self.assertDelta( List1[4],List2[4],angtolerance,"Error in "+Var[4]) + elif List1[1]> List1[2]-tolerance: + self.assertDelta(List1[3],List2[3],angtolerance,"Error in "+Var[3]) + if math.fabs(List1[4]-List2[4])>angtolerance: + List1= self.XchangeSides(List1,1,2) + + self.assertDelta(List1[4],List2[4],angtolerance,"Error in "+Var[5]) + + self.assertDelta(List1[5],List2[5],angtolerance,"Error in "+Var[5]) + else: + self.assertDelta(List1[3],List2[3],angtolerance,"Error in "+Var[3]) + + self.assertDelta(List1[4],List2[4],angtolerance,"Error in "+Var[5]) + + self.assertDelta(List1[5],List2[5],angtolerance,"Error in "+Var[5]) + + + def XchangeSides( self, Lat1, s1,s2): + Lat=list(Lat1) + if s1<0 or s2<0 or s1>=3 or s2>2 or s1==s2: + return Lat + sav=Lat[s1] + Lat[s1]=Lat[s2] + Lat[s2]=sav + sav=Lat[s1+3] + Lat[s1+3]=Lat[s2+3] + Lat[s2+3]=sav + + return Lat + + def GetConvCell( self,Peaks,XtalCenter1,wsName, nOrigIndexed,tolerance,matchLat): + + CopySample(Peaks,wsName,CopyMaterial="0",CopyEnvironment="0",CopyName="0",CopyShape="0",CopyLattice="1") + OrLat= mtd[wsName].sample().getOrientedLattice() + Lat1= [OrLat.a(),OrLat.b(),OrLat.c(),OrLat.alpha(),OrLat.beta(),OrLat.gamma()] + FormXtal=XtalCenter1[2] + FormCenter= XtalCenter1[3] + i1=0 + i2=0 + Lat0= self.FixLatParams( matchLat) + Lat1= self.FixLatParams( Lat1) + # print "--------------------- Getting the Conventional Cell for--------------------------------" + # print Lat1 + # print Lat0 + # print [FormXtal,FormCenter] + angTolerance = tolerance*180/math.pi + while i1< len(FormXtal) and i2 < len(FormCenter): + if FormXtal[i1]FormCenter[i2]: + i2=i2+1 + else: + Res=SelectCellWithForm(Peaks, FormXtal[i1],True) + + if Res[0] > .85* nOrigIndexed: + CopySample(Peaks,"Temp",CopyMaterial="0",CopyEnvironment="0",CopyName="0",CopyShape="0",CopyLattice="1") + OrLat= mtd["Temp"].sample().getOrientedLattice() + Lat1= [OrLat.a(),OrLat.b(),OrLat.c(),OrLat.alpha(),OrLat.beta(),OrLat.gamma()] + Lat1 = self.FixLatParams(Lat1) + print ["Formnum,Lat1,Lat0",FormXtal[i1],Lat1,Lat0] + if math.fabs(Lat0[0]-Lat1[0])Lat1[1]-tolerance: + Lat1=self.XchangeSides( Lat1,0,1) + + if math.fabs(Lat0[3]-Lat1[3])Lat1[2]- tolerance: + Lat1=self.XchangeSides( Lat1,1,2) + + if math.fabs(Lat0[3]-Lat1[3])4,"Conventional values do not match") + #"XYXYZS" + def requiredFiles(self): + return [] diff --git a/Code/Mantid/Testing/SystemTests/tests/analysis/PolrefExample.py b/Code/Mantid/Testing/SystemTests/tests/analysis/PolrefExample.py new file mode 100644 index 000000000000..0fdd30dd62a1 --- /dev/null +++ b/Code/Mantid/Testing/SystemTests/tests/analysis/PolrefExample.py @@ -0,0 +1,39 @@ +import stresstesting +from mantid.simpleapi import * + +''' Sample script from Tim Charlton. Described as Mantid version of quick:lam''' +''' +Owen Arnold +29/06/2012 +The analysis performed here is a subset of what is done in ReflectometryISIS.py. We may want to remove this test in the furture to avoid duplication. However, +I'm leaving this in here for now because Tim Charlton suggests making the ReflectometryISIS.py test more generic for every reflectometry instrument. +''' +class PolrefExample(stresstesting.MantidStressTest): + + def runTest(self): + LoadRaw(Filename="POLREF00003014.raw",OutputWorkspace="W",SpectrumMax="4",LoadMonitors="Separate") + ConvertUnits(InputWorkspace="W_monitors",OutputWorkspace="M",Target="Wavelength",AlignBins="1") + DeleteWorkspace(Workspace="W_monitors") + CalculateFlatBackground(InputWorkspace="M",OutputWorkspace="M",WorkspaceIndexList="0,1,2",StartX="15",EndX="17") + ConvertUnits(InputWorkspace="W",OutputWorkspace="D",Target="Wavelength",AlignBins="1") + DeleteWorkspace(Workspace="W") + OneMinusExponentialCor(InputWorkspace="D",OutputWorkspace="D",C="1.99012524619") + ExponentialCorrection(InputWorkspace="D",OutputWorkspace="D",C1="0.0100836650034") + PolynomialCorrection(InputWorkspace="D",OutputWorkspace="D",Coefficients="-1.3697,0.8602,-0.7839,0.2866,-0.0447,0.0025") + ExponentialCorrection(InputWorkspace="M",OutputWorkspace="M",C1="0.42672",Operation="Multiply") + CreateSingleValuedWorkspace(OutputWorkspace="shift",DataValue="3.16666666667") + Plus(LHSWorkspace="M",RHSWorkspace="shift",OutputWorkspace="M") + OneMinusExponentialCor(InputWorkspace="M",OutputWorkspace="M",C="0.42672") + RebinToWorkspace(WorkspaceToRebin="M",WorkspaceToMatch="D",OutputWorkspace="M") + CropWorkspace(InputWorkspace="M",OutputWorkspace="I0",StartWorkspaceIndex="2") + DeleteWorkspace(Workspace="M") + Divide(LHSWorkspace="D",RHSWorkspace="I0",OutputWorkspace="R") + DeleteWorkspace(Workspace="D") + DeleteWorkspace(Workspace="I0") + + def validate(self): + # Need to disable checking of the Spectra-Detector map because it isn't + # fully saved out to the nexus file (it's limited to the spectra that + # are actually present in the saved workspace). + self.disableChecking.append('SpectraMap') + return 'R_1','PolrefTest.nxs' diff --git a/Code/Mantid/Testing/SystemTests/tests/analysis/PowderDiffProfileCalibrateTest.py b/Code/Mantid/Testing/SystemTests/tests/analysis/PowderDiffProfileCalibrateTest.py new file mode 100644 index 000000000000..6fc0813712b1 --- /dev/null +++ b/Code/Mantid/Testing/SystemTests/tests/analysis/PowderDiffProfileCalibrateTest.py @@ -0,0 +1,236 @@ +######################################################################## +# +# This is the system test for workflow algorithms +# 1. ExaminePowder... +# 2. SeqRefinement... +# Both of which are based on LeBailFit to do peak profile calibration +# for powder diffractometers. +# +######################################################################## +import stresstesting +import mantid.simpleapi as api +from mantid.simpleapi import * + +def getSaveDir(): + """determine where to save - the current working directory""" + import os + return os.path.abspath(os.path.curdir) + +class VulcanExamineProfile(stresstesting.MantidStressTest): + irf_file = 'arg_powder.irf' + dat_file = 'arg_si.dat' + bkgd_file = 'arg_si_bkgd_polynomial.nxs' + + def requiredFiles(self): + files = [self.irf_file, self.dat_file, self.bkgd_file] + return files + + def runTest(self): + savedir = getSaveDir() + + LoadAscii(Filename=self.dat_file, OutputWorkspace='arg_si',Unit='TOF') + + LoadNexusProcessed(Filename=self.bkgd_file, OutputWorkspace='Arg_Si_Bkgd_Parameter') + + CreateLeBailFitInput(FullprofParameterFile=self.irf_file, + GenerateBraggReflections='1',LatticeConstant='5.4313640', + InstrumentParameterWorkspace='Arg_Bank1', BraggPeakParameterWorkspace='ReflectionTable') + + # run the actual code + ExaminePowderDiffProfile( + InputWorkspace = 'arg_si', + StartX = 1990., + EndX = 29100., + ProfileType = 'Back-to-back exponential convoluted with PseudoVoigt', + ProfileWorkspace = 'Arg_Bank1', + BraggPeakWorkspace = 'ReflectionTable', + BackgroundParameterWorkspace = 'Arg_Si_Bkgd_Parameter', + BackgroundType = 'Polynomial', + BackgroundWorkspace = 'Arg_Si_Background', + OutputWorkspace = 'Arg_Si_Calculated') + + + # load output gsas file and the golden one + Load(Filename = "Arg_Si_ref.nxs", OutputWorkspace = "Arg_Si_golden") + + def validateMethod(self): + self.tolerance=1.0e-6 + return "ValidateWorkspaceToWorkspace" + + def validate(self): + self.tolerance=1.0e-6 + return ('Arg_Si_Calculated','Arg_Si_golden') + +class VulcanSeqRefineProfileFromScratch(stresstesting.MantidStressTest): + """ System test for sequential refinement + """ + irf_file = 'VULCAN_SNS_1.irf' + dat_file = 'VULCAN_22946_NOM.dat' + + def requiredFiles(self): + files = [self.irf_file, self.dat_file] + return files + + def runTest(self): + savedir = getSaveDir() + + # Data + LoadAscii(Filename=self.dat_file, OutputWorkspace='VULCAN_22946_NOM',Unit='TOF') + + # Reflections and starting profile parameters + CreateLeBailFitInput(FullprofParameterFile=self.irf_file, + GenerateBraggReflections='1',LatticeConstant='5.431364000', + InstrumentParameterWorkspace='Vulcan_B270_Profile', + BraggPeakParameterWorkspace='GeneralReflectionTable') + + # Pre-refined background + paramnames = ["Bkpos", "A0", "A1", "A2", "A3", "A4", "A5"] + paramvalues = [11000.000, 0.034, 0.027, -0.129, 0.161, -0.083, .015] + bkgdtablewsname = "VULCAN_22946_Bkgd_Parameter" + api.CreateEmptyTableWorkspace(OutputWorkspace=bkgdtablewsname) + ws = mtd[bkgdtablewsname] + ws.addColumn("str", "Name") + ws.addColumn("double", "Value") + for i in xrange(len(paramnames)): + ws.addRow([paramnames[i], paramvalues[i]]) + + # Examine profile + ExaminePowderDiffProfile( + InputWorkspace = "VULCAN_22946_NOM", + LoadData = False, + StartX = 7000., + EndX = 33000., + ProfileType = "Back-to-back exponential convoluted with PseudoVoigt", + ProfileWorkspace = "Vulcan_B270_Profile", + BraggPeakWorkspace = "GeneralReflectionTable", + GenerateInformationWS = False, + BackgroundParameterWorkspace = "VULCAN_22946_Bkgd_Parameter", + ProcessBackground = False, + BackgroundType = "FullprofPolynomial", + BackgroundWorkspace = "Dummy", + OutputWorkspace = "VULCAN_22946_Calculated") + + # Set up sequential refinement + api.RefinePowderDiffProfileSeq( + InputWorkspace = "VULCAN_22946_NOM", + SeqControlInfoWorkspace = "", + InputProfileWorkspace = "Vulcan_B270_Profile", + InputBraggPeaksWorkspace = "GeneralReflectionTable", + InputBackgroundParameterWorkspace = "VULCAN_22946_Bkgd_Parameter", + StartX = 7000., + EndX = 33000., + FunctionOption = "Setup", # or "Refine" + RefinementOption = "Random Walk", + ParametersToRefine = "Alph0", + NumRefineCycles = 1000, + ProfileType = "Neutron Back-to-back exponential convoluted with pseudo-voigt", + BackgroundType = "FullprofPolynomial", + ProjectID = "IDx890") + + # Refine step 1 + api.RefinePowderDiffProfileSeq( + InputWorkspace = "VULCAN_22946_NOM", + SeqControlInfoWorkspace = "RecordIDx890Table", + InputProfileWorkspace = "Vulcan_B270_Profile", + InputBraggPeaksWorkspace = "GeneralReflectionTable", + InputBackgroundParameterWorkspace = "VULCAN_22946_Bkgd_Parameter", + StartX = 7000., + EndX = 33000., + FunctionOption = "Refine", # or "Refine" + RefinementOption = "Random Walk", + ParametersToRefine = "Alph0", + NumRefineCycles = 1000, + ProfileType = "Neutron Back-to-back exponential convoluted with pseudo-voigt", + BackgroundType = "FullprofPolynomial", + ProjectID = "IDx890") + + + # Refine step 2 + api.RefinePowderDiffProfileSeq( + InputWorkspace = "VULCAN_22946_NOM", + SeqControlInfoWorkspace = "RecordIDx890Table", + # InputProfileWorkspace = "Vulcan_B270_Profile", + # InputBraggPeaksWorkspace = "GeneralReflectionTable", + # InputBackgroundParameterWorkspace = "VULCAN_22946_Bkgd_Parameter", + StartX = 7000., + EndX = 33000., + FunctionOption = "Refine", # or "Refine" + RefinementOption = "Random Walk", + ParametersToRefine = "Beta0, Beta1", + NumRefineCycles = 100, + # ProfileType = "Neutron Back-to-back exponential convoluted with psuedo-voigt", + # BackgroundType = "FullprofPolynomial" + ProjectID = "IDx890") + + + # Refine step 3 (not from previous cycle) + api.RefinePowderDiffProfileSeq( + InputWorkspace = "VULCAN_22946_NOM", + SeqControlInfoWorkspace = "RecordIDx890Table", + StartX = 7000., + EndX = 33000., + FunctionOption = "Refine", # or "Refine" + RefinementOption = "Random Walk", + ParametersToRefine = "Beta0, Beta1", + NumRefineCycles = 100, + FromStep = 1, + ProjectID = "IDx890") + + # Save + api.RefinePowderDiffProfileSeq( + InputWorkspace = "VULCAN_22946_NOM", + SeqControlInfoWorkspace = "RecordIDx890Table", + FunctionOption = "Save", + OutputProjectFilename = "temp991.nxs", + ProjectID = "IDx890") + + return + + def validateMethod(self): + """ Return None as running is all that we want at this moment. + """ + return None + + def validate(self): + self.tolerance=1.0e-6 + return ('VULCAN_22946_Calculated', 'VULCAN_22946_Calculated') + +class VulcanSeqRefineProfileLoadPlus(stresstesting.MantidStressTest): + """ System test for sequential refinement + """ + seqfile = "VULCAN_Calibrate_Seq.nxs" + + def requiredFiles(self): + files = [self.seqfile] + return files + + def runTest(self): + savedir = getSaveDir() + + # Load + api.RefinePowderDiffProfileSeq( + FunctionOption = "Load", + InputProjectFilename = self.seqfile, + ProjectID = "IDx890") + + # Refine step 4 + api.RefinePowderDiffProfileSeq( + InputWorkspace = "VULCAN_22946_NOM", + SeqControlInfoWorkspace = "RecordIDx890Table", + startx = 7000., + EndX = 33000., + FunctionOption = "Refine", # or "Refine" + RefinementOption = "Random Walk", + ParametersToRefine = "Alph1", + NumRefineCycles = 200, + ProjectID = "IDx890") + + + def validateMethod(self): + """ Return None as running is all that we want at this moment. + """ + return None + + def validate(self): + self.tolerance=1.0e-6 + return ('VULCAN_22946_Calculated', 'VULCAN_22946_Calculated') diff --git a/Code/Mantid/Testing/SystemTests/tests/analysis/REFMReduction.py b/Code/Mantid/Testing/SystemTests/tests/analysis/REFMReduction.py new file mode 100644 index 000000000000..a020eb64ed51 --- /dev/null +++ b/Code/Mantid/Testing/SystemTests/tests/analysis/REFMReduction.py @@ -0,0 +1,35 @@ +import stresstesting +from mantid import * + +from mantid.simpleapi import * + +class REFMReduction(stresstesting.MantidStressTest): + def runTest(self): + RefReduction(DataRun=str(9709), + NormalizationRun=str(9684), + SignalPeakPixelRange=[216, 224], + SubtractSignalBackground=True, + SignalBackgroundPixelRange=[172, 197], + PerformNormalization=True, + NormPeakPixelRange=[226, 238], + NormBackgroundPixelRange=[130, 183], + SubtractNormBackground=False, + CropLowResDataAxis=True, + CropLowResNormAxis=False, + LowResDataAxisPixelRange = [86, 159], + NBins=40, + Theta=0.086, + PolarizedData=True, + Instrument="REF_M", + OutputWorkspacePrefix='reflectivity') + + def validate(self): + # Be more tolerant with the output, mainly because of the errors. + # The following tolerance check the errors up to the third digit. + self.tolerance = 0.25 + self.disableChecking.append('Instrument') + self.disableChecking.append('Sample') + self.disableChecking.append('SpectraMap') + self.disableChecking.append('Axes') + return "reflectivity-Off_Off", 'REFMReduction_off_off.nxs' + diff --git a/Code/Mantid/Testing/SystemTests/tests/analysis/RROAutoFunctionalityTests.py b/Code/Mantid/Testing/SystemTests/tests/analysis/RROAutoFunctionalityTests.py new file mode 100644 index 000000000000..c5333ea91d55 --- /dev/null +++ b/Code/Mantid/Testing/SystemTests/tests/analysis/RROAutoFunctionalityTests.py @@ -0,0 +1,169 @@ +import stresstesting +from algorithm_decorator import make_decorator +from mantid.simpleapi import * +import mantid.api + +class RROAutoFunctionalityTest(stresstesting.MantidStressTest): + """ + This test is to check the functionality of ReflectometryReductionOneAuto. Data testing is done separately + """ + + + def __init__(self): + super(RROAutoFunctionalityTest, self).__init__() + data_ws = Load('INTER00013460.nxs') + self.__data_ws = data_ws + trans_ws_1 = Load('INTER00013463.nxs') + self.__trans_ws_1 = trans_ws_1 + trans_ws_2 = Load('INTER00013464.nxs') + self.__trans_ws_2 = trans_ws_2 + line_detector_ws = Load('POLREF00004699.nxs') + self.__line_detector_ws = line_detector_ws + + def __del__(self): + DeleteWorkspace(self.__data_ws) + DeleteWorkspace(self.__trans_ws_1) + DeleteWorkspace(self.__trans_ws_2) + DeleteWorkspace(self.__self.__line_detector_ws) + + + def construct_standard_algorithm(self): + alg = make_decorator(ReflectometryReductionOneAuto) + alg.set_WavelengthMin(0.0) + alg.set_WavelengthMax(1.0) + alg.set_I0MonitorIndex(0) + alg.set_ProcessingInstructions("0, 1") + alg.set_MonitorBackgroundWavelengthMin(0.0) + alg.set_MonitorBackgroundWavelengthMax(1.0) + alg.set_MonitorIntegrationWavelengthMin(0.0) + alg.set_MonitorIntegrationWavelengthMax(1.0) + alg.set_additional({'OutputWorkspaceWavelength': 'out_ws_wav'}) + return alg + + def test_point_detector_run_with_single_transmission_workspace(self): + alg = self.construct_standard_algorithm() + alg.set_InputWorkspace(self.__data_ws) + alg.set_ProcessingInstructions("3,4") + alg.set_FirstTransmissionRun(self.__trans_ws_1) + alg.set_ThetaIn(0.2) + + out_ws_q, out_ws_lam, theta = alg.execute() + self.assertEqual(0.2, theta, "Theta in and out should be the same") + + self.assertTrue(isinstance(out_ws_lam, mantid.api.MatrixWorkspace), "Should be a matrix workspace") + self.assertEqual("Wavelength", out_ws_lam.getAxis(0).getUnit().unitID()) + + self.assertTrue(isinstance(out_ws_q, mantid.api.MatrixWorkspace), "Should be a matrix workspace") + self.assertEqual("MomentumTransfer", out_ws_q.getAxis(0).getUnit().unitID()) + + self.assertEqual(2, out_ws_lam.getNumberHistograms()) + + def test_point_detector_run_with_two_transmission_workspaces(self): + alg = self.construct_standard_algorithm() + + alg.set_InputWorkspace(self.__data_ws) + alg.set_ProcessingInstructions("3,4") + alg.set_FirstTransmissionRun(self.__trans_ws_1) + alg.set_SecondTransmissionRun(self.__trans_ws_2) + alg.set_ThetaIn(0.2) + + out_ws_q, out_ws_lam, theta = alg.execute() + + + def test_spectrum_map_mismatch_throws_when_strict(self): + alg = self.construct_standard_algorithm() + ''' + Here we convert the transmission run to Lam. The workspace will NOT have the same spectra map as the input workspace, + and strict checking is turned on, so this will throw upon execution. + ''' + trans_run1_lam = ConvertUnits(self.__trans_ws_1, Target='Wavelength') + trans_run1_lam = CropWorkspace(trans_run1_lam, EndWorkspaceIndex=1) + + alg.set_InputWorkspace(self.__data_ws) + alg.set_ProcessingInstructions("3,4") # This will make spectrum numbers in input workspace different from denominator + alg.set_FirstTransmissionRun(trans_run1_lam) + alg.set_StrictSpectrumChecking(True) + + self.assertRaises(Exception, alg.execute) # Should throw due to spectrum missmatch. + + + def test_spectrum_map_mismatch_doesnt_throw_when_not_strict(self): + alg = self.construct_standard_algorithm() + + ''' + Here we convert the transmission run to Lam. The workspace will NOT have the same spectra map as the input workspace, + and strict checking is turned off, so this will NOT throw upon execution. + ''' + trans_run1_lam = ConvertUnits(self.__trans_ws_1, Target='Wavelength') + trans_run1_lam = CropWorkspace(trans_run1_lam, EndWorkspaceIndex=1) + + alg.set_InputWorkspace(self.__data_ws) + alg.set_ProcessingInstructions("3,4") # This will make spectrum numbers in input workspace different from denominator + alg.set_FirstTransmissionRun(trans_run1_lam) + alg.set_StrictSpectrumChecking(False) # Will not crash-out on spectrum checking. + + alg.execute()# Should not throw + + + def test_multidetector_run(self): + alg = self.construct_standard_algorithm() + + alg.set_InputWorkspace(self.__line_detector_ws[0]) + alg.set_AnalysisMode("MultiDetectorAnalysis") + alg.set_DetectorComponentName('lineardetector') + alg.set_ProcessingInstructions("10") # Fictional values + alg.set_CorrectDetectorPositions(False) + alg.set_RegionOfDirectBeam("20, 30") # Fictional values + alg.set_ThetaIn(0.1) # Fictional values + + out_ws_q, out_ws_lam, theta = alg.execute() + + self.assertTrue(isinstance(out_ws_lam, mantid.api.MatrixWorkspace), "Should be a matrix workspace") + self.assertEqual("Wavelength", out_ws_lam.getAxis(0).getUnit().unitID()) + + self.assertTrue(isinstance(out_ws_q, mantid.api.MatrixWorkspace), "Should be a matrix workspace") + self.assertEqual("MomentumTransfer", out_ws_q.getAxis(0).getUnit().unitID()) + + def test_multidetector_run_correct_positions(self): + alg = self.construct_standard_algorithm() + + alg.set_InputWorkspace(self.__line_detector_ws[0]) + alg.set_AnalysisMode("MultiDetectorAnalysis") + alg.set_DetectorComponentName('lineardetector') + alg.set_ProcessingInstructions("73") # Fictional values + alg.set_CorrectDetectorPositions(True) + alg.set_RegionOfDirectBeam("28, 29") # Fictional values + alg.set_ThetaIn(0.49 / 2) # Fictional values + + out_ws_q, out_ws_lam, theta = alg.execute() + + self.assertTrue(isinstance(out_ws_lam, mantid.api.MatrixWorkspace), "Should be a matrix workspace") + self.assertEqual("Wavelength", out_ws_lam.getAxis(0).getUnit().unitID()) + + self.assertTrue(isinstance(out_ws_q, mantid.api.MatrixWorkspace), "Should be a matrix workspace") + self.assertEqual("MomentumTransfer", out_ws_q.getAxis(0).getUnit().unitID()) + + instrument = out_ws_lam.getInstrument() + detector_pos = instrument.getComponentByName("lineardetector").getPos() + + self.assertDelta(-0.05714, detector_pos.Z(), 0.0001) + + + def runTest(self): + + self.test_point_detector_run_with_single_transmission_workspace() + + self.test_point_detector_run_with_two_transmission_workspaces() + + self.test_spectrum_map_mismatch_throws_when_strict() + + self.test_spectrum_map_mismatch_doesnt_throw_when_not_strict() + + self.test_multidetector_run() + + self.test_multidetector_run_correct_positions() + + + + def validate(self): + return True diff --git a/Code/Mantid/Testing/SystemTests/tests/analysis/RawVNexus.py b/Code/Mantid/Testing/SystemTests/tests/analysis/RawVNexus.py new file mode 100644 index 000000000000..ec956b766294 --- /dev/null +++ b/Code/Mantid/Testing/SystemTests/tests/analysis/RawVNexus.py @@ -0,0 +1,11 @@ +import stresstesting +from mantid.simpleapi import * + +''' Simply tests that our LoadRaw and LoadISISNexus algorithms produce the same workspace''' +class RawVNexus(stresstesting.MantidStressTest): + + def runTest(self): + Raw = LoadRaw(Filename='SANS2D00000808.raw') + + def validate(self): + return 'Raw','SANS2D00000808.nxs' diff --git a/Code/Mantid/Testing/SystemTests/tests/analysis/ReduceOneSCD_Run.py b/Code/Mantid/Testing/SystemTests/tests/analysis/ReduceOneSCD_Run.py new file mode 100644 index 000000000000..8f777f689799 --- /dev/null +++ b/Code/Mantid/Testing/SystemTests/tests/analysis/ReduceOneSCD_Run.py @@ -0,0 +1,251 @@ +# File: ReduceOneSCD_Run.py +# +# Version 2.0, modified to work with Mantid's new python interface. +# +# This script will reduce one SCD run. The configuration is set up in the +# first few lines in the method runTest. This script will load, find peaks, +# index and integrate either found or predicted peaks for the specified run. +# Either sphere integration or the Mantid PeakIntegration algorithms are +# currently supported, but it may be updated to support other integration +# methods. Users should make a directory to hold the output of this script, +# and must specify that output directory with the other configuration +#information. +# +# +import os +import sys +import shutil +import time + +import stresstesting +import numpy + + +from mantid.api import * +#sys.path.append("/home/ruth/GIT_MantidBuild/bin/") +from mantid.simpleapi import * + +class ReduceOneSCD_Run( stresstesting.MantidStressTest): + + + def requiredMemoryMB(self): + """ Require about 12GB free """ + return 6000 + + def runTest(self): + start_time = time.time() + + + instrument_name = "TOPAZ" + calibration_file_1 = "TOPAZ_2011_02_16.DetCal" + calibration_file_2 = None + + self.output_directory = config["defaultsave.directory"] + + min_tof = "400" + max_tof = "16666" + min_monitor_tof = "1000" + max_monitor_tof = "12500" + monitor_index = "0" + cell_type = "Orthorhombic" + centering = "P" + num_peaks_to_find = "150" + min_d = "4" + max_d = "12" + tolerance = ".12" + integrate_predicted_peaks = False + min_pred_wl = ".25" + max_pred_wl = "3.5" + min_pred_dspacing = ".2" + max_pred_dspacing = "2.5" + use_sphere_integration = True + use_fit_peaks_integration = False + peak_radius = ".2" + bkg_inner_radius = ".2" + bkg_outer_radius = ".25" + integrate_if_edge_peak = False + rebin_step = "-.004" + preserve_events = True + use_ikeda_carpenter = False + n_bad_edge_pixels = "10" + + rebin_params = min_tof+ ","+ rebin_step +"," +max_tof + run = "3132" + self.saved=False; +# +# Get the fully qualified input run file name, either from a specified data +# directory or from findnexus +# + + full_name = instrument_name + "_" + (run) + "_event.nxs" + + print "\nProcessing File: " + full_name + " ......\n" + +# +# Name the files to write for this run +# + run_niggli_matrix_file = self.output_directory + "/" + run + "_Niggli.mat" + run_niggli_integrate_file = self.output_directory + "/" + run + "_Niggli.integrate" + + +# +# Load the run data and find the total monitor counts +# + event_ws = LoadEventNexus( Filename=full_name, + FilterByTofMin=min_tof, FilterByTofMax=max_tof ) + + if (calibration_file_1 is not None) or (calibration_file_2 is not None): + LoadIsawDetCal( event_ws, + Filename=calibration_file_1) + + monitor_ws = LoadNexusMonitors( Filename=full_name ) + + integrated_monitor_ws = Integration( InputWorkspace=monitor_ws, + RangeLower=min_monitor_tof, RangeUpper=max_monitor_tof, + StartWorkspaceIndex=monitor_index, EndWorkspaceIndex=monitor_index ) + + monitor_count = integrated_monitor_ws.dataY(0)[0] + print "\n", run, " has calculated monitor count", monitor_count, "\n" + +# +# Make MD workspace using Lorentz correction, to find peaks +# + MDEW = ConvertToMD( InputWorkspace=event_ws, QDimensions="Q3D", + dEAnalysisMode="Elastic", QConversionScales="Q in A^-1", + LorentzCorrection='1', MinValues="-50,-50,-50", MaxValues="50,50,50", + SplitInto='2', SplitThreshold='50',MaxRecursionDepth='11' ) +# +# Find the requested number of peaks. Once the peaks are found, we no longer +# need the weighted MD event workspace, so delete it. +# + distance_threshold = 0.9 * 6.28 / float(max_d) + peaks_ws = FindPeaksMD( MDEW, MaxPeaks=num_peaks_to_find, + PeakDistanceThreshold=distance_threshold ) + + AnalysisDataService.remove( MDEW.getName() ) +# SaveIsawPeaks( InputWorkspace=peaks_ws, AppendFile=False, +# Filename='A'+run_niggli_integrate_file ) +# +# Find a Niggli UB matrix that indexes the peaks in this run +# + FindUBUsingFFT( PeaksWorkspace=peaks_ws, MinD=min_d, MaxD=max_d, Tolerance=tolerance ) + IndexPeaks( PeaksWorkspace=peaks_ws, Tolerance=tolerance ) + +# +# Save UB and peaks file, so if something goes wrong latter, we can at least +# see these partial results +# +# SaveIsawUB( InputWorkspace=peaks_ws,Filename=run_niggli_matrix_file ) +# SaveIsawPeaks( InputWorkspace=peaks_ws, AppendFile=False, +# Filename=run_niggli_integrate_file ) + +# +# Get complete list of peaks to be integrated and load the UB matrix into +# the predicted peaks workspace, so that information can be used by the +# PeakIntegration algorithm. +# + if integrate_predicted_peaks: + print "PREDICTING peaks to integrate...." + peaks_ws = PredictPeaks( InputWorkspace=peaks_ws, + WavelengthMin=min_pred_wl, WavelengthMax=max_pred_wl, + MinDSpacing=min_pred_dspacing, MaxDSpacing=max_pred_dspacing, + ReflectionCondition='Primitive' ) + else: + print "Only integrating FOUND peaks ...." +# +# Set the monitor counts for all the peaks that will be integrated +# + num_peaks = peaks_ws.getNumberPeaks() + for i in range(num_peaks): + peak = peaks_ws.getPeak(i) + peak.setMonitorCount( monitor_count ) + + if use_sphere_integration: +# +# Integrate found or predicted peaks in Q space using spheres, and save +# integrated intensities, with Niggli indexing. First get an un-weighted +# workspace to do raw integration (we don't need high resolution or +# LorentzCorrection to do the raw sphere integration ) +# + MDEW = ConvertToDiffractionMDWorkspace( InputWorkspace=event_ws, + LorentzCorrection='0', OutputDimensions='Q (lab frame)', + SplitInto='2', SplitThreshold='500', MaxRecursionDepth='5' ) + + peaks_ws = IntegratePeaksMD( InputWorkspace=MDEW, PeakRadius=peak_radius, + BackgroundOuterRadius=bkg_outer_radius, + BackgroundInnerRadius=bkg_inner_radius, + PeaksWorkspace=peaks_ws, + IntegrateIfOnEdge=integrate_if_edge_peak ) + + elif use_fit_peaks_integration: + event_ws = Rebin( InputWorkspace=event_ws, + Params=rebin_params, PreserveEvents=preserve_events ) + peaks_ws = PeakIntegration( InPeaksWorkspace=peaks_ws, InputWorkspace=event_ws, + IkedaCarpenterTOF=use_ikeda_carpenter, + MatchingRunNo=True, + NBadEdgePixels=n_bad_edge_pixels ) +# +# Save the final integrated peaks, using the Niggli reduced cell. +# This is the only file needed, for the driving script to get a combined +# result.(UNComment to get new values if algorithms change) +# +# SaveIsawPeaks( InputWorkspace=peaks_ws, AppendFile=False, +# Filename=run_niggli_integrate_file ) + +# +# If requested, also switch to the specified conventional cell and save the +# corresponding matrix and integrate file +# + if (not cell_type is None) and (not centering is None) : + self.run_conventional_matrix_file = self.output_directory + "/" + run + "_" + \ + cell_type + "_" + centering + ".mat" + run_conventional_integrate_file = self.output_directory + "/" + run + "_" + \ + cell_type + "_" + centering + ".integrate" + SelectCellOfType( PeaksWorkspace=peaks_ws, + CellType=cell_type, Centering=centering, + Apply=True, Tolerance=tolerance ) + # UNCOMMENT the line below to get new output values if an algorithm changes + #SaveIsawPeaks( InputWorkspace=peaks_ws, AppendFile=False, Filename=run_conventional_integrate_file ) + SaveIsawUB( InputWorkspace=peaks_ws, Filename=self.run_conventional_matrix_file ) + self.saved = True + + end_time = time.time() + + CreateSingleValuedWorkspace(OutputWorkspace="XX1",DataValue="3") + + + LoadIsawUB(InputWorkspace="XX1",Filename=self.run_conventional_matrix_file ) + s1 = mtd["XX1"].sample() + + LoadIsawPeaks(OutputWorkspace="PeaksP", Filename="3132_Orthorhombic_P.integrate") + LoadIsawUB(InputWorkspace=peaks_ws,Filename="3132_Orthorhombic_P.mat") + IndexPeaks( PeaksWorkspace=peaks_ws, Tolerance=tolerance ) + CreateSingleValuedWorkspace(OutputWorkspace="XX2",DataValue="3") + LoadIsawUB(InputWorkspace="XX2",Filename="3132_Orthorhombic_P.mat") + + s2 = mtd["XX2"].sample() + ol = s1.getOrientedLattice() + o2 = s2.getOrientedLattice() + self.assertDelta( ol.a(), ol.a(), 0.01, "Correct lattice a value not found.") + self.assertDelta( ol.b(), ol.b(), 0.01, "Correct lattice b value not found.") + self.assertDelta( ol.c(), ol.c(), 0.01, "Correct lattice c value not found.") + self.assertDelta( ol.alpha(), ol.alpha(), 0.4, "Correct lattice angle alpha value not found.") + self.assertDelta( ol.beta(), ol.beta(), 0.4, "Correct lattice angle beta value not found.") + self.assertDelta( ol.gamma(), ol.gamma(), 0.4, "Correct lattice angle gamma value not found.") + + self.__reduced_ws_name = str(peaks_ws) + + print '\nReduced run ' + str(run) + ' in ' + str(end_time - start_time) + ' sec' + print ["output directory=",self.output_directory] + + def cleanup(self): + if self.saved: + import os + os.remove( self.run_conventional_matrix_file) + + def validateMethod(self): + return "ValidateWorkspaceToWorkspace" + + def validate(self): + return [self.__reduced_ws_name,'PeaksP'] + diff --git a/Code/Mantid/Testing/SystemTests/tests/analysis/ReflectometryISIS.py b/Code/Mantid/Testing/SystemTests/tests/analysis/ReflectometryISIS.py new file mode 100644 index 000000000000..b6b7b9993976 --- /dev/null +++ b/Code/Mantid/Testing/SystemTests/tests/analysis/ReflectometryISIS.py @@ -0,0 +1,101 @@ +""" +These system tests are to verify the behaviour of the ISIS reflectometry reduction scripts +""" + +import stresstesting +from mantid.simpleapi import * + +from abc import ABCMeta, abstractmethod + +class ReflectometryISIS(stresstesting.MantidStressTest): + + __metaclass__ = ABCMeta # Mark as an abstract class + + @abstractmethod + def get_workspace_name(self): + """Returns the name of the workspace""" + raise NotImplementedError("Implement get_workspace_name to return ") + + def runTest(self): + + workspace_name = self.get_workspace_name() + workspace_nexus_file = workspace_name + ".nxs" + + PIX=1.1E-3 #m + SC=75 + avgDB=29 + Load(Filename=workspace_nexus_file,OutputWorkspace=workspace_name) + X=mtd[workspace_name] + X = ConvertUnits(InputWorkspace=X,Target="Wavelength",AlignBins="1") + # Reference intensity to normalise by + CropWorkspace(InputWorkspace=X,OutputWorkspace='Io',XMin=0.8,XMax=14.5,StartWorkspaceIndex=2,EndWorkspaceIndex=2) + # Crop out transmission and noisy data + CropWorkspace(InputWorkspace=X,OutputWorkspace='D',XMin=0.8,XMax=14.5,StartWorkspaceIndex=3) + Io=mtd['Io'] + D=mtd['D'] + + # Peform the normaisation step + Divide(LHSWorkspace=D,RHSWorkspace=Io,OutputWorkspace='I', + AllowDifferentNumberSpectra='1',ClearRHSWorkspace='1') + I=mtd['I'][0] + + # Automatically determine the SC and averageDB + FindReflectometryLines(InputWorkspace=I, StartWavelength=10, OutputWorkspace='spectrum_numbers') + spectrum_table = mtd['spectrum_numbers'] + self.assertTrue(2 == spectrum_table.columnCount()) + self.assertTrue(1 == spectrum_table.rowCount()) + self.assertTrue(SC == spectrum_table.cell(0, 0)) #Check that the algorithm found the expected answer for the reflected line + self.assertTrue(avgDB == spectrum_table.cell(0, 1)) #Check that the algorithm found the expected answer for the transmisson line + + # Move the detector so that the detector channel matching the reflected beam is at 0,0 + MoveInstrumentComponent(Workspace=I,ComponentName="lineardetector",X=0,Y=0,Z=-PIX*( (SC-avgDB)/2.0 +avgDB) ) + + # Should now have signed theta vs Lambda + ConvertSpectrumAxis(InputWorkspace=I,OutputWorkspace='SignedTheta_vs_Wavelength',Target='signed_theta') + + # Check that signed two theta is being caluclated correctly (not normalised) + ws1 = mtd['SignedTheta_vs_Wavelength'] + upperHistogram = ws1.getNumberHistograms()-1 + for i in range(0, upperHistogram): + thisTheta = ws1.detectorSignedTwoTheta(ws1.getDetector(i)) + nextTheta = ws1.detectorSignedTwoTheta(ws1.getDetector(i+1)) + #This check would fail if negative values were being normalised. + self.assertTrue(thisTheta < nextTheta) + + # MD transformations + ConvertToReflectometryQ(InputWorkspace='SignedTheta_vs_Wavelength',OutputWorkspace='QxQy',OutputDimensions='Q (lab frame)', Extents='-0.0005,0.0005,0,0.12') + ConvertToReflectometryQ(InputWorkspace='SignedTheta_vs_Wavelength',OutputWorkspace='KiKf',OutputDimensions='K (incident, final)', Extents='0,0.05,0,0.05') + ConvertToReflectometryQ(InputWorkspace='SignedTheta_vs_Wavelength',OutputWorkspace='PiPf',OutputDimensions='P (lab frame)', Extents='0,0.1,-0.02,0.15') + + # Bin the outputs to histograms because observations are not important. + BinMD(InputWorkspace='QxQy',AxisAligned='0',BasisVector0='Qx,(Ang^-1),1,0',BasisVector1='Qz,(Ang^-1),0,1',OutputExtents='-0.0005,0.0005,0,0.12',OutputBins='100,100',Parallel='1',OutputWorkspace='QxQy_rebinned') + BinMD(InputWorkspace='KiKf',AxisAligned='0',BasisVector0='Ki,(Ang^-1),1,0',BasisVector1='Kf,(Ang^-1),0,1',OutputExtents='0,0.05,0,0.05',OutputBins='200,200',Parallel='1',OutputWorkspace='KiKf_rebinned') + BinMD(InputWorkspace='PiPf',AxisAligned='0',BasisVector0='Pz_i + Pz_f,(Ang^-1),1,0',BasisVector1='Pz_i - Pz_f,(Ang^-1),0,1',OutputExtents='0,0.1,-0.02,0.15',OutputBins='50,50',Parallel='1',OutputWorkspace='PiPf_rebinned') + + # Fetch benchmarks for testing against + LoadMD(Filename="POLREF_qxqy_benchmark.nxs", OutputWorkspace="QxQy_benchmark") + LoadMD(Filename="POLREF_kikf_benchmark.nxs", OutputWorkspace="KiKf_benchmark") + LoadMD(Filename="POLREF_pipf_benchmark.nxs", OutputWorkspace="PiPf_benchmark") + + # Check the outputs + qxqy_comparison = CompareMDWorkspaces(Workspace1='QxQy_rebinned',Workspace2='QxQy_benchmark', Tolerance=0.01, CheckEvents=False) + kikf_comparison = CompareMDWorkspaces(Workspace1='KiKf_rebinned',Workspace2='KiKf_benchmark', Tolerance=0.01, CheckEvents=False) + pipf_comparison = CompareMDWorkspaces(Workspace1='PiPf_rebinned',Workspace2='PiPf_benchmark', Tolerance=0.01, CheckEvents=False) + + # Assert against the outputs + self.assertTrue(int(qxqy_comparison[0]) == 1) + self.assertTrue(int(kikf_comparison[0]) == 1) + self.assertTrue(int(pipf_comparison[0]) == 1) + + return True; + + def doValidate(self): + return True; + +# Specialisation for testing POLREF +class POLREF_ReflectometryISIS(ReflectometryISIS): + def get_workspace_name(self): + return "POLREF4699" + + +#Others to follow here. diff --git a/Code/Mantid/Testing/SystemTests/tests/analysis/ReflectometryQuickCombineMulti.py b/Code/Mantid/Testing/SystemTests/tests/analysis/ReflectometryQuickCombineMulti.py new file mode 100644 index 000000000000..85f805fcfc8d --- /dev/null +++ b/Code/Mantid/Testing/SystemTests/tests/analysis/ReflectometryQuickCombineMulti.py @@ -0,0 +1,55 @@ +import stresstesting +from mantid.simpleapi import * +from isis_reflectometry import quick +from isis_reflectometry import combineMulti + +class ReflectometryQuickCombineMulti(stresstesting.MantidStressTest): + """ + This is a system test for the top-level CombineMulti routines. Quick is the name given to the + ISIS reflectometry reduction scripts. CombineMulti is used for stitching together runs converted Into I/I0 vs |Q| taken at + different incident angles (and hence covering different Q-ranges) + """ + + __stitchedWorkspaceName = "stitched_13460_13462" + + def doQuickOnRun(self, runNumber, transmissionNumbers, instrument, incidentAngle): + defaultInstKey = 'default.instrument' + defaultInstrument = config[defaultInstKey] + try: + config[defaultInstKey] = instrument + LoadISISNexus(Filename=str(runNumber), OutputWorkspace=str(runNumber)) + for transmissionNumber in transmissionNumbers: + LoadISISNexus(Filename=str(transmissionNumber), OutputWorkspace=str(transmissionNumber)) + + transmissionRuns = ",".join(map(str, transmissionNumbers)) + # Run quick + quick.quick(str(runNumber), trans=transmissionRuns, theta=incidentAngle) + finally: + config[defaultInstKey] = defaultInstrument + return mtd[str(runNumber) + '_IvsQ'] + + def createBinningParam(self, low, step, high): + return "%f,%f,%f" %(low, step, high) + + def runTest(self): + step = 0.040 + run1QLow = 0.010 + run1QHigh = 0.06 + run2QLow = 0.035 + run2QHigh = 0.300 + + # Create IvsQ workspaces + IvsQ1 = self.doQuickOnRun(runNumber=13460, transmissionNumbers=[13463,13464], instrument='INTER', incidentAngle=0.7) + IvsQ1Binned = Rebin(InputWorkspace=IvsQ1, Params=self.createBinningParam(run1QLow, -step, run1QHigh)) + + # Create IvsQ workspaces + IvsQ2 = self.doQuickOnRun(runNumber=13462, transmissionNumbers=[13463,13464], instrument='INTER', incidentAngle=2.3) + IvsQ2Binned = Rebin(InputWorkspace=IvsQ2, Params=self.createBinningParam(run2QLow, -step, run2QHigh)) + + # Peform the stitching + combineMulti.combineDataMulti([IvsQ1Binned.name(), IvsQ2Binned.name()], self.__stitchedWorkspaceName, [run1QLow, run2QLow], [run1QHigh, run2QHigh], run1QLow, run2QHigh, -step, 1) + + + def validate(self): + self.disableChecking.append('Instrument') + return self.__stitchedWorkspaceName,'QuickStitchedReferenceResult.nxs' diff --git a/Code/Mantid/Testing/SystemTests/tests/analysis/ReflectometryQuickMultiDetector.py b/Code/Mantid/Testing/SystemTests/tests/analysis/ReflectometryQuickMultiDetector.py new file mode 100644 index 000000000000..99c1859228d2 --- /dev/null +++ b/Code/Mantid/Testing/SystemTests/tests/analysis/ReflectometryQuickMultiDetector.py @@ -0,0 +1,25 @@ +import stresstesting +from mantid.simpleapi import * +from isis_reflectometry import quick + +class ReflectometryQuickMultiDetector(stresstesting.MantidStressTest): + """ + This is a system test for the top-level quick routines. Quick is the name given to the + ISIS reflectometry reduction scripts. + + This test uses the multidetector functionality within the script. No transmission runs are passed, so it uses correction algorithms instead. + """ + + def runTest(self): + workspace_name = "POLREF4699" + workspace_nexus_file = workspace_name + ".nxs" + ws = Load(workspace_nexus_file, OutputWorkspace=workspace_name) + + first_ws = ws[0] + + quick.quick_explicit(first_ws, i0_monitor_index=0, lambda_min=0.8, lambda_max=14.5, background_min=0.8, background_max=14.5, int_min=0.8, int_max=14.5, + point_detector_start=0, point_detector_stop=245, multi_detector_start=1, theta=0, pointdet=False, roi=[74,74]) + + def validate(self): + self.disableChecking.append('Instrument') + return '4699_IvsQ','4699_IvsQ_Result.nxs' diff --git a/Code/Mantid/Testing/SystemTests/tests/analysis/ReflectometryQuickPointDetector.py b/Code/Mantid/Testing/SystemTests/tests/analysis/ReflectometryQuickPointDetector.py new file mode 100644 index 000000000000..18e42cd8d2e6 --- /dev/null +++ b/Code/Mantid/Testing/SystemTests/tests/analysis/ReflectometryQuickPointDetector.py @@ -0,0 +1,30 @@ +import stresstesting +from mantid.simpleapi import * +from isis_reflectometry import quick + +class ReflectometryQuickPointDetector(stresstesting.MantidStressTest): + """ + This is a system test for the top-level quick routines. Quick is the name given to the + ISIS reflectometry reduction scripts. Uses the point detector functionality with real transmission corrections. + + """ + + def runTest(self): + defaultInstKey = 'default.instrument' + defaultInstrument = config[defaultInstKey] + try: + config[defaultInstKey] = 'INTER' + LoadISISNexus(Filename='13463', OutputWorkspace='13463') + LoadISISNexus(Filename='13464', OutputWorkspace='13464') + LoadISISNexus(Filename='13460', OutputWorkspace='13460') + + transmissionRuns = '13463,13464' + runNo = '13460' + incidentAngle = 0.7 + quick.quick(runNo, trans=transmissionRuns, theta=incidentAngle) + finally: + config[defaultInstKey] = defaultInstrument + + def validate(self): + self.disableChecking.append('Instrument') + return '13460_IvsQ','QuickReferenceResult.nxs' diff --git a/Code/Mantid/Testing/SystemTests/tests/analysis/ReflectometryQuickPointDetectorMakeTransmission.py b/Code/Mantid/Testing/SystemTests/tests/analysis/ReflectometryQuickPointDetectorMakeTransmission.py new file mode 100644 index 000000000000..3644e3f384dd --- /dev/null +++ b/Code/Mantid/Testing/SystemTests/tests/analysis/ReflectometryQuickPointDetectorMakeTransmission.py @@ -0,0 +1,32 @@ +import stresstesting +from mantid.simpleapi import * +from isis_reflectometry import quick + +class ReflectometryQuickPointDetectorMakeTransmission(stresstesting.MantidStressTest): + """ + This is a system test for the top-level quick routines. Quick is the name given to the + ISIS reflectometry reduction scripts. Uses the point detector functionality with real transmission corrections. + + """ + + def runTest(self): + defaultInstKey = 'default.instrument' + defaultInstrument = config[defaultInstKey] + try: + config[defaultInstKey] = 'INTER' + LoadISISNexus(Filename='13463', OutputWorkspace='13463') + LoadISISNexus(Filename='13464', OutputWorkspace='13464') + LoadISISNexus(Filename='13460', OutputWorkspace='13460') + + transmissionRuns = '13463,13464' + runNo = '13460' + incidentAngle = 0.7 + transmissionWs=quick.make_trans_corr(transmissionRuns, stitch_start_overlap=10, + stitch_end_overlap=12, stitch_params=[1.5,0.02,17]) + quick.quick(runNo, trans=transmissionWs, theta=incidentAngle) + finally: + config[defaultInstKey] = defaultInstrument + + def validate(self): + self.disableChecking.append('Instrument') + return '13460_IvsQ','QuickReferenceResult.nxs' diff --git a/Code/Mantid/Testing/SystemTests/tests/analysis/ReuseExistingCalibration.py b/Code/Mantid/Testing/SystemTests/tests/analysis/ReuseExistingCalibration.py new file mode 100644 index 000000000000..3f678a8704e5 --- /dev/null +++ b/Code/Mantid/Testing/SystemTests/tests/analysis/ReuseExistingCalibration.py @@ -0,0 +1,36 @@ +""" + Verifies that a calibration file can be loaded once and reused to apply, using CopyInstrumentParameters, the same calibration + in successive reductions. +""" +import stresstesting + +class ReuseExistingCalibration(stresstesting.MantidStressTest): + + def requiredFiles(self): + return ["HRP39180.RAW", "HRP38094Calib.nxs"] + + def runTest(self): + from mantid.simpleapi import Load, CopyInstrumentParameters, MoveInstrumentComponent + + def do_reduction(calibration): + # load data + data = Load("HRP39180.RAW") + # copy parameters from calibration to data + CopyInstrumentParameters(calibration, data) + # Now move component on data workspace using a relative move, where that component was a detector in the calibrated workspace + MoveInstrumentComponent(data, DetectorID=1100,X=0.0,Y=0.0,Z=5.0,RelativePosition=True) + return data.getDetector(0).getPos() + #### + + # load calibration + calibration = Load("HRP38094Calib") + self.det_pos_first_run = do_reduction(calibration) + # again not reloading of calibration + self.det_pos_second_run = do_reduction(calibration) + + def validate(self): + if self.det_pos_second_run == self.det_pos_first_run: + return True + else: + print "Error: Detector position is not the same after the second reduction!" + return False \ No newline at end of file diff --git a/Code/Mantid/Testing/SystemTests/tests/analysis/SANS2DBatch.py b/Code/Mantid/Testing/SystemTests/tests/analysis/SANS2DBatch.py new file mode 100644 index 000000000000..57403ba5816d --- /dev/null +++ b/Code/Mantid/Testing/SystemTests/tests/analysis/SANS2DBatch.py @@ -0,0 +1,61 @@ +import stresstesting + +from mantid.simpleapi import * +from ISISCommandInterface import * +from mantid.simpleapi import * +from mantid import config +from SANSBatchMode import * +import os.path + +# test batch mode with sans2d and selecting a period in batch mode +class SANS2DBatch(stresstesting.MantidStressTest): + + def runTest(self): + + SANS2D() + Set1D() + Detector("rear-detector") + MaskFile('MASKSANS2Doptions.091A') + Gravity(True) + + csv_file = FileFinder.getFullPath('SANS2D_periodTests.csv') + + BatchReduce(csv_file, 'nxs', plotresults=False, saveAlgs={'SaveCanSAS1D':'xml','SaveNexus':'nxs'}) + + os.remove(os.path.join(config['defaultsave.directory'],'5512p7_SANS2DBatch.xml')) + + def validate(self): + # Need to disable checking of the Spectra-Detector map because it isn't + # fully saved out to the nexus file (it's limited to the spectra that + # are actually present in the saved workspace). + self.disableChecking.append('SpectraMap') + self.disableChecking.append('Axes') + self.disableChecking.append('Instrument') + + return '5512p7_SANS2DBatch','SANS2DBatch.nxs' + +class SANS2DNewSettingsCarriedAcrossInBatchMode(stresstesting.MantidStressTest): + """ + We want to make sure that any settings saved in the PropertyManager objects + are used across all iterations of the reduction in Batch mode. The MASKFILE + command uses this new way of storing settings in ISIS SANS, and so we'll + see if the same masks get applied in the second iteration as they do in the + first. + """ + def runTest(self): + config['default.instrument'] = 'SANS2D' + SANS2D() + Set1D() + Detector("rear-detector") + # This contains two MASKFILE commands, each resulting in a seperate call to MaskDetectors. + MaskFile('MaskSANS2DReductionGUI_MaskFiles.txt') + Gravity(True) + + # This does 2 seperate reductions of the same data, but saving the result of each to a different workspace. + csv_file = FileFinder.getFullPath("SANS2D_mask_batch.csv") + BatchReduce(csv_file, 'nxs', plotresults=False) + + def validate(self): + self.tolerance_is_reller = True + self.tolerance = 1.0e-2 + return "iteration_2", "SANS2DNewSettingsCarriedAcross.nxs" diff --git a/Code/Mantid/Testing/SystemTests/tests/analysis/SANS2DFrontNoGrav.py b/Code/Mantid/Testing/SystemTests/tests/analysis/SANS2DFrontNoGrav.py new file mode 100644 index 000000000000..3038f9f5e279 --- /dev/null +++ b/Code/Mantid/Testing/SystemTests/tests/analysis/SANS2DFrontNoGrav.py @@ -0,0 +1,25 @@ +import stresstesting +from mantid.simpleapi import * +from ISISCommandInterface import * + +class SANS2DFrontNoGrav(stresstesting.MantidStressTest): + + def runTest(self): + + SANS2D() + MaskFile('MASKSANS2D_094i_RKH.txt') + SetDetectorOffsets('REAR', -16.0, 58.0, 0.0, 0.0, 0.0, 0.0) + SetDetectorOffsets('FRONT', -44.0, -20.0, 47.0, 0.0, 1.0, 1.0) + Gravity(False) + Set1D() + + + AssignSample('2500.nxs') + + WavRangeReduction(4.6, 12.85, False) + + def validate(self): + self.disableChecking.append('SpectraMap') + self.disableChecking.append('Axes') + self.disableChecking.append('Instrument') + return '2500front_1D_4.6_12.85','SANS2DFrontNoGrav.nxs' \ No newline at end of file diff --git a/Code/Mantid/Testing/SystemTests/tests/analysis/SANS2DLOQReloadWorkspaces.py b/Code/Mantid/Testing/SystemTests/tests/analysis/SANS2DLOQReloadWorkspaces.py new file mode 100644 index 000000000000..ced0e61b7913 --- /dev/null +++ b/Code/Mantid/Testing/SystemTests/tests/analysis/SANS2DLOQReloadWorkspaces.py @@ -0,0 +1,326 @@ +import stresstesting +from mantid.simpleapi import * +from mantid.api import Workspace +from ISISCommandInterface import * +import numpy +import unittest + +## export PYTHONPATH=/apps/workspace/mantid_debug/bin/:/apps/mantid/systemtests/StressTestFramework/:/apps/mantid/mantid/Code/Mantid/scripts/SANS/:/apps/mantid/mantid/Code/Mantid/scripts/reduction + + +""" +Allowing the reduction to use already loaded workspace will make it easier to +deal with event mode and producing new workspaces for the reduction of data. +Till 06/2013 the reload option was available, but not implemented. + +In order to protect the system, it is suggested the following integration tests +to ensure that allowing workspaces as input to the reduction will not disturb the +reduction itself, and it is safe. + +LOQReductionShouldAcceptLoadedWorkspace ensure some requirements for the reloading. +SANS2DReductionShouldAcceptLoadedWorkspace and SANS2DReductionShouldAcceptLoadedWorkspaceRawFile +apply the same requirements for SANS2D instruments. + + +LOQReductionShouldAcceptLoadedWorkspaceStressTest, SANS2DReductionShouldAcceptLoadedWorkspaceStressTest +and SANS2DReductionShouldAcceptLoadedWorkspace are wrappers to make unittest.TestCase to fit the stresstesting +framework. + +The other tests are here to ensure the results of providing directly workspaces will be the same that loading +from files. + +""" + +class LOQReductionShouldAcceptLoadedWorkspace(unittest.TestCase): + """ + The following tests is to ensure that the reload obeys the following requirement: + * If reload is True the real data will be always reloaded from the file + * If reload is False, it will be used, if it pass the following tests: + * The instrument components have not been moved + """ + def setUp(self): + self.load_run = '54431.raw' + config["default.instrument"] = "LOQ" + LOQ() + MaskFile("MASK.094AA") + self.control_name = '54431main_1D_2.2_10.0' + self.inst_comp = 'main-detector-bank' + + def tearDown(self): + mtd.clear() + + def test_accept_loaded_workspace_only_if_reload_false(self): + my_workspace = Load(self.load_run) + #set the value for my_workspace to ensure it is the one used + aux = my_workspace.dataY(0) + aux[10]=5 + my_workspace.setY(0,aux) + # ask to use the loaded workspace + AssignSample(my_workspace,reload=False) + + ws_name = ReductionSingleton().get_sample().get_wksp_name() + + self.assertTrue(ws_name, my_workspace.name()) + + self.assertTrue(my_workspace.dataY(0)[10],5) + # ensure that it is able to execute the reduction + Reduce() + self.assertTrue(self.control_name in mtd) + + + def test_accept_loaded_workspace_but_reload_the_data_file_if_reload_true(self): + my_workspace = Load(self.load_run) + #set the value for my_workspace to ensure it is the one used + aux = my_workspace.dataY(0) + aux[10]=5 + my_workspace.setY(0,aux) + # ask to use the loaded workspace + AssignSample(my_workspace,reload=True) + + ws_name = ReductionSingleton().get_sample().get_wksp_name() + # it is different, because, it will compose the name using its rule, + # wich, for sure, will be different of my_workspace. + self.assertFalse(ws_name==my_workspace.name()) + self.assertFalse(mtd[ws_name].dataY(0)[10]==5) + # it is not necessary to ensure the Reduce occurs + + def test_should_not_accept_loaded_workspace_if_moved(self): + my_workspace = Load(self.load_run) + MoveInstrumentComponent(my_workspace,self.inst_comp,X=2,Y=1,Z=0) + ## attempt to use a workspace that has been moved + self.assertRaises(RuntimeError, AssignSample, my_workspace, False) + + + def test_should_not_accept_loaded_workspace_if_moved_2(self): + # assign sample loads and move the workspace to the defined center + AssignSample(self.load_run) + + # this makes it load this worksapce and generates an output workspace + ws_name = ReductionSingleton().get_sample().get_wksp_name() + # the workspace is renamed, so it seems another workspace + my_workspace = RenameWorkspace(ws_name) + ## trying to assing it again to AssingSample must fail + self.assertRaises(RuntimeError, AssignSample, my_workspace, False) + +class SANS2DReductionShouldAcceptLoadedWorkspace(LOQReductionShouldAcceptLoadedWorkspace): + def setUp(self): + self.load_run = '2500.nxs' + config["default.instrument"] = "SANS2D" + SANS2D() + MaskFile("MASKSANS2D_094i_RKH.txt") + self.control_name = '2500front_1D_4.6_12.85' + self.inst_comp = 'rear-detector' + +class SANS2DReductionShouldAcceptLoadedWorkspaceRawFile(SANS2DReductionShouldAcceptLoadedWorkspace): + def setUp(self): + SANS2DReductionShouldAcceptLoadedWorkspace.setUp(self) + self.load_run = '5547.raw' + self.control_name = '5547front_1D_4.6_12.85' + +class LOQReductionShouldAcceptLoadedWorkspaceStressTest(stresstesting.MantidStressTest): + cl = LOQReductionShouldAcceptLoadedWorkspace + def runTest(self): + self._success = False + # Custom code to create and run this single test suite + suite = unittest.TestSuite() + suite.addTest( unittest.makeSuite(self.cl, "test")) + runner = unittest.TextTestRunner() + # Run using either runner + res = runner.run(suite) + if res.wasSuccessful(): + self._success = True + + def validate(self): + return self._success + +class SANS2DReductionShouldAcceptLoadedWorkspaceStressTest(LOQReductionShouldAcceptLoadedWorkspaceStressTest): + cl = SANS2DReductionShouldAcceptLoadedWorkspace + +class SANS2DReductionShouldAcceptLoadedWorkspaceStressTest2(LOQReductionShouldAcceptLoadedWorkspaceStressTest): + cl = SANS2DReductionShouldAcceptLoadedWorkspaceRawFile + + +class LOQTransFitWorkspace2DWithLoadedWorkspace(stresstesting.MantidStressTest): + def runTest(self): + config["default.instrument"] = "LOQ" + LOQ() + MaskFile('MASK.094AA') + Gravity(False) + Set2D() + Detector("main-detector-bank") + Sample = LoadRaw('54431.raw') + AssignSample(Sample,False) + Can = LoadRaw('54432.raw') + AssignCan(Can,False) + LimitsWav(3,4, 0.2, 'LIN') + TransFit('LOG',3.0,8.0) + Sample_Trans = LoadRaw('54435.raw') + Sample_Direct = LoadRaw('54433.raw') + TransmissionSample(Sample_Trans, Sample_Direct, False) + Can_Trans = LoadRaw('54434.raw') + Can_Direct = LoadRaw('54433.raw') + TransmissionCan(Can_Trans, Can_Direct, False) + + #run the reduction + WavRangeReduction(3, 4, False, '_suff') + + def validate(self): + self.disableChecking.append('SpectraMap') + #when comparing LOQ files you seem to need the following + self.disableChecking.append('Axes') + self.disableChecking.append('Instrument') + return '54431main_2D_3.0_4.0_suff','LOQTransFitWorkspace2D.nxs' + +class LOQReductionOnLoadedWorkspaceMustProduceTheSameResult_1(stresstesting.MantidStressTest): + """ It will repeat the test done at LOQCentreNoGrav but using + loaded workspaces + """ + def runTest(self): + config["default.instrument"] = "LOQ" + LOQ() + + Set1D() + Detector("rear-detector") + MaskFile('MASK.094AA') + Gravity(False) + Sample = LoadRaw('54431.raw') + Trans_Sample = LoadRaw('54435.raw') + Trans_Direct = LoadRaw('54433.raw') + Can = LoadRaw('54432.raw') + CanTrans_Sample = LoadRaw('54434.raw') + CanTrans_Direct = LoadRaw('54433.raw') + + AssignSample(Sample, False) + TransmissionSample(Trans_Sample, Trans_Direct, False) + AssignCan(Can, False) + TransmissionCan(CanTrans_Sample, CanTrans_Direct, False) + + FindBeamCentre(60,200, 9) + + WavRangeReduction(3, 9, DefaultTrans) + + def validate(self): + return '54431main_1D_3.0_9.0','LOQCentreNoGravSearchCentreFixed.nxs' + +class LOQReductionOnLoadedWorkspaceMustProduceTheSameResult_2(stresstesting.MantidStressTest): + """Before ticket #8461 test LOQReductionOnLoadedWorkspaceMustProduceTheSameResult_1 used + to produce a workspace that matches LOQCentreNoGrav.nxs. This test is created to ensure + that if we put the same centre that was produced before, we finish in the same result + for the reduction""" + def runTest(self): + config["default.instrument"] = "LOQ" + LOQ() + + Set1D() + Detector("rear-detector") + MaskFile('MASK.094AA') + Gravity(False) + Sample = LoadRaw('54431.raw') + Trans_Sample = LoadRaw('54435.raw') + Trans_Direct = LoadRaw('54433.raw') + Can = LoadRaw('54432.raw') + CanTrans_Sample = LoadRaw('54434.raw') + CanTrans_Direct = LoadRaw('54433.raw') + + SetCentre(324.765, 327.670) + + AssignSample(Sample, False) + TransmissionSample(Trans_Sample, Trans_Direct, False) + AssignCan(Can, False) + TransmissionCan(CanTrans_Sample, CanTrans_Direct, False) + + WavRangeReduction(3, 9, DefaultTrans) + + def validate(self): + # Need to disable checking of the Spectra-Detector map becauseit isn't + # fully saved out to the nexus file (it's limited to the spectra that + # are actually present in the saved workspace). + self.disableChecking.append('SpectraMap') + self.disableChecking.append('Axes') + self.disableChecking.append('Instrument') + + return '54431main_1D_3.0_9.0','LOQCentreNoGrav.nxs' + + +class SANSLOQCan2DReloadWorkspace(stresstesting.MantidStressTest): + + def runTest(self): + config["default.instrument"] = "LOQ" + LOQ() + Set2D() + Detector("main-detector-bank") + MaskFile('MASK.094AA') + # apply some small artificial shift + SetDetectorOffsets('REAR', -1.0, 1.0, 0.0, 0.0, 0.0, 0.0) + Gravity(True) + sample = Load('99630') + can = Load('99631') + AssignSample(sample, False) + AssignCan(can, False) + + WavRangeReduction(None, None, False) + + + def validate(self): + # Need to disable checking of the Spectra-Detector map because it isn't + # fully saved out to the nexus file (it's limited to the spectra that + # are actually present in the saved workspace). + self.disableChecking.append('SpectraMap') + self.disableChecking.append('Instrument') + #when comparing LOQ files you seem to need the following + self.disableChecking.append('Axes') + # the change in number is because the run number reported from 99630 is 53615 + return '53615main_2D_2.2_10.0','SANSLOQCan2D.nxs' + +class SANS2DFrontNoGravReloadWorkspace(stresstesting.MantidStressTest): + + def runTest(self): + config["default.instrument"] = "SANS2D" + SANS2D() + MaskFile('MASKSANS2D_094i_RKH.txt') + SetDetectorOffsets('REAR', -16.0, 58.0, 0.0, 0.0, 0.0, 0.0) + SetDetectorOffsets('FRONT', -44.0, -20.0, 47.0, 0.0, 1.0, 1.0) + Gravity(False) + Set1D() + Sample = LoadNexus('2500') + AssignSample(Sample, False) + WavRangeReduction(4.6, 12.85, False) + + def validate(self): + self.disableChecking.append('SpectraMap') + self.disableChecking.append('Axes') + self.disableChecking.append('Instrument') + return '2500front_1D_4.6_12.85','SANS2DFrontNoGrav.nxs' + +class SANS2DWaveloopsReloadWorkspace(stresstesting.MantidStressTest): + + def runTest(self): + config["default.instrument"] = "SANS2D" + SANS2D() + MaskFile('MASKSANS2D.091A') + Gravity(True) + Set1D() + s = Load('992') + s_t = Load('988') + direct = Load('987') + direct_can = CloneWorkspace(direct) + c = Load('993') + c_t = Load('989') + AssignSample(s,False) + TransmissionSample(s_t, direct, False) + AssignCan(c, False) + TransmissionCan(c_t, direct_can, False) + + CompWavRanges([3, 5, 7, 11], False) + + def validate(self): + self.disableChecking.append('SpectraMap') + self.disableChecking.append('Axes') + self.disableChecking.append('Instrument') + # testing one of the workspaces that is produced, best not to choose the + # first one in produced by the loop as this is the least error prone + return '992rear_1D_7.0_11.0','SANS2DWaveloops.nxs' + + +if __name__ == "__main__": + unittest.main() diff --git a/Code/Mantid/Testing/SystemTests/tests/analysis/SANS2DLimitEventsTime.py b/Code/Mantid/Testing/SystemTests/tests/analysis/SANS2DLimitEventsTime.py new file mode 100644 index 000000000000..29e74f2a2fec --- /dev/null +++ b/Code/Mantid/Testing/SystemTests/tests/analysis/SANS2DLimitEventsTime.py @@ -0,0 +1,17 @@ +import stresstesting +from mantid.simpleapi import * +from ISISCommandInterface import * + +class SANS2DLimitEventsTime(stresstesting.MantidStressTest): + + def runTest(self): + SANS2D() + MaskFile('MaskSANS2DReductionGUI_LimitEventsTime.txt') + AssignSample('22048') + reduced = WavRangeReduction() + + def validate(self): + self.disableChecking.append('SpectraMap') + self.disableChecking.append('Axes') + self.disableChecking.append('Instrument') + return '22048rear_1D_1.5_12.5','SANSReductionGUI_LimitEventsTime.nxs' \ No newline at end of file diff --git a/Code/Mantid/Testing/SystemTests/tests/analysis/SANS2DMultiPeriod.py b/Code/Mantid/Testing/SystemTests/tests/analysis/SANS2DMultiPeriod.py new file mode 100644 index 000000000000..a075de22d982 --- /dev/null +++ b/Code/Mantid/Testing/SystemTests/tests/analysis/SANS2DMultiPeriod.py @@ -0,0 +1,48 @@ +import stresstesting + +from mantid.simpleapi import * +from ISISCommandInterface import * +from mantid.simpleapi import * +from mantid import config +from SANSBatchMode import * +import os.path + +# test batch mode with sans2d and selecting a period in batch mode +class SANS2DMultiPeriodSingle(stresstesting.MantidStressTest): + + def runTest(self): + + SANS2D() + Set1D() + Detector("rear-detector") + MaskFile('MASKSANS2Doptions.091A') + Gravity(True) + + AssignSample('5512') + self.reduced = WavRangeReduction() + + def validate(self): + # Need to disable checking of the Spectra-Detector map because it isn't + # fully saved out to the nexus file (it's limited to the spectra that + # are actually present in the saved workspace). + self.disableChecking.append('SpectraMap') + self.disableChecking.append('Axes') + self.disableChecking.append('Instrument') + + return mtd[self.reduced][6].name(),'SANS2DBatch.nxs' + +class SANS2DMultiPeriodBatch(SANS2DMultiPeriodSingle): + + def runTest(self): + + SANS2D() + Set1D() + Detector("rear-detector") + MaskFile('MASKSANS2Doptions.091A') + Gravity(True) + + csv_file = FileFinder.getFullPath('SANS2D_multiPeriodTests.csv') + + BatchReduce(csv_file, 'nxs', saveAlgs={}) + self.reduced = '5512_SANS2DBatch' + \ No newline at end of file diff --git a/Code/Mantid/Testing/SystemTests/tests/analysis/SANS2DMultiPeriodAddFiles.py b/Code/Mantid/Testing/SystemTests/tests/analysis/SANS2DMultiPeriodAddFiles.py new file mode 100644 index 000000000000..2d66c401afa6 --- /dev/null +++ b/Code/Mantid/Testing/SystemTests/tests/analysis/SANS2DMultiPeriodAddFiles.py @@ -0,0 +1,38 @@ +import stresstesting +from mantid.simpleapi import * +from mantid import config +from ISISCommandInterface import * + +class SANS2DMultiPeriodAddFiles(stresstesting.MantidStressTest): + + def requiredMemoryMB(self): + """Requires 2.5Gb""" + return 2500 + + def runTest(self): + + SANS2D() + Set1D() + Detector("rear-detector") + MaskFile('MASKSANS2Doptions.091A') + Gravity(True) + + add_runs( ('5512', '5512') ,'SANS2D', 'nxs', lowMem=True) + + #one period of a multi-period Nexus file + AssignSample('5512-add.nxs', period=7) + + WavRangeReduction(2, 4, DefaultTrans) + + os.remove(os.path.join(config['defaultsave.directory'],'SANS2D00005512-add.nxs')) + os.remove(os.path.join(config['defaultsave.directory'],'SANS2D00005512.log')) + + def validate(self): + # Need to disable checking of the Spectra-Detector map because it isn't + # fully saved out to the nexus file (it's limited to the spectra that + # are actually present in the saved workspace). + self.disableChecking.append('SpectraMap') + self.disableChecking.append('Instrument') + self.disableChecking.append('Axes') + + return '5512p7rear_1D_2.0_4.0Phi-45.0_45.0','SANS2DMultiPeriodAddFiles.nxs' diff --git a/Code/Mantid/Testing/SystemTests/tests/analysis/SANS2DReductionGUI.py b/Code/Mantid/Testing/SystemTests/tests/analysis/SANS2DReductionGUI.py new file mode 100644 index 000000000000..27b19964cc35 --- /dev/null +++ b/Code/Mantid/Testing/SystemTests/tests/analysis/SANS2DReductionGUI.py @@ -0,0 +1,290 @@ +""" +These tests ensure that all the steps that the SANS Interface GUI performs to reduce SANS data +on the SANS2D instrument is avalailable and is conforming to this test. + +Although verbotic, it is all the steps that the GUI calls when asked to perform a full reduction +on SANS2D instrument. + +This test also allows an easy comparison of the steps used by the reduction in batch mode and in single mode. + +The first 2 Tests ensures that the result provided by the GUI are the same for the minimalistic script. + +Test was first created to apply to Mantid Release 3.0. +""" + +import sys +import os + +if __name__ == "__main__": + # it is just to allow running this test in Mantid, allowing the following import + sys.path.append('/apps/mantid/systemtests/StressTestFramework/') + +import stresstesting +from mantid.simpleapi import * +import isis_reducer +import ISISCommandInterface as i +import isis_instrument +import isis_reduction_steps +import copy + +MASKFILE = FileFinder.getFullPath('MaskSANS2DReductionGUI.txt') +BATCHFILE = FileFinder.getFullPath('sans2d_reduction_gui_batch.csv') + +def s(obj): + print '!'+str(obj)+'!',type(obj) + +class SANS2DMinimalBatchReduction(stresstesting.MantidStressTest): + """Minimal script to perform full reduction in batch mode + """ + def __init__(self): + super(SANS2DMinimalBatchReduction, self).__init__() + config['default.instrument'] = 'SANS2D' + + def runTest(self): + import SANSBatchMode as batch + i.SANS2D() + i.MaskFile(MASKFILE) + fit_settings = batch.BatchReduce(BATCHFILE,'.nxs', combineDet='rear') + + def validate(self): + self.tolerance_is_reller = True + self.tolerance = 1.0e-2 + return "trans_test_rear","SANSReductionGUI.nxs" + + + +class SANS2DMinimalSingleReduction(SANS2DMinimalBatchReduction): + """Minimal script to perform full reduction in single mode""" + def runTest(self): + i.SANS2D() + i.MaskFile(MASKFILE) + i.AssignSample('22048') + i.AssignCan('22023') + i.TransmissionSample('22041','22024') + i.TransmissionCan('22024', '22024') + reduced = i.WavRangeReduction() + RenameWorkspace(reduced, OutputWorkspace='trans_test_rear') + + + + +class SANS2DGUIBatchReduction(SANS2DMinimalBatchReduction): + """Script executed by SANS GUI Interface to perform Batch Reduction""" + + def checkFloat(self, f1, f2): + self.assertDelta(f1,f2,0.0001) + + def checkStr(self, s1, s2): + self.assertTrue(s1==s2, '%s != %s'%(s1,s2)) + + def checkObj(self, ob1, ob2): + self.assertTrue(ob1 == ob2, '%s != %s'%(str(ob1),str(ob2))) + + def checkFirstPart(self): + self.checkObj(i.ReductionSingleton().instrument.listDetectors(),('rear-detector', 'front-detector')) + self.checkStr(i.ReductionSingleton().instrument.cur_detector().name() , 'rear-detector') + self.checkFloat(i.ReductionSingleton().mask.min_radius, 0.041) + self.checkFloat(i.ReductionSingleton().mask.max_radius, -0.001) + self.checkFloat(i.ReductionSingleton().to_wavelen.wav_low, 1.5) + self.checkFloat(i.ReductionSingleton().to_wavelen.wav_high, 12.5) + self.checkFloat(i.ReductionSingleton().to_wavelen.wav_step, 0.125) + self.checkStr(i.ReductionSingleton().to_Q.binning, " .001,.001,.0126,-.08,.2") + self.checkFloat(i.ReductionSingleton().QXY2,0.05) + self.checkFloat(i.ReductionSingleton().DQXY, 0.001) + self.checkFloat(i.ReductionSingleton().transmission_calculator.lambdaMin('SAMPLE'), 1.5) + self.checkStr(i.ReductionSingleton().transmission_calculator.fitMethod('SAMPLE'), 'LOGARITHMIC') + self.checkFloat(i.ReductionSingleton().transmission_calculator.lambdaMin('CAN'), 1.5) + self.checkFloat(i.ReductionSingleton().instrument.WAV_RANGE_MIN, 2.0) + self.checkFloat(i.ReductionSingleton().instrument.WAV_RANGE_MAX, 14.0) + self.checkFloat(i.ReductionSingleton().transmission_calculator.lambdaMax('CAN'), 12.5) + self.checkStr(i.ReductionSingleton().transmission_calculator.fitMethod('CAN'), 'LOGARITHMIC') + self.checkFloat(i.ReductionSingleton().transmission_calculator.lambdaMin('SAMPLE'), 1.5) + self.checkStr(i.ReductionSingleton().transmission_calculator.fitMethod('SAMPLE'), 'LOGARITHMIC') + self.checkFloat(i.ReductionSingleton().instrument.getDetector('FRONT').rescaleAndShift.scale, 1.0) + self.checkFloat(i.ReductionSingleton().instrument.getDetector('FRONT').rescaleAndShift.shift, 0.0) + self.assertTrue(not i.ReductionSingleton().instrument.getDetector('FRONT').rescaleAndShift.fitScale) + self.assertTrue(not i.ReductionSingleton().instrument.getDetector('FRONT').rescaleAndShift.fitShift) + self.assertTrue(not i.ReductionSingleton().instrument.getDetector('FRONT').rescaleAndShift.qRangeUserSelected) + self.checkFloat(i.ReductionSingleton().instrument.get_incident_mon(), 1) + self.checkFloat(i.ReductionSingleton().instrument.incid_mon_4_trans_calc, 1) + self.assertTrue(i.ReductionSingleton().instrument.is_interpolating_norm()) + self.assertTrue(i.ReductionSingleton().transmission_calculator.interpolate) + self.assertTrue("DIRECTM1_15785_12m_31Oct12_v12.dat" in i.ReductionSingleton().instrument.detector_file('rear')) + self.assertTrue("DIRECTM1_15785_12m_31Oct12_v12.dat" in i.ReductionSingleton().instrument.detector_file('front')) + self.checkStr(i.ReductionSingleton().prep_normalize.getPixelCorrFile('REAR'), "") + self.checkStr(i.ReductionSingleton().prep_normalize.getPixelCorrFile('FRONT'), "") + self.checkFloat(i.ReductionSingleton()._corr_and_scale.rescale, 7.4) + self.checkFloat(i.ReductionSingleton().instrument.SAMPLE_Z_CORR, 0.053) + self.assertDelta(i.ReductionSingleton().get_beam_center('rear')[0], 0.15545,0.0001) + self.checkFloat(i.ReductionSingleton().get_beam_center('rear')[1], -0.16965) + self.checkFloat(i.ReductionSingleton().get_beam_center('front')[0], 0.15545) + self.checkFloat(i.ReductionSingleton().get_beam_center('front')[1], -0.16965) + self.assertTrue(i.ReductionSingleton().to_Q.get_gravity()) + self.checkStr(i.ReductionSingleton().instrument.det_selection, 'REAR') + self.checkFloat(i.ReductionSingleton().mask.phi_min, -90.0) + self.checkFloat(i.ReductionSingleton().mask.phi_max, 90.0) + self.checkStr(i.ReductionSingleton().mask.spec_mask_r, ",H0,H190>H191,H167>H172,V0,V191") + self.checkStr(i.ReductionSingleton().mask.spec_mask_f, ",H0,H190>H191,V0,V191,H156>H159") + self.checkStr(i.ReductionSingleton().mask.time_mask, ";17500 22000") + self.checkStr(i.ReductionSingleton().mask.time_mask_r, "") + self.checkStr(i.ReductionSingleton().mask.time_mask_f, "") + self.checkStr(i.ReductionSingleton().mask.time_mask_f, "") + self.assertTrue(i.ReductionSingleton().mask.arm_width is None) + self.assertTrue(i.ReductionSingleton().mask.arm_angle is None) + self.assertTrue(i.ReductionSingleton().mask.arm_x is None) + self.assertTrue(i.ReductionSingleton().mask.arm_y is None) + self.assertTrue(i.ReductionSingleton().mask.phi_mirror) + + def applyGUISettings(self): + i.ReductionSingleton().instrument.setDetector('rear-detector') + i.ReductionSingleton().to_Q.output_type='1D' + i.ReductionSingleton().user_settings.readLimitValues('L/R '+'41 '+'-1 '+'1', i.ReductionSingleton()) + i.LimitsWav(1.5,12.5,0.125,'LIN') + i.ReductionSingleton().user_settings.readLimitValues('L/Q .001,.001,.0126,-.08,.2', i.ReductionSingleton()) + i.LimitsQXY(0.0,0.05,0.001,'LIN') + i.SetPhiLimit(-90.0,90.0, True) + i.SetDetectorFloodFile('','REAR') + i.SetDetectorFloodFile('','FRONT') + i.TransFit(mode='Logarithmic', lambdamin='1.5', lambdamax='12.5', selector='BOTH') + i.SetFrontDetRescaleShift(scale=1.0,shift=0.0) + i.Gravity(True) + i.SetSampleOffset('53') + i.SetMonitorSpectrum('1',True) + i.SetTransSpectrum('1',True) + i.SetCentre('155.45','-169.6','rear') + i.SetCentre('155.45','-169.6','front') + i.Mask('MASK/CLEAR') + i.Mask('MASK/CLEAR/TIME') + i.Mask('MASK/REAR H0') + i.Mask('MASK/REAR H190>H191') + i.Mask('MASK/REAR H167>H172') + i.Mask('MASK/REAR V0') + i.Mask('MASK/REAR V191') + i.Mask('MASK/FRONT H0') + i.Mask('MASK/FRONT H190>H191') + i.Mask('MASK/FRONT V0') + i.Mask('MASK/FRONT V191') + i.Mask('MASK/FRONT H156>H159') + i.Mask('MASK/TIME 17500 22000') + i.Mask('L/PHI -90.0 90.0') + i.SetVerboseMode(True) + + def checkFittingSettings(self, fitdict): + self.checkFloat(fitdict['scale'], 1.0) + self.checkFloat(fitdict['shift'], 0.0) + + + + def initialization(self): + if i.ReductionSingleton().get_instrument() != 'SANS2D': + i.ReductionSingleton.clean(isis_reducer.ISISReducer) + i.ReductionSingleton().set_instrument(isis_instrument.SANS2D()) + + i.ReductionSingleton.clean(isis_reducer.ISISReducer) + i.ReductionSingleton().set_instrument(isis_instrument.SANS2D()) + i.ReductionSingleton().user_settings =isis_reduction_steps.UserFile(MASKFILE); + i.ReductionSingleton().user_settings.execute(i.ReductionSingleton()) + return i + + def runTest(self): + self.initialization() + + self.checkFirstPart() + + import SANSBatchMode as batch + + self.applyGUISettings() + + _user_settings_copy = copy.deepcopy(i.ReductionSingleton().user_settings) + + fit_settings={'scale':1.0,'shift':0.0} + fit_settings = batch.BatchReduce(BATCHFILE,'.nxs', saveAlgs={}, reducer=i.ReductionSingleton().reference(),combineDet='rear'); + + self.checkFittingSettings(fit_settings) + + def validate(self): + self.tolerance_is_reller = True + self.tolerance = 1.0e-2 + return "trans_test_rear","SANSReductionGUI.nxs" + +class SANS2DGUIReduction(SANS2DGUIBatchReduction): + """Script executed by SANS GUI Interface to perform reduction in single mode""" + + def checkAfterLoad(self): + self.checkFloat(i.ReductionSingleton().get_sample().loader.periods_in_file, 1) + self.checkFloat(i.ReductionSingleton().background_subtracter.periods_in_file, 1) + self.checkFloat(i.ReductionSingleton().samp_trans_load.direct.periods_in_file, 1) + self.checkFloat(i.ReductionSingleton().can_trans_load.direct.periods_in_file,1) + self.assertTrue(not i.GetMismatchedDetList()) + + def loadSettings(self): + i.ReductionSingleton().instrument.setDetector('rear-detector') + i.SetCentre('155.45','-169.6','rear') + i.SetCentre('155.45','-169.6','front') + SCATTER_SAMPLE, logvalues = i.AssignSample(r'SANS2D00022048.nxs', reload = True, period = 1) + + i.SetCentre('155.45','-169.6','rear') + i.SetCentre('155.45','-169.6','front') + SCATTER_SAMPLE, logvalues = i.AssignCan(r'SANS2D00022023.nxs', reload = True, period = 1) + + t1, t2 = i.TransmissionSample(r'SANS2D00022041.nxs', r'SANS2D00022024.nxs', period_t=1, period_d=1) + + t1, t2 = i.TransmissionCan(r'SANS2D00022024.nxs', r'SANS2D00022024.nxs', period_t=1, period_d=1) + + def applySampleSettings(self): + i.ReductionSingleton().get_sample().geometry.shape = 3 + i.ReductionSingleton().get_sample().geometry.height = 8 + i.ReductionSingleton().get_sample().geometry.width = 8 + i.ReductionSingleton().get_sample().geometry.thickness = 2 + + + def checkFittingSettings(self): + settings = {'scale':i.ReductionSingleton().instrument.getDetector('FRONT').rescaleAndShift.scale, + 'shift':i.ReductionSingleton().instrument.getDetector('FRONT').rescaleAndShift.shift} + super(SANS2DGUIReduction,self).checkFittingSettings(settings) + + + def cleanReduction(self, user_settings): + i.ReductionSingleton.clean(isis_reducer.ISISReducer) + i.ReductionSingleton().set_instrument(isis_instrument.SANS2D()) + #i.ReductionSingleton().user_file_path='' + i.ReductionSingleton().user_settings = user_settings + i.ReductionSingleton().user_settings.execute(i.ReductionSingleton()); + + + + def singleModePrepare(self): + self.initialization() + + self.checkFirstPart() + + self.loadSettings() + + self.checkAfterLoad() + + self.applyGUISettings() + + self.applySampleSettings() + + def runTest(self): + self.singleModePrepare() + + _user_settings_copy = copy.deepcopy(i.ReductionSingleton().user_settings) + + reduced = i.WavRangeReduction(full_trans_wav=False, resetSetup=False) + + self.checkFittingSettings() + + RenameWorkspace(reduced, OutputWorkspace='trans_test_rear') + + self.cleanReduction(_user_settings_copy) + + _user_settings_copy = copy.deepcopy(i.ReductionSingleton().user_settings) + + + +if __name__ == "__main__": + #test = SANS2DGUIBatchReduction() + #test.execute() + test = SANS2DGUIReduction() + test.execute() diff --git a/Code/Mantid/Testing/SystemTests/tests/analysis/SANS2DReductionGUIAdded.py b/Code/Mantid/Testing/SystemTests/tests/analysis/SANS2DReductionGUIAdded.py new file mode 100644 index 000000000000..3f3d963d1c3b --- /dev/null +++ b/Code/Mantid/Testing/SystemTests/tests/analysis/SANS2DReductionGUIAdded.py @@ -0,0 +1,58 @@ +import sys +import os + +if __name__ == "__main__": + # it is just to allow running this test in Mantid, allowing the following import + sys.path.append('/apps/mantid/systemtests/StressTestFramework/') + +from mantid.simpleapi import * +import ISISCommandInterface as i +import isis_reducer +import isis_instrument +import isis_reduction_steps +import copy +import SANS2DReductionGUI as sansgui + +class SANS2DReductionGUIAddedFiles(sansgui.SANS2DGUIReduction): + def runTest(self): + self.initialization() + + self.checkFirstPart() + + # add files (SAMPLE and CAN) + import SANSadd2 + SANSadd2.add_runs(('22048','22048'),'SANS2D', '.nxs', rawTypes=('.add','.raw','.s*'), lowMem=False) + SANSadd2.add_runs(('22023','22023'),'SANS2D', '.nxs', rawTypes=('.add','.raw','.s*'), lowMem=False) + + # load values: + i.SetCentre('155.45','-169.6','rear') + i.SetCentre('155.45','-169.6','front') + SCATTER_SAMPLE, logvalues = i.AssignSample(r'SANS2D00022048-add.nxs', reload = True, period = 1) + SCATTER_SAMPLE, logvalues = i.AssignCan(r'SANS2D00022023-add.nxs', reload = True, period = 1) + i.TransmissionSample(r'SANS2D00022041.nxs', r'SANS2D00022024.nxs', period_t=1, period_d=1) + i.TransmissionCan(r'SANS2D00022024.nxs', r'SANS2D00022024.nxs', period_t=1, period_d=1) + + self.checkAfterLoad() + + self.applyGUISettings() + + self.applySampleSettings() + _user_settings_copy = copy.deepcopy(i.ReductionSingleton().user_settings) + + reduced = i.WavRangeReduction(full_trans_wav=False, resetSetup=False) + RenameWorkspace(reduced, OutputWorkspace='trans_test_rear') + + self.checkFittingSettings() + self.cleanReduction(_user_settings_copy) + + def validate(self): + # we have double the sample and the can, this means that the reduced data will be + # almost the same + self.tolerance_is_reller = True + self.tolerance = 0.35 + return "trans_test_rear","SANSReductionGUI.nxs" + + +if __name__ == "__main__": + test = SANS2DReductionGUIAddedFiles() + test.execute() diff --git a/Code/Mantid/Testing/SystemTests/tests/analysis/SANS2DSearchCentreGUI.py b/Code/Mantid/Testing/SystemTests/tests/analysis/SANS2DSearchCentreGUI.py new file mode 100644 index 000000000000..6f88b70ac380 --- /dev/null +++ b/Code/Mantid/Testing/SystemTests/tests/analysis/SANS2DSearchCentreGUI.py @@ -0,0 +1,69 @@ +import sys +import os +if __name__ == "__main__": + # it is just to allow running this test in Mantid, allowing the following import + sys.path.append('/apps/mantid/systemtests/StressTestFramework/') +from mantid.simpleapi import * +import ISISCommandInterface as i +import isis_reducer +import isis_instrument +import isis_reduction_steps +import SANS2DReductionGUI as sansgui + +class SANS2DGUISearchCentre(sansgui.SANS2DGUIReduction): + + def checkCentreResult(self): + self.checkFloat(i.ReductionSingleton().get_beam_center('rear')[0], 0.165) + self.checkFloat(i.ReductionSingleton().get_beam_center('rear')[1], -0.145 ) + + def runTest(self): + self.singleModePrepare() + + i.FindBeamCentre(rlow=41,rupp=280,MaxIter=3,xstart=float(150)/1000.,ystart=float(-160)/1000., tolerance=0.0001251) + self.checkCentreResult() + # clean up + + i.ReductionSingleton.clean(isis_reducer.ISISReducer) + i.ReductionSingleton().set_instrument(isis_instrument.SANS2D()) + i.ReductionSingleton().user_settings =isis_reduction_steps.UserFile(sansgui.MASKFILE) + i.ReductionSingleton().user_settings.execute(i.ReductionSingleton()) + + def validate(self): + # there is no workspace to be checked against + return True + +if __name__ == "__main__": + test = SANS2DGUISearchCentre() + test.execute() + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Code/Mantid/Testing/SystemTests/tests/analysis/SANS2DSlicing.py b/Code/Mantid/Testing/SystemTests/tests/analysis/SANS2DSlicing.py new file mode 100644 index 000000000000..9633884aadf7 --- /dev/null +++ b/Code/Mantid/Testing/SystemTests/tests/analysis/SANS2DSlicing.py @@ -0,0 +1,46 @@ +import sys + +if __name__ == "__main__": + # it is just to allow running this test in Mantid, allowing the following import + sys.path.append('/apps/mantid/systemtests/StressTestFramework/') + +import stresstesting + +from mantid.simpleapi import * +import ISISCommandInterface as i + +MASKFILE = FileFinder.getFullPath('MaskSANS2DReductionGUI.txt') +BATCHFILE = FileFinder.getFullPath('sans2d_reduction_gui_batch.csv') + +class SANS2DMinimalBatchReductionSliced(stresstesting.MantidStressTest): + def __init__(self): + super(SANS2DMinimalBatchReductionSliced, self).__init__() + config['default.instrument']='SANS2D' + def runTest(self): + import SANSBatchMode as batch + i.SANS2D() + i.MaskFile(MASKFILE) + i.SetEventSlices("0.0-451, 5-10") + fit_settings = batch.BatchReduce(BATCHFILE, '.nxs',saveAlgs={}, combineDet='rear') + + def validate(self): + self.tolerance = 0.02 + self.tolerance_is_reller=True + return str(mtd['trans_test_rear'][0]), 'SANSReductionGUI.nxs' + +class SANS2DMinimalSingleReductionSliced(SANS2DMinimalBatchReductionSliced): + def runTest(self): + i.SANS2D() + i.MaskFile(MASKFILE) + i.AssignSample('22048') + i.AssignCan('22023') + i.TransmissionSample('22041','22024') + i.TransmissionCan('22024', '22024') + i.SetEventSlices("0.0-450, 5-10") + reduced = i.WavRangeReduction() + RenameWorkspace(reduced, OutputWorkspace='trans_test_rear') + + +if __name__ == "__main__": + test = SANS2DMinimalSingleReductionSliced() + test.execute() diff --git a/Code/Mantid/Testing/SystemTests/tests/analysis/SANS2DWaveloops.py b/Code/Mantid/Testing/SystemTests/tests/analysis/SANS2DWaveloops.py new file mode 100644 index 000000000000..1edc29440506 --- /dev/null +++ b/Code/Mantid/Testing/SystemTests/tests/analysis/SANS2DWaveloops.py @@ -0,0 +1,27 @@ +import stresstesting +from mantid.simpleapi import * +from ISISCommandInterface import * + +class SANS2DWaveloops(stresstesting.MantidStressTest): + + def runTest(self): + + SANS2D() + MaskFile('MASKSANS2D.091A') + Gravity(True) + Set1D() + + AssignSample('992.raw') + TransmissionSample('988.raw', '987.raw') + AssignCan('993.raw') + TransmissionCan('989.raw', '987.raw') + + CompWavRanges([3, 5, 7, 11], False) + + def validate(self): + self.disableChecking.append('SpectraMap') + self.disableChecking.append('Axes') + self.disableChecking.append('Instrument') + # testing one of the workspaces that is produced, best not to choose the + # first one in produced by the loop as this is the least error prone + return '992rear_1D_7.0_11.0','SANS2DWaveloops.nxs' diff --git a/Code/Mantid/Testing/SystemTests/tests/analysis/SANSCentreSample.py b/Code/Mantid/Testing/SystemTests/tests/analysis/SANSCentreSample.py new file mode 100644 index 000000000000..a2057a4f1f1a --- /dev/null +++ b/Code/Mantid/Testing/SystemTests/tests/analysis/SANSCentreSample.py @@ -0,0 +1,27 @@ +import stresstesting +from mantid.simpleapi import * +from ISISCommandInterface import * + +class SANSCentreSample(stresstesting.MantidStressTest): + + def runTest(self): + + SANS2D() + + Set1D() + Detector("rear-detector") + MaskFile('MASKSANS2D.091A') + + AssignSample('992.raw') + + FindBeamCentre(60, 280, 19, 100.0/1000.0, -200.0/1000.0) + + def validate(self): + # Need to disable checking of the Spectra-Detector map because it isn't + # fully saved out to the nexus file (it's limited to the spectra that + # are actually present in the saved workspace). + self.disableChecking.append('SpectraMap') + self.disableChecking.append('Axes') + self.disableChecking.append('Instrument') + + return '992_sans_raw','SANSCentreSample.nxs' diff --git a/Code/Mantid/Testing/SystemTests/tests/analysis/SANSLOQBatch.py b/Code/Mantid/Testing/SystemTests/tests/analysis/SANSLOQBatch.py new file mode 100644 index 000000000000..4d2c72dd712a --- /dev/null +++ b/Code/Mantid/Testing/SystemTests/tests/analysis/SANSLOQBatch.py @@ -0,0 +1,44 @@ +import stresstesting +from mantid.simpleapi import * +from mantid import config +from ISISCommandInterface import * +from SANSBatchMode import * +import os.path + +class SANSLOQBatch(stresstesting.MantidStressTest): + + def runTest(self): + #DataPath("../Data/LOQ/") + #UserPath("../Data/LOQ/") + + #here we are testing the LOQ setup + LOQ() + #rear detector + Detector("main-detector-bank") + #test batch mode, although only the analysis from the last line is checked + # Find the file , this should really be in the BatchReduce reduction step + csv_file = FileFinder.getFullPath('batch_input.csv') + + Set1D() + MaskFile('MASK.094AA') + Gravity(True) + + BatchReduce(csv_file, 'raw', plotresults=False, saveAlgs={'SaveCanSAS1D':'xml','SaveNexus':'nxs'}) + + LoadNexus(Filename='54433sans.nxs',OutputWorkspace= 'result') + Plus(LHSWorkspace='result',RHSWorkspace= '99630sanotrans',OutputWorkspace= 'result') + + os.remove(os.path.join(config['defaultsave.directory'],'54433sans.nxs')) + os.remove(os.path.join(config['defaultsave.directory'],'99630sanotrans.nxs')) + os.remove(os.path.join(config['defaultsave.directory'],'54433sans.xml')) + os.remove(os.path.join(config['defaultsave.directory'],'99630sanotrans.xml')) + + def validate(self): + # Need to disable checking of the Spectra-Detector map because it isn't + # fully saved out to the nexus file (it's limited to the spectra that + # are actually present in the saved workspace). + self.disableChecking.append('SpectraMap') + self.disableChecking.append('Axes') + self.disableChecking.append('Instrument') + + return 'result','SANSLOQBatch.nxs' diff --git a/Code/Mantid/Testing/SystemTests/tests/analysis/SANSLOQCan2D.py b/Code/Mantid/Testing/SystemTests/tests/analysis/SANSLOQCan2D.py new file mode 100644 index 000000000000..1b01a008accb --- /dev/null +++ b/Code/Mantid/Testing/SystemTests/tests/analysis/SANSLOQCan2D.py @@ -0,0 +1,34 @@ +import stresstesting +from mantid.simpleapi import * +from ISISCommandInterface import * + +# Test is giving odd results on Linux, but only this 2D one. + +class SANSLOQCan2D(stresstesting.MantidStressTest): + + def runTest(self): + + LOQ() + Set2D() + Detector("main-detector-bank") + MaskFile('MASK.094AA') + # apply some small artificial shift + SetDetectorOffsets('REAR', -1.0, 1.0, 0.0, 0.0, 0.0, 0.0) + Gravity(True) + + AssignSample('99630.RAW') + AssignCan('99631.RAW') + + WavRangeReduction(None, None, False) + + + def validate(self): + # Need to disable checking of the Spectra-Detector map because it isn't + # fully saved out to the nexus file (it's limited to the spectra that + # are actually present in the saved workspace). + self.disableChecking.append('SpectraMap') + self.disableChecking.append('Instrument') + #when comparing LOQ files you seem to need the following + self.disableChecking.append('Axes') + + return '99630main_2D_2.2_10.0','SANSLOQCan2D.nxs' diff --git a/Code/Mantid/Testing/SystemTests/tests/analysis/SANSLoadersTest.py b/Code/Mantid/Testing/SystemTests/tests/analysis/SANSLoadersTest.py new file mode 100644 index 000000000000..0de445f4f489 --- /dev/null +++ b/Code/Mantid/Testing/SystemTests/tests/analysis/SANSLoadersTest.py @@ -0,0 +1,164 @@ +""" +Check the loaders of ISIS SANS reduction. It is created as systemtest because it does +take considerable time because it involves loading data. Besides, it uses data that is +currently available inside the systemtests. +""" + +import unittest +import stresstesting +from mantid.simpleapi import * +import isis_reduction_steps as steps +import ISISCommandInterface as ici +import isis_reducer + +class LoadRunTest(unittest.TestCase): + def setUp(self): + config['default.instrument'] = 'SANS2D' + ici.SANS2D() + + + def loadAndAssign(self, run_spec,options=dict()): + loadRun = steps.LoadRun(str(run_spec), **options) + loadRun._assignHelper(ici.ReductionSingleton()) + return loadRun + + def passWsAndAssign(self, ws, options=dict()): + loadRun = steps.LoadRun(ws, **options) + loadRun._assignHelper(ici.ReductionSingleton()) + return loadRun + + + def basicChecks(self, loadRun, file_path, runnum, periods_in_file, ws_name): + self.assertTrue('Data/SystemTest/SANS2D/'+file_path in loadRun._data_file.replace('\\','/'), 'Wrong data file: ' + loadRun._data_file) + self.assertEqual(loadRun.periods_in_file, periods_in_file) + self.assertEqual(loadRun.wksp_name, ws_name) + self.assertEqual(loadRun.shortrun_no, runnum) + + if periods_in_file == 1: + self.assertEqual(loadRun._wksp_name, ws_name) + self.assertTrue(not loadRun.move2ws(0)) + self.assertEqual(loadRun.wksp_name, ws_name) + else: + self.assertTrue(loadRun.move2ws(0)) + self.assertEqual(loadRun.wksp_name, ws_name) + + + + def test_single_period_nxs_file(self): + runnum = 22048 + loadRun = self.loadAndAssign(runnum) + self.basicChecks(loadRun, 'SANS2D00022048.nxs', runnum, 1, '22048_sans_nxs') + + self.assertEqual(loadRun._period, -1) + self.assertEqual(loadRun.ext, 'nxs') + + def test_single_period_raw_file(self): + runnum = 5547 + loadRun = self.loadAndAssign(runnum) + self.basicChecks(loadRun, 'SANS2D0000%d.raw'%(runnum), runnum, 1, '5547_sans_raw') + self.assertEqual(loadRun._period, -1) + self.assertEqual(loadRun.ext, 'raw') + + + def test_single_period_from_workspace_reload_true(self): + runnum = 22048 + ws22048 = Load(str(runnum)) + loadRun = self.passWsAndAssign(ws22048) + self.basicChecks(loadRun, 'SANS2D00022048.nxs', runnum, 1, '22048_sans_nxs') + + self.assertEqual(loadRun._period, -1) + self.assertEqual(loadRun.ext, 'nxs') + + def test_single_period_from_workspace_reload_false(self): + runnum = 22048 + ws22048 = Load(str(runnum)) + loadRun = self.passWsAndAssign(ws22048, {'reload':False}) + self.basicChecks(loadRun, 'SANS2D00022048.nxs', runnum, 1, ws22048.name()) + + self.assertEqual(loadRun._period, -1) + self.assertEqual(loadRun.ext, 'nxs') + + def test_single_period_trans_raw(self): + runnum = 988 + loadRun = self.loadAndAssign(runnum, {'trans':True}) + self.basicChecks(loadRun, 'SANS2D00000988.raw', runnum, 1, '988_trans_raw') + self.assertEqual(loadRun._period, -1) + self.assertEqual(loadRun.ext, 'raw') + + def test_multiperiod_nxs_file(self): + runnum = 5512 + loadRun = self.loadAndAssign(runnum) + self.basicChecks(loadRun, 'SANS2D00005512.nxs', runnum, 13, '5512_sans_nxs_1') + self.assertEqual(loadRun._period, -1) + self.assertTrue(loadRun.move2ws(12)) + self.assertEqual(loadRun.wksp_name, '5512_sans_nxs_13') + + def test_multiperiod_from_workspace_reload_false(self): + runnum = 5512 + ws5512 = Load(str(runnum)) + loadRun = self.passWsAndAssign(ws5512, {'reload':False}) + self.basicChecks(loadRun, 'SANS2D00005512.nxs', runnum, 13, ws5512[0].name()) + self.assertEqual(loadRun._period, -1) + self.assertTrue(loadRun.move2ws(12)) + self.assertEqual(loadRun.wksp_name, ws5512[12].name()) + + def test_loading_single_period_in_multiperiod(self): + runnum = 5512 + loadRun = self.loadAndAssign(runnum, {'entry':5}) + name = '5512p5_sans_nxs' + self.basicChecks(loadRun, 'SANS2D00005512.nxs', runnum, 1, name) + self.assertEqual(loadRun._period, 5) + self.assertTrue(not loadRun.move2ws(1)) + self.assertEqual(loadRun.wksp_name, name) + +class LoadSampleTest(unittest.TestCase): + """LoadSample extends LoadRun in order to move the workspaces to the defined centre""" + def setUp(self): + config['default.instrument'] = 'SANS2D' + ici.SANS2D() + + def test_single_period_nxs_file(self): + ici.SetCentre(1,-2) + loadSample = steps.LoadSample('22048') + loadSample.execute(ici.ReductionSingleton(), True) + self.assertEqual(loadSample.wksp_name, '22048_sans_nxs') + self.assertTrue(not loadSample.entries) + cur_pos = ici.ReductionSingleton().instrument.cur_detector_position(loadSample.wksp_name) + self.assertAlmostEqual(cur_pos[0],1/1000.0) + self.assertAlmostEqual(cur_pos[1], -2/1000.0) + + def test_multiperiod_nxs_file(self): + ici.SetCentre(1, -2) + loadSample = steps.LoadSample('5512') + loadSample.execute(ici.ReductionSingleton(), True) + self.assertEqual(loadSample.wksp_name, '5512_sans_nxs_1') + self.assertEqual(loadSample.entries, range(0,13)) + for index in [0,5,12]: + loadSample.move2ws(index) + self.assertEqual(loadSample.wksp_name, '5512_sans_nxs_'+str(index+1)) + cur_pos = ici.ReductionSingleton().instrument.cur_detector_position(loadSample.wksp_name) + self.assertAlmostEqual(cur_pos[0], 0.001) + self.assertAlmostEqual(cur_pos[1], -0.002) + + +class LoadSampleTestStressTest(stresstesting.MantidStressTest): + def runTest(self): + self._success = False + suite = unittest.TestSuite() + suite.addTest(unittest.makeSuite(LoadRunTest, 'test')) + suite.addTest(unittest.makeSuite(LoadSampleTest, 'test')) + runner = unittest.TextTestRunner() + res = runner.run(suite) + if res.wasSuccessful(): + self._success = True + + def requiredMemoryMB(self): + return 2000 + + def validate(self): + return self._success + + + +if __name__ == '__main__': + unittest.main() diff --git a/Code/Mantid/Testing/SystemTests/tests/analysis/SEQUOIAreduction.py b/Code/Mantid/Testing/SystemTests/tests/analysis/SEQUOIAreduction.py new file mode 100644 index 000000000000..8c88add11396 --- /dev/null +++ b/Code/Mantid/Testing/SystemTests/tests/analysis/SEQUOIAreduction.py @@ -0,0 +1,267 @@ +""" +Test the SNS inelatic reduction scripts. +""" + +import stresstesting +import os +import shutil +import glob +import mantid +from mantid.simpleapi import * +from numpy import * + +class DirectInelaticSNSTest(stresstesting.MantidStressTest): + + #setup routines + def topbottom(self): + #create top and bottom mask + LoadEventNexus(Filename='SEQ_12384_event.nxs', OutputWorkspace='mask',CompressTolerance=0.1) + Rebin(InputWorkspace='mask',OutputWorkspace='mask',Params="500,15500,16000",PreserveEvents=False) + w=mtd['mask'] + indexlist=[] + for i in range(w.getNumberHistograms()): + if (i%128) in [0,1,2,3,4,5,6,7,120,121,122,123,124,125,126,127]: + indexlist.append(i) + + MaskDetectors(Workspace='mask',WorkspaceIndexList=indexlist) + SaveNexus(InputWorkspace="mask",Filename = os.path.join(self.customDataDir,"mask_top_bottom.nxs")) + DeleteWorkspace('mask') + + def setupFiles(self): + self.customDataDir = os.path.join(mantid.config['defaultsave.directory'], 'temp') + datasearch = mantid.config.getDataSearchDirs() + filename='' + for d in datasearch: + temp = os.path.join(d, 'SEQ_12384_event.nxs') + if os.path.exists(temp): + filename=temp + self.cleanup() + os.mkdir(self.customDataDir) + shutil.copyfile(filename,os.path.join(self.customDataDir,'SEQ_12384_event.nxs')) + shutil.copyfile(filename,os.path.join(self.customDataDir,'SEQ_12385_event.nxs')) + self.topbottom() + + + #Routines from SNS scripts + def createanglelist(self,ws,amin,amax,astep): + """ + Function to create a map of detectors corresponding to angles in a certain range + """ + bin_angles=arange(amin+astep*0.5,amax+astep*0.5,astep) + a=[[] for i in range(len(bin_angles))] #list of list with detector IDs + w=mtd[ws] + origin = w.getInstrument().getSample().getPos() + for i in range(w.getNumberHistograms()): + ang=w.getDetector(i).getTwoTheta(origin,mantid.kernel.V3D(0,0,1))*180/math.pi + index=int((ang-amin)/astep) + if (index>=0) and (index0): + a[index].append(w.getSpectrum(i).getSpectrumNo()) + #create lists with angles and detector ID only for bins where there are detectors + ang_list=[] + detIDlist=[] + for elem,ang in zip(a,bin_angles): + if len(elem)>0: + detIDlist.append(elem) + ang_list.append(ang) + # file with grouping information + f = open(os.path.join(self.customDataDir,"group.map"),'w') + print >>f,len(ang_list) + for i in range(len(ang_list)): + print >>f,i + print >>f,len(detIDlist[i]) + mystring=str(detIDlist[i]).strip(']').strip('[') + mystring=mystring.replace(',','') + print >>f,mystring + f.close() + # par file + f = open(os.path.join(self.customDataDir,"group.par"),'w') + print >>f,len(ang_list) + for i in range(len(ang_list)): + print >>f,5.5,ang_list[i],0.0,1.0,1.0,1 + f.close() + return [ang_list,detIDlist] + + def GetEiT0(self,ws_name,EiGuess): + """ + Function to get Ei and -T0 + """ + alg=GetEi(InputWorkspace=ws_name,EnergyEstimate=EiGuess)#Run GetEi algorithm + [Ei,Tzero]=[alg[0],-alg[3]] #Extract incident energy and T0 + return [Ei,Tzero] + + def LoadPathMaker(self,runs,folder,prefix,suffix): + """ + Function to create paths to files from runnumbers + return a list of lists with the path, and a corrected list of runs. Files in the inner lists are added together + side effects: none + """ + path=[] + newruns=[] + try: + len(runs) + except: + runs=[runs] + for r in runs: + try: + len(r) + except: + r=[r] + temppath=[] + tempnewruns=[] + for i in range(len(r)): + temppath.append(os.path.join(folder,prefix+str(r[i])+suffix)) + tempnewruns.append(r[i]) + if (not(os.path.isfile(temppath[i]))): + raise IOError(temppath[i]+" not found") + path.append(temppath) + newruns.append(tempnewruns) + return [path,newruns] + + def CreateMasksAndVanadiumNormalization(self,vanfile,maskfile=''): + """ + Creates the Van workspace, one bin for each histogram, containing the integrated Vanadium intensity + VAN also contains the mask. + """ + if not os.path.isfile(os.path.join(self.customDataDir, "van.nx5")): + LoadEventNexus(Filename=vanfile,OutputWorkspace="VAN") + + Rebin(InputWorkspace="VAN",OutputWorkspace="VAN",Params="1000,15000,16000",PreserveEvents=False) #integrate all events between 1000 and 16000 microseconds + NormaliseByCurrent(InputWorkspace="VAN",OutputWorkspace="VAN") #normalize by proton charge + MedianDetectorTest(InputWorkspace="VAN",OutputWorkspace="MASK",SignificanceTest=100,HighThreshold =100) #determine which detectors to mask, and store them in the "MASK" workspace + if len(maskfile)>0: + LoadNexus(Filename=maskfile,OutputWorkspace="temp_mask") + MaskDetectors(Workspace="MASK",MaskedWorkspace="temp_mask") #add detectors masked in "temp_mask" to "MASK" + DeleteWorkspace(Workspace="temp_mask") + MaskDetectors(Workspace="VAN",MaskedWorkspace="MASK") #Mask "VAN". This prevents dividing by 0 + DeleteWorkspace(Workspace="MASK") #Mask is carried by VAN workspace + SaveNexus(InputWorkspace="VAN",Filename=os.path.join(self.customDataDir,"van.nx5")) + else: + LoadNexus(Filename=os.path.join(self.customDataDir,"van.nx5"),OutputWorkspace="VAN") + + + #functions from stresstesting + def requiredFiles(self): + return ['SEQ_12384_event.nxs'] + + + def cleanup(self): + for ws in ['IWS', 'OWST', 'VAN', 'monitor_ws']: + if mantid.AnalysisDataService.doesExist(ws): + DeleteWorkspace(ws) + if os.path.exists(self.customDataDir): + shutil.rmtree(self.customDataDir) + + def runTest(self): + self.setupFiles() + runs=[[12384,12385]] + maskfile = os.path.join(self.customDataDir,'mask_top_bottom.nxs') + V_file=os.path.join(self.customDataDir, 'SEQ_12384_event.nxs') + Eguess=35.0 #initial energy guess + Erange="-10.0,0.25,32.0" #Energy bins: Emin,Estep,Emax + datadir=self.customDataDir #Data directory + outdir=self.customDataDir #Output directory + fout_prefix="Ei_35.0_" + ang_offset=0.0 + angle_name='SEOCRot' #Name of the angle to read + maskandnormalize=True #flag to do the masking and normalization to Vanadium + flag_spe=False #flag to generate an spe file + flag_nxspe=True #flag to generate an nxspe file + do_powder=True #group detectors by angle + anglemin=0. #minumum angle + anglemax=70. #maximum angle + anglestep=1. #angle step - this can be fine tuned for pixel arc over detectors + + if (maskandnormalize): + self.CreateMasksAndVanadiumNormalization(V_file,maskfile=maskfile) #Creates a worspaces for Vanadium normalization and masking + + [paths,runs]=self.LoadPathMaker(runs,self.customDataDir,'SEQ_','_event.nxs') #process teh runlist + for flist,rlist,i in zip(paths,runs,range(len(paths))): #rlist is the inner list of runnumbers + psitmp=[] + for f,j in zip(flist,range(len(flist))): + if (j==0): + LoadEventNexus(Filename=f,OutputWorkspace="IWS") #Load an event Nexus file + LoadNexusMonitors(Filename=f,OutputWorkspace="monitor_ws") #Load monitors + else: + LoadEventNexus(Filename=f,OutputWorkspace="IWS_temp") #Load an event Nexus file + LoadNexusMonitors(Filename=f,OutputWorkspace="monitor_ws_temp") #Load monitors + Plus(LHSWorkspace="IWS",RHSWorkspace="IWS_temp",OutputWorkspace="IWS") #Add events to the original workspcace + Plus(LHSWorkspace="monitor_ws",RHSWorkspace="monitor_ws_temp",OutputWorkspace="monitor_ws") #Add monitors to the original monitor workspcace + #cleanup + DeleteWorkspace("IWS_temp") + DeleteWorkspace("monitor_ws_temp") + w=mtd["IWS"] + psi=array(w.getRun()[angle_name].value).mean()+ang_offset + FilterBadPulses(InputWorkspace="IWS",OutputWorkspace = "IWS",LowerCutoff = 50) # get psi before filtering bad pulses + [Efixed,T0]=self.GetEiT0("monitor_ws",Eguess) #Get Ei and -T0 using the function defined before + ChangeBinOffset(InputWorkspace="IWS",OutputWorkspace="OWS",Offset=T0) #Change all TOF by -T0 + NormaliseByCurrent(InputWorkspace="OWS",OutputWorkspace="OWS") #normalize by proton charge + ConvertUnits(InputWorkspace="OWS",OutputWorkspace="OWS",Target="Wavelength",EMode="Direct",EFixed=Efixed) #The algorithm for He3 tube efficiency requires wavelength units + He3TubeEfficiency(InputWorkspace="OWS",OutputWorkspace="OWS") #Apply correction due to absorption in He3 + ConvertUnits(InputWorkspace="OWS",OutputWorkspace="OWS",Target="DeltaE",EMode="Direct",EFixed=Efixed) #Switch to energy transfer + CorrectKiKf(InputWorkspace="OWS",OutputWorkspace="OWS") # apply ki/kf correction + Rebin(InputWorkspace="OWS",OutputWorkspace="OWST",Params=Erange,PreserveEvents=False) # go to histogram mode (forget events) + ConvertToDistribution(Workspace="OWST") #Convert to differential cross section by dividing by the energy bin width + DeleteWorkspace("OWS") + if (maskandnormalize): + MaskDetectors(Workspace="OWST",MaskedWorkspace="VAN") #apply overall mask + # the following is commented, since it's the same run, not a real vanadium + #Divide(LHSWorkspace="OWST",RHSWorkspace="VAN",OutputWorkspace="OWST") #normalize by Vanadium, if desired + if (do_powder): + if (i==0): + mapping=self.createanglelist("OWST",anglemin,anglemax,anglestep) + GroupDetectors(InputWorkspace="OWST",OutputWorkspace="OWST",MapFile=os.path.join(self.customDataDir,"group.map"),Behaviour="Sum") + SolidAngle(InputWorkspace="OWST",OutputWorkspace="sa") + Divide(LHSWorkspace="OWST",RHSWorkspace="sa",OutputWorkspace="OWST") + DeleteWorkspace("sa") + barefname = "%s%d_%g" % (fout_prefix,rlist[0],psi) + fname_out = os.path.join(outdir, barefname) + if flag_spe: + SaveSPE(InputWorkspace="OWST",Filename=fname_out+".spe") #save the data in spe format. + if (i==0): + SavePHX(InputWorkspace="OWST",Filename=fname_out+".spe") + if flag_nxspe: + #save in NXSPE format + nxspe_name = fname_out+".nxspe" + self._nxspe_filename = nxspe_name + if (do_powder): + SaveNXSPE(InputWorkspace="OWST",Filename=nxspe_name,Efixed=Efixed,psi=psi,KiOverKfScaling=True, + ParFile=os.path.join(outdir, "group.par")) + else: + SaveNXSPE(InputWorkspace="OWST",Filename=nxspe_name,Efixed=Efixed,psi=psi,KiOverKfScaling=True) + + def validate(self): + #check if required files are created + mapfile = os.path.join(self.customDataDir, 'group.map') + parfile = os.path.join(self.customDataDir, 'group.par') + self.assertTrue(os.path.exists(mapfile)) + self.assertDelta(os.path.getsize(mapfile),700000,100000) + self.assertTrue(os.path.exists(parfile)) + self.assertGreaterThan(os.path.getsize(parfile),1000) + vanadiumfile = os.path.join(self.customDataDir, 'van.nx5') + self.assertTrue(os.path.exists(vanadiumfile)) + self.assertGreaterThan(os.path.getsize(vanadiumfile),10000000) + + # Check saved file (there should only be one) + #find the nxspe filename: it should be only one, but the name might depend on the rounding of phi + nxspelist=glob.glob(os.path.join(self.customDataDir,'*.nxspe')) + if len(nxspelist)>1 or len(nxspelist) == 0: + print "Error: Expected single nxspe file in %s. Found %d" % (self.customDataDir, len(nxspelist)) + return False + + # Name encodes rotation + self.assertGreaterThan(os.path.getsize(self._nxspe_filename),100000) + psi_part=self._nxspe_filename.split('12384_')[1] + psi_param=float(psi_part.split('.nxspe')[0]) + self.assertDelta(psi_param,-24,0.01) + + #input workspace + self.assertLessThan(mtd["IWS"].getNumberEvents(),100000) + self.assertGreaterThan(mtd["IWS"].getNumberEvents(),90000) + + # Need to disable checking of the Spectra-Detector map because it isn't + # fully saved out to the nexus file; some masked detectors should be picked + # up with by the mask values in the spectra + self.disableChecking.append('SpectraMap') + self.disableChecking.append('Instrument') + return "OWST",'SEQUOIAReduction.nxs' + diff --git a/Code/Mantid/Testing/SystemTests/tests/analysis/SNSConvertToMDTest.py b/Code/Mantid/Testing/SystemTests/tests/analysis/SNSConvertToMDTest.py new file mode 100644 index 000000000000..4fd364d6f23f --- /dev/null +++ b/Code/Mantid/Testing/SystemTests/tests/analysis/SNSConvertToMDTest.py @@ -0,0 +1,203 @@ +import stresstesting +import numpy +import os +from mantid.simpleapi import * + +###################################################################### +# Common configuration +# Main data file /SNS/SEQ/IPTS-4783/data +DATA_FILE = "SEQ_11499_event.nxs" +# Vanadium file +VAN_FILE = "SEQ_van.nxs" +# Initial energy guess +E_GUESS = 50 +# Energy bins: Emin, Estep, Emax +E_RANGE = "-10.0,0.2,45.0" +####################################################################### + +def makeOutputName(ws_name, dohist, doproj): + md_ws_name = ws_name + '_md' + tag="" + if dohist: + tag += "h" + else: + tag += "e" + if doproj: + tag += "wp" + else: + tag += "np" + + md_ws_name += "_" + tag + return md_ws_name + +def execReduction(dohist, doproj): + # Set the facility + config['default.facility'] = "SNS" + # SPE workspace name + workspace_name = "reduced" + # Run the reduction + DgsReduction(SampleInputFile=DATA_FILE, + IncidentBeamNormalisation="ByCurrent", + OutputWorkspace=workspace_name, + IncidentEnergyGuess=E_GUESS, + EnergyTransferRange=E_RANGE, + SofPhiEIsDistribution=dohist, + DetectorVanadiumInputFile=VAN_FILE, + UseProcessedDetVan=True) + + # Set the goniometer. Add a rotation angle fix as well. + SetGoniometer(Workspace=workspace_name, Axis0="CCR13VRot,0,1,0,1", + Axis1="49.73,0,1,0,1") + + # Set the information for the UB matrix + SetUB(Workspace=workspace_name, + a=3.643, b=3.643, c=5.781, alpha=90, beta=90, gamma=120, + u='1,1,0', v='0,0,1') + + # Create the MDEventWorkspace + md_output_ws = makeOutputName(workspace_name, dohist, doproj) + + if not doproj: + ConvertToMD(InputWorkspace=workspace_name, + OutputWorkspace=md_output_ws, + QDimensions='Q3D', MinValues='-5,-5,-5,-10', + QConversionScales='HKL', + MaxValues='5,5,5,45', MaxRecursionDepth='1') + else: + ConvertToMD(InputWorkspace=workspace_name, + OutputWorkspace=md_output_ws, + QDimensions='Q3D', MinValues='-5,-5,-5,-10', + QConversionScales='HKL', + MaxValues='5,5,5,45', MaxRecursionDepth='1', + Uproj='1,1,0', Vproj='1,-1,0', Wproj='0,0,1') + + # Remove SPE workspace + DeleteWorkspace(Workspace=workspace_name) + + return md_output_ws + +def validateMD(result,reference,tol=1.e-5,class_name='dummy',mismatchName=None): + """Returns the name of the workspace & file to compare""" + #elf.disableChecking.append('SpectraMap') + #elf.disableChecking.append('Instrument') + + valNames = [result,reference] + from mantid.simpleapi import Load,CompareMDWorkspaces,FrameworkManager,SaveNexus + + if not (reference in mtd): + Load(Filename=reference,OutputWorkspace=valNames[1]) + + checker = AlgorithmManager.create("CompareMDWorkspaces") + checker.setLogging(True) + checker.setPropertyValue("Workspace1",result) + checker.setPropertyValue("Workspace2",valNames[1]) + checker.setPropertyValue("Tolerance", str(tol)) + checker.setPropertyValue("IgnoreBoxID", "1") + checker.setPropertyValue("CheckEvents", "1") + + checker.execute() + if checker.getPropertyValue("Equals") != "1": + print " Workspaces do not match, result: ",checker.getPropertyValue("Result") + print " Test {0} fails".format(class_name) + if mismatchName: + targetFilename = class_name+mismatchName+'-mismatch.nxs' + else: + targetFilename = class_name+'-mismatch.nxs' + + SaveMD(InputWorkspace=valNames[0],Filename=targetFilename ) + return False + else: + return True; + + + +class SNSConvertToMDNoHistNoProjTest(stresstesting.MantidStressTest): + truth_file = "SEQ_11499_md_enp.nxs" + + def requiredMemoryMB(self): + """ Require about 2.5GB free """ + return 2500 + + def requiredFiles(self): + files = [self.truth_file, DATA_FILE] + return files + + def runTest(self): + self.output_ws = execReduction(False, False) + + self.gold_ws_name = self.truth_file.split('.')[0] + "_golden" + LoadMD(self.truth_file, OutputWorkspace=self.gold_ws_name) + + + def validate(self): + self.tolerance = 1.0e-1 + return validateMD(self.output_ws, self.gold_ws_name,self.tolerance,self.__class__.__name__); + +class SNSConvertToMDHistNoProjTest(stresstesting.MantidStressTest): + truth_file = "SEQ_11499_md_hnp.nxs" + + def requiredMemoryMB(self): + """ Require about 2.5GB free """ + return 2500 + + def requiredFiles(self): + config.appendDataSearchDir("/home/builder/data/SystemTests/AnalysisTests/ReferenceResults/"); + files = [self.truth_file, DATA_FILE] + return files + + def runTest(self): + self.output_ws = execReduction(True, False) + + self.gold_ws_name = self.truth_file.split('.')[0] + "_golden" + LoadMD(self.truth_file, OutputWorkspace=self.gold_ws_name) + + def validate(self): + self.tolerance = 1.0e-1 + return validateMD(self.output_ws, self.gold_ws_name,self.tolerance,self.__class__.__name__,self.gold_ws_name); + +class SNSConvertToMDNoHistProjTest(stresstesting.MantidStressTest): + truth_file = "SEQ_11499_md_ewp.nxs" + + def requiredMemoryMB(self): + """ Require about 2.5GB free """ + return 2500 + + def requiredFiles(self): + files = [self.truth_file, DATA_FILE] + return files + + def runTest(self): + self.output_ws = execReduction(False, True) + + self.gold_ws_name = self.truth_file.split('.')[0] + "_golden" + LoadMD(self.truth_file, OutputWorkspace=self.gold_ws_name) + + + def validate(self): + self.tolerance = 1.0e-3 + return validateMD(self.output_ws, self.gold_ws_name,self.tolerance,self.__class__.__name__,self.gold_ws_name); + #return (self.output_ws, self.gold_ws_name) + +class SNSConvertToMDHistProjTest(stresstesting.MantidStressTest): + truth_file = "SEQ_11499_md_hwp.nxs" + + def requiredMemoryMB(self): + """ Require about 2.5GB free """ + return 2500 + + def requiredFiles(self): + files = [self.truth_file, DATA_FILE] + return files + + def runTest(self): + self.output_ws = execReduction(True, True) + + self.gold_ws_name = self.truth_file.split('.')[0] + "_golden" + LoadMD(self.truth_file, OutputWorkspace=self.gold_ws_name) + + + def validate(self): + self.tolerance = 1.0e-3 + return validateMD(self.output_ws, self.gold_ws_name,self.tolerance,self.__class__.__name__,self.gold_ws_name); + #return (self.output_ws, self.gold_ws_name) + diff --git a/Code/Mantid/Testing/SystemTests/tests/analysis/SNSPowderRedux.py b/Code/Mantid/Testing/SystemTests/tests/analysis/SNSPowderRedux.py new file mode 100644 index 000000000000..4f8878a0c6ae --- /dev/null +++ b/Code/Mantid/Testing/SystemTests/tests/analysis/SNSPowderRedux.py @@ -0,0 +1,234 @@ +import stresstesting +from mantid.simpleapi import * +from mantid.api import FileFinder + +import os + +def getSaveDir(): + """determine where to save - the current working directory""" + import os + return os.path.abspath(os.path.curdir) + +def do_cleanup(): + Files = ["PG3_9829.gsa", + "PG3_9829.py", + "PG3_9830.gsa", + "PG3_9830.py"] + for file in Files: + absfile = FileFinder.getFullPath(file) + if os.path.exists(absfile): + os.remove(absfile) + return True + +class PG3Analysis(stresstesting.MantidStressTest): + ref_file = 'PG3_4844_reference.gsa' + cal_file = "PG3_FERNS_d4832_2011_08_24.cal" + char_file = "PG3_characterization_2011_08_31-HR.txt" + + def cleanup(self): + do_cleanup() + return True + + def requiredFiles(self): + files = [self.ref_file, self.cal_file, self.char_file] + files.append("PG3_4844_event.nxs") # /SNS/PG3/IPTS-2767/0/ + files.append("PG3_4866_event.nxs") # /SNS/PG3/IPTS-2767/0/ + files.append("PG3_5226_event.nxs") # /SNS/PG3/IPTS-2767/0/ + return files + + def runTest(self): + savedir = getSaveDir() + + # run the actual code + SNSPowderReduction(Instrument="PG3", RunNumber=4844, Extension="_event.nxs", + PreserveEvents=True, + CalibrationFile=self.cal_file, + CharacterizationRunsFile=self.char_file, + LowResRef=15000, RemovePromptPulseWidth=50, + Binning=-0.0004, BinInDspace=True, FilterBadPulses=95, + SaveAs="gsas and fullprof and pdfgetn", OutputDirectory=savedir, + FinalDataUnits="dSpacing") + + + # load output gsas file and the golden one + LoadGSS(Filename="PG3_4844.gsa", OutputWorkspace="PG3_4844") + LoadGSS(Filename=self.ref_file, OutputWorkspace="PG3_4844_golden") + + def validateMethod(self): + self.tolerance = 1.0e-2 + return "ValidateWorkspaceToWorkspace" + + def validate(self): + self.tolerance = 1.0e-2 + return ('PG3_4844','PG3_4844_golden') + +class PG3StripPeaks(stresstesting.MantidStressTest): + ref_file = 'PG3_4866_reference.gsa' + cal_file = "PG3_FERNS_d4832_2011_08_24.cal" + + def cleanup(self): + do_cleanup() + return True + + def requiredFiles(self): + files = [self.ref_file, self.cal_file] + files.append("PG3_4866_event.nxs") # vanadium + return files + + def runTest(self): + # determine where to save + import os + savedir = os.path.abspath(os.path.curdir) + + LoadEventNexus(Filename="PG3_4866_event.nxs", + OutputWorkspace="PG3_4866", + Precount=True) + FilterBadPulses(InputWorkspace="PG3_4866", + OutputWorkspace="PG3_4866") + RemovePromptPulse(InputWorkspace="PG3_4866", + OutputWorkspace="PG3_4866", + Width=50) + CompressEvents(InputWorkspace="PG3_4866", + OutputWorkspace="PG3_4866", + Tolerance=0.01) + SortEvents(InputWorkspace="PG3_4866") + CropWorkspace(InputWorkspace="PG3_4866", + OutputWorkspace="PG3_4866", + XMax=16666.669999999998) + LoadCalFile(InputWorkspace="PG3_4866", + CalFilename=self.cal_file, + WorkspaceName="PG3") + MaskDetectors(Workspace="PG3_4866", + MaskedWorkspace="PG3_mask") + AlignDetectors(InputWorkspace="PG3_4866", + OutputWorkspace="PG3_4866", + OffsetsWorkspace="PG3_offsets") + ConvertUnits(InputWorkspace="PG3_4866", + OutputWorkspace="PG3_4866", + Target="TOF") + UnwrapSNS(InputWorkspace="PG3_4866", + OutputWorkspace="PG3_4866", + LRef=62) + RemoveLowResTOF(InputWorkspace="PG3_4866", + OutputWorkspace="PG3_4866", + ReferenceDIFC=1500) + ConvertUnits(InputWorkspace="PG3_4866", + OutputWorkspace="PG3_4866", + Target="dSpacing") + Rebin(InputWorkspace="PG3_4866", + OutputWorkspace="PG3_4866", + Params=(0.1,-0.0004,2.2)) + SortEvents(InputWorkspace="PG3_4866") + DiffractionFocussing(InputWorkspace="PG3_4866", + OutputWorkspace="PG3_4866", + GroupingWorkspace="PG3_group") + EditInstrumentGeometry(Workspace="PG3_4866", + PrimaryFlightPath=60, + SpectrumIDs=[1], + L2=[3.2208], + Polar=[90.8074], + Azimuthal=[0]) + ConvertUnits(InputWorkspace="PG3_4866", + OutputWorkspace="PG3_4866", + Target="TOF") + Rebin(InputWorkspace="PG3_4866", + OutputWorkspace="PG3_4866", + Params=[-0.0004]) + ConvertUnits(InputWorkspace="PG3_4866", + OutputWorkspace="PG3_4866", + Target="dSpacing") + StripVanadiumPeaks(InputWorkspace="PG3_4866", + OutputWorkspace="PG3_4866", + PeakPositionTolerance=0.05, + FWHM=8, + BackgroundType="Quadratic") + ConvertUnits(InputWorkspace="PG3_4866", + OutputWorkspace="PG3_4866", + Target="TOF") + SaveGSS(InputWorkspace="PG3_4866", + Filename=os.path.join(savedir, "PG3_4866.gsa"), + SplitFiles=False, + Append=False, + Format="SLOG", + MultiplyByBinWidth=False, + ExtendedHeader=True) + + # load output gsas file and the golden one + LoadGSS(Filename="PG3_4866.gsa", OutputWorkspace="PG3_4866") + LoadGSS(Filename=self.ref_file, OutputWorkspace="PG3_4866_golden") + + def validateMethod(self): + self.tolerance = 1.0e-2 + return "ValidateWorkspaceToWorkspace" + + def validate(self): + self.tolerance = 1.0e-2 + return ('PG3_4866','PG3_4866_golden') + +class SeriesAndConjoinFilesTest(stresstesting.MantidStressTest): + cal_file = "PG3_FERNS_d4832_2011_08_24.cal" + char_file = "PG3_characterization_2012_02_23-HR-ILL.txt" + ref_files = ['PG3_9829_reference.gsa', 'PG3_9830_reference.gsa'] + data_files = ['PG3_9829_event.nxs', 'PG3_9830_event.nxs'] + + def cleanup(self): + do_cleanup() + return True + + def requiredMemoryMB(self): + """Requires 3Gb""" + return 3000 + + def requiredFiles(self): + files = [self.cal_file, self.char_file] + files.extend(self.ref_files) + files.extend(self.data_files) + return files + + def runTest(self): + savedir = getSaveDir() + + # reduce a sum of runs - and drop it + SNSPowderReduction(Instrument="PG3", RunNumber=[9829,9830], Extension="_event.nxs", + Sum=True, # This is the difference with the next call + PreserveEvents=True, VanadiumNumber=-1, + CalibrationFile=self.cal_file, + CharacterizationRunsFile=self.char_file, + LowResRef=15000, RemovePromptPulseWidth=50, + Binning=-0.0004, BinInDspace=True, FilterBadPulses=True, + SaveAs="gsas", OutputDirectory=savedir, + FinalDataUnits="dSpacing") + + # reduce a series of runs + SNSPowderReduction(Instrument="PG3", RunNumber=[9829,9830], Extension="_event.nxs", + PreserveEvents=True, VanadiumNumber=-1, + CalibrationFile=self.cal_file, + CharacterizationRunsFile=self.char_file, + LowResRef=15000, RemovePromptPulseWidth=50, + Binning=-0.0004, BinInDspace=True, FilterBadPulses=True, + SaveAs="gsas", OutputDirectory=savedir, + FinalDataUnits="dSpacing") + + # needs to be set for ConjoinFiles to work + config['default.facility'] = 'SNS' + config['default.instrument'] = 'POWGEN' + + # load back in the resulting gsas files + ConjoinFiles(RunNumbers=[9829,9830], OutputWorkspace='ConjoinFilesTest', Directory=savedir) + # convert units makes sure the geometry was picked up + ConvertUnits(InputWorkspace='ConjoinFilesTest', OutputWorkspace='ConjoinFilesTest', + Target="dSpacing") + + # prepare for validation + LoadGSS(Filename="PG3_9829.gsa", OutputWorkspace="PG3_9829") + LoadGSS(Filename=self.ref_files[0], OutputWorkspace="PG3_4844_golden") + #LoadGSS("PG3_9830.gsa", "PG3_9830") # can only validate one workspace + #LoadGSS(self.ref_file[1], "PG3_9830_golden") + + def validateMethod(self): + return None # it running is all that we need + + def validate(self): + self.tolerance = 1.0e-2 + return ('PG3_9829','PG3_9829_golden') + #return ('PG3_9830','PG3_9830_golden') # can only validate one workspace diff --git a/Code/Mantid/Testing/SystemTests/tests/analysis/SXDAnalysis.py b/Code/Mantid/Testing/SystemTests/tests/analysis/SXDAnalysis.py new file mode 100644 index 000000000000..c6f6f6e4bee2 --- /dev/null +++ b/Code/Mantid/Testing/SystemTests/tests/analysis/SXDAnalysis.py @@ -0,0 +1,54 @@ +import stresstesting +from mantid.simpleapi import * + +class SXDAnalysis(stresstesting.MantidStressTest): + """ + Start of a system test for SXD data analyiss + """ + + def runTest(self): + + ws = Load(Filename='SXD23767.raw', LoadMonitors='Exclude') + #AddSampleLog(Workspace=ws,LogName='NUM_THREADS',LogText='0',LogType='Number') + from time import clock + + # A lower SplitThreshold, with a reasonable bound on the recursion depth, helps find weaker peaks at higher Q. + start = clock(); + QLab = ConvertToDiffractionMDWorkspace(InputWorkspace=ws, OutputDimensions='Q (lab frame)', SplitThreshold=50, LorentzCorrection='1',MaxRecursionDepth='13',Extents='-15,15,-15,15,-15,15',OneEventPerBin='0') + print " ConvertToMD runs for: ",clock()-start,' sec' + + # NaCl has a relatively small unit cell, so the distance between peaks is relatively large. Setting the PeakDistanceThreshold + # higher avoids finding high count regions on the sides of strong peaks as separate peaks. + peaks_qLab = FindPeaksMD(InputWorkspace='QLab', MaxPeaks=300, DensityThresholdFactor=10, PeakDistanceThreshold=1.0) + + FindUBUsingFFT(PeaksWorkspace=peaks_qLab, MinD='3', MaxD='5',Tolerance=0.08) + + out_params = IndexPeaks(PeaksWorkspace=peaks_qLab,Tolerance=0.12,RoundHKLs=1) + number_peaks_indexed = out_params[0] + ratio_indexed = float(number_peaks_indexed)/peaks_qLab.getNumberPeaks() + self.assertTrue(ratio_indexed >= 0.8, "Not enough peaks indexed. Ratio indexed : " + str(ratio_indexed)) + + ShowPossibleCells(PeaksWorkspace=peaks_qLab,MaxScalarError='0.5') + SelectCellOfType(PeaksWorkspace=peaks_qLab, CellType='Cubic', Centering='F', Apply=True) + + unitcell_length = 5.64 # Angstroms + unitcell_angle = 90 + length_tolerance = 0.1 + # + angle_tolelerance = 0.25 # Actual tolernce seems is 0.17 + # + # Check results. + latt = peaks_qLab.sample().getOrientedLattice() + self.assertDelta( latt.a(), unitcell_length, length_tolerance, "a length is different from expected") + self.assertDelta( latt.b(), unitcell_length, length_tolerance, "b length is different from expected") + self.assertDelta( latt.c(), unitcell_length, length_tolerance, "c length is different from expected") + self.assertDelta( latt.alpha(), unitcell_angle, angle_tolelerance, "alpha angle is different from expected") + self.assertDelta( latt.beta(), unitcell_angle, angle_tolelerance, "beta angle is different from expected") + self.assertDelta( latt.gamma(), unitcell_angle, angle_tolelerance, "gamma angle length is different from expected") + + def doValidation(self): + # If we reach here, no validation failed + return True + def requiredMemoryMB(self): + """Far too slow for managed workspaces. They're tested in other places. Requires 2Gb""" + return 1000 diff --git a/Code/Mantid/Testing/SystemTests/tests/analysis/SpaceGroupFactoryTest.py b/Code/Mantid/Testing/SystemTests/tests/analysis/SpaceGroupFactoryTest.py new file mode 100644 index 000000000000..4f3065ff11ef --- /dev/null +++ b/Code/Mantid/Testing/SystemTests/tests/analysis/SpaceGroupFactoryTest.py @@ -0,0 +1,53 @@ +import stresstesting +import os +import re +from mantid.simpleapi import * +from mantid.geometry import * + +'''Check that the space groups generated by Mantid are correct.''' +class SpaceGroupFactoryTest(stresstesting.MantidStressTest): + def runTest(self): + self.spaceGroupData = self.loadReferenceData() + + availableSpaceGroups = SpaceGroupFactoryImpl.Instance().allSubscribedSpaceGroupSymbols() + + for symbol in availableSpaceGroups: + self.checkSpaceGroup(symbol) + + def checkSpaceGroup(self, symbol): + group = SpaceGroupFactoryImpl.Instance().createSpaceGroup(symbol) + + groupOperations = set(group.getSymmetryOperationStrings()) + referenceOperations = self.spaceGroupData[group.number()] + + differenceOne = groupOperations - referenceOperations + differenceTwo = referenceOperations - groupOperations + + self.assertTrue(len(differenceOne) == 0, "Problem in space group " + str(group.number()) + " (" + symbol + ")") + self.assertTrue(len(differenceTwo) == 0, "Problem in space group " + str(group.number()) + " (" + symbol + ")") + self.assertTrue(groupOperations == referenceOperations, "Problem in space group " + str(group.number()) + " (" + symbol + ")") + + def loadReferenceData(self): + from mantid.api import FileFinder + # Reference data. + # Dictionary has a string set for each space group number. + separatorMatcher = re.compile("(\d+)") + + fileName = FileFinder.Instance().getFullPath('SpaceGroupSymmetryOperations.txt') + + print fileName + + fileHandle = open(fileName, 'r') + spaceGroups = {} + currentGroup = 0 + for currentLine in fileHandle: + matchedSeparator = separatorMatcher.match(currentLine) + + if matchedSeparator is not None: + currentGroup = int(matchedSeparator.group(1)) + spaceGroups[currentGroup] = set() + else: + spaceGroups[currentGroup].add(SymmetryOperationFactoryImpl.Instance().createSymOp(currentLine.strip().replace(" ", "")).identifier()) + + return spaceGroups + diff --git a/Code/Mantid/Testing/SystemTests/tests/analysis/SphinxWarnings.py b/Code/Mantid/Testing/SystemTests/tests/analysis/SphinxWarnings.py new file mode 100644 index 000000000000..42030bcf7a64 --- /dev/null +++ b/Code/Mantid/Testing/SystemTests/tests/analysis/SphinxWarnings.py @@ -0,0 +1,107 @@ +""" +Some of the sphinx warnings come from the C++ code, from the properties of the algorithms or from the summary string +This test tries to detect the most common such errors. +It also detects if a new category is created (i.e. someone uses Utilities instead of Utility) +""" +import stresstesting +import mantid +import re + +class SphinxWarnings(stresstesting.MantidStressTest): + def __init__(self): + stresstesting.MantidStressTest.__init__(self) + self.allowedCategories=['Arithmetic', + 'CorrectionFunctions', + 'Crystal', + 'DataHandling', + 'Diagnostics', + 'Diffraction', + 'Events', + 'Examples', + 'ISIS', + 'Inelastic', + 'MDAlgorithms', + 'MPI', + 'Muon', + 'Optimization', + 'PythonAlgorithms', + 'Quantification', + 'Reflectometry', + 'Remote', + 'SANS', + 'SINQ', + 'Sample', + 'Transforms', + 'Utility', + 'Workflow'] + self.errorMessage="" + + def checkString(self,s): + tocheck=s + outputString='' + #replace strong emphasis: Space**NotSpaceText** + sub=re.compile(r' \*\*[^ ].+?\*\*') + for i in sub.findall(tocheck): + tocheck=tocheck.replace(i," ") + #replace emphasis: Space*NotSpaceText* + sub=re.compile(r' \*[^ ].+?\*') + for i in sub.findall(tocheck): + tocheck=tocheck.replace(i," ") + #replace correctly named hyperlinks: Space`Name link>`__ + sub=re.compile(r' \`.+? <.+?.\`__') + for i in sub.findall(tocheck): + tocheck=tocheck.replace(i," ") + + #find strong emphasis errors + sub=re.compile(r' \*\*[^ ]+') + result=sub.findall(tocheck) + if len(result)>0: + outputString+="Strong emphasis error: "+str(result)+"\n" + #find emphasis errors + sub=re.compile(r' \*[^ ]+') + result=sub.findall(tocheck) + if len(result)>0: + outputString+="Emphasis error: "+str(result)+"\n" + #find potentially duplicate named hyperlinks + sub=re.compile(r' \`.+? <.+?.\`_') + result=sub.findall(tocheck) + if len(result)>0: + outputString+="Potentially unsafe named hyperlink: "+str(result)+"\n" + #find potentially wrong substitutions + sub=re.compile(r'\|.+?\|') + result=sub.findall(tocheck) + if len(result)>0: + outputString+="Potentially unsafe substitution: "+str(result)+"\n" + return outputString + + def runTest(self): + algs = mantid.AlgorithmFactory.getRegisteredAlgorithms(True) + for (name, versions) in algs.iteritems(): + for version in versions: + if mantid.api.DeprecatedAlgorithmChecker(name,version).isDeprecated()=='': + # get an instance + alg = mantid.AlgorithmManager.create(name, version) + #check categories + for cat in alg.categories(): + if cat.split("\\")[0] not in self.allowedCategories: + self.errorMessage+=name+" "+str(version)+" Category: "+cat.split("\\")[0]+" is not in the allowed list. If you need this category, please add it to the systemtest.\n" + #check summary + summary=alg.summary() + result=self.checkString(summary) + if len(result)>0: + self.errorMessage+=name+" "+str(version)+" Summary: "+result+"\n" + #check properties + properties=alg.getProperties() + for prop in properties: + propName=prop.name + propDoc=prop.documentation + result=self.checkString(propDoc) + if len(result)>0: + self.errorMessage+=name+" "+str(version)+" Property: "+propName+" Documentation: "+result +"\n" + + def validate(self): + if self.errorMessage!="": + print "Found the following errors:\n",self.errorMessage + return False + + return True diff --git a/Code/Mantid/Testing/SystemTests/tests/analysis/StepScan.py b/Code/Mantid/Testing/SystemTests/tests/analysis/StepScan.py new file mode 100644 index 000000000000..3e892652ecdc --- /dev/null +++ b/Code/Mantid/Testing/SystemTests/tests/analysis/StepScan.py @@ -0,0 +1,13 @@ +import stresstesting +from mantid.simpleapi import * + +'''Tests the StepScan workflow algorithm''' +class StepScanWorkflowAlgorithm(stresstesting.MantidStressTest): + + def runTest(self): + LoadMask(Instrument='HYS',InputFile=r'HYSA_mask.xml',OutputWorkspace='HYSA_mask') + Load(Filename='HYSA_2934.nxs.h5',OutputWorkspace='HYSA_2934',LoadMonitors='1') + StepScan(InputWorkspace='HYSA_2934',OutputWorkspace='StepScan',MaskWorkspace='HYSA_mask',XMin='3.25',XMax='3.75',RangeUnit='dSpacing') + + def validate(self): + return 'StepScan','StepScan.nxs' diff --git a/Code/Mantid/Testing/SystemTests/tests/analysis/SurfLoadingTest.py b/Code/Mantid/Testing/SystemTests/tests/analysis/SurfLoadingTest.py new file mode 100644 index 000000000000..65b217dc4c53 --- /dev/null +++ b/Code/Mantid/Testing/SystemTests/tests/analysis/SurfLoadingTest.py @@ -0,0 +1,23 @@ +from LoadAndCheckBase import * + +''' +Test File loading and basic data integrity checks of SURF data in Mantid. +''' +class SurfLoadingTest(LoadAndCheckBase): + def get_raw_workspace_filename(self): + return "SRF92132.raw" + + def get_nexus_workspace_filename(self): + return "SRF92132.nxs" + + def get_expected_number_of_periods(self): + return 22 + + def get_integrated_reference_workspace_filename(self): + return "SRF92132_1Integrated.nxs" + + def get_expected_instrument_name(self): + return "SURF" + + def enable_instrument_checking(self): + return True # No IDF in Mantid \ No newline at end of file diff --git a/Code/Mantid/Testing/SystemTests/tests/analysis/TOPAZPeakFinding.py b/Code/Mantid/Testing/SystemTests/tests/analysis/TOPAZPeakFinding.py new file mode 100644 index 000000000000..1275e600db0d --- /dev/null +++ b/Code/Mantid/Testing/SystemTests/tests/analysis/TOPAZPeakFinding.py @@ -0,0 +1,95 @@ +""" +System test that loads TOPAZ single-crystal data, +converts to Q space, finds peaks and indexes +them. +""" +import stresstesting +import numpy +from mantid.simpleapi import * + +class TOPAZPeakFinding(stresstesting.MantidStressTest): + + def requiredMemoryMB(self): + """ Require about 2GB free """ + return 2000 + + def runTest(self): + # Load then convert to Q in the lab frame + LoadEventNexus(Filename=r'TOPAZ_3132_event.nxs',OutputWorkspace='topaz_3132') + ConvertToDiffractionMDWorkspace(InputWorkspace='topaz_3132',OutputWorkspace='topaz_3132_MD',LorentzCorrection='1',SplitInto='2',SplitThreshold='150',OneEventPerBin='0') + + # Find peaks and UB matrix + FindPeaksMD(InputWorkspace='topaz_3132_MD',PeakDistanceThreshold='0.12',MaxPeaks='200',OutputWorkspace='peaks') + FindUBUsingFFT(PeaksWorkspace='peaks',MinD='2',MaxD='16') + + # Index the peaks and check + results = IndexPeaks(PeaksWorkspace='peaks') + indexed = results[0] + if indexed < 199: + raise Exception("Expected at least 199 of 200 peaks to be indexed. Only indexed %d!" % indexed) + + # Check the oriented lattice + CopySample(InputWorkspace='peaks',OutputWorkspace='topaz_3132',CopyName='0',CopyMaterial='0',CopyEnvironment='0',CopyShape='0') + originalUB = numpy.array(mtd["topaz_3132"].sample().getOrientedLattice().getUB()) + w = mtd["topaz_3132"] + s = w.sample() + ol = s.getOrientedLattice() + self.assertDelta( ol.a(), 4.712, 0.01, "Correct lattice a value not found.") + self.assertDelta( ol.b(), 6.06, 0.01, "Correct lattice b value not found.") + self.assertDelta( ol.c(), 10.41, 0.01, "Correct lattice c value not found.") + self.assertDelta( ol.alpha(), 90, 0.4, "Correct lattice angle alpha value not found.") + self.assertDelta( ol.beta(), 90, 0.4, "Correct lattice angle beta value not found.") + self.assertDelta( ol.gamma(), 90, 0.4, "Correct lattice angle gamma value not found.") + + # Go to HKL + ConvertToDiffractionMDWorkspace(InputWorkspace='topaz_3132',OutputWorkspace='topaz_3132_HKL',OutputDimensions='HKL',LorentzCorrection='1',SplitInto='2',SplitThreshold='150') + + # Bin to a line (H=0 to 6, L=3, K=3) + BinMD(InputWorkspace='topaz_3132_HKL',AxisAligned='0', + BasisVector0='X,units,1,0,0',BasisVector1='Y,units,6.12323e-17,1,0',BasisVector2='2,units,-0,0,1', + Translation='-0,3,6',OutputExtents='0,6, -0.1,0.1, -0.1,0.1',OutputBins='60,1,1', + OutputWorkspace='topaz_3132_HKL_line') + + # Now check the integrated bin and the peaks + w = mtd["topaz_3132_HKL_line"] + self.assertLessThan( w.signalAt(1), 1e4, "Limited background signal" ) + # The following tests are unstable for flips in HKL: + #self.assertDelta( w.signalAt(10), 1043651, 10e3, "Peak 1") + #self.assertDelta( w.signalAt(20), 354159, 10e3, "Peak 2") + #self.assertDelta( w.signalAt(30), 231615, 10e3, "Peak 3") + + # Now do the same peak finding with Q in the sample frame + ConvertToDiffractionMDWorkspace(InputWorkspace='topaz_3132',OutputWorkspace='topaz_3132_QSample',OutputDimensions='Q (sample frame)',LorentzCorrection='1',SplitInto='2',SplitThreshold='150') + FindPeaksMD(InputWorkspace='topaz_3132_QSample',PeakDistanceThreshold='0.12',MaxPeaks='200',OutputWorkspace='peaks_QSample') + FindUBUsingFFT(PeaksWorkspace='peaks_QSample',MinD='2',MaxD='16') + CopySample(InputWorkspace='peaks_QSample',OutputWorkspace='topaz_3132',CopyName='0',CopyMaterial='0',CopyEnvironment='0',CopyShape='0') + + # Index the peaks and check + results = IndexPeaks(PeaksWorkspace='peaks_QSample') + indexed = results[0] + if indexed < 199: + raise Exception("Expected at least 199 of 200 peaks to be indexed. Only indexed %d!" % indexed) + + # Check the UB matrix + w = mtd["topaz_3132"] + s = w.sample() + ol = s.getOrientedLattice() + self.assertDelta( ol.a(), 4.714, 0.01, "Correct lattice a value not found.") + self.assertDelta( ol.b(), 6.06, 0.01, "Correct lattice b value not found.") + self.assertDelta( ol.c(), 10.42, 0.01, "Correct lattice c value not found.") + self.assertDelta( ol.alpha(), 90, 0.4, "Correct lattice angle alpha value not found.") + self.assertDelta( ol.beta(), 90, 0.4, "Correct lattice angle beta value not found.") + self.assertDelta( ol.gamma(), 90, 0.4, "Correct lattice angle gamma value not found.") + + # Compare new and old UBs + newUB = numpy.array(mtd["topaz_3132"].sample().getOrientedLattice().getUB()) + # UB Matrices are not necessarily the same, some of the H,K and/or L sign can be reversed + diff = abs(newUB) - abs(originalUB) < 0.001 + for c in xrange(3): + # This compares each column, allowing old == new OR old == -new + if not (numpy.all(diff[:,c]) ): + raise Exception("More than 0.001 difference between UB matrices: Q (lab frame):\n%s\nQ (sample frame):\n%s" % (originalUB, newUB) ) + + def doValidation(self): + # If we reach here, no validation failed + return True diff --git a/Code/Mantid/Testing/SystemTests/tests/analysis/TobyFitResolutionSimulationTest.py b/Code/Mantid/Testing/SystemTests/tests/analysis/TobyFitResolutionSimulationTest.py new file mode 100644 index 000000000000..8d40be9d876c --- /dev/null +++ b/Code/Mantid/Testing/SystemTests/tests/analysis/TobyFitResolutionSimulationTest.py @@ -0,0 +1,127 @@ +"""Testing of the VATES quantification using +the TobyFitResolutionModel +""" +from stresstesting import MantidStressTest +from mantid.simpleapi import * + +def create_cuboid_xml(xlength,ylength,zlength): + xml = """ + + + + + + +""" + return xml % {"xpt": xlength/2.0,"ypt":ylength/2.0,"zpt":zlength/2.0} + +class TobyFitResolutionSimulationTest(MantidStressTest): + + _success = False + + def skipTests(self): + return False + + def requiredMemoryMB(self): + return 16000 + + def runTest(self): + ei = 300. + bins = [-30,3,279] + temperature = 6. + chopper_speed = 600. + + # Oriented lattice & goniometer. + alatt = 5.57 + blatt = 5.51 + clatt = 12.298 + uvec = [9.700000e-03,9.800000e-03,9.996000e-01] + vvec = [9.992000e-01,-3.460000e-02,-4.580000e-02] + + omega = 0.0 + alpha = 0.0 + beta = 0.0 + gamma = 0.0 + + # sample dimensions + sx = 0.05 # Perp + sy = 0.025 # Up direction + sz = 0.04 # Beam direction + + # Crystal mosaic + eta_sig = 4.0 + + fake_data = CreateSimulationWorkspace(Instrument='MERLIN', + BinParams=bins,UnitX='DeltaE', + DetectorTableFilename='MER06398.raw') + + ## + ## Required log entries, can be taken from real ones by placing an instrument parameter of the same + ## name pointing to the log name + ## + AddSampleLog(Workspace=fake_data, LogName='Ei',LogText=str(ei), LogType="Number") + AddSampleLog(Workspace=fake_data, LogName='temperature_log',LogText=str(temperature), LogType="Number") + AddSampleLog(Workspace=fake_data, LogName='chopper_speed_log',LogText=str(chopper_speed), LogType="Number") + AddSampleLog(Workspace=fake_data, LogName='eta_sigma',LogText=str(eta_sig), LogType="Number") + + ## + ## Sample shape + ## + CreateSampleShape(InputWorkspace=fake_data, ShapeXML=create_cuboid_xml(sx,sy,sz)) + + ## + ## Chopper & Moderator models. + ## + CreateModeratorModel(Workspace=fake_data,ModelType='IkedaCarpenterModerator', + Parameters="TiltAngle=32,TauF=2.7,TauS=0,R=0") + CreateChopperModel(Workspace=fake_data,ModelType='FermiChopperModel', + Parameters="AngularVelocity=chopper_speed_log,ChopperRadius=0.049,SlitThickness=0.0023,SlitRadius=1.3,Ei=Ei,JitterSigma=0.0") + + ## + ## UB matrix + ## + SetUB(Workspace=fake_data,a=alatt,b=blatt,c=clatt,u=uvec,v=vvec) + + ## + ## Sample rotation. Simulate 1 run at zero degrees psi + ## + + psi = 0.0 + AddSampleLog(Workspace=fake_data,LogName='psi',LogText=str(psi),LogType='Number') + SetGoniometer(Workspace=fake_data,Axis0="psi,0,1,0,1") + + # Create the MD workspace + qscale = 'Q in A^-1' + fake_md = ConvertToMD(InputWorkspace=fake_data, QDimensions="Q3D", QConversionScales=qscale, + SplitInto=[3], SplitThreshold=100, + MinValues="-15,-15,-15,-30", MaxValues="25,25,25,279",OverwriteExisting=True) + + # Run the simulation. + resol_model = "TobyFitResolutionModel" + xsec_model = "Strontium122" + parameters = "Seff=0.7,J1a=38.7,J1b=-5.0,J2=27.3,SJc=10.0,GammaSlope=0.08,MultEps=0,TwinType=0,MCLoopMin=10,MCLoopMax=10,MCType=1" # Use sobol & restart each pixel to ensure reproducible result + simulated = SimulateResolutionConvolvedModel(InputWorkspace=fake_md, + ResolutionFunction=resol_model, + ForegroundModel=xsec_model, + Parameters=parameters) + # Take a slice + slice_ws = BinMD(InputWorkspace=simulated, + AlignedDim0='[H,0,0], -12.000000, 9.000000, 100', + AlignedDim1='[0,K,0], -6.000000, 7.000000, 100', + AlignedDim2='[0,0,L], 0.000000, 6.000000, 1', + AlignedDim3='DeltaE, 100.000000, 150.000000, 1') + + # Check + ref_file = LoadMD(Filename='TobyFitResolutionSimulationTest.nxs') + result = CheckWorkspacesMatch(Workspace1=slice_ws, + Workspace2=ref_file, + Tolerance=1e-08) + self._success = ('success' in result.lower()) + + if not self._success: + SaveMD(InputWorkspace=slice_ws, + Filename='TobyFitResolutionSimulationTest-mismatch.nxs') + + def validate(self): + return self._success + diff --git a/Code/Mantid/Testing/SystemTests/tests/analysis/UserAlgotithmsBuild.py b/Code/Mantid/Testing/SystemTests/tests/analysis/UserAlgotithmsBuild.py new file mode 100644 index 000000000000..4cec914af176 --- /dev/null +++ b/Code/Mantid/Testing/SystemTests/tests/analysis/UserAlgotithmsBuild.py @@ -0,0 +1,41 @@ +import stresstesting +import sys +import os + +class UserAlgorithmsBuild(stresstesting.MantidStressTest): + + build_success = False + + def skipTests(self): + " We skip this test if the system is not Windows." + if sys.platform.startswith('win'): + return False + else: + return True + + def runTest(self): + """ + System test for testing that the UserAlgorithm build script works + """ + # Run the build + import subprocess + retcode = subprocess.call(["C:\\MantidInstall\\UserAlgorithms\\build.bat","--quiet"]) + if retcode == 0: + self.build_success = True + else: + self.build_success = False + + def cleanup(self): + # Remove build files as they will be loaded by the next + # process that runs this test and it then can't remove them! + install_dir = r'C:\MantidInstall\plugins' + lib_name = 'UserAlgorithms' + exts = ['.dll', '.exp', '.lib'] + for ext in exts: + try: + os.remove(os.path.join(install_dir, lib_name + ext)) + except OSError: + pass + + def validate(self): + return self.build_success diff --git a/Code/Mantid/Testing/SystemTests/tests/analysis/ValidateFacilitiesFile.py b/Code/Mantid/Testing/SystemTests/tests/analysis/ValidateFacilitiesFile.py new file mode 100644 index 000000000000..7ef8988def68 --- /dev/null +++ b/Code/Mantid/Testing/SystemTests/tests/analysis/ValidateFacilitiesFile.py @@ -0,0 +1,46 @@ +from mantid import config +import os +import re +import stresstesting +import glob + + +EXPECTED_EXT = '.expected' + +class ValidateFacilitiesFile(stresstesting.MantidStressTest): + + def skipTests(self): + try: + import genxmlif + import minixsv + except ImportError: + return True + return False + + + def runTest(self): + """Main entry point for the test suite""" + from genxmlif import GenXmlIfError + from minixsv import pyxsval + direc = config['instrumentDefinition.directory'] + filename = os.path.join(direc,'Facilities.xml') + xsdFile = os.path.join(direc,'Schema/Facilities/1.0/','FacilitiesSchema.xsd') + + # run the tests + failed = [] + try: + print "----------------------------------------" + print "Validating Facilities.xml" + pyxsval.parseAndValidateXmlInput(filename, xsdFile=xsdFile, validateSchema=0) + except Exception, e: + print "VALIDATION OF Facilities.xml FAILED WITH ERROR:" + print e + failed.append(filename) + + # final say on whether or not it 'worked' + print "----------------------------------------" + if len(failed) != 0: + print "SUMMARY OF FAILED FILES" + raise RuntimeError("Failed Validation of Facilities.xml") + else: + print "Succesfully Validated Facilities.xml" \ No newline at end of file diff --git a/Code/Mantid/Testing/SystemTests/tests/analysis/ValidateGroupingFiles.py b/Code/Mantid/Testing/SystemTests/tests/analysis/ValidateGroupingFiles.py new file mode 100644 index 000000000000..802e2fc1cfe3 --- /dev/null +++ b/Code/Mantid/Testing/SystemTests/tests/analysis/ValidateGroupingFiles.py @@ -0,0 +1,62 @@ +from mantid import config +import os +import re +import stresstesting +import glob + +EXPECTED_EXT = '.expected' + +class ValidateGroupingFiles(stresstesting.MantidStressTest): + + def skipTests(self): + try: + import genxmlif + import minixsv + except ImportError: + return True + return False + + def __getDataFileList__(self): + # get a list of directories to look in + direc = config['instrumentDefinition.directory'] + direc = os.path.join(direc,'Grouping') + print "Looking for Grouping files in: %s" % direc + cwd = os.getcwd() + os.chdir(direc) + myFiles = glob.glob("*Grouping*.xml") + os.chdir(cwd) + files = [] + for filename in myFiles: + files.append(os.path.join(direc, filename)) + return files + + def runTest(self): + """Main entry point for the test suite""" + from genxmlif import GenXmlIfError + from minixsv import pyxsval + direc = config['instrumentDefinition.directory'] + self.xsdFile = os.path.join(direc,'Schema/Grouping/1.0/','GroupingSchema.xsd') + files = self.__getDataFileList__() + + # run the tests + failed = [] + for filename in files: + try: + print "----------------------------------------" + print "Validating '%s'" % filename + pyxsval.parseAndValidateXmlInput(filename, xsdFile=self.xsdFile, validateSchema=0) + except Exception, e: + print "VALIDATION OF '%s' FAILED WITH ERROR:" % filename + print e + failed.append(filename) + + # final say on whether or not it 'worked' + print "----------------------------------------" + if len(failed) != 0: + print "SUMMARY OF FAILED FILES" + for filename in failed: + print filename + raise RuntimeError("Failed Validation for %d of %d files" \ + % (len(failed), len(files))) + else: + print "Succesfully Validated %d files" % len(files) diff --git a/Code/Mantid/Testing/SystemTests/tests/analysis/ValidateInstrumentDefinitionFiles.py b/Code/Mantid/Testing/SystemTests/tests/analysis/ValidateInstrumentDefinitionFiles.py new file mode 100644 index 000000000000..4c65a1306f5e --- /dev/null +++ b/Code/Mantid/Testing/SystemTests/tests/analysis/ValidateInstrumentDefinitionFiles.py @@ -0,0 +1,92 @@ +from mantid import config +import os +import re +import stresstesting +import glob + + +EXPECTED_EXT = '.expected' + +class ValidateInstrumentDefinitionFiles(stresstesting.MantidStressTest): + + def skipTests(self): + try: + import genxmlif + import minixsv + except ImportError: + return True + return False + + def __getDataFileList__(self): + # get a list of directories to look in + direc = config['instrumentDefinition.directory'] + print "Looking for instrument definition files in: %s" % direc + cwd = os.getcwd() + os.chdir(direc) + myFiles = glob.glob("*Definition*.xml") + os.chdir(cwd) + files = [] + for filename in myFiles: + files.append(os.path.join(direc, filename)) + return files + + def runTest(self): + """Main entry point for the test suite""" + from genxmlif import GenXmlIfError + from minixsv import pyxsval + + # need to extend minixsv library to add method for that forces it to + # validate against local schema when the xml file itself has + # reference to schema online. The preference is to systemtest against + # a local schema file to avoid this systemtest failing is + # external url temporariliy not available. Secondary it also avoid + # having to worry about proxies. + + class MyXsValidator(pyxsval.XsValidator): + ######################################## + # force validation of XML input against local file + # + def validateXmlInputForceReadFile (self, xmlInputFile, inputTreeWrapper, xsdFile): + xsdTreeWrapper = self.parse (xsdFile) + xsdTreeWrapperList = [] + xsdTreeWrapperList.append(xsdTreeWrapper) + self._validateXmlInput (xmlInputFile, inputTreeWrapper, xsdTreeWrapperList) + for xsdTreeWrapper in xsdTreeWrapperList: + xsdTreeWrapper.unlink() + return inputTreeWrapper + + def parseAndValidateXmlInputForceReadFile (inputFile, xsdFile=None, **kw): + myXsValidator = MyXsValidator(**kw) + # parse XML input file + inputTreeWrapper = myXsValidator.parse (inputFile) + # validate XML input file + return myXsValidator.validateXmlInputForceReadFile (inputFile, inputTreeWrapper, xsdFile) + + + + direc = config['instrumentDefinition.directory'] + self.xsdFile = os.path.join(direc,'Schema/IDF/1.0/','IDFSchema.xsd') + files = self.__getDataFileList__() + + # run the tests + failed = [] + for filename in files: + try: + print "----------------------------------------" + print "Validating '%s'" % filename + parseAndValidateXmlInputForceReadFile(filename, xsdFile=self.xsdFile) + except Exception, e: + print "VALIDATION OF '%s' FAILED WITH ERROR:" % filename + print e + failed.append(filename) + + # final say on whether or not it 'worked' + print "----------------------------------------" + if len(failed) != 0: + print "SUMMARY OF FAILED FILES" + for filename in failed: + print filename + raise RuntimeError("Failed Validation for %d of %d files" \ + % (len(failed), len(files))) + else: + print "Succesfully Validated %d files" % len(files) diff --git a/Code/Mantid/Testing/SystemTests/tests/analysis/ValidateParameterFiles.py b/Code/Mantid/Testing/SystemTests/tests/analysis/ValidateParameterFiles.py new file mode 100644 index 000000000000..49aec6296346 --- /dev/null +++ b/Code/Mantid/Testing/SystemTests/tests/analysis/ValidateParameterFiles.py @@ -0,0 +1,62 @@ +from mantid import config +import os +import re +import stresstesting +import glob +import time + +EXPECTED_EXT = '.expected' + +class ValidateParameterFiles(stresstesting.MantidStressTest): + + def skipTests(self): + try: + import genxmlif + import minixsv + except ImportError: + return True + return False + + def __getDataFileList__(self): + # get a list of directories to look in + direc = config['instrumentDefinition.directory'] + print "Looking for instrument definition files in: %s" % direc + cwd = os.getcwd() + os.chdir(direc) + myFiles = glob.glob("*Parameters*.xml") + os.chdir(cwd) + files = [] + for filename in myFiles: + files.append(os.path.join(direc, filename)) + return files + + def runTest(self): + """Main entry point for the test suite""" + from genxmlif import GenXmlIfError + from minixsv import pyxsval + direc = config['instrumentDefinition.directory'] + self.xsdFile = os.path.join(direc,'Schema/ParameterFile/1.0/','ParameterFileSchema.xsd') + files = self.__getDataFileList__() + + # run the tests + failed = [] + for filename in files: + try: + print "----------------------------------------" + print "Validating '%s'" % filename + pyxsval.parseAndValidateXmlInput(filename, xsdFile=self.xsdFile, validateSchema=0) + except Exception, e: + print "VALIDATION OF '%s' FAILED WITH ERROR:" % filename + print e + failed.append(filename) + + # final say on whether or not it 'worked' + print "----------------------------------------" + if len(failed) != 0: + print "SUMMARY OF FAILED FILES" + for filename in failed: + print filename + raise RuntimeError("Failed Validation for %d of %d files" \ + % (len(failed), len(files))) + else: + print "Succesfully Validated %d files" % len(files) diff --git a/Code/Mantid/Testing/SystemTests/tests/analysis/VesuvioFittingTest.py b/Code/Mantid/Testing/SystemTests/tests/analysis/VesuvioFittingTest.py new file mode 100644 index 000000000000..07f29ba93ee0 --- /dev/null +++ b/Code/Mantid/Testing/SystemTests/tests/analysis/VesuvioFittingTest.py @@ -0,0 +1,114 @@ +import stresstesting +from mantid.simpleapi import * + +import platform + +#------------------------------------------------------------------------------------------------------------------ +WS_PREFIX="fit" + +def do_fit_no_background(k_is_free): + """ + Run the Vesuvio fit without background. If k_is_free is False then it is fixed to f0.Width*sqrt(2)/12 + """ + function_str = \ + "composite=ComptonScatteringCountRate,NumDeriv=1,IntensityConstraints=\"Matrix(1|3)0|-1|3\";"\ + "name=GramCharlierComptonProfile,Mass=1.007940,HermiteCoeffs=1 0 1;"\ + "name=GaussianComptonProfile,Mass=27.000000;"\ + "name=GaussianComptonProfile,Mass=91.000000" + # Run fit + _do_fit(function_str, k_is_free) + +def do_fit_with_quadratic_background(): + """ + Run the Vesuvio fit without background. If k_is_free is False then it is fixed to f0.Width*sqrt(2)/12 + """ + function_str = \ + "composite=ComptonScatteringCountRate,NumDeriv=1,IntensityConstraints=\"Matrix(1|3)0|-1|3\";"\ + "name=GramCharlierComptonProfile,Mass=1.007940,HermiteCoeffs=1 0 1;"\ + "name=GaussianComptonProfile,Mass=27.000000;"\ + "name=GaussianComptonProfile,Mass=91.000000;name=Polynomial,n=2,A0=0,A1=0,A2=0" + # Run fit + _do_fit(function_str, k_is_free=False) + +def _do_fit(function_str, k_is_free): + """ + Run the Vesuvio . If k_is_free is False then it is fixed to f0.Width*sqrt(2)/12 + + """ + LoadVesuvio(Filename='14188-14190',OutputWorkspace='raw_ws',SpectrumList='135',Mode='SingleDifference', + InstrumentParFile=r'IP0005.dat') + CropWorkspace(InputWorkspace='raw_ws',OutputWorkspace='raw_ws',XMin=50,XMax=562) + # Convert to seconds + ScaleX(InputWorkspace='raw_ws',OutputWorkspace='raw_ws',Operation='Multiply',Factor=1e-06) + + if k_is_free: + ties_str = "f1.Width=10.000000,f2.Width=25.000000" + else: + ties_str = "f1.Width=10.000000,f2.Width=25.000000,f0.FSECoeff=f0.Width*sqrt(2)/12" + + constraints_str = "2.000000 < f0.Width < 7.000000" + + Fit(InputWorkspace='raw_ws',Function=function_str,Ties=ties_str,Constraints=constraints_str, + Output=WS_PREFIX, CreateOutput=True,OutputCompositeMembers=True,MaxIterations=5000, + Minimizer="Levenberg-Marquardt,AbsError=1e-08,RelError=1e-08") + # Convert to microseconds + ScaleX(InputWorkspace=WS_PREFIX + '_Workspace',OutputWorkspace=WS_PREFIX + '_Workspace',Operation='Multiply',Factor=1e06) + +def tolerance(): + # Not too happy about this but the gsl seems to behave slightly differently on Windows/Mac but the reference result is from Linux + # The results however are still acceptable + system = platform.system() + if system == "Windows": + if platform.architecture()[0] == "64bit": + return 1e-2 # Other fitting tests seem to require this level too. + else: + return 1e-1 + elif system == "Darwin": + return 1e-1 # Other fitting tests seem to require this level too. + else: + return 1e-6 + +#------------------------------------------------------------------------------------------------------------------ + +class VesuvioFittingTest(stresstesting.MantidStressTest): + + def runTest(self): + do_fit_no_background(k_is_free=False) + + self.assertTrue(WS_PREFIX + "_Workspace" in mtd, "Expected function workspace in ADS") + self.assertTrue(WS_PREFIX + "_Parameters" in mtd, "Expected parameters workspace in ADS") + self.assertTrue(WS_PREFIX + "_NormalisedCovarianceMatrix" in mtd, "Expected covariance workspace in ADS") + + def validate(self): + self.tolerance = tolerance() + return "fit_Workspace","VesuvioFittingTest.nxs" + +#------------------------------------------------------------------------------------------------------------------ + +class VesuvioFittingWithKFreeTest(stresstesting.MantidStressTest): + + def runTest(self): + do_fit_no_background(k_is_free=True) + + self.assertTrue(WS_PREFIX + "_Workspace" in mtd, "Expected function workspace in ADS") + self.assertTrue(WS_PREFIX + "_Parameters" in mtd, "Expected parameters workspace in ADS") + self.assertTrue(WS_PREFIX + "_NormalisedCovarianceMatrix" in mtd, "Expected covariance workspace in ADS") + + def validate(self): + self.tolerance = tolerance() + return "fit_Workspace","VesuvioFittingWithKFreeTest.nxs" + +#------------------------------------------------------------------------------------------------------------------ + +class VesuvioFittingWithQuadraticBackgroundTest(stresstesting.MantidStressTest): + + def runTest(self): + do_fit_with_quadratic_background() + + self.assertTrue(WS_PREFIX + "_Workspace" in mtd, "Expected function workspace in ADS") + self.assertTrue(WS_PREFIX + "_Parameters" in mtd, "Expected parameters workspace in ADS") + self.assertTrue(WS_PREFIX + "_NormalisedCovarianceMatrix" in mtd, "Expected covariance workspace in ADS") + + def validate(self): + self.tolerance = tolerance() + return "fit_Workspace","VesuvioFittingWithQuadraticBackgroundTest.nxs" diff --git a/Code/Mantid/Testing/SystemTests/tests/analysis/WishAnalysis.py b/Code/Mantid/Testing/SystemTests/tests/analysis/WishAnalysis.py new file mode 100644 index 000000000000..9cb2a9d4da82 --- /dev/null +++ b/Code/Mantid/Testing/SystemTests/tests/analysis/WishAnalysis.py @@ -0,0 +1,54 @@ +import stresstesting +from mantid.simpleapi import * + +class WishAnalysis(stresstesting.MantidStressTest): + """ + Runs the WISH analysis chain on one bank of data + """ + + def runTest(self): + # MG: 5/5/2010: The test machine only has 1 Gb of RAM and can't handle a whole bank of WISH + # load Data + LoadRaw(Filename="WISH00016748.raw",OutputWorkspace="w16748-1",LoadLogFiles="0",SpectrumMin="6",SpectrumMax="5000") + ConvertUnits(InputWorkspace="w16748-1",OutputWorkspace="w16748-1",Target="Wavelength") + # load monitors + LoadRaw(Filename="WISH00016748.raw",OutputWorkspace="monitor16748",LoadLogFiles="0",SpectrumMin="4",SpectrumMax="4") + ConvertUnits(InputWorkspace="monitor16748",OutputWorkspace="monitor16748",Target="Wavelength") + #etract integral section of monitor + CropWorkspace(InputWorkspace="monitor16748",OutputWorkspace="monitor16748",XMin="0.6",XMax="9.8") + ConvertToDistribution(Workspace="monitor16748") + # mask out vanadium peaks + MaskBins(InputWorkspace="monitor16748",OutputWorkspace="monitor16748",XMin="4.57",XMax="4.76") + MaskBins(InputWorkspace="monitor16748",OutputWorkspace="monitor16748",XMin="3.87",XMax="4.12") + MaskBins(InputWorkspace="monitor16748",OutputWorkspace="monitor16748",XMin="2.75",XMax="2.91") + MaskBins(InputWorkspace="monitor16748",OutputWorkspace="monitor16748",XMin="2.24",XMax="2.5") + #generate sspline and smooth + SplineBackground(InputWorkspace="monitor16748",OutputWorkspace="monitor16748",NCoeff="30") + SmoothData(InputWorkspace="monitor16748",OutputWorkspace="monitor16748",NPoints="50") + ConvertFromDistribution(Workspace="monitor16748") + #normalise data to the monitor in wavelength + NormaliseToMonitor(InputWorkspace="w16748-1",OutputWorkspace="w16748-1",MonitorWorkspace="monitor16748") + NormaliseToMonitor(InputWorkspace="w16748-1",OutputWorkspace="w16748-1",MonitorWorkspace="monitor16748",IntegrationRangeMin="0.6",IntegrationRangeMax="9.8") + #align detectors + ConvertUnits(InputWorkspace="w16748-1",OutputWorkspace="w16748-1",Target="TOF") + ReplaceSpecialValues(InputWorkspace="w16748-1",OutputWorkspace="w16748-1",NaNValue="0",InfinityValue="0") + AlignDetectors(InputWorkspace="w16748-1",OutputWorkspace="w16748-1",CalibrationFile="wish_grouping_noends2_no_offsets_nov2009.cal") + #focus data + DiffractionFocussing(InputWorkspace="w16748-1",OutputWorkspace="w16748-1foc",GroupingFileName="wish_grouping_noends2_no_offsets_nov2009.cal") + DeleteWorkspace(Workspace="w16748-1") + CropWorkspace(InputWorkspace="w16748-1foc",OutputWorkspace="w16748-1foc",XMin="0.83",XMax="45") + #load pre-processed empty and subtract + LoadNexusProcessed(Filename="emptycryo3307-1foc.nx5",OutputWorkspace="empty") + RebinToWorkspace(WorkspaceToRebin="empty",WorkspaceToMatch="w16748-1foc",OutputWorkspace="empty") + Minus(LHSWorkspace="w16748-1foc",RHSWorkspace="empty",OutputWorkspace="w16748-1foc") + DeleteWorkspace(Workspace="empty") + #Load preprocessed Vanadium and divide + LoadNexusProcessed(Filename="vana3123-1foc-SS.nx5",OutputWorkspace="vana") + RebinToWorkspace(WorkspaceToRebin="vana",WorkspaceToMatch="w16748-1foc",OutputWorkspace="vana") + Divide(LHSWorkspace="w16748-1foc",RHSWorkspace="vana",OutputWorkspace="w16748-1foc") + DeleteWorkspace(Workspace="vana") + #convert back to TOF for ouput to GSAS/Fullprof + ConvertUnits(InputWorkspace="w16748-1foc",OutputWorkspace="w16748-1foc",Target="TOF") + + def validate(self): + return 'w16748-1foc','WishAnalysis.nxs' diff --git a/Code/Mantid/Testing/SystemTests/tests/analysis/WishDiffuseScattering.py b/Code/Mantid/Testing/SystemTests/tests/analysis/WishDiffuseScattering.py new file mode 100644 index 000000000000..2e825993f1e8 --- /dev/null +++ b/Code/Mantid/Testing/SystemTests/tests/analysis/WishDiffuseScattering.py @@ -0,0 +1,62 @@ +""" +Tests diffuse scattering reduction as used on WISH +If this breaks for whatever reason, there is a good chance that unregistered scripts will also be broken. +- Email Pascal Manuel @ ISIS if things break here and let him know how his scripts may need to be modified. +""" + +import stresstesting +from mantid.simpleapi import * + +class WishDiffuseScattering(stresstesting.MantidStressTest): + + def requiredMemoryMB(self): + return 2000 + + def runTest(self): + + Load(Filename= 'Wish_Diffuse_Scattering_C.nxs',OutputWorkspace='C',LoadLogFiles='0',LoadMonitors='Exclude') + NormaliseByCurrent(InputWorkspace='C',OutputWorkspace='C') + CropWorkspace(InputWorkspace='C',OutputWorkspace='C',XMin='6000',XMax='99000') + Rebin(InputWorkspace='C',OutputWorkspace='C',Params='6000,-0.004,99900') + SmoothNeighbours(InputWorkspace='C',OutputWorkspace='Csn',RadiusUnits='NumberOfPixels',Radius='3',NumberOfNeighbours='25',PreserveEvents='0') + + Load(Filename= 'Wish_Diffuse_Scattering_B.nxs',OutputWorkspace='B',LoadLogFiles='0',LoadMonitors='Exclude') + NormaliseByCurrent(InputWorkspace='B',OutputWorkspace='B') + CropWorkspace(InputWorkspace='B',OutputWorkspace='B',XMin='6000',XMax='99000') + Rebin(InputWorkspace='B',OutputWorkspace='B',Params='6000,-0.004,99900') + SmoothNeighbours(InputWorkspace='B',OutputWorkspace='Bsn',RadiusUnits='NumberOfPixels',Radius='3',NumberOfNeighbours='25',PreserveEvents='0') + + Load(Filename= 'Wish_Diffuse_Scattering_A.nxs',OutputWorkspace='A',LoadLogFiles='0',LoadMonitors='Exclude') + NormaliseByCurrent(InputWorkspace='A',OutputWorkspace='A') + CropWorkspace(InputWorkspace='A',OutputWorkspace='A',XMin='6000',XMax='99000') + Rebin(InputWorkspace='A',OutputWorkspace='A',Params='6000,-0.004,99900') + SmoothNeighbours(InputWorkspace='A',OutputWorkspace='Asn',RadiusUnits='NumberOfPixels',Radius='3',NumberOfNeighbours='25',PreserveEvents='0') + SmoothData(InputWorkspace='Asn',OutputWorkspace='Asn-smooth',NPoints='50') + + Divide(LHSWorkspace='Csn',RHSWorkspace='Asn-smooth',OutputWorkspace='C_div_A_sn_smooth') + ReplaceSpecialValues(InputWorkspace='C_div_A_sn_smooth',OutputWorkspace='C_div_A_sn_smooth',NaNValue='0',InfinityValue='100000',BigNumberThreshold='99000') + + Divide(LHSWorkspace='Bsn',RHSWorkspace='Asn-smooth',OutputWorkspace='B_div_A_sn_smooth') + ReplaceSpecialValues(InputWorkspace='B_div_A_sn_smooth',OutputWorkspace='B_div_A_sn_smooth',NaNValue='0',InfinityValue='100000',BigNumberThreshold='99000') + + Minus(LHSWorkspace='C_div_A_sn_smooth',RHSWorkspace='B_div_A_sn_smooth',OutputWorkspace='CminusB_smooth') + + LoadIsawUB(InputWorkspace='CminusB_smooth',Filename='Wish_Diffuse_Scattering_ISAW_UB.mat') + + AddSampleLog(Workspace='CminusB_smooth',LogName='psi',LogText='0.0',LogType='Number Series') + SetGoniometer(Workspace='CminusB_smooth',Axis0='psi,0,1,0,1') + ConvertToDiffractionMDWorkspace(InputWorkspace='CminusB_smooth',OutputWorkspace='CminusB_smooth_MD_HKL',OutputDimensions='HKL',Version=2) + + + BinMD(InputWorkspace='CminusB_smooth_MD_HKL',AlignedDim0='[H,0,0],-1.0,8.0,200',AlignedDim1='[0,K,0],-1.0,8.0,200',AlignedDim2='[0,0,L],0,1.5,200',OutputWorkspace='test_rebin') + + #Quick sanity checks. No comparison with a saved workspace because SliceMD is too expensive compared to BinMD. + result = mtd['test_rebin'] + self.assertTrue(result.getNumDims() == 3) + self.assertTrue(result.getNPoints() == 8000000) + + return True; + + def doValidate(self): + return True; + diff --git a/Code/Mantid/Testing/SystemTests/tests/analysis/WishMasking.py b/Code/Mantid/Testing/SystemTests/tests/analysis/WishMasking.py new file mode 100644 index 000000000000..833af066ff34 --- /dev/null +++ b/Code/Mantid/Testing/SystemTests/tests/analysis/WishMasking.py @@ -0,0 +1,147 @@ +""" +Tests masking functionality specific to WISH. Working masking behaviour is critical in general, but is heavily used on WISH. +- Email Pascal Manuel @ ISIS if things break here and let him know how his scripts may need to be modified. +""" + +import stresstesting +import os +from mantid.simpleapi import * + +class WishMasking(stresstesting.MantidStressTest): + + # Utility function will return the masking corresponding to a workspace index from a cal file. + def get_masking_for_index(self, cal_file, requested_index): + while True: + line = cal_file.readline() + if line == "": + raise LookupError + line_contents = line.split() + try: + index = int(line_contents[0].strip()) + select = int(line_contents[3].strip()) + group = int(line_contents[4].strip()) + if(index == requested_index): + return select + except ValueError: + continue + + # Tests that the cal file is being created in the expected way. + # 1) Uses the masks to create a cal file + # 2) Read the cal file + # 3) Use the known masking boundaries to determine whether the cal file has been created propertly accoring to the function inputs. + def do_test_cal_file(self, masked_workspace, should_invert, expected_masking_identifier, expected_not_masking_identifier, masking_edge): + + cal_filename = 'wish_masking_system_test_temp.cal' + cal_file_full_path = os.path.join(config['defaultsave.directory'],cal_filename) + MaskWorkspaceToCalFile(InputWorkspace=masked_workspace, OutputFile=cal_file_full_path, Invert=should_invert) + file = open(cal_file_full_path, 'r') + try: + mask_boundary_inside = self.get_masking_for_index(file, masking_edge) + mask_boundary_outside = self.get_masking_for_index(file, masking_edge+1) + self.assertTrue(mask_boundary_inside == expected_masking_identifier) + self.assertTrue(mask_boundary_outside == expected_not_masking_identifier) + except LookupError: + print "Could not find the requested index" + self.assertTrue(False) + finally: + file.close() + os.remove(cal_file_full_path) + + def requiredMemoryMB(self): + return 2000 + + def runTest(self): + Load(Filename='WISH00016748.raw',OutputWorkspace='wish_ws') + ws = mtd['wish_ws'] + MaskDetectors(Workspace=ws, WorkspaceIndexList='0,1,2,3,4,5,6,7,8,9') + + # We just masked all detectors up to index == 9 + masking_edge = 9 + + # Test the 'isMasked' property on the detectors of the original workspace + self.assertTrue( ws.getDetector(masking_edge).isMasked() ) + self.assertTrue( not ws.getDetector(masking_edge + 1).isMasked() ) + + # Extract a masking workspace + ExtractMask( InputWorkspace=ws, OutputWorkspace='masking_wish_workspace' ) + mask_ws = mtd['masking_wish_workspace'] + + ## COMPLETE TESTS: These following are the tests that should pass when everything works. See below for reasons why. + + # Test the 'isMasked' property on the detectors of the masked workspace + # The following tests have been added even though they are broken because extracted workspaces currently do not preserve the Masking flags (buty they SHOULD!). Hopefully the broken functionality will be fixed and I can enable them. + #self.assertTrue( mask_ws.getDetector(masking_edge).isMasked() ) + #self.assertTrue( not mask_ws.getDetector(masking_edge + 1).isMasked() ) + + # Save masking + mask_file = 'wish_masking_system_test_mask_file_temp.xml' + SaveMask(InputWorkspace=mask_ws,OutputFile=mask_file) + mask_file_path = os.path.join(config['defaultsave.directory'], mask_file) + # Check the mask file was created. + self.assertTrue(os.path.isfile(mask_file_path)) + # ... and has the correct contents + masking_xml = open(mask_file_path, 'r') + found_correct_ids = False + for line in masking_xml: + if "1-5,1100000-1100019" in line: + found_correct_ids = True + masking_xml.close() + self.assertTrue(found_correct_ids) + os.remove(mask_file_path) + + ## END COMPLETE TESTS + + ## CHARACTERISATION TESTS: These tests characterise the current breakage of the masking code. + ## I've included these false-positives as a testing strategy because it will flag up that the functionality has been fixed when these tests start failing (we can then test the right thing, see above) + + # Testing that the isMasking is the same on both sides of the masking boundary. If things were working properly the following would not pass! + self.assertTrue( mask_ws.getDetector(masking_edge).isMasked() == mask_ws.getDetector(masking_edge + 1).isMasked() ) + ## END CHARACTERISATION TESTS + + #Test creation with normal masking + invert_masking = False; + self.do_test_cal_file(ws, invert_masking, 0, 1, masking_edge) + + #Test with masking inversed, because that is a real schenario too. + invert_masking = True; + self.do_test_cal_file(ws, invert_masking, 1, 0, masking_edge) + + #Test merge cal files + master_cal_file_name = 'master.cal' + update_cal_file_name = 'update.cal' + merged_cal_file_name = 'merged.cal' + save_path = config['defaultsave.directory'] + master_cal_file_path = os.path.join(save_path,master_cal_file_name) + update_cal_file_path = os.path.join(save_path,update_cal_file_name) + merged_cal_file_path = os.path.join(save_path,merged_cal_file_name) + + try: + MaskWorkspaceToCalFile(InputWorkspace=ws, OutputFile=master_cal_file_name, Invert=False) + MaskWorkspaceToCalFile(InputWorkspace=ws, OutputFile=update_cal_file_name, Invert=True) + + MergeCalFiles(UpdateFile=update_cal_file_path, MasterFile=master_cal_file_path, + OutputFile=merged_cal_file_name, MergeSelections=True) + + update_cal_file = open(update_cal_file_path, 'r') + merged_cal_file = open(merged_cal_file_path, 'r') + + merged_mask_boundary_inside = self.get_masking_for_index(merged_cal_file, masking_edge) + merged_mask_boundary_outside = self.get_masking_for_index(merged_cal_file, masking_edge+1) + update_mask_boundary_inside = self.get_masking_for_index(update_cal_file, masking_edge) + update_mask_boundary_outside = self.get_masking_for_index(update_cal_file, masking_edge+1) + + #Test that the merged output cal file has actually taken the masking from the update file. + self.assertTrue(merged_mask_boundary_inside != merged_mask_boundary_outside) + self.assertTrue(merged_mask_boundary_inside == update_mask_boundary_inside) + self.assertTrue(merged_mask_boundary_outside == update_mask_boundary_outside) + + finally: + #clean up no matter what. + merged_cal_file.close() + update_cal_file.close() + os.remove(master_cal_file_path) + os.remove(update_cal_file_path) + os.remove(merged_cal_file_path) + + def doValidate(self): + return True; diff --git a/Code/Mantid/Testing/SystemTests/tests/analysis/reference/3132_Orthorhombic_P.integrate.md5 b/Code/Mantid/Testing/SystemTests/tests/analysis/reference/3132_Orthorhombic_P.integrate.md5 new file mode 100644 index 000000000000..9571c1cd1b71 --- /dev/null +++ b/Code/Mantid/Testing/SystemTests/tests/analysis/reference/3132_Orthorhombic_P.integrate.md5 @@ -0,0 +1 @@ +df726dc544b8eb1db9b0ba098bdfd73f \ No newline at end of file diff --git a/Code/Mantid/Testing/SystemTests/tests/analysis/reference/3132_Orthorhombic_P.mat.md5 b/Code/Mantid/Testing/SystemTests/tests/analysis/reference/3132_Orthorhombic_P.mat.md5 new file mode 100644 index 000000000000..3323c9c724ba --- /dev/null +++ b/Code/Mantid/Testing/SystemTests/tests/analysis/reference/3132_Orthorhombic_P.mat.md5 @@ -0,0 +1 @@ +c9a7b3fc842bccf8c33d5fd594214057 \ No newline at end of file diff --git a/Code/Mantid/Testing/SystemTests/tests/analysis/reference/4699_IvsQ_Result.nxs.md5 b/Code/Mantid/Testing/SystemTests/tests/analysis/reference/4699_IvsQ_Result.nxs.md5 new file mode 100644 index 000000000000..428af220a708 --- /dev/null +++ b/Code/Mantid/Testing/SystemTests/tests/analysis/reference/4699_IvsQ_Result.nxs.md5 @@ -0,0 +1 @@ +e30c9c332c2e2ba26ac9fe511f2c862e \ No newline at end of file diff --git a/Code/Mantid/Testing/SystemTests/tests/analysis/reference/ARCSsystemtest.nxs.md5 b/Code/Mantid/Testing/SystemTests/tests/analysis/reference/ARCSsystemtest.nxs.md5 new file mode 100644 index 000000000000..56a2302a638a --- /dev/null +++ b/Code/Mantid/Testing/SystemTests/tests/analysis/reference/ARCSsystemtest.nxs.md5 @@ -0,0 +1 @@ +98c9c3beb2a0d04c064875f9f171cb54 \ No newline at end of file diff --git a/Code/Mantid/Testing/SystemTests/tests/analysis/reference/ARGUSAnalysis.nxs.md5 b/Code/Mantid/Testing/SystemTests/tests/analysis/reference/ARGUSAnalysis.nxs.md5 new file mode 100644 index 000000000000..673f2a28c603 --- /dev/null +++ b/Code/Mantid/Testing/SystemTests/tests/analysis/reference/ARGUSAnalysis.nxs.md5 @@ -0,0 +1 @@ +0f081a994ee34e5de84f51dc8b107c93 \ No newline at end of file diff --git a/Code/Mantid/Testing/SystemTests/tests/analysis/reference/ARGUSAnalysisLogFwd.nxs.md5 b/Code/Mantid/Testing/SystemTests/tests/analysis/reference/ARGUSAnalysisLogFwd.nxs.md5 new file mode 100644 index 000000000000..78b9fba746b8 --- /dev/null +++ b/Code/Mantid/Testing/SystemTests/tests/analysis/reference/ARGUSAnalysisLogFwd.nxs.md5 @@ -0,0 +1 @@ +a656d3a36c14bf2f708e879a33ed300e \ No newline at end of file diff --git a/Code/Mantid/Testing/SystemTests/tests/analysis/reference/Arg_Si_ref.nxs.md5 b/Code/Mantid/Testing/SystemTests/tests/analysis/reference/Arg_Si_ref.nxs.md5 new file mode 100644 index 000000000000..2cf712519b17 --- /dev/null +++ b/Code/Mantid/Testing/SystemTests/tests/analysis/reference/Arg_Si_ref.nxs.md5 @@ -0,0 +1 @@ +6ba70947b1029b10dd90983109a25b8e \ No newline at end of file diff --git a/Code/Mantid/Testing/SystemTests/tests/analysis/reference/BASISAutoReduction.nxs.md5 b/Code/Mantid/Testing/SystemTests/tests/analysis/reference/BASISAutoReduction.nxs.md5 new file mode 100644 index 000000000000..a11d29b18018 --- /dev/null +++ b/Code/Mantid/Testing/SystemTests/tests/analysis/reference/BASISAutoReduction.nxs.md5 @@ -0,0 +1 @@ +ae57a75f07b36a4f934092f2c4607bfe \ No newline at end of file diff --git a/Code/Mantid/Testing/SystemTests/tests/analysis/reference/CNCSReduction.nxs.md5 b/Code/Mantid/Testing/SystemTests/tests/analysis/reference/CNCSReduction.nxs.md5 new file mode 100644 index 000000000000..66147dac548a --- /dev/null +++ b/Code/Mantid/Testing/SystemTests/tests/analysis/reference/CNCSReduction.nxs.md5 @@ -0,0 +1 @@ +4c1d253e42310e83e3294fb298eb1d89 \ No newline at end of file diff --git a/Code/Mantid/Testing/SystemTests/tests/analysis/reference/CNCSReduction_TIBasEvents.nxs.md5 b/Code/Mantid/Testing/SystemTests/tests/analysis/reference/CNCSReduction_TIBasEvents.nxs.md5 new file mode 100644 index 000000000000..3bd9997c84a8 --- /dev/null +++ b/Code/Mantid/Testing/SystemTests/tests/analysis/reference/CNCSReduction_TIBasEvents.nxs.md5 @@ -0,0 +1 @@ +38425b5a8f456db00527660cdc35ce21 \ No newline at end of file diff --git a/Code/Mantid/Testing/SystemTests/tests/analysis/reference/CSP85423_1Integrated.nxs.md5 b/Code/Mantid/Testing/SystemTests/tests/analysis/reference/CSP85423_1Integrated.nxs.md5 new file mode 100644 index 000000000000..17c4512832d4 --- /dev/null +++ b/Code/Mantid/Testing/SystemTests/tests/analysis/reference/CSP85423_1Integrated.nxs.md5 @@ -0,0 +1 @@ +a55525b246d5a1fcd7df851ac2775745 \ No newline at end of file diff --git a/Code/Mantid/Testing/SystemTests/tests/analysis/reference/ConvertToMDSample.nxs.md5 b/Code/Mantid/Testing/SystemTests/tests/analysis/reference/ConvertToMDSample.nxs.md5 new file mode 100644 index 000000000000..9c825340c6ea --- /dev/null +++ b/Code/Mantid/Testing/SystemTests/tests/analysis/reference/ConvertToMDSample.nxs.md5 @@ -0,0 +1 @@ +770b925b5fd311c41d9615ff7eb11016 \ No newline at end of file diff --git a/Code/Mantid/Testing/SystemTests/tests/analysis/reference/DirectInelasticDiagnostic.txt.md5 b/Code/Mantid/Testing/SystemTests/tests/analysis/reference/DirectInelasticDiagnostic.txt.md5 new file mode 100644 index 000000000000..5de8c7e451c8 --- /dev/null +++ b/Code/Mantid/Testing/SystemTests/tests/analysis/reference/DirectInelasticDiagnostic.txt.md5 @@ -0,0 +1 @@ +b3e7024e9e190b2d29c48138158cf8f9 \ No newline at end of file diff --git a/Code/Mantid/Testing/SystemTests/tests/analysis/reference/EMUAnalysis.nxs.md5 b/Code/Mantid/Testing/SystemTests/tests/analysis/reference/EMUAnalysis.nxs.md5 new file mode 100644 index 000000000000..6776f8477654 --- /dev/null +++ b/Code/Mantid/Testing/SystemTests/tests/analysis/reference/EMUAnalysis.nxs.md5 @@ -0,0 +1 @@ +9aea8c25e0d442ebe62756a68de795fd \ No newline at end of file diff --git a/Code/Mantid/Testing/SystemTests/tests/analysis/reference/EMUAnalysisAsymFwd.nxs.md5 b/Code/Mantid/Testing/SystemTests/tests/analysis/reference/EMUAnalysisAsymFwd.nxs.md5 new file mode 100644 index 000000000000..6de53f543f63 --- /dev/null +++ b/Code/Mantid/Testing/SystemTests/tests/analysis/reference/EMUAnalysisAsymFwd.nxs.md5 @@ -0,0 +1 @@ +256aec30630e396abbae7f6cd3b97199 \ No newline at end of file diff --git a/Code/Mantid/Testing/SystemTests/tests/analysis/reference/EQSANSBeamCenter.nxs.md5 b/Code/Mantid/Testing/SystemTests/tests/analysis/reference/EQSANSBeamCenter.nxs.md5 new file mode 100644 index 000000000000..5b37cbbee62e --- /dev/null +++ b/Code/Mantid/Testing/SystemTests/tests/analysis/reference/EQSANSBeamCenter.nxs.md5 @@ -0,0 +1 @@ +3317eaddf68de34ebc71ffc973a3dc13 \ No newline at end of file diff --git a/Code/Mantid/Testing/SystemTests/tests/analysis/reference/EQSANSBeamMonitor.nxs.md5 b/Code/Mantid/Testing/SystemTests/tests/analysis/reference/EQSANSBeamMonitor.nxs.md5 new file mode 100644 index 000000000000..860152c590f9 --- /dev/null +++ b/Code/Mantid/Testing/SystemTests/tests/analysis/reference/EQSANSBeamMonitor.nxs.md5 @@ -0,0 +1 @@ +e7501ce72578234cd5ca5a2ac440b45e \ No newline at end of file diff --git a/Code/Mantid/Testing/SystemTests/tests/analysis/reference/EQSANSComputeEff.nxs.md5 b/Code/Mantid/Testing/SystemTests/tests/analysis/reference/EQSANSComputeEff.nxs.md5 new file mode 100644 index 000000000000..339c559e021e --- /dev/null +++ b/Code/Mantid/Testing/SystemTests/tests/analysis/reference/EQSANSComputeEff.nxs.md5 @@ -0,0 +1 @@ +96c4b850c06d8e654754b51b3a147dff \ No newline at end of file diff --git a/Code/Mantid/Testing/SystemTests/tests/analysis/reference/EQSANSDarkCurrent.nxs.md5 b/Code/Mantid/Testing/SystemTests/tests/analysis/reference/EQSANSDarkCurrent.nxs.md5 new file mode 100644 index 000000000000..3c0111982384 --- /dev/null +++ b/Code/Mantid/Testing/SystemTests/tests/analysis/reference/EQSANSDarkCurrent.nxs.md5 @@ -0,0 +1 @@ +36bbbbe32a96cd111c9e238f5b6eebbb \ No newline at end of file diff --git a/Code/Mantid/Testing/SystemTests/tests/analysis/reference/EQSANSDirectTransFS.nxs.md5 b/Code/Mantid/Testing/SystemTests/tests/analysis/reference/EQSANSDirectTransFS.nxs.md5 new file mode 100644 index 000000000000..3bbb3f8c7b4c --- /dev/null +++ b/Code/Mantid/Testing/SystemTests/tests/analysis/reference/EQSANSDirectTransFS.nxs.md5 @@ -0,0 +1 @@ +5a08d17a2db88d3d1e51e6816e68f5d8 \ No newline at end of file diff --git a/Code/Mantid/Testing/SystemTests/tests/analysis/reference/EQSANSEff.nxs.md5 b/Code/Mantid/Testing/SystemTests/tests/analysis/reference/EQSANSEff.nxs.md5 new file mode 100644 index 000000000000..32994e6a9a15 --- /dev/null +++ b/Code/Mantid/Testing/SystemTests/tests/analysis/reference/EQSANSEff.nxs.md5 @@ -0,0 +1 @@ +8fa13c81cbe8e00346c3e48e8021232f \ No newline at end of file diff --git a/Code/Mantid/Testing/SystemTests/tests/analysis/reference/EQSANSFlatTest.nxs.md5 b/Code/Mantid/Testing/SystemTests/tests/analysis/reference/EQSANSFlatTest.nxs.md5 new file mode 100644 index 000000000000..7486c168ee23 --- /dev/null +++ b/Code/Mantid/Testing/SystemTests/tests/analysis/reference/EQSANSFlatTest.nxs.md5 @@ -0,0 +1 @@ +bf35d0a54fc88dc3eb48b9d73ea46263 \ No newline at end of file diff --git a/Code/Mantid/Testing/SystemTests/tests/analysis/reference/EQSANSIQOutput.nxs.md5 b/Code/Mantid/Testing/SystemTests/tests/analysis/reference/EQSANSIQOutput.nxs.md5 new file mode 100644 index 000000000000..dc6f1cfd9735 --- /dev/null +++ b/Code/Mantid/Testing/SystemTests/tests/analysis/reference/EQSANSIQOutput.nxs.md5 @@ -0,0 +1 @@ +563ca6e51d289881df77e433ae5c6e2f \ No newline at end of file diff --git a/Code/Mantid/Testing/SystemTests/tests/analysis/reference/EQSANSLive.nxs.md5 b/Code/Mantid/Testing/SystemTests/tests/analysis/reference/EQSANSLive.nxs.md5 new file mode 100644 index 000000000000..ddba826c537c --- /dev/null +++ b/Code/Mantid/Testing/SystemTests/tests/analysis/reference/EQSANSLive.nxs.md5 @@ -0,0 +1 @@ +144d1724315b56acac2c808da0da0aba \ No newline at end of file diff --git a/Code/Mantid/Testing/SystemTests/tests/analysis/reference/EQSANSNormalisation_DefaultFlux.nxs.md5 b/Code/Mantid/Testing/SystemTests/tests/analysis/reference/EQSANSNormalisation_DefaultFlux.nxs.md5 new file mode 100644 index 000000000000..f71618d84a08 --- /dev/null +++ b/Code/Mantid/Testing/SystemTests/tests/analysis/reference/EQSANSNormalisation_DefaultFlux.nxs.md5 @@ -0,0 +1 @@ +7acb7a34921fe27eafd101f426209ae4 \ No newline at end of file diff --git a/Code/Mantid/Testing/SystemTests/tests/analysis/reference/EQSANSNormalisation_InputFlux.nxs.md5 b/Code/Mantid/Testing/SystemTests/tests/analysis/reference/EQSANSNormalisation_InputFlux.nxs.md5 new file mode 100644 index 000000000000..01b53e597bb1 --- /dev/null +++ b/Code/Mantid/Testing/SystemTests/tests/analysis/reference/EQSANSNormalisation_InputFlux.nxs.md5 @@ -0,0 +1 @@ +ffb8f147ed978cfae31b3c479f5108e6 \ No newline at end of file diff --git a/Code/Mantid/Testing/SystemTests/tests/analysis/reference/EQSANSNormalisation_NoFlux.nxs.md5 b/Code/Mantid/Testing/SystemTests/tests/analysis/reference/EQSANSNormalisation_NoFlux.nxs.md5 new file mode 100644 index 000000000000..43010800715f --- /dev/null +++ b/Code/Mantid/Testing/SystemTests/tests/analysis/reference/EQSANSNormalisation_NoFlux.nxs.md5 @@ -0,0 +1 @@ +90153668f16d29e20387643a8da3e057 \ No newline at end of file diff --git a/Code/Mantid/Testing/SystemTests/tests/analysis/reference/EQSANSProcessedEff.nxs.md5 b/Code/Mantid/Testing/SystemTests/tests/analysis/reference/EQSANSProcessedEff.nxs.md5 new file mode 100644 index 000000000000..723e7b408360 --- /dev/null +++ b/Code/Mantid/Testing/SystemTests/tests/analysis/reference/EQSANSProcessedEff.nxs.md5 @@ -0,0 +1 @@ +45871cfa56c63b8a750083bf0f66b837 \ No newline at end of file diff --git a/Code/Mantid/Testing/SystemTests/tests/analysis/reference/EQSANSSolid.nxs.md5 b/Code/Mantid/Testing/SystemTests/tests/analysis/reference/EQSANSSolid.nxs.md5 new file mode 100644 index 000000000000..23aa318eb5be --- /dev/null +++ b/Code/Mantid/Testing/SystemTests/tests/analysis/reference/EQSANSSolid.nxs.md5 @@ -0,0 +1 @@ +3f900f8a24b25360ab65eaaef9cd38af \ No newline at end of file diff --git a/Code/Mantid/Testing/SystemTests/tests/analysis/reference/EQSANSTrans.nxs.md5 b/Code/Mantid/Testing/SystemTests/tests/analysis/reference/EQSANSTrans.nxs.md5 new file mode 100644 index 000000000000..0bf860737a4b --- /dev/null +++ b/Code/Mantid/Testing/SystemTests/tests/analysis/reference/EQSANSTrans.nxs.md5 @@ -0,0 +1 @@ +94aae0f07e1fefe07e4b0cfde2d4bde5 \ No newline at end of file diff --git a/Code/Mantid/Testing/SystemTests/tests/analysis/reference/EQSANSTransEvent.nxs.md5 b/Code/Mantid/Testing/SystemTests/tests/analysis/reference/EQSANSTransEvent.nxs.md5 new file mode 100644 index 000000000000..4414a093fe8a --- /dev/null +++ b/Code/Mantid/Testing/SystemTests/tests/analysis/reference/EQSANSTransEvent.nxs.md5 @@ -0,0 +1 @@ +c61ca2205d2f231a2f8e3404320ac840 \ No newline at end of file diff --git a/Code/Mantid/Testing/SystemTests/tests/analysis/reference/EQSANSTransmissionCompatibility.nxs.md5 b/Code/Mantid/Testing/SystemTests/tests/analysis/reference/EQSANSTransmissionCompatibility.nxs.md5 new file mode 100644 index 000000000000..ce00e642fe67 --- /dev/null +++ b/Code/Mantid/Testing/SystemTests/tests/analysis/reference/EQSANSTransmissionCompatibility.nxs.md5 @@ -0,0 +1 @@ +40f62f5d445bc19493ef3c017e3103a2 \ No newline at end of file diff --git a/Code/Mantid/Testing/SystemTests/tests/analysis/reference/EQSANSTransmissionDC.nxs.md5 b/Code/Mantid/Testing/SystemTests/tests/analysis/reference/EQSANSTransmissionDC.nxs.md5 new file mode 100644 index 000000000000..39eaa579f968 --- /dev/null +++ b/Code/Mantid/Testing/SystemTests/tests/analysis/reference/EQSANSTransmissionDC.nxs.md5 @@ -0,0 +1 @@ +866983c8aea0108fefbd5ef5ebc4938d \ No newline at end of file diff --git a/Code/Mantid/Testing/SystemTests/tests/analysis/reference/EQSANSTransmissionFS.nxs.md5 b/Code/Mantid/Testing/SystemTests/tests/analysis/reference/EQSANSTransmissionFS.nxs.md5 new file mode 100644 index 000000000000..0ae7163b0f66 --- /dev/null +++ b/Code/Mantid/Testing/SystemTests/tests/analysis/reference/EQSANSTransmissionFS.nxs.md5 @@ -0,0 +1 @@ +bdfcc0170daee78f603dd3a568a014cc \ No newline at end of file diff --git a/Code/Mantid/Testing/SystemTests/tests/analysis/reference/GEM58654.gss.md5 b/Code/Mantid/Testing/SystemTests/tests/analysis/reference/GEM58654.gss.md5 new file mode 100644 index 000000000000..579fddef799f --- /dev/null +++ b/Code/Mantid/Testing/SystemTests/tests/analysis/reference/GEM58654.gss.md5 @@ -0,0 +1 @@ +eead0936e68daf726babb86033ae5a78 \ No newline at end of file diff --git a/Code/Mantid/Testing/SystemTests/tests/analysis/reference/GEM58654.nxs.md5 b/Code/Mantid/Testing/SystemTests/tests/analysis/reference/GEM58654.nxs.md5 new file mode 100644 index 000000000000..b570c2ee4f34 --- /dev/null +++ b/Code/Mantid/Testing/SystemTests/tests/analysis/reference/GEM58654.nxs.md5 @@ -0,0 +1 @@ +d35b0d48b794d741f39322ffd37cc12c \ No newline at end of file diff --git a/Code/Mantid/Testing/SystemTests/tests/analysis/reference/GEM58654_b1_D.dat.md5 b/Code/Mantid/Testing/SystemTests/tests/analysis/reference/GEM58654_b1_D.dat.md5 new file mode 100644 index 000000000000..7d74cd95f9b5 --- /dev/null +++ b/Code/Mantid/Testing/SystemTests/tests/analysis/reference/GEM58654_b1_D.dat.md5 @@ -0,0 +1 @@ +b2084b38ac642efe26dcfe0f9e2d9141 \ No newline at end of file diff --git a/Code/Mantid/Testing/SystemTests/tests/analysis/reference/GEM58654_b1_TOF.dat.md5 b/Code/Mantid/Testing/SystemTests/tests/analysis/reference/GEM58654_b1_TOF.dat.md5 new file mode 100644 index 000000000000..e31eb13dc3ff --- /dev/null +++ b/Code/Mantid/Testing/SystemTests/tests/analysis/reference/GEM58654_b1_TOF.dat.md5 @@ -0,0 +1 @@ +d77d8173349409e21e2aa0aea2ff66c9 \ No newline at end of file diff --git a/Code/Mantid/Testing/SystemTests/tests/analysis/reference/GEM58654_b2_D.dat.md5 b/Code/Mantid/Testing/SystemTests/tests/analysis/reference/GEM58654_b2_D.dat.md5 new file mode 100644 index 000000000000..5785de851d52 --- /dev/null +++ b/Code/Mantid/Testing/SystemTests/tests/analysis/reference/GEM58654_b2_D.dat.md5 @@ -0,0 +1 @@ +533391d1cfc1a706ee3b06a17f25be90 \ No newline at end of file diff --git a/Code/Mantid/Testing/SystemTests/tests/analysis/reference/GEM58654_b2_TOF.dat.md5 b/Code/Mantid/Testing/SystemTests/tests/analysis/reference/GEM58654_b2_TOF.dat.md5 new file mode 100644 index 000000000000..887b0caf2a44 --- /dev/null +++ b/Code/Mantid/Testing/SystemTests/tests/analysis/reference/GEM58654_b2_TOF.dat.md5 @@ -0,0 +1 @@ +b5c1b19b6ff15badb921719515c57063 \ No newline at end of file diff --git a/Code/Mantid/Testing/SystemTests/tests/analysis/reference/GEM58654_b3_D.dat.md5 b/Code/Mantid/Testing/SystemTests/tests/analysis/reference/GEM58654_b3_D.dat.md5 new file mode 100644 index 000000000000..622e65060c81 --- /dev/null +++ b/Code/Mantid/Testing/SystemTests/tests/analysis/reference/GEM58654_b3_D.dat.md5 @@ -0,0 +1 @@ +1badf1dfbb95ba3e1539d82f61a28879 \ No newline at end of file diff --git a/Code/Mantid/Testing/SystemTests/tests/analysis/reference/GEM58654_b3_TOF.dat.md5 b/Code/Mantid/Testing/SystemTests/tests/analysis/reference/GEM58654_b3_TOF.dat.md5 new file mode 100644 index 000000000000..5d6b23323a40 --- /dev/null +++ b/Code/Mantid/Testing/SystemTests/tests/analysis/reference/GEM58654_b3_TOF.dat.md5 @@ -0,0 +1 @@ +d7eeb6f7ba7576e570977389b3679e31 \ No newline at end of file diff --git a/Code/Mantid/Testing/SystemTests/tests/analysis/reference/GEM58654_b4_D.dat.md5 b/Code/Mantid/Testing/SystemTests/tests/analysis/reference/GEM58654_b4_D.dat.md5 new file mode 100644 index 000000000000..dda2379b94d3 --- /dev/null +++ b/Code/Mantid/Testing/SystemTests/tests/analysis/reference/GEM58654_b4_D.dat.md5 @@ -0,0 +1 @@ +e22dbc11a4ff64f9bc0785090c9ccf7a \ No newline at end of file diff --git a/Code/Mantid/Testing/SystemTests/tests/analysis/reference/GEM58654_b4_TOF.dat.md5 b/Code/Mantid/Testing/SystemTests/tests/analysis/reference/GEM58654_b4_TOF.dat.md5 new file mode 100644 index 000000000000..1225d97e59b9 --- /dev/null +++ b/Code/Mantid/Testing/SystemTests/tests/analysis/reference/GEM58654_b4_TOF.dat.md5 @@ -0,0 +1 @@ +6b36f04e698dbe9fbfd376fb2408f314 \ No newline at end of file diff --git a/Code/Mantid/Testing/SystemTests/tests/analysis/reference/GEM58654_b5_D.dat.md5 b/Code/Mantid/Testing/SystemTests/tests/analysis/reference/GEM58654_b5_D.dat.md5 new file mode 100644 index 000000000000..b97007b18ab7 --- /dev/null +++ b/Code/Mantid/Testing/SystemTests/tests/analysis/reference/GEM58654_b5_D.dat.md5 @@ -0,0 +1 @@ +ca947649c2375d9fd3552f9b0a453541 \ No newline at end of file diff --git a/Code/Mantid/Testing/SystemTests/tests/analysis/reference/GEM58654_b5_TOF.dat.md5 b/Code/Mantid/Testing/SystemTests/tests/analysis/reference/GEM58654_b5_TOF.dat.md5 new file mode 100644 index 000000000000..6112fb472ea7 --- /dev/null +++ b/Code/Mantid/Testing/SystemTests/tests/analysis/reference/GEM58654_b5_TOF.dat.md5 @@ -0,0 +1 @@ +acd3de5536b95b02541c31840837c9c5 \ No newline at end of file diff --git a/Code/Mantid/Testing/SystemTests/tests/analysis/reference/GEM58654_b6_D.dat.md5 b/Code/Mantid/Testing/SystemTests/tests/analysis/reference/GEM58654_b6_D.dat.md5 new file mode 100644 index 000000000000..06abf31007fc --- /dev/null +++ b/Code/Mantid/Testing/SystemTests/tests/analysis/reference/GEM58654_b6_D.dat.md5 @@ -0,0 +1 @@ +19001835c749ba4e2664a1c220b42232 \ No newline at end of file diff --git a/Code/Mantid/Testing/SystemTests/tests/analysis/reference/GEM58654_b6_TOF.dat.md5 b/Code/Mantid/Testing/SystemTests/tests/analysis/reference/GEM58654_b6_TOF.dat.md5 new file mode 100644 index 000000000000..97d1f99dace6 --- /dev/null +++ b/Code/Mantid/Testing/SystemTests/tests/analysis/reference/GEM58654_b6_TOF.dat.md5 @@ -0,0 +1 @@ +d139ed508e916c076b59be3da1a3fd7c \ No newline at end of file diff --git a/Code/Mantid/Testing/SystemTests/tests/analysis/reference/GEM_offsets_2011_cycle111b.cal.md5 b/Code/Mantid/Testing/SystemTests/tests/analysis/reference/GEM_offsets_2011_cycle111b.cal.md5 new file mode 100644 index 000000000000..f7f660af181d --- /dev/null +++ b/Code/Mantid/Testing/SystemTests/tests/analysis/reference/GEM_offsets_2011_cycle111b.cal.md5 @@ -0,0 +1 @@ +06d65ec8b42054d59f069681cc4db7da \ No newline at end of file diff --git a/Code/Mantid/Testing/SystemTests/tests/analysis/reference/HFIRAbsoluteScalingReference.nxs.md5 b/Code/Mantid/Testing/SystemTests/tests/analysis/reference/HFIRAbsoluteScalingReference.nxs.md5 new file mode 100644 index 000000000000..e4e0ab160fad --- /dev/null +++ b/Code/Mantid/Testing/SystemTests/tests/analysis/reference/HFIRAbsoluteScalingReference.nxs.md5 @@ -0,0 +1 @@ +d410144479c069d889453866dbbeb02c \ No newline at end of file diff --git a/Code/Mantid/Testing/SystemTests/tests/analysis/reference/HFIRBackground.nxs.md5 b/Code/Mantid/Testing/SystemTests/tests/analysis/reference/HFIRBackground.nxs.md5 new file mode 100644 index 000000000000..94635c489d0a --- /dev/null +++ b/Code/Mantid/Testing/SystemTests/tests/analysis/reference/HFIRBackground.nxs.md5 @@ -0,0 +1 @@ +5cee686db6700ae8b756a6953370fd12 \ No newline at end of file diff --git a/Code/Mantid/Testing/SystemTests/tests/analysis/reference/HFIRBackgroundBeamSpreaderTrans.nxs.md5 b/Code/Mantid/Testing/SystemTests/tests/analysis/reference/HFIRBackgroundBeamSpreaderTrans.nxs.md5 new file mode 100644 index 000000000000..e1595b26fe14 --- /dev/null +++ b/Code/Mantid/Testing/SystemTests/tests/analysis/reference/HFIRBackgroundBeamSpreaderTrans.nxs.md5 @@ -0,0 +1 @@ +6eed42564c6d79448bde6bf277217e6f \ No newline at end of file diff --git a/Code/Mantid/Testing/SystemTests/tests/analysis/reference/HFIRBackgroundDirectBeamTrans.nxs.md5 b/Code/Mantid/Testing/SystemTests/tests/analysis/reference/HFIRBackgroundDirectBeamTrans.nxs.md5 new file mode 100644 index 000000000000..17e6a9099394 --- /dev/null +++ b/Code/Mantid/Testing/SystemTests/tests/analysis/reference/HFIRBackgroundDirectBeamTrans.nxs.md5 @@ -0,0 +1 @@ +248bc6267c5a2e9c04932878cb3c7a43 \ No newline at end of file diff --git a/Code/Mantid/Testing/SystemTests/tests/analysis/reference/HFIRBackgroundDirectBeamTransDC.nxs.md5 b/Code/Mantid/Testing/SystemTests/tests/analysis/reference/HFIRBackgroundDirectBeamTransDC.nxs.md5 new file mode 100644 index 000000000000..96c2dcc94bd9 --- /dev/null +++ b/Code/Mantid/Testing/SystemTests/tests/analysis/reference/HFIRBackgroundDirectBeamTransDC.nxs.md5 @@ -0,0 +1 @@ +2f698116fa96487a9cab85c054a7e0dd \ No newline at end of file diff --git a/Code/Mantid/Testing/SystemTests/tests/analysis/reference/HFIRBackgroundTransDarkCurrent.nxs.md5 b/Code/Mantid/Testing/SystemTests/tests/analysis/reference/HFIRBackgroundTransDarkCurrent.nxs.md5 new file mode 100644 index 000000000000..d428b94b4d24 --- /dev/null +++ b/Code/Mantid/Testing/SystemTests/tests/analysis/reference/HFIRBackgroundTransDarkCurrent.nxs.md5 @@ -0,0 +1 @@ +21601e1c269c80da5603a1381d2ef9c8 \ No newline at end of file diff --git a/Code/Mantid/Testing/SystemTests/tests/analysis/reference/HFIRBackgroundTransmission.nxs.md5 b/Code/Mantid/Testing/SystemTests/tests/analysis/reference/HFIRBackgroundTransmission.nxs.md5 new file mode 100644 index 000000000000..425d42400777 --- /dev/null +++ b/Code/Mantid/Testing/SystemTests/tests/analysis/reference/HFIRBackgroundTransmission.nxs.md5 @@ -0,0 +1 @@ +feaec0fa6071129f7ed9d79d84f24cc0 \ No newline at end of file diff --git a/Code/Mantid/Testing/SystemTests/tests/analysis/reference/HFIREff.nxs.md5 b/Code/Mantid/Testing/SystemTests/tests/analysis/reference/HFIREff.nxs.md5 new file mode 100644 index 000000000000..159bab603a03 --- /dev/null +++ b/Code/Mantid/Testing/SystemTests/tests/analysis/reference/HFIREff.nxs.md5 @@ -0,0 +1 @@ +b0b430c9ac0ab163a22f0c3e6aeb73e1 \ No newline at end of file diff --git a/Code/Mantid/Testing/SystemTests/tests/analysis/reference/HFIRReduction.nxs.md5 b/Code/Mantid/Testing/SystemTests/tests/analysis/reference/HFIRReduction.nxs.md5 new file mode 100644 index 000000000000..3975fc548ed2 --- /dev/null +++ b/Code/Mantid/Testing/SystemTests/tests/analysis/reference/HFIRReduction.nxs.md5 @@ -0,0 +1 @@ +efeb2e36fe35fecb8ce30b0f33106765 \ No newline at end of file diff --git a/Code/Mantid/Testing/SystemTests/tests/analysis/reference/HFIRSensitivityDirectBeamCenter.nxs.md5 b/Code/Mantid/Testing/SystemTests/tests/analysis/reference/HFIRSensitivityDirectBeamCenter.nxs.md5 new file mode 100644 index 000000000000..9562f9c6ae13 --- /dev/null +++ b/Code/Mantid/Testing/SystemTests/tests/analysis/reference/HFIRSensitivityDirectBeamCenter.nxs.md5 @@ -0,0 +1 @@ +5f5743ad2fe897b5c969c48e3c352c52 \ No newline at end of file diff --git a/Code/Mantid/Testing/SystemTests/tests/analysis/reference/HFIRSensitivityScatteringBeamCenter.nxs.md5 b/Code/Mantid/Testing/SystemTests/tests/analysis/reference/HFIRSensitivityScatteringBeamCenter.nxs.md5 new file mode 100644 index 000000000000..1c9a13705998 --- /dev/null +++ b/Code/Mantid/Testing/SystemTests/tests/analysis/reference/HFIRSensitivityScatteringBeamCenter.nxs.md5 @@ -0,0 +1 @@ +36b2d238870e46de8652a1d686debe93 \ No newline at end of file diff --git a/Code/Mantid/Testing/SystemTests/tests/analysis/reference/HFIRTrans.nxs.md5 b/Code/Mantid/Testing/SystemTests/tests/analysis/reference/HFIRTrans.nxs.md5 new file mode 100644 index 000000000000..0ec3cbe1853f --- /dev/null +++ b/Code/Mantid/Testing/SystemTests/tests/analysis/reference/HFIRTrans.nxs.md5 @@ -0,0 +1 @@ +16e47674d772f7c0b40850e9279052d1 \ No newline at end of file diff --git a/Code/Mantid/Testing/SystemTests/tests/analysis/reference/HFIRTransmissionBeamSpreader.nxs.md5 b/Code/Mantid/Testing/SystemTests/tests/analysis/reference/HFIRTransmissionBeamSpreader.nxs.md5 new file mode 100644 index 000000000000..12669204f28b --- /dev/null +++ b/Code/Mantid/Testing/SystemTests/tests/analysis/reference/HFIRTransmissionBeamSpreader.nxs.md5 @@ -0,0 +1 @@ +5e4c5c7df9d8a1afcff22a0fe57abf41 \ No newline at end of file diff --git a/Code/Mantid/Testing/SystemTests/tests/analysis/reference/HFIRTransmissionBeamSpreaderDBC.nxs.md5 b/Code/Mantid/Testing/SystemTests/tests/analysis/reference/HFIRTransmissionBeamSpreaderDBC.nxs.md5 new file mode 100644 index 000000000000..83459d3ecdf3 --- /dev/null +++ b/Code/Mantid/Testing/SystemTests/tests/analysis/reference/HFIRTransmissionBeamSpreaderDBC.nxs.md5 @@ -0,0 +1 @@ +8cc577ba32f7718efe607bb71b4702f5 \ No newline at end of file diff --git a/Code/Mantid/Testing/SystemTests/tests/analysis/reference/HFIRTransmissionBeamSpreaderDC.nxs.md5 b/Code/Mantid/Testing/SystemTests/tests/analysis/reference/HFIRTransmissionBeamSpreaderDC.nxs.md5 new file mode 100644 index 000000000000..01f1391a312d --- /dev/null +++ b/Code/Mantid/Testing/SystemTests/tests/analysis/reference/HFIRTransmissionBeamSpreaderDC.nxs.md5 @@ -0,0 +1 @@ +8fc36841abececc9b1ce81dfdecbfd56 \ No newline at end of file diff --git a/Code/Mantid/Testing/SystemTests/tests/analysis/reference/HFIRTransmissionDarkCurrent.nxs.md5 b/Code/Mantid/Testing/SystemTests/tests/analysis/reference/HFIRTransmissionDarkCurrent.nxs.md5 new file mode 100644 index 000000000000..051e3432cfa6 --- /dev/null +++ b/Code/Mantid/Testing/SystemTests/tests/analysis/reference/HFIRTransmissionDarkCurrent.nxs.md5 @@ -0,0 +1 @@ +b8277f6caa53a278f9718f28c1010a77 \ No newline at end of file diff --git a/Code/Mantid/Testing/SystemTests/tests/analysis/reference/HFIRTransmissionDirectBeamCenter.nxs.md5 b/Code/Mantid/Testing/SystemTests/tests/analysis/reference/HFIRTransmissionDirectBeamCenter.nxs.md5 new file mode 100644 index 000000000000..419ac5c3c124 --- /dev/null +++ b/Code/Mantid/Testing/SystemTests/tests/analysis/reference/HFIRTransmissionDirectBeamCenter.nxs.md5 @@ -0,0 +1 @@ +91fe0c5fdd452b0a4043d54e523e154a \ No newline at end of file diff --git a/Code/Mantid/Testing/SystemTests/tests/analysis/reference/HYSPECReduction.nxs.md5 b/Code/Mantid/Testing/SystemTests/tests/analysis/reference/HYSPECReduction.nxs.md5 new file mode 100644 index 000000000000..d2488335c963 --- /dev/null +++ b/Code/Mantid/Testing/SystemTests/tests/analysis/reference/HYSPECReduction.nxs.md5 @@ -0,0 +1 @@ +a283842e2db30992ee9cbdf5ff698905 \ No newline at end of file diff --git a/Code/Mantid/Testing/SystemTests/tests/analysis/reference/HYSPECReduction_TIBasEvents.nxs.md5 b/Code/Mantid/Testing/SystemTests/tests/analysis/reference/HYSPECReduction_TIBasEvents.nxs.md5 new file mode 100644 index 000000000000..fd70306a58e1 --- /dev/null +++ b/Code/Mantid/Testing/SystemTests/tests/analysis/reference/HYSPECReduction_TIBasEvents.nxs.md5 @@ -0,0 +1 @@ +846f32a2e87499c798ec56418bc5c5ee \ No newline at end of file diff --git a/Code/Mantid/Testing/SystemTests/tests/analysis/reference/HiFiAnalysis.nxs.md5 b/Code/Mantid/Testing/SystemTests/tests/analysis/reference/HiFiAnalysis.nxs.md5 new file mode 100644 index 000000000000..14781fbac489 --- /dev/null +++ b/Code/Mantid/Testing/SystemTests/tests/analysis/reference/HiFiAnalysis.nxs.md5 @@ -0,0 +1 @@ +ae39bc4d0804d42e4f2cf4d1df6c729c \ No newline at end of file diff --git a/Code/Mantid/Testing/SystemTests/tests/analysis/reference/HiFiAnalysisAsym0.nxs.md5 b/Code/Mantid/Testing/SystemTests/tests/analysis/reference/HiFiAnalysisAsym0.nxs.md5 new file mode 100644 index 000000000000..f899dd4df39c --- /dev/null +++ b/Code/Mantid/Testing/SystemTests/tests/analysis/reference/HiFiAnalysisAsym0.nxs.md5 @@ -0,0 +1 @@ +f13e9b8b90e5ee06d39af3cc58fcbc78 \ No newline at end of file diff --git a/Code/Mantid/Testing/SystemTests/tests/analysis/reference/II.AnalysisElWinMulti.nxs.md5 b/Code/Mantid/Testing/SystemTests/tests/analysis/reference/II.AnalysisElWinMulti.nxs.md5 new file mode 100644 index 000000000000..871ffa7d1915 --- /dev/null +++ b/Code/Mantid/Testing/SystemTests/tests/analysis/reference/II.AnalysisElWinMulti.nxs.md5 @@ -0,0 +1 @@ +c411c711cfef6fea15184c45d733a480 \ No newline at end of file diff --git a/Code/Mantid/Testing/SystemTests/tests/analysis/reference/II.DOSCrossSectionScaleTest.nxs.md5 b/Code/Mantid/Testing/SystemTests/tests/analysis/reference/II.DOSCrossSectionScaleTest.nxs.md5 new file mode 100644 index 000000000000..107a29f4b9bc --- /dev/null +++ b/Code/Mantid/Testing/SystemTests/tests/analysis/reference/II.DOSCrossSectionScaleTest.nxs.md5 @@ -0,0 +1 @@ +6f3b563aa83e54b6660012250d58996e \ No newline at end of file diff --git a/Code/Mantid/Testing/SystemTests/tests/analysis/reference/II.DOSIRTest.nxs.md5 b/Code/Mantid/Testing/SystemTests/tests/analysis/reference/II.DOSIRTest.nxs.md5 new file mode 100644 index 000000000000..1f77f3e753ed --- /dev/null +++ b/Code/Mantid/Testing/SystemTests/tests/analysis/reference/II.DOSIRTest.nxs.md5 @@ -0,0 +1 @@ +2f1b6b24e0dbd6ee65f651daaa987573 \ No newline at end of file diff --git a/Code/Mantid/Testing/SystemTests/tests/analysis/reference/II.DOSPartialCrossSectionScaleTest.nxs.md5 b/Code/Mantid/Testing/SystemTests/tests/analysis/reference/II.DOSPartialCrossSectionScaleTest.nxs.md5 new file mode 100644 index 000000000000..923bb88f1b17 --- /dev/null +++ b/Code/Mantid/Testing/SystemTests/tests/analysis/reference/II.DOSPartialCrossSectionScaleTest.nxs.md5 @@ -0,0 +1 @@ +5aaa9d41941cfe5ea366abd9cb078cff \ No newline at end of file diff --git a/Code/Mantid/Testing/SystemTests/tests/analysis/reference/II.DOSPartialTest.nxs.md5 b/Code/Mantid/Testing/SystemTests/tests/analysis/reference/II.DOSPartialTest.nxs.md5 new file mode 100644 index 000000000000..829f78a23b46 --- /dev/null +++ b/Code/Mantid/Testing/SystemTests/tests/analysis/reference/II.DOSPartialTest.nxs.md5 @@ -0,0 +1 @@ +b73586c19affd6aebb7c55a409885c7a \ No newline at end of file diff --git a/Code/Mantid/Testing/SystemTests/tests/analysis/reference/II.DOSRamanTest.nxs.md5 b/Code/Mantid/Testing/SystemTests/tests/analysis/reference/II.DOSRamanTest.nxs.md5 new file mode 100644 index 000000000000..771136431899 --- /dev/null +++ b/Code/Mantid/Testing/SystemTests/tests/analysis/reference/II.DOSRamanTest.nxs.md5 @@ -0,0 +1 @@ +ce10a080f95ded5befc6446a648c75e4 \ No newline at end of file diff --git a/Code/Mantid/Testing/SystemTests/tests/analysis/reference/II.DOSTest.nxs.md5 b/Code/Mantid/Testing/SystemTests/tests/analysis/reference/II.DOSTest.nxs.md5 new file mode 100644 index 000000000000..a6465014b9cb --- /dev/null +++ b/Code/Mantid/Testing/SystemTests/tests/analysis/reference/II.DOSTest.nxs.md5 @@ -0,0 +1 @@ +581a68c6745ebcf393cf136b5678a515 \ No newline at end of file diff --git a/Code/Mantid/Testing/SystemTests/tests/analysis/reference/II.IRISApplyCorrections.nxs.md5 b/Code/Mantid/Testing/SystemTests/tests/analysis/reference/II.IRISApplyCorrections.nxs.md5 new file mode 100644 index 000000000000..8befe4244991 --- /dev/null +++ b/Code/Mantid/Testing/SystemTests/tests/analysis/reference/II.IRISApplyCorrections.nxs.md5 @@ -0,0 +1 @@ +50832fb590cbb8bc94f5149dcd4f38ea \ No newline at end of file diff --git a/Code/Mantid/Testing/SystemTests/tests/analysis/reference/II.IRISApplyCorrectionsWithCan.nxs.md5 b/Code/Mantid/Testing/SystemTests/tests/analysis/reference/II.IRISApplyCorrectionsWithCan.nxs.md5 new file mode 100644 index 000000000000..25b1ece26c79 --- /dev/null +++ b/Code/Mantid/Testing/SystemTests/tests/analysis/reference/II.IRISApplyCorrectionsWithCan.nxs.md5 @@ -0,0 +1 @@ +df8da92bafd420bd4edb019eb7b0ddf8 \ No newline at end of file diff --git a/Code/Mantid/Testing/SystemTests/tests/analysis/reference/II.IRISApplyCorrectionsWithCorrectionsWS.nxs.md5 b/Code/Mantid/Testing/SystemTests/tests/analysis/reference/II.IRISApplyCorrectionsWithCorrectionsWS.nxs.md5 new file mode 100644 index 000000000000..8911be798a92 --- /dev/null +++ b/Code/Mantid/Testing/SystemTests/tests/analysis/reference/II.IRISApplyCorrectionsWithCorrectionsWS.nxs.md5 @@ -0,0 +1 @@ +c9bfe97d89e807e9e20717483f653865 \ No newline at end of file diff --git a/Code/Mantid/Testing/SystemTests/tests/analysis/reference/II.IRISCalibration.nxs.md5 b/Code/Mantid/Testing/SystemTests/tests/analysis/reference/II.IRISCalibration.nxs.md5 new file mode 100644 index 000000000000..a42db57069ba --- /dev/null +++ b/Code/Mantid/Testing/SystemTests/tests/analysis/reference/II.IRISCalibration.nxs.md5 @@ -0,0 +1 @@ +17cd423e104d95c19d19bc6ffd3818d5 \ No newline at end of file diff --git a/Code/Mantid/Testing/SystemTests/tests/analysis/reference/II.IRISConvFitSeq.nxs.md5 b/Code/Mantid/Testing/SystemTests/tests/analysis/reference/II.IRISConvFitSeq.nxs.md5 new file mode 100644 index 000000000000..e0952eae655b --- /dev/null +++ b/Code/Mantid/Testing/SystemTests/tests/analysis/reference/II.IRISConvFitSeq.nxs.md5 @@ -0,0 +1 @@ +198c7c3e2acfbca86c321561b25be63f \ No newline at end of file diff --git a/Code/Mantid/Testing/SystemTests/tests/analysis/reference/II.IRISDiagnostics.nxs.md5 b/Code/Mantid/Testing/SystemTests/tests/analysis/reference/II.IRISDiagnostics.nxs.md5 new file mode 100644 index 000000000000..f7757bbdfe66 --- /dev/null +++ b/Code/Mantid/Testing/SystemTests/tests/analysis/reference/II.IRISDiagnostics.nxs.md5 @@ -0,0 +1 @@ +b91ef5d3739a6e88f067e6eaea14f675 \ No newline at end of file diff --git a/Code/Mantid/Testing/SystemTests/tests/analysis/reference/II.IRISElwinEQ1.nxs.md5 b/Code/Mantid/Testing/SystemTests/tests/analysis/reference/II.IRISElwinEQ1.nxs.md5 new file mode 100644 index 000000000000..0b5959438e86 --- /dev/null +++ b/Code/Mantid/Testing/SystemTests/tests/analysis/reference/II.IRISElwinEQ1.nxs.md5 @@ -0,0 +1 @@ +4db150e10407b67985cbe39bbbcc12ac \ No newline at end of file diff --git a/Code/Mantid/Testing/SystemTests/tests/analysis/reference/II.IRISElwinEQ2.nxs.md5 b/Code/Mantid/Testing/SystemTests/tests/analysis/reference/II.IRISElwinEQ2.nxs.md5 new file mode 100644 index 000000000000..d5ab77c6702e --- /dev/null +++ b/Code/Mantid/Testing/SystemTests/tests/analysis/reference/II.IRISElwinEQ2.nxs.md5 @@ -0,0 +1 @@ +ac24957b62f4c1d6c4dc418ff7c376ae \ No newline at end of file diff --git a/Code/Mantid/Testing/SystemTests/tests/analysis/reference/II.IRISFury.nxs.md5 b/Code/Mantid/Testing/SystemTests/tests/analysis/reference/II.IRISFury.nxs.md5 new file mode 100644 index 000000000000..e404ec292fdd --- /dev/null +++ b/Code/Mantid/Testing/SystemTests/tests/analysis/reference/II.IRISFury.nxs.md5 @@ -0,0 +1 @@ +bcc2818e50c3b3dd2635afbef3bb845d \ No newline at end of file diff --git a/Code/Mantid/Testing/SystemTests/tests/analysis/reference/II.IRISFuryFitMulti.nxs.md5 b/Code/Mantid/Testing/SystemTests/tests/analysis/reference/II.IRISFuryFitMulti.nxs.md5 new file mode 100644 index 000000000000..7ee97fbbcb40 --- /dev/null +++ b/Code/Mantid/Testing/SystemTests/tests/analysis/reference/II.IRISFuryFitMulti.nxs.md5 @@ -0,0 +1 @@ +e03bcfdbe7be536f96af1bcef6ebb108 \ No newline at end of file diff --git a/Code/Mantid/Testing/SystemTests/tests/analysis/reference/II.IRISFuryFitSeq.nxs.md5 b/Code/Mantid/Testing/SystemTests/tests/analysis/reference/II.IRISFuryFitSeq.nxs.md5 new file mode 100644 index 000000000000..568f5c167d64 --- /dev/null +++ b/Code/Mantid/Testing/SystemTests/tests/analysis/reference/II.IRISFuryFitSeq.nxs.md5 @@ -0,0 +1 @@ +1d2482d4f5fc5540aa2c4a7da7b8f030 \ No newline at end of file diff --git a/Code/Mantid/Testing/SystemTests/tests/analysis/reference/II.IRISMSDFit.nxs.md5 b/Code/Mantid/Testing/SystemTests/tests/analysis/reference/II.IRISMSDFit.nxs.md5 new file mode 100644 index 000000000000..5d245a008dee --- /dev/null +++ b/Code/Mantid/Testing/SystemTests/tests/analysis/reference/II.IRISMSDFit.nxs.md5 @@ -0,0 +1 @@ +57c1e21b06c1e694564318f4e3a728a0 \ No newline at end of file diff --git a/Code/Mantid/Testing/SystemTests/tests/analysis/reference/II.IRISMoments.nxs.md5 b/Code/Mantid/Testing/SystemTests/tests/analysis/reference/II.IRISMoments.nxs.md5 new file mode 100644 index 000000000000..8c35b4dde951 --- /dev/null +++ b/Code/Mantid/Testing/SystemTests/tests/analysis/reference/II.IRISMoments.nxs.md5 @@ -0,0 +1 @@ +7f10d5dcad3a94e17af3f8d21ded8adb \ No newline at end of file diff --git a/Code/Mantid/Testing/SystemTests/tests/analysis/reference/II.IRISMultiFileReduction1.nxs.md5 b/Code/Mantid/Testing/SystemTests/tests/analysis/reference/II.IRISMultiFileReduction1.nxs.md5 new file mode 100644 index 000000000000..484f42c374a9 --- /dev/null +++ b/Code/Mantid/Testing/SystemTests/tests/analysis/reference/II.IRISMultiFileReduction1.nxs.md5 @@ -0,0 +1 @@ +5bf32dd0e2d067376b9456b69e215cb0 \ No newline at end of file diff --git a/Code/Mantid/Testing/SystemTests/tests/analysis/reference/II.IRISMultiFileSummedReduction.nxs.md5 b/Code/Mantid/Testing/SystemTests/tests/analysis/reference/II.IRISMultiFileSummedReduction.nxs.md5 new file mode 100644 index 000000000000..76c2e28e2f03 --- /dev/null +++ b/Code/Mantid/Testing/SystemTests/tests/analysis/reference/II.IRISMultiFileSummedReduction.nxs.md5 @@ -0,0 +1 @@ +d6b8752fa3d982cbb58bde32452f7b22 \ No newline at end of file diff --git a/Code/Mantid/Testing/SystemTests/tests/analysis/reference/II.IRISReductionFromFile.nxs.md5 b/Code/Mantid/Testing/SystemTests/tests/analysis/reference/II.IRISReductionFromFile.nxs.md5 new file mode 100644 index 000000000000..ba872359e40b --- /dev/null +++ b/Code/Mantid/Testing/SystemTests/tests/analysis/reference/II.IRISReductionFromFile.nxs.md5 @@ -0,0 +1 @@ +ad023239413ac3d1ea834b541d051b93 \ No newline at end of file diff --git a/Code/Mantid/Testing/SystemTests/tests/analysis/reference/II.IRISResolution.nxs.md5 b/Code/Mantid/Testing/SystemTests/tests/analysis/reference/II.IRISResolution.nxs.md5 new file mode 100644 index 000000000000..9e3c43250139 --- /dev/null +++ b/Code/Mantid/Testing/SystemTests/tests/analysis/reference/II.IRISResolution.nxs.md5 @@ -0,0 +1 @@ +8fbb035c43d925db9b49bbc2e6021a6b \ No newline at end of file diff --git a/Code/Mantid/Testing/SystemTests/tests/analysis/reference/II.IRISTransmissionMonitor.nxs.md5 b/Code/Mantid/Testing/SystemTests/tests/analysis/reference/II.IRISTransmissionMonitor.nxs.md5 new file mode 100644 index 000000000000..89599d394724 --- /dev/null +++ b/Code/Mantid/Testing/SystemTests/tests/analysis/reference/II.IRISTransmissionMonitor.nxs.md5 @@ -0,0 +1 @@ +45aa175193fc91bb3bb7dfcbaa75b0d4 \ No newline at end of file diff --git a/Code/Mantid/Testing/SystemTests/tests/analysis/reference/II.OSIRISCalibration.nxs.md5 b/Code/Mantid/Testing/SystemTests/tests/analysis/reference/II.OSIRISCalibration.nxs.md5 new file mode 100644 index 000000000000..a7530e42cf50 --- /dev/null +++ b/Code/Mantid/Testing/SystemTests/tests/analysis/reference/II.OSIRISCalibration.nxs.md5 @@ -0,0 +1 @@ +84706d9cf6bf1d5feba17dbd9fc37f7e \ No newline at end of file diff --git a/Code/Mantid/Testing/SystemTests/tests/analysis/reference/II.OSIRISConvFitSeq.nxs.md5 b/Code/Mantid/Testing/SystemTests/tests/analysis/reference/II.OSIRISConvFitSeq.nxs.md5 new file mode 100644 index 000000000000..6cfaeb768dbc --- /dev/null +++ b/Code/Mantid/Testing/SystemTests/tests/analysis/reference/II.OSIRISConvFitSeq.nxs.md5 @@ -0,0 +1 @@ +8b7d8c29d94bd766ef494a3cc6079527 \ No newline at end of file diff --git a/Code/Mantid/Testing/SystemTests/tests/analysis/reference/II.OSIRISDiagnostics.nxs.md5 b/Code/Mantid/Testing/SystemTests/tests/analysis/reference/II.OSIRISDiagnostics.nxs.md5 new file mode 100644 index 000000000000..ef89fbae0a74 --- /dev/null +++ b/Code/Mantid/Testing/SystemTests/tests/analysis/reference/II.OSIRISDiagnostics.nxs.md5 @@ -0,0 +1 @@ +dd821d93d90f185a4e70efee4e89d8ea \ No newline at end of file diff --git a/Code/Mantid/Testing/SystemTests/tests/analysis/reference/II.OSIRISElwinEQ1.nxs.md5 b/Code/Mantid/Testing/SystemTests/tests/analysis/reference/II.OSIRISElwinEQ1.nxs.md5 new file mode 100644 index 000000000000..30b4beb20e99 --- /dev/null +++ b/Code/Mantid/Testing/SystemTests/tests/analysis/reference/II.OSIRISElwinEQ1.nxs.md5 @@ -0,0 +1 @@ +0c5453fe71f6cffe3b44949fa09ffce5 \ No newline at end of file diff --git a/Code/Mantid/Testing/SystemTests/tests/analysis/reference/II.OSIRISElwinEQ2.nxs.md5 b/Code/Mantid/Testing/SystemTests/tests/analysis/reference/II.OSIRISElwinEQ2.nxs.md5 new file mode 100644 index 000000000000..a1a319cbac0a --- /dev/null +++ b/Code/Mantid/Testing/SystemTests/tests/analysis/reference/II.OSIRISElwinEQ2.nxs.md5 @@ -0,0 +1 @@ +f6f9adcb6cd9b59d41c777a76b415f13 \ No newline at end of file diff --git a/Code/Mantid/Testing/SystemTests/tests/analysis/reference/II.OSIRISFury.nxs.md5 b/Code/Mantid/Testing/SystemTests/tests/analysis/reference/II.OSIRISFury.nxs.md5 new file mode 100644 index 000000000000..9454c99cd23e --- /dev/null +++ b/Code/Mantid/Testing/SystemTests/tests/analysis/reference/II.OSIRISFury.nxs.md5 @@ -0,0 +1 @@ +d2b2df2928ceddd97493394516ef7c29 \ No newline at end of file diff --git a/Code/Mantid/Testing/SystemTests/tests/analysis/reference/II.OSIRISFuryFitMulti.nxs.md5 b/Code/Mantid/Testing/SystemTests/tests/analysis/reference/II.OSIRISFuryFitMulti.nxs.md5 new file mode 100644 index 000000000000..45df54268034 --- /dev/null +++ b/Code/Mantid/Testing/SystemTests/tests/analysis/reference/II.OSIRISFuryFitMulti.nxs.md5 @@ -0,0 +1 @@ +ccd9eaa73c22e4de18190035de1f90e5 \ No newline at end of file diff --git a/Code/Mantid/Testing/SystemTests/tests/analysis/reference/II.OSIRISFuryFitSeq.nxs.md5 b/Code/Mantid/Testing/SystemTests/tests/analysis/reference/II.OSIRISFuryFitSeq.nxs.md5 new file mode 100644 index 000000000000..53b9426c7520 --- /dev/null +++ b/Code/Mantid/Testing/SystemTests/tests/analysis/reference/II.OSIRISFuryFitSeq.nxs.md5 @@ -0,0 +1 @@ +f24ce578d938ba1f4ab181ece1bf1e97 \ No newline at end of file diff --git a/Code/Mantid/Testing/SystemTests/tests/analysis/reference/II.OSIRISMSDFit.nxs.md5 b/Code/Mantid/Testing/SystemTests/tests/analysis/reference/II.OSIRISMSDFit.nxs.md5 new file mode 100644 index 000000000000..d7a7d92cb400 --- /dev/null +++ b/Code/Mantid/Testing/SystemTests/tests/analysis/reference/II.OSIRISMSDFit.nxs.md5 @@ -0,0 +1 @@ +d7bfe3d9fd5f9eaecb607366425cf968 \ No newline at end of file diff --git a/Code/Mantid/Testing/SystemTests/tests/analysis/reference/II.OSIRISMoments.nxs.md5 b/Code/Mantid/Testing/SystemTests/tests/analysis/reference/II.OSIRISMoments.nxs.md5 new file mode 100644 index 000000000000..8bd1379ea9b1 --- /dev/null +++ b/Code/Mantid/Testing/SystemTests/tests/analysis/reference/II.OSIRISMoments.nxs.md5 @@ -0,0 +1 @@ +0f1bfeffea3f3a8b861f0fd64d53eda4 \ No newline at end of file diff --git a/Code/Mantid/Testing/SystemTests/tests/analysis/reference/II.OSIRISMultiFileReduction1.nxs.md5 b/Code/Mantid/Testing/SystemTests/tests/analysis/reference/II.OSIRISMultiFileReduction1.nxs.md5 new file mode 100644 index 000000000000..b7b772ef140c --- /dev/null +++ b/Code/Mantid/Testing/SystemTests/tests/analysis/reference/II.OSIRISMultiFileReduction1.nxs.md5 @@ -0,0 +1 @@ +6e18bd32432fdc34f69d5adcafacb906 \ No newline at end of file diff --git a/Code/Mantid/Testing/SystemTests/tests/analysis/reference/II.OSIRISMultiFileSummedReduction.nxs.md5 b/Code/Mantid/Testing/SystemTests/tests/analysis/reference/II.OSIRISMultiFileSummedReduction.nxs.md5 new file mode 100644 index 000000000000..bdb8d9380bfd --- /dev/null +++ b/Code/Mantid/Testing/SystemTests/tests/analysis/reference/II.OSIRISMultiFileSummedReduction.nxs.md5 @@ -0,0 +1 @@ +4e0e097bc4843e1aa0549bd50a122e19 \ No newline at end of file diff --git a/Code/Mantid/Testing/SystemTests/tests/analysis/reference/II.OSIRISReductionFromFile.nxs.md5 b/Code/Mantid/Testing/SystemTests/tests/analysis/reference/II.OSIRISReductionFromFile.nxs.md5 new file mode 100644 index 000000000000..34f7621b7e78 --- /dev/null +++ b/Code/Mantid/Testing/SystemTests/tests/analysis/reference/II.OSIRISReductionFromFile.nxs.md5 @@ -0,0 +1 @@ +ca8cb35dc426335e5696ddaa998c72f2 \ No newline at end of file diff --git a/Code/Mantid/Testing/SystemTests/tests/analysis/reference/II.OSIRISResolution.nxs.md5 b/Code/Mantid/Testing/SystemTests/tests/analysis/reference/II.OSIRISResolution.nxs.md5 new file mode 100644 index 000000000000..a2ed1a4c4189 --- /dev/null +++ b/Code/Mantid/Testing/SystemTests/tests/analysis/reference/II.OSIRISResolution.nxs.md5 @@ -0,0 +1 @@ +1a27f63a71668ccff72d88f09358b102 \ No newline at end of file diff --git a/Code/Mantid/Testing/SystemTests/tests/analysis/reference/II.TOSCAMultiFileReduction1.nxs.md5 b/Code/Mantid/Testing/SystemTests/tests/analysis/reference/II.TOSCAMultiFileReduction1.nxs.md5 new file mode 100644 index 000000000000..f7285ad3ec66 --- /dev/null +++ b/Code/Mantid/Testing/SystemTests/tests/analysis/reference/II.TOSCAMultiFileReduction1.nxs.md5 @@ -0,0 +1 @@ +08e5c66edc636128e37738202cf51202 \ No newline at end of file diff --git a/Code/Mantid/Testing/SystemTests/tests/analysis/reference/II.TOSCAMultiFileReduction2.nxs.md5 b/Code/Mantid/Testing/SystemTests/tests/analysis/reference/II.TOSCAMultiFileReduction2.nxs.md5 new file mode 100644 index 000000000000..e1bc4905088e --- /dev/null +++ b/Code/Mantid/Testing/SystemTests/tests/analysis/reference/II.TOSCAMultiFileReduction2.nxs.md5 @@ -0,0 +1 @@ +ed6aea923444b6d1c6e5dfd810cb329f \ No newline at end of file diff --git a/Code/Mantid/Testing/SystemTests/tests/analysis/reference/II.TOSCAMultiFileSummedReduction.nxs.md5 b/Code/Mantid/Testing/SystemTests/tests/analysis/reference/II.TOSCAMultiFileSummedReduction.nxs.md5 new file mode 100644 index 000000000000..cb9d722ba490 --- /dev/null +++ b/Code/Mantid/Testing/SystemTests/tests/analysis/reference/II.TOSCAMultiFileSummedReduction.nxs.md5 @@ -0,0 +1 @@ +943e5478ff1614a87e6924e1aac6d59f \ No newline at end of file diff --git a/Code/Mantid/Testing/SystemTests/tests/analysis/reference/II.TOSCAReductionFromFile.nxs.md5 b/Code/Mantid/Testing/SystemTests/tests/analysis/reference/II.TOSCAReductionFromFile.nxs.md5 new file mode 100644 index 000000000000..af36dafcd7dc --- /dev/null +++ b/Code/Mantid/Testing/SystemTests/tests/analysis/reference/II.TOSCAReductionFromFile.nxs.md5 @@ -0,0 +1 @@ +7e2a9fdc1abc0c084fe2abfc60039950 \ No newline at end of file diff --git a/Code/Mantid/Testing/SystemTests/tests/analysis/reference/INTER00007709Integrated.nxs.md5 b/Code/Mantid/Testing/SystemTests/tests/analysis/reference/INTER00007709Integrated.nxs.md5 new file mode 100644 index 000000000000..56be3c73494e --- /dev/null +++ b/Code/Mantid/Testing/SystemTests/tests/analysis/reference/INTER00007709Integrated.nxs.md5 @@ -0,0 +1 @@ +80aa2ec10ccd249fd7ca9e61570651f6 \ No newline at end of file diff --git a/Code/Mantid/Testing/SystemTests/tests/analysis/reference/IRISDiffspecDiffractionTest.nxs.md5 b/Code/Mantid/Testing/SystemTests/tests/analysis/reference/IRISDiffspecDiffractionTest.nxs.md5 new file mode 100644 index 000000000000..468ffa7f6633 --- /dev/null +++ b/Code/Mantid/Testing/SystemTests/tests/analysis/reference/IRISDiffspecDiffractionTest.nxs.md5 @@ -0,0 +1 @@ +2e197b638ee991fbb5272a97327ba5b7 \ No newline at end of file diff --git a/Code/Mantid/Testing/SystemTests/tests/analysis/reference/ISISIndirectAbsCor_AbsRunFeederDiffractionTest.nxs.md5 b/Code/Mantid/Testing/SystemTests/tests/analysis/reference/ISISIndirectAbsCor_AbsRunFeederDiffractionTest.nxs.md5 new file mode 100644 index 000000000000..0d146f299e72 --- /dev/null +++ b/Code/Mantid/Testing/SystemTests/tests/analysis/reference/ISISIndirectAbsCor_AbsRunFeederDiffractionTest.nxs.md5 @@ -0,0 +1 @@ +0629482ea49b9214fb86697d596be459 \ No newline at end of file diff --git a/Code/Mantid/Testing/SystemTests/tests/analysis/reference/ISISIndirectAbsCor_AbsRunFeederTest.nxs.md5 b/Code/Mantid/Testing/SystemTests/tests/analysis/reference/ISISIndirectAbsCor_AbsRunFeederTest.nxs.md5 new file mode 100644 index 000000000000..e2d7ab3c1d98 --- /dev/null +++ b/Code/Mantid/Testing/SystemTests/tests/analysis/reference/ISISIndirectAbsCor_AbsRunFeederTest.nxs.md5 @@ -0,0 +1 @@ +894dff752eea6de77f128b04927bf299 \ No newline at end of file diff --git a/Code/Mantid/Testing/SystemTests/tests/analysis/reference/ISISIndirectAbsCor_ChemicalFormulaTest.nxs.md5 b/Code/Mantid/Testing/SystemTests/tests/analysis/reference/ISISIndirectAbsCor_ChemicalFormulaTest.nxs.md5 new file mode 100644 index 000000000000..15e468a84039 --- /dev/null +++ b/Code/Mantid/Testing/SystemTests/tests/analysis/reference/ISISIndirectAbsCor_ChemicalFormulaTest.nxs.md5 @@ -0,0 +1 @@ +16ff55cb666596aaa9ec4506d7a50605 \ No newline at end of file diff --git a/Code/Mantid/Testing/SystemTests/tests/analysis/reference/ISISIndirectAbsCor_CylAbsTest.nxs.md5 b/Code/Mantid/Testing/SystemTests/tests/analysis/reference/ISISIndirectAbsCor_CylAbsTest.nxs.md5 new file mode 100644 index 000000000000..3df759424936 --- /dev/null +++ b/Code/Mantid/Testing/SystemTests/tests/analysis/reference/ISISIndirectAbsCor_CylAbsTest.nxs.md5 @@ -0,0 +1 @@ +08b03dfd2ccb9c6f40ca0da4e5d9d594 \ No newline at end of file diff --git a/Code/Mantid/Testing/SystemTests/tests/analysis/reference/ISISIndirectAbsCor_DefaultBeamWidthTest.nxs.md5 b/Code/Mantid/Testing/SystemTests/tests/analysis/reference/ISISIndirectAbsCor_DefaultBeamWidthTest.nxs.md5 new file mode 100644 index 000000000000..f92e3dda3789 --- /dev/null +++ b/Code/Mantid/Testing/SystemTests/tests/analysis/reference/ISISIndirectAbsCor_DefaultBeamWidthTest.nxs.md5 @@ -0,0 +1 @@ +78f74cb976ae848b170a1fd6b6ad9b26 \ No newline at end of file diff --git a/Code/Mantid/Testing/SystemTests/tests/analysis/reference/ISISIndirectAbsCor_FltAbsTSecCloseTo90Test.nxs.md5 b/Code/Mantid/Testing/SystemTests/tests/analysis/reference/ISISIndirectAbsCor_FltAbsTSecCloseTo90Test.nxs.md5 new file mode 100644 index 000000000000..d01294a28eef --- /dev/null +++ b/Code/Mantid/Testing/SystemTests/tests/analysis/reference/ISISIndirectAbsCor_FltAbsTSecCloseTo90Test.nxs.md5 @@ -0,0 +1 @@ +79d8b967f0136743ca73ba8ca718f730 \ No newline at end of file diff --git a/Code/Mantid/Testing/SystemTests/tests/analysis/reference/ISISIndirectAbsCor_FltAbsTest.nxs.md5 b/Code/Mantid/Testing/SystemTests/tests/analysis/reference/ISISIndirectAbsCor_FltAbsTest.nxs.md5 new file mode 100644 index 000000000000..ba425958047b --- /dev/null +++ b/Code/Mantid/Testing/SystemTests/tests/analysis/reference/ISISIndirectAbsCor_FltAbsTest.nxs.md5 @@ -0,0 +1 @@ +cbc911eb1d9461eae70d61c753f9eae8 \ No newline at end of file diff --git a/Code/Mantid/Testing/SystemTests/tests/analysis/reference/ISISIndirectBayes_JumpCETest.nxs.md5 b/Code/Mantid/Testing/SystemTests/tests/analysis/reference/ISISIndirectBayes_JumpCETest.nxs.md5 new file mode 100644 index 000000000000..4b36586a486a --- /dev/null +++ b/Code/Mantid/Testing/SystemTests/tests/analysis/reference/ISISIndirectBayes_JumpCETest.nxs.md5 @@ -0,0 +1 @@ +98fbf74ea7914ee4bce2a6e032d823f5 \ No newline at end of file diff --git a/Code/Mantid/Testing/SystemTests/tests/analysis/reference/ISISIndirectBayes_JumpFickTest.nxs.md5 b/Code/Mantid/Testing/SystemTests/tests/analysis/reference/ISISIndirectBayes_JumpFickTest.nxs.md5 new file mode 100644 index 000000000000..833af258be00 --- /dev/null +++ b/Code/Mantid/Testing/SystemTests/tests/analysis/reference/ISISIndirectBayes_JumpFickTest.nxs.md5 @@ -0,0 +1 @@ +c7d6178e6d54cd7935c8fd6530e9fb56 \ No newline at end of file diff --git a/Code/Mantid/Testing/SystemTests/tests/analysis/reference/ISISIndirectBayes_JumpHallRossTest.nxs.md5 b/Code/Mantid/Testing/SystemTests/tests/analysis/reference/ISISIndirectBayes_JumpHallRossTest.nxs.md5 new file mode 100644 index 000000000000..c11d659a1ab5 --- /dev/null +++ b/Code/Mantid/Testing/SystemTests/tests/analysis/reference/ISISIndirectBayes_JumpHallRossTest.nxs.md5 @@ -0,0 +1 @@ +ddcb8728ddd00dcc5fac77f64aae69a3 \ No newline at end of file diff --git a/Code/Mantid/Testing/SystemTests/tests/analysis/reference/ISISIndirectBayes_JumpTeixeiraTest.nxs.md5 b/Code/Mantid/Testing/SystemTests/tests/analysis/reference/ISISIndirectBayes_JumpTeixeiraTest.nxs.md5 new file mode 100644 index 000000000000..9013c89cf1e3 --- /dev/null +++ b/Code/Mantid/Testing/SystemTests/tests/analysis/reference/ISISIndirectBayes_JumpTeixeiraTest.nxs.md5 @@ -0,0 +1 @@ +dd9c080b39820e4d84bbf10bfa58e1eb \ No newline at end of file diff --git a/Code/Mantid/Testing/SystemTests/tests/analysis/reference/ISISIndirectBayes_QLDataTest.nxs.md5 b/Code/Mantid/Testing/SystemTests/tests/analysis/reference/ISISIndirectBayes_QLDataTest.nxs.md5 new file mode 100644 index 000000000000..b53a99bebd76 --- /dev/null +++ b/Code/Mantid/Testing/SystemTests/tests/analysis/reference/ISISIndirectBayes_QLDataTest.nxs.md5 @@ -0,0 +1 @@ +0d5efed60ad5724ee1be63352d72589e \ No newline at end of file diff --git a/Code/Mantid/Testing/SystemTests/tests/analysis/reference/ISISIndirectBayes_QLr_ResNorm_Test.nxs.md5 b/Code/Mantid/Testing/SystemTests/tests/analysis/reference/ISISIndirectBayes_QLr_ResNorm_Test.nxs.md5 new file mode 100644 index 000000000000..cd31e4d6921d --- /dev/null +++ b/Code/Mantid/Testing/SystemTests/tests/analysis/reference/ISISIndirectBayes_QLr_ResNorm_Test.nxs.md5 @@ -0,0 +1 @@ +a248a0a1de78d09683cf5707e85536f0 \ No newline at end of file diff --git a/Code/Mantid/Testing/SystemTests/tests/analysis/reference/ISISIndirectBayes_QLr_width_Test.nxs.md5 b/Code/Mantid/Testing/SystemTests/tests/analysis/reference/ISISIndirectBayes_QLr_width_Test.nxs.md5 new file mode 100644 index 000000000000..753094656890 --- /dev/null +++ b/Code/Mantid/Testing/SystemTests/tests/analysis/reference/ISISIndirectBayes_QLr_width_Test.nxs.md5 @@ -0,0 +1 @@ +1278f9f7b9021f17e483d111417e37bc \ No newline at end of file diff --git a/Code/Mantid/Testing/SystemTests/tests/analysis/reference/ISISIndirectBayes_QSeTest.nxs.md5 b/Code/Mantid/Testing/SystemTests/tests/analysis/reference/ISISIndirectBayes_QSeTest.nxs.md5 new file mode 100644 index 000000000000..663323f9aa16 --- /dev/null +++ b/Code/Mantid/Testing/SystemTests/tests/analysis/reference/ISISIndirectBayes_QSeTest.nxs.md5 @@ -0,0 +1 @@ +bff628d5514cbc3d06d388b7c7353c09 \ No newline at end of file diff --git a/Code/Mantid/Testing/SystemTests/tests/analysis/reference/ISISIndirectBayes_QlresTest.nxs.md5 b/Code/Mantid/Testing/SystemTests/tests/analysis/reference/ISISIndirectBayes_QlresTest.nxs.md5 new file mode 100644 index 000000000000..072c51d2f392 --- /dev/null +++ b/Code/Mantid/Testing/SystemTests/tests/analysis/reference/ISISIndirectBayes_QlresTest.nxs.md5 @@ -0,0 +1 @@ +17d04f7b57a4475366c84242f6334701 \ No newline at end of file diff --git a/Code/Mantid/Testing/SystemTests/tests/analysis/reference/ISISIndirectBayes_QuestTest.nxs.md5 b/Code/Mantid/Testing/SystemTests/tests/analysis/reference/ISISIndirectBayes_QuestTest.nxs.md5 new file mode 100644 index 000000000000..663f5bdad338 --- /dev/null +++ b/Code/Mantid/Testing/SystemTests/tests/analysis/reference/ISISIndirectBayes_QuestTest.nxs.md5 @@ -0,0 +1 @@ +8ecaf2576985b1869135b3b4c7bede76 \ No newline at end of file diff --git a/Code/Mantid/Testing/SystemTests/tests/analysis/reference/ISISIndirectBayes_ResNormTest.nxs.md5 b/Code/Mantid/Testing/SystemTests/tests/analysis/reference/ISISIndirectBayes_ResNormTest.nxs.md5 new file mode 100644 index 000000000000..9a624f31227c --- /dev/null +++ b/Code/Mantid/Testing/SystemTests/tests/analysis/reference/ISISIndirectBayes_ResNormTest.nxs.md5 @@ -0,0 +1 @@ +57e79c3a8db3023c9e7b54e32dcb25ba \ No newline at end of file diff --git a/Code/Mantid/Testing/SystemTests/tests/analysis/reference/ISISIndirectLoadAscii_IN10SiliconTest.nxs.md5 b/Code/Mantid/Testing/SystemTests/tests/analysis/reference/ISISIndirectLoadAscii_IN10SiliconTest.nxs.md5 new file mode 100644 index 000000000000..c56fba061511 --- /dev/null +++ b/Code/Mantid/Testing/SystemTests/tests/analysis/reference/ISISIndirectLoadAscii_IN10SiliconTest.nxs.md5 @@ -0,0 +1 @@ +ea9ecafb4f5a79957105a8777211836d \ No newline at end of file diff --git a/Code/Mantid/Testing/SystemTests/tests/analysis/reference/ISISIndirectLoadAscii_IN13CaFTest.nxs.md5 b/Code/Mantid/Testing/SystemTests/tests/analysis/reference/ISISIndirectLoadAscii_IN13CaFTest.nxs.md5 new file mode 100644 index 000000000000..4a85f54a2260 --- /dev/null +++ b/Code/Mantid/Testing/SystemTests/tests/analysis/reference/ISISIndirectLoadAscii_IN13CaFTest.nxs.md5 @@ -0,0 +1 @@ +468b4c124b2f8d83bedec5c08aba61b6 \ No newline at end of file diff --git a/Code/Mantid/Testing/SystemTests/tests/analysis/reference/ISISIndirectLoadAscii_IN13CaFTest2.nxs.md5 b/Code/Mantid/Testing/SystemTests/tests/analysis/reference/ISISIndirectLoadAscii_IN13CaFTest2.nxs.md5 new file mode 100644 index 000000000000..fbefe3d43183 --- /dev/null +++ b/Code/Mantid/Testing/SystemTests/tests/analysis/reference/ISISIndirectLoadAscii_IN13CaFTest2.nxs.md5 @@ -0,0 +1 @@ +5942e9154eb658d2cd63dd420b121896 \ No newline at end of file diff --git a/Code/Mantid/Testing/SystemTests/tests/analysis/reference/ISISIndirectLoadAscii_IN16SiliconTest.nxs.md5 b/Code/Mantid/Testing/SystemTests/tests/analysis/reference/ISISIndirectLoadAscii_IN16SiliconTest.nxs.md5 new file mode 100644 index 000000000000..6b0ee448e04d --- /dev/null +++ b/Code/Mantid/Testing/SystemTests/tests/analysis/reference/ISISIndirectLoadAscii_IN16SiliconTest.nxs.md5 @@ -0,0 +1 @@ +4a972916d5e5c75d6dd99322b2d92676 \ No newline at end of file diff --git a/Code/Mantid/Testing/SystemTests/tests/analysis/reference/ISISIndirectSimulation_MolDynCDL.nxs.md5 b/Code/Mantid/Testing/SystemTests/tests/analysis/reference/ISISIndirectSimulation_MolDynCDL.nxs.md5 new file mode 100644 index 000000000000..10257ff23a63 --- /dev/null +++ b/Code/Mantid/Testing/SystemTests/tests/analysis/reference/ISISIndirectSimulation_MolDynCDL.nxs.md5 @@ -0,0 +1 @@ +ece35367023987de7dc41f02e9ecf681 \ No newline at end of file diff --git a/Code/Mantid/Testing/SystemTests/tests/analysis/reference/ISISIndirectSimulation_MolDynCDL_SQW.nxs.md5 b/Code/Mantid/Testing/SystemTests/tests/analysis/reference/ISISIndirectSimulation_MolDynCDL_SQW.nxs.md5 new file mode 100644 index 000000000000..c7f3e1473f80 --- /dev/null +++ b/Code/Mantid/Testing/SystemTests/tests/analysis/reference/ISISIndirectSimulation_MolDynCDL_SQW.nxs.md5 @@ -0,0 +1 @@ +622523464dca7eda79d604e51a0795c2 \ No newline at end of file diff --git a/Code/Mantid/Testing/SystemTests/tests/analysis/reference/ISISIndirectSimulation_MolDynDAT.nxs.md5 b/Code/Mantid/Testing/SystemTests/tests/analysis/reference/ISISIndirectSimulation_MolDynDAT.nxs.md5 new file mode 100644 index 000000000000..a21e268edc40 --- /dev/null +++ b/Code/Mantid/Testing/SystemTests/tests/analysis/reference/ISISIndirectSimulation_MolDynDAT.nxs.md5 @@ -0,0 +1 @@ +bc22e1ca81aa608b028c11f7099b9f6c \ No newline at end of file diff --git a/Code/Mantid/Testing/SystemTests/tests/analysis/reference/IndirectEnergyConversionTest.nxs.md5 b/Code/Mantid/Testing/SystemTests/tests/analysis/reference/IndirectEnergyConversionTest.nxs.md5 new file mode 100644 index 000000000000..f9c2b68909f7 --- /dev/null +++ b/Code/Mantid/Testing/SystemTests/tests/analysis/reference/IndirectEnergyConversionTest.nxs.md5 @@ -0,0 +1 @@ +7e54440a8e5133729d4bacd4b2571496 \ No newline at end of file diff --git a/Code/Mantid/Testing/SystemTests/tests/analysis/reference/IndirectTransmissionTest.nxs.md5 b/Code/Mantid/Testing/SystemTests/tests/analysis/reference/IndirectTransmissionTest.nxs.md5 new file mode 100644 index 000000000000..c28c7811b50e --- /dev/null +++ b/Code/Mantid/Testing/SystemTests/tests/analysis/reference/IndirectTransmissionTest.nxs.md5 @@ -0,0 +1 @@ +0468433ef4b5a9e20340ec6fdc9743d0 \ No newline at end of file diff --git a/Code/Mantid/Testing/SystemTests/tests/analysis/reference/L2QReferenceResult.nxs.md5 b/Code/Mantid/Testing/SystemTests/tests/analysis/reference/L2QReferenceResult.nxs.md5 new file mode 100644 index 000000000000..309459a3b1c4 --- /dev/null +++ b/Code/Mantid/Testing/SystemTests/tests/analysis/reference/L2QReferenceResult.nxs.md5 @@ -0,0 +1 @@ +57144b9309c8dbb1232a15c6daa2e904 \ No newline at end of file diff --git a/Code/Mantid/Testing/SystemTests/tests/analysis/reference/LET14305_3_4meV2015.nxs.md5 b/Code/Mantid/Testing/SystemTests/tests/analysis/reference/LET14305_3_4meV2015.nxs.md5 new file mode 100644 index 000000000000..6ed489c5d183 --- /dev/null +++ b/Code/Mantid/Testing/SystemTests/tests/analysis/reference/LET14305_3_4meV2015.nxs.md5 @@ -0,0 +1 @@ +df968e07d52c10b9c3ecf4b2c5db596a \ No newline at end of file diff --git a/Code/Mantid/Testing/SystemTests/tests/analysis/reference/LET14305_3_4mev.nxs.md5 b/Code/Mantid/Testing/SystemTests/tests/analysis/reference/LET14305_3_4mev.nxs.md5 new file mode 100644 index 000000000000..b0cc82739220 --- /dev/null +++ b/Code/Mantid/Testing/SystemTests/tests/analysis/reference/LET14305_3_4mev.nxs.md5 @@ -0,0 +1 @@ +94a08cffaa147469c35863a07e77f8e2 \ No newline at end of file diff --git a/Code/Mantid/Testing/SystemTests/tests/analysis/reference/LET14305_8_0meV2015.nxs.md5 b/Code/Mantid/Testing/SystemTests/tests/analysis/reference/LET14305_8_0meV2015.nxs.md5 new file mode 100644 index 000000000000..b5ea401ab0c8 --- /dev/null +++ b/Code/Mantid/Testing/SystemTests/tests/analysis/reference/LET14305_8_0meV2015.nxs.md5 @@ -0,0 +1 @@ +ebe8b924084f11a09b9af25c4737a092 \ No newline at end of file diff --git a/Code/Mantid/Testing/SystemTests/tests/analysis/reference/LET14305_8_0mev.nxs.md5 b/Code/Mantid/Testing/SystemTests/tests/analysis/reference/LET14305_8_0mev.nxs.md5 new file mode 100644 index 000000000000..ecbe7a432ca6 --- /dev/null +++ b/Code/Mantid/Testing/SystemTests/tests/analysis/reference/LET14305_8_0mev.nxs.md5 @@ -0,0 +1 @@ +89e4436d52b2f94cc9aa7e267523a815 \ No newline at end of file diff --git a/Code/Mantid/Testing/SystemTests/tests/analysis/reference/LETReduction.nxs.md5 b/Code/Mantid/Testing/SystemTests/tests/analysis/reference/LETReduction.nxs.md5 new file mode 100644 index 000000000000..795de7fc9236 --- /dev/null +++ b/Code/Mantid/Testing/SystemTests/tests/analysis/reference/LETReduction.nxs.md5 @@ -0,0 +1 @@ +bb0346aa19e1bf20cad95cb1c838ea30 \ No newline at end of file diff --git a/Code/Mantid/Testing/SystemTests/tests/analysis/reference/LOQCentreNoGrav.nxs.md5 b/Code/Mantid/Testing/SystemTests/tests/analysis/reference/LOQCentreNoGrav.nxs.md5 new file mode 100644 index 000000000000..6bbe1d3fbbec --- /dev/null +++ b/Code/Mantid/Testing/SystemTests/tests/analysis/reference/LOQCentreNoGrav.nxs.md5 @@ -0,0 +1 @@ +c810f04752496e3872c6f8acd76705d3 \ No newline at end of file diff --git a/Code/Mantid/Testing/SystemTests/tests/analysis/reference/LOQCentreNoGravSearchCentreFixed.nxs.md5 b/Code/Mantid/Testing/SystemTests/tests/analysis/reference/LOQCentreNoGravSearchCentreFixed.nxs.md5 new file mode 100644 index 000000000000..ae9eb85a7989 --- /dev/null +++ b/Code/Mantid/Testing/SystemTests/tests/analysis/reference/LOQCentreNoGravSearchCentreFixed.nxs.md5 @@ -0,0 +1 @@ +c6451ee0b2d3e5f27d1c873e1c6d8879 \ No newline at end of file diff --git a/Code/Mantid/Testing/SystemTests/tests/analysis/reference/LOQReductionMergedData.nxs.md5 b/Code/Mantid/Testing/SystemTests/tests/analysis/reference/LOQReductionMergedData.nxs.md5 new file mode 100644 index 000000000000..019871517203 --- /dev/null +++ b/Code/Mantid/Testing/SystemTests/tests/analysis/reference/LOQReductionMergedData.nxs.md5 @@ -0,0 +1 @@ +805fc03c9961d67b03a617efef6ac2ea \ No newline at end of file diff --git a/Code/Mantid/Testing/SystemTests/tests/analysis/reference/LOQTransFitWorkspace2D.nxs.md5 b/Code/Mantid/Testing/SystemTests/tests/analysis/reference/LOQTransFitWorkspace2D.nxs.md5 new file mode 100644 index 000000000000..ee80795f13c5 --- /dev/null +++ b/Code/Mantid/Testing/SystemTests/tests/analysis/reference/LOQTransFitWorkspace2D.nxs.md5 @@ -0,0 +1 @@ +31a8e29b5ca02c108528ecacdbbdca33 \ No newline at end of file diff --git a/Code/Mantid/Testing/SystemTests/tests/analysis/reference/MAPSDgreduceReduction.nxs.md5 b/Code/Mantid/Testing/SystemTests/tests/analysis/reference/MAPSDgreduceReduction.nxs.md5 new file mode 100644 index 000000000000..d17f4dd65a02 --- /dev/null +++ b/Code/Mantid/Testing/SystemTests/tests/analysis/reference/MAPSDgreduceReduction.nxs.md5 @@ -0,0 +1 @@ +009f2fee8d2b166cdd31e833b2a1d324 \ No newline at end of file diff --git a/Code/Mantid/Testing/SystemTests/tests/analysis/reference/MARIReduction.nxs.md5 b/Code/Mantid/Testing/SystemTests/tests/analysis/reference/MARIReduction.nxs.md5 new file mode 100644 index 000000000000..70f13447a4e7 --- /dev/null +++ b/Code/Mantid/Testing/SystemTests/tests/analysis/reference/MARIReduction.nxs.md5 @@ -0,0 +1 @@ +fdb545b8a7f6bb5a6b52585769559057 \ No newline at end of file diff --git a/Code/Mantid/Testing/SystemTests/tests/analysis/reference/MARIReductionMonSeparate.nxs.md5 b/Code/Mantid/Testing/SystemTests/tests/analysis/reference/MARIReductionMonSeparate.nxs.md5 new file mode 100644 index 000000000000..edd222570a84 --- /dev/null +++ b/Code/Mantid/Testing/SystemTests/tests/analysis/reference/MARIReductionMonSeparate.nxs.md5 @@ -0,0 +1 @@ +bb170be95d9c13cd540e6c60ad0c2b15 \ No newline at end of file diff --git a/Code/Mantid/Testing/SystemTests/tests/analysis/reference/MARIReductionSum.nxs.md5 b/Code/Mantid/Testing/SystemTests/tests/analysis/reference/MARIReductionSum.nxs.md5 new file mode 100644 index 000000000000..a0c14267ca31 --- /dev/null +++ b/Code/Mantid/Testing/SystemTests/tests/analysis/reference/MARIReductionSum.nxs.md5 @@ -0,0 +1 @@ +a135903cc822c55c818e94cd8b2e4b1d \ No newline at end of file diff --git a/Code/Mantid/Testing/SystemTests/tests/analysis/reference/MERLINReduction.nxs.md5 b/Code/Mantid/Testing/SystemTests/tests/analysis/reference/MERLINReduction.nxs.md5 new file mode 100644 index 000000000000..e3db5b70ad82 --- /dev/null +++ b/Code/Mantid/Testing/SystemTests/tests/analysis/reference/MERLINReduction.nxs.md5 @@ -0,0 +1 @@ +6ba46ef250726347c9d02243101cef41 \ No newline at end of file diff --git a/Code/Mantid/Testing/SystemTests/tests/analysis/reference/MuSRAnalysis.nxs.md5 b/Code/Mantid/Testing/SystemTests/tests/analysis/reference/MuSRAnalysis.nxs.md5 new file mode 100644 index 000000000000..8fad56c366ff --- /dev/null +++ b/Code/Mantid/Testing/SystemTests/tests/analysis/reference/MuSRAnalysis.nxs.md5 @@ -0,0 +1 @@ +cb0b0fd2521871f545ab77643ecd6157 \ No newline at end of file diff --git a/Code/Mantid/Testing/SystemTests/tests/analysis/reference/MuSRAnalysisLog1.nxs.md5 b/Code/Mantid/Testing/SystemTests/tests/analysis/reference/MuSRAnalysisLog1.nxs.md5 new file mode 100644 index 000000000000..82483d54fea7 --- /dev/null +++ b/Code/Mantid/Testing/SystemTests/tests/analysis/reference/MuSRAnalysisLog1.nxs.md5 @@ -0,0 +1 @@ +87bcdd779c971ccc0188228d87a11b2d \ No newline at end of file diff --git a/Code/Mantid/Testing/SystemTests/tests/analysis/reference/MuonLoad_MUSR00015192.nxs.md5 b/Code/Mantid/Testing/SystemTests/tests/analysis/reference/MuonLoad_MUSR00015192.nxs.md5 new file mode 100644 index 000000000000..375ff4a9afff --- /dev/null +++ b/Code/Mantid/Testing/SystemTests/tests/analysis/reference/MuonLoad_MUSR00015192.nxs.md5 @@ -0,0 +1 @@ +ed05e8a90ba843b8e2ad88cd10773e22 \ No newline at end of file diff --git a/Code/Mantid/Testing/SystemTests/tests/analysis/reference/OFFSPEC00010791_1Integrated.nxs.md5 b/Code/Mantid/Testing/SystemTests/tests/analysis/reference/OFFSPEC00010791_1Integrated.nxs.md5 new file mode 100644 index 000000000000..a8147bc35e07 --- /dev/null +++ b/Code/Mantid/Testing/SystemTests/tests/analysis/reference/OFFSPEC00010791_1Integrated.nxs.md5 @@ -0,0 +1 @@ +cca0684e0375d56fb9b6add1dbd790cf \ No newline at end of file diff --git a/Code/Mantid/Testing/SystemTests/tests/analysis/reference/OffspecSESANS.nxs.md5 b/Code/Mantid/Testing/SystemTests/tests/analysis/reference/OffspecSESANS.nxs.md5 new file mode 100644 index 000000000000..de8f7ce9d96f --- /dev/null +++ b/Code/Mantid/Testing/SystemTests/tests/analysis/reference/OffspecSESANS.nxs.md5 @@ -0,0 +1 @@ +2f730f07ebb2350d9e82fd5296b3e49b \ No newline at end of file diff --git a/Code/Mantid/Testing/SystemTests/tests/analysis/reference/OffspecSESANSP0.nxs.md5 b/Code/Mantid/Testing/SystemTests/tests/analysis/reference/OffspecSESANSP0.nxs.md5 new file mode 100644 index 000000000000..5431ed76e56d --- /dev/null +++ b/Code/Mantid/Testing/SystemTests/tests/analysis/reference/OffspecSESANSP0.nxs.md5 @@ -0,0 +1 @@ +05f626962363970f35ca80b2942b9e3f \ No newline at end of file diff --git a/Code/Mantid/Testing/SystemTests/tests/analysis/reference/OsirisDiffractionTest.nxs.md5 b/Code/Mantid/Testing/SystemTests/tests/analysis/reference/OsirisDiffractionTest.nxs.md5 new file mode 100644 index 000000000000..13e04e92169c --- /dev/null +++ b/Code/Mantid/Testing/SystemTests/tests/analysis/reference/OsirisDiffractionTest.nxs.md5 @@ -0,0 +1 @@ +f4d38526029567435afb8455d8d67751 \ No newline at end of file diff --git a/Code/Mantid/Testing/SystemTests/tests/analysis/reference/OsirisDiffspecDiffractionTest.nxs.md5 b/Code/Mantid/Testing/SystemTests/tests/analysis/reference/OsirisDiffspecDiffractionTest.nxs.md5 new file mode 100644 index 000000000000..474d39abe8e9 --- /dev/null +++ b/Code/Mantid/Testing/SystemTests/tests/analysis/reference/OsirisDiffspecDiffractionTest.nxs.md5 @@ -0,0 +1 @@ +04b17016bf7313e34716c849899a435f \ No newline at end of file diff --git a/Code/Mantid/Testing/SystemTests/tests/analysis/reference/PEARL74795_74797-0.gss.md5 b/Code/Mantid/Testing/SystemTests/tests/analysis/reference/PEARL74795_74797-0.gss.md5 new file mode 100644 index 000000000000..aa0aafff1f5f --- /dev/null +++ b/Code/Mantid/Testing/SystemTests/tests/analysis/reference/PEARL74795_74797-0.gss.md5 @@ -0,0 +1 @@ +1e8c15d7fd2ae1b1945c7c47184b2dc0 \ No newline at end of file diff --git a/Code/Mantid/Testing/SystemTests/tests/analysis/reference/PEARL74795_74797.nxs.md5 b/Code/Mantid/Testing/SystemTests/tests/analysis/reference/PEARL74795_74797.nxs.md5 new file mode 100644 index 000000000000..b89b18db8e99 --- /dev/null +++ b/Code/Mantid/Testing/SystemTests/tests/analysis/reference/PEARL74795_74797.nxs.md5 @@ -0,0 +1 @@ +b79caa842a8a992e74c73a48fe3e1289 \ No newline at end of file diff --git a/Code/Mantid/Testing/SystemTests/tests/analysis/reference/PEARL74798_74800-0.gss.md5 b/Code/Mantid/Testing/SystemTests/tests/analysis/reference/PEARL74798_74800-0.gss.md5 new file mode 100644 index 000000000000..a065efa62102 --- /dev/null +++ b/Code/Mantid/Testing/SystemTests/tests/analysis/reference/PEARL74798_74800-0.gss.md5 @@ -0,0 +1 @@ +5d656e3da1f872e61e9cb7cfe1f1d999 \ No newline at end of file diff --git a/Code/Mantid/Testing/SystemTests/tests/analysis/reference/PEARL74798_74800.nxs.md5 b/Code/Mantid/Testing/SystemTests/tests/analysis/reference/PEARL74798_74800.nxs.md5 new file mode 100644 index 000000000000..d152012f31cb --- /dev/null +++ b/Code/Mantid/Testing/SystemTests/tests/analysis/reference/PEARL74798_74800.nxs.md5 @@ -0,0 +1 @@ +560fee80b3ae7af43f6d8ac204d46499 \ No newline at end of file diff --git a/Code/Mantid/Testing/SystemTests/tests/analysis/reference/PEARL75318_75323-0.gss.md5 b/Code/Mantid/Testing/SystemTests/tests/analysis/reference/PEARL75318_75323-0.gss.md5 new file mode 100644 index 000000000000..3cc47a2241d6 --- /dev/null +++ b/Code/Mantid/Testing/SystemTests/tests/analysis/reference/PEARL75318_75323-0.gss.md5 @@ -0,0 +1 @@ +24cc123c0dd8c40e8b9f238d128b09d9 \ No newline at end of file diff --git a/Code/Mantid/Testing/SystemTests/tests/analysis/reference/PEARL75318_75323.nxs.md5 b/Code/Mantid/Testing/SystemTests/tests/analysis/reference/PEARL75318_75323.nxs.md5 new file mode 100644 index 000000000000..cedefce42087 --- /dev/null +++ b/Code/Mantid/Testing/SystemTests/tests/analysis/reference/PEARL75318_75323.nxs.md5 @@ -0,0 +1 @@ +810dd6901f516903a4610376ff96d9a1 \ No newline at end of file diff --git a/Code/Mantid/Testing/SystemTests/tests/analysis/reference/PEARL75318_75323_noatten.nxs.md5 b/Code/Mantid/Testing/SystemTests/tests/analysis/reference/PEARL75318_75323_noatten.nxs.md5 new file mode 100644 index 000000000000..c126d8144706 --- /dev/null +++ b/Code/Mantid/Testing/SystemTests/tests/analysis/reference/PEARL75318_75323_noatten.nxs.md5 @@ -0,0 +1 @@ +d9b6e1e71716f9bfbd34637ce63b8388 \ No newline at end of file diff --git a/Code/Mantid/Testing/SystemTests/tests/analysis/reference/PEARLPowderDiffraction.nxs.md5 b/Code/Mantid/Testing/SystemTests/tests/analysis/reference/PEARLPowderDiffraction.nxs.md5 new file mode 100644 index 000000000000..9b79e679c16c --- /dev/null +++ b/Code/Mantid/Testing/SystemTests/tests/analysis/reference/PEARLPowderDiffraction.nxs.md5 @@ -0,0 +1 @@ +8b9dcecb5ff0605e5fa5190abc1841d0 \ No newline at end of file diff --git a/Code/Mantid/Testing/SystemTests/tests/analysis/reference/PG3_4844_reference.gsa.md5 b/Code/Mantid/Testing/SystemTests/tests/analysis/reference/PG3_4844_reference.gsa.md5 new file mode 100644 index 000000000000..48653d1b66da --- /dev/null +++ b/Code/Mantid/Testing/SystemTests/tests/analysis/reference/PG3_4844_reference.gsa.md5 @@ -0,0 +1 @@ +142ec3335e39f6df985903a58617e7db \ No newline at end of file diff --git a/Code/Mantid/Testing/SystemTests/tests/analysis/reference/PG3_4866_Stable.gsa.md5 b/Code/Mantid/Testing/SystemTests/tests/analysis/reference/PG3_4866_Stable.gsa.md5 new file mode 100644 index 000000000000..b55d66346d07 --- /dev/null +++ b/Code/Mantid/Testing/SystemTests/tests/analysis/reference/PG3_4866_Stable.gsa.md5 @@ -0,0 +1 @@ +1204f5f1553de865647741794d91b9af \ No newline at end of file diff --git a/Code/Mantid/Testing/SystemTests/tests/analysis/reference/PG3_4866_reference.gsa.md5 b/Code/Mantid/Testing/SystemTests/tests/analysis/reference/PG3_4866_reference.gsa.md5 new file mode 100644 index 000000000000..4098ae460a70 --- /dev/null +++ b/Code/Mantid/Testing/SystemTests/tests/analysis/reference/PG3_4866_reference.gsa.md5 @@ -0,0 +1 @@ +f06a8fc5325f3ae2f9a0d25668df8c1e \ No newline at end of file diff --git a/Code/Mantid/Testing/SystemTests/tests/analysis/reference/PG3_9829_reference.gsa.md5 b/Code/Mantid/Testing/SystemTests/tests/analysis/reference/PG3_9829_reference.gsa.md5 new file mode 100644 index 000000000000..f03c1a3430f8 --- /dev/null +++ b/Code/Mantid/Testing/SystemTests/tests/analysis/reference/PG3_9829_reference.gsa.md5 @@ -0,0 +1 @@ +ac91279f6a81ea6e0146a91c8ffdc410 \ No newline at end of file diff --git a/Code/Mantid/Testing/SystemTests/tests/analysis/reference/PG3_9830_reference.gsa.md5 b/Code/Mantid/Testing/SystemTests/tests/analysis/reference/PG3_9830_reference.gsa.md5 new file mode 100644 index 000000000000..85945478daea --- /dev/null +++ b/Code/Mantid/Testing/SystemTests/tests/analysis/reference/PG3_9830_reference.gsa.md5 @@ -0,0 +1 @@ +32f08458016cba424ed15b0f8ba6cc8d \ No newline at end of file diff --git a/Code/Mantid/Testing/SystemTests/tests/analysis/reference/PG3_golden.cal.md5 b/Code/Mantid/Testing/SystemTests/tests/analysis/reference/PG3_golden.cal.md5 new file mode 100644 index 000000000000..64215e72c7c3 --- /dev/null +++ b/Code/Mantid/Testing/SystemTests/tests/analysis/reference/PG3_golden.cal.md5 @@ -0,0 +1 @@ +69889b01c7aa33d5802360a8182740e1 \ No newline at end of file diff --git a/Code/Mantid/Testing/SystemTests/tests/analysis/reference/PG3_goldenCC.cal.md5 b/Code/Mantid/Testing/SystemTests/tests/analysis/reference/PG3_goldenCC.cal.md5 new file mode 100644 index 000000000000..0d55939b117d --- /dev/null +++ b/Code/Mantid/Testing/SystemTests/tests/analysis/reference/PG3_goldenCC.cal.md5 @@ -0,0 +1 @@ +01b7c52ff856f4474a8d971c7b088add \ No newline at end of file diff --git a/Code/Mantid/Testing/SystemTests/tests/analysis/reference/POLREF00004699_1Integrated.nxs.md5 b/Code/Mantid/Testing/SystemTests/tests/analysis/reference/POLREF00004699_1Integrated.nxs.md5 new file mode 100644 index 000000000000..79b3334ae18b --- /dev/null +++ b/Code/Mantid/Testing/SystemTests/tests/analysis/reference/POLREF00004699_1Integrated.nxs.md5 @@ -0,0 +1 @@ +d9ccfa79498207118b3c6e3708115148 \ No newline at end of file diff --git a/Code/Mantid/Testing/SystemTests/tests/analysis/reference/POLREF_kikf_benchmark.nxs.md5 b/Code/Mantid/Testing/SystemTests/tests/analysis/reference/POLREF_kikf_benchmark.nxs.md5 new file mode 100644 index 000000000000..f42b138e7e72 --- /dev/null +++ b/Code/Mantid/Testing/SystemTests/tests/analysis/reference/POLREF_kikf_benchmark.nxs.md5 @@ -0,0 +1 @@ +6aec6789c6d31578c475035a30ef9d93 \ No newline at end of file diff --git a/Code/Mantid/Testing/SystemTests/tests/analysis/reference/POLREF_pipf_benchmark.nxs.md5 b/Code/Mantid/Testing/SystemTests/tests/analysis/reference/POLREF_pipf_benchmark.nxs.md5 new file mode 100644 index 000000000000..a1a5ed4fedb5 --- /dev/null +++ b/Code/Mantid/Testing/SystemTests/tests/analysis/reference/POLREF_pipf_benchmark.nxs.md5 @@ -0,0 +1 @@ +6085411f0eeae0a9e02bfded54f8df1b \ No newline at end of file diff --git a/Code/Mantid/Testing/SystemTests/tests/analysis/reference/POLREF_qxqy_benchmark.nxs.md5 b/Code/Mantid/Testing/SystemTests/tests/analysis/reference/POLREF_qxqy_benchmark.nxs.md5 new file mode 100644 index 000000000000..cc04be8e7ff6 --- /dev/null +++ b/Code/Mantid/Testing/SystemTests/tests/analysis/reference/POLREF_qxqy_benchmark.nxs.md5 @@ -0,0 +1 @@ +99b9cd85189b9e35648bee67c44d2ea0 \ No newline at end of file diff --git a/Code/Mantid/Testing/SystemTests/tests/analysis/reference/PolrefTest.nxs.md5 b/Code/Mantid/Testing/SystemTests/tests/analysis/reference/PolrefTest.nxs.md5 new file mode 100644 index 000000000000..79d52c213f33 --- /dev/null +++ b/Code/Mantid/Testing/SystemTests/tests/analysis/reference/PolrefTest.nxs.md5 @@ -0,0 +1 @@ +587d02b9241653dc82464dda6f370a9e \ No newline at end of file diff --git a/Code/Mantid/Testing/SystemTests/tests/analysis/reference/QuickReferenceResult.nxs.md5 b/Code/Mantid/Testing/SystemTests/tests/analysis/reference/QuickReferenceResult.nxs.md5 new file mode 100644 index 000000000000..24446114e135 --- /dev/null +++ b/Code/Mantid/Testing/SystemTests/tests/analysis/reference/QuickReferenceResult.nxs.md5 @@ -0,0 +1 @@ +b9b63ffed74809bc9017f907f63668db \ No newline at end of file diff --git a/Code/Mantid/Testing/SystemTests/tests/analysis/reference/QuickStitchedReferenceResult.nxs.md5 b/Code/Mantid/Testing/SystemTests/tests/analysis/reference/QuickStitchedReferenceResult.nxs.md5 new file mode 100644 index 000000000000..38c0cec45703 --- /dev/null +++ b/Code/Mantid/Testing/SystemTests/tests/analysis/reference/QuickStitchedReferenceResult.nxs.md5 @@ -0,0 +1 @@ +d89098974bcf70c3e076c2e8ef126850 \ No newline at end of file diff --git a/Code/Mantid/Testing/SystemTests/tests/analysis/reference/REFLReduction.nxs.md5 b/Code/Mantid/Testing/SystemTests/tests/analysis/reference/REFLReduction.nxs.md5 new file mode 100644 index 000000000000..354044e2b8c1 --- /dev/null +++ b/Code/Mantid/Testing/SystemTests/tests/analysis/reference/REFLReduction.nxs.md5 @@ -0,0 +1 @@ +35c194317a1ec1cd43999fc304d85e54 \ No newline at end of file diff --git a/Code/Mantid/Testing/SystemTests/tests/analysis/reference/REFMReduction_off_off.nxs.md5 b/Code/Mantid/Testing/SystemTests/tests/analysis/reference/REFMReduction_off_off.nxs.md5 new file mode 100644 index 000000000000..46901bd0de00 --- /dev/null +++ b/Code/Mantid/Testing/SystemTests/tests/analysis/reference/REFMReduction_off_off.nxs.md5 @@ -0,0 +1 @@ +832ae8c2215e593dd8571cca901c7d9b \ No newline at end of file diff --git a/Code/Mantid/Testing/SystemTests/tests/analysis/reference/SANS2DBatch.nxs.md5 b/Code/Mantid/Testing/SystemTests/tests/analysis/reference/SANS2DBatch.nxs.md5 new file mode 100644 index 000000000000..80f2632df851 --- /dev/null +++ b/Code/Mantid/Testing/SystemTests/tests/analysis/reference/SANS2DBatch.nxs.md5 @@ -0,0 +1 @@ +6af04f7ddc80cc68cb571a13581975d0 \ No newline at end of file diff --git a/Code/Mantid/Testing/SystemTests/tests/analysis/reference/SANS2DFrontNoGrav.nxs.md5 b/Code/Mantid/Testing/SystemTests/tests/analysis/reference/SANS2DFrontNoGrav.nxs.md5 new file mode 100644 index 000000000000..560b56e4db31 --- /dev/null +++ b/Code/Mantid/Testing/SystemTests/tests/analysis/reference/SANS2DFrontNoGrav.nxs.md5 @@ -0,0 +1 @@ +111f2dd7388c1d136992d11c47695319 \ No newline at end of file diff --git a/Code/Mantid/Testing/SystemTests/tests/analysis/reference/SANS2DMultiPeriodAddFiles.nxs.md5 b/Code/Mantid/Testing/SystemTests/tests/analysis/reference/SANS2DMultiPeriodAddFiles.nxs.md5 new file mode 100644 index 000000000000..36856ca9cbd5 --- /dev/null +++ b/Code/Mantid/Testing/SystemTests/tests/analysis/reference/SANS2DMultiPeriodAddFiles.nxs.md5 @@ -0,0 +1 @@ +83ca9f177c163ba77d2c6f7b3d606ef9 \ No newline at end of file diff --git a/Code/Mantid/Testing/SystemTests/tests/analysis/reference/SANS2DNewSettingsCarriedAcross.nxs.md5 b/Code/Mantid/Testing/SystemTests/tests/analysis/reference/SANS2DNewSettingsCarriedAcross.nxs.md5 new file mode 100644 index 000000000000..9b0ee62c1267 --- /dev/null +++ b/Code/Mantid/Testing/SystemTests/tests/analysis/reference/SANS2DNewSettingsCarriedAcross.nxs.md5 @@ -0,0 +1 @@ +6ee3d1a1775652c5ae36a9f11a93c210 \ No newline at end of file diff --git a/Code/Mantid/Testing/SystemTests/tests/analysis/reference/SANS2DWaveloops.nxs.md5 b/Code/Mantid/Testing/SystemTests/tests/analysis/reference/SANS2DWaveloops.nxs.md5 new file mode 100644 index 000000000000..8c1fe5526e5c --- /dev/null +++ b/Code/Mantid/Testing/SystemTests/tests/analysis/reference/SANS2DWaveloops.nxs.md5 @@ -0,0 +1 @@ +30a0a0412cae770151ebd148765a9b78 \ No newline at end of file diff --git a/Code/Mantid/Testing/SystemTests/tests/analysis/reference/SANSCentreSample.nxs.md5 b/Code/Mantid/Testing/SystemTests/tests/analysis/reference/SANSCentreSample.nxs.md5 new file mode 100644 index 000000000000..81b9ba4d3159 --- /dev/null +++ b/Code/Mantid/Testing/SystemTests/tests/analysis/reference/SANSCentreSample.nxs.md5 @@ -0,0 +1 @@ +a7336159a0807d5a904ce16d17b29290 \ No newline at end of file diff --git a/Code/Mantid/Testing/SystemTests/tests/analysis/reference/SANSLOQBatch.nxs.md5 b/Code/Mantid/Testing/SystemTests/tests/analysis/reference/SANSLOQBatch.nxs.md5 new file mode 100644 index 000000000000..f47f66083b2d --- /dev/null +++ b/Code/Mantid/Testing/SystemTests/tests/analysis/reference/SANSLOQBatch.nxs.md5 @@ -0,0 +1 @@ +2ba0cb478a6efaf1351e541414760881 \ No newline at end of file diff --git a/Code/Mantid/Testing/SystemTests/tests/analysis/reference/SANSLOQCan2D.nxs.md5 b/Code/Mantid/Testing/SystemTests/tests/analysis/reference/SANSLOQCan2D.nxs.md5 new file mode 100644 index 000000000000..96ef8cbd00db --- /dev/null +++ b/Code/Mantid/Testing/SystemTests/tests/analysis/reference/SANSLOQCan2D.nxs.md5 @@ -0,0 +1 @@ +4042732e35f86fbdbc25de6587e117c1 \ No newline at end of file diff --git a/Code/Mantid/Testing/SystemTests/tests/analysis/reference/SANSReductionGUI.nxs.md5 b/Code/Mantid/Testing/SystemTests/tests/analysis/reference/SANSReductionGUI.nxs.md5 new file mode 100644 index 000000000000..bfddc6b9faa7 --- /dev/null +++ b/Code/Mantid/Testing/SystemTests/tests/analysis/reference/SANSReductionGUI.nxs.md5 @@ -0,0 +1 @@ +f81073e6ec798d1df1b7046e96bd01d8 \ No newline at end of file diff --git a/Code/Mantid/Testing/SystemTests/tests/analysis/reference/SANSReductionGUI_LimitEventsTime.nxs.md5 b/Code/Mantid/Testing/SystemTests/tests/analysis/reference/SANSReductionGUI_LimitEventsTime.nxs.md5 new file mode 100644 index 000000000000..62e9f7cbafc3 --- /dev/null +++ b/Code/Mantid/Testing/SystemTests/tests/analysis/reference/SANSReductionGUI_LimitEventsTime.nxs.md5 @@ -0,0 +1 @@ +9ddc1129964b8be41d53d0c283279cb0 \ No newline at end of file diff --git a/Code/Mantid/Testing/SystemTests/tests/analysis/reference/SEQUOIAReduction.nxs.md5 b/Code/Mantid/Testing/SystemTests/tests/analysis/reference/SEQUOIAReduction.nxs.md5 new file mode 100644 index 000000000000..4c0980447820 --- /dev/null +++ b/Code/Mantid/Testing/SystemTests/tests/analysis/reference/SEQUOIAReduction.nxs.md5 @@ -0,0 +1 @@ +af7f5f9808a756ad7eadce1ef928f0e2 \ No newline at end of file diff --git a/Code/Mantid/Testing/SystemTests/tests/analysis/reference/SEQ_11499_md_enp.nxs.md5 b/Code/Mantid/Testing/SystemTests/tests/analysis/reference/SEQ_11499_md_enp.nxs.md5 new file mode 100644 index 000000000000..e1aaaf188f6c --- /dev/null +++ b/Code/Mantid/Testing/SystemTests/tests/analysis/reference/SEQ_11499_md_enp.nxs.md5 @@ -0,0 +1 @@ +d2f0263526629fcc3b03cbb72999b15c \ No newline at end of file diff --git a/Code/Mantid/Testing/SystemTests/tests/analysis/reference/SEQ_11499_md_ewp.nxs.md5 b/Code/Mantid/Testing/SystemTests/tests/analysis/reference/SEQ_11499_md_ewp.nxs.md5 new file mode 100644 index 000000000000..f43e6ab00fd2 --- /dev/null +++ b/Code/Mantid/Testing/SystemTests/tests/analysis/reference/SEQ_11499_md_ewp.nxs.md5 @@ -0,0 +1 @@ +0117833cf17d83c84497993153ba84f8 \ No newline at end of file diff --git a/Code/Mantid/Testing/SystemTests/tests/analysis/reference/SRF92132_1Integrated.nxs.md5 b/Code/Mantid/Testing/SystemTests/tests/analysis/reference/SRF92132_1Integrated.nxs.md5 new file mode 100644 index 000000000000..4c422d480a23 --- /dev/null +++ b/Code/Mantid/Testing/SystemTests/tests/analysis/reference/SRF92132_1Integrated.nxs.md5 @@ -0,0 +1 @@ +f56d3fbf38e9aefdeac1c863724dc9f4 \ No newline at end of file diff --git a/Code/Mantid/Testing/SystemTests/tests/analysis/reference/SpaceGroupSymmetryOperations.txt.md5 b/Code/Mantid/Testing/SystemTests/tests/analysis/reference/SpaceGroupSymmetryOperations.txt.md5 new file mode 100644 index 000000000000..6d7e871ae806 --- /dev/null +++ b/Code/Mantid/Testing/SystemTests/tests/analysis/reference/SpaceGroupSymmetryOperations.txt.md5 @@ -0,0 +1 @@ +e73578bc766def2245ce0f05864c0973 \ No newline at end of file diff --git a/Code/Mantid/Testing/SystemTests/tests/analysis/reference/StepScan.nxs.md5 b/Code/Mantid/Testing/SystemTests/tests/analysis/reference/StepScan.nxs.md5 new file mode 100644 index 000000000000..1995f2c72be2 --- /dev/null +++ b/Code/Mantid/Testing/SystemTests/tests/analysis/reference/StepScan.nxs.md5 @@ -0,0 +1 @@ +6792b636f3bcd01e713169ea3a06a4a3 \ No newline at end of file diff --git a/Code/Mantid/Testing/SystemTests/tests/analysis/reference/TOPAZ_3132_reference.hkl.md5 b/Code/Mantid/Testing/SystemTests/tests/analysis/reference/TOPAZ_3132_reference.hkl.md5 new file mode 100644 index 000000000000..db2dbe2f6e30 --- /dev/null +++ b/Code/Mantid/Testing/SystemTests/tests/analysis/reference/TOPAZ_3132_reference.hkl.md5 @@ -0,0 +1 @@ +3fa2a0ff7078de5c4af3b12ebfcef005 \ No newline at end of file diff --git a/Code/Mantid/Testing/SystemTests/tests/analysis/reference/TOSCADiffractionTest.nxs.md5 b/Code/Mantid/Testing/SystemTests/tests/analysis/reference/TOSCADiffractionTest.nxs.md5 new file mode 100644 index 000000000000..7d114f6366c9 --- /dev/null +++ b/Code/Mantid/Testing/SystemTests/tests/analysis/reference/TOSCADiffractionTest.nxs.md5 @@ -0,0 +1 @@ +0a7d3002b96483d00099ccd2b85979b6 \ No newline at end of file diff --git a/Code/Mantid/Testing/SystemTests/tests/analysis/reference/TobyFitResolutionSimulationTest.nxs.md5 b/Code/Mantid/Testing/SystemTests/tests/analysis/reference/TobyFitResolutionSimulationTest.nxs.md5 new file mode 100644 index 000000000000..0cc88bb8f19c --- /dev/null +++ b/Code/Mantid/Testing/SystemTests/tests/analysis/reference/TobyFitResolutionSimulationTest.nxs.md5 @@ -0,0 +1 @@ +87640430007d9b53cf2672de529718ea \ No newline at end of file diff --git a/Code/Mantid/Testing/SystemTests/tests/analysis/reference/VesuvioFittingTest.nxs.md5 b/Code/Mantid/Testing/SystemTests/tests/analysis/reference/VesuvioFittingTest.nxs.md5 new file mode 100644 index 000000000000..a50acd4474a5 --- /dev/null +++ b/Code/Mantid/Testing/SystemTests/tests/analysis/reference/VesuvioFittingTest.nxs.md5 @@ -0,0 +1 @@ +fec63b1c0811764ef598afaa7db23b88 \ No newline at end of file diff --git a/Code/Mantid/Testing/SystemTests/tests/analysis/reference/VesuvioFittingWithKFreeTest.nxs.md5 b/Code/Mantid/Testing/SystemTests/tests/analysis/reference/VesuvioFittingWithKFreeTest.nxs.md5 new file mode 100644 index 000000000000..88d61c67eee7 --- /dev/null +++ b/Code/Mantid/Testing/SystemTests/tests/analysis/reference/VesuvioFittingWithKFreeTest.nxs.md5 @@ -0,0 +1 @@ +f81deb00a06ff6a1f371747cf652bec2 \ No newline at end of file diff --git a/Code/Mantid/Testing/SystemTests/tests/analysis/reference/VesuvioFittingWithQuadraticBackgroundTest.nxs.md5 b/Code/Mantid/Testing/SystemTests/tests/analysis/reference/VesuvioFittingWithQuadraticBackgroundTest.nxs.md5 new file mode 100644 index 000000000000..5c97bd0a8566 --- /dev/null +++ b/Code/Mantid/Testing/SystemTests/tests/analysis/reference/VesuvioFittingWithQuadraticBackgroundTest.nxs.md5 @@ -0,0 +1 @@ +7119fbcabeaac4bb9908c664bd11ece6 \ No newline at end of file diff --git a/Code/Mantid/Testing/SystemTests/tests/analysis/reference/WishAnalysis.nxs.md5 b/Code/Mantid/Testing/SystemTests/tests/analysis/reference/WishAnalysis.nxs.md5 new file mode 100644 index 000000000000..3886027bea50 --- /dev/null +++ b/Code/Mantid/Testing/SystemTests/tests/analysis/reference/WishAnalysis.nxs.md5 @@ -0,0 +1 @@ +c748a5e1f3e4de6e1439ab856fb5c507 \ No newline at end of file diff --git a/Code/Mantid/Testing/SystemTests/tests/analysis/reference/poldi2013n006903_reference.nxs.md5 b/Code/Mantid/Testing/SystemTests/tests/analysis/reference/poldi2013n006903_reference.nxs.md5 new file mode 100644 index 000000000000..1d15c5b65fe7 --- /dev/null +++ b/Code/Mantid/Testing/SystemTests/tests/analysis/reference/poldi2013n006903_reference.nxs.md5 @@ -0,0 +1 @@ +67ee0590dcf73bab8f5a7f9ec1cc3ab8 \ No newline at end of file diff --git a/Code/Mantid/Testing/SystemTests/tests/analysis/reference/poldi2013n006903_reference_Peaks.nxs.md5 b/Code/Mantid/Testing/SystemTests/tests/analysis/reference/poldi2013n006903_reference_Peaks.nxs.md5 new file mode 100644 index 000000000000..24c3e64c8dde --- /dev/null +++ b/Code/Mantid/Testing/SystemTests/tests/analysis/reference/poldi2013n006903_reference_Peaks.nxs.md5 @@ -0,0 +1 @@ +1967a6b77adde6653a574286e7117a83 \ No newline at end of file diff --git a/Code/Mantid/Testing/SystemTests/tests/analysis/reference/poldi2013n006904_1d_reference_Spectrum.nxs.md5 b/Code/Mantid/Testing/SystemTests/tests/analysis/reference/poldi2013n006904_1d_reference_Spectrum.nxs.md5 new file mode 100644 index 000000000000..937f3b177619 --- /dev/null +++ b/Code/Mantid/Testing/SystemTests/tests/analysis/reference/poldi2013n006904_1d_reference_Spectrum.nxs.md5 @@ -0,0 +1 @@ +81faf15ffe0df64a0459277af2799e26 \ No newline at end of file diff --git a/Code/Mantid/Testing/SystemTests/tests/analysis/reference/poldi2013n006904_2d_reference_Peaks.nxs.md5 b/Code/Mantid/Testing/SystemTests/tests/analysis/reference/poldi2013n006904_2d_reference_Peaks.nxs.md5 new file mode 100644 index 000000000000..c27aca28c3d0 --- /dev/null +++ b/Code/Mantid/Testing/SystemTests/tests/analysis/reference/poldi2013n006904_2d_reference_Peaks.nxs.md5 @@ -0,0 +1 @@ +1fea3655ffcb5356a01f0f330719ae31 \ No newline at end of file diff --git a/Code/Mantid/Testing/SystemTests/tests/analysis/reference/poldi2013n006904_2d_reference_Spectrum.nxs.md5 b/Code/Mantid/Testing/SystemTests/tests/analysis/reference/poldi2013n006904_2d_reference_Spectrum.nxs.md5 new file mode 100644 index 000000000000..8d3cd69a2014 --- /dev/null +++ b/Code/Mantid/Testing/SystemTests/tests/analysis/reference/poldi2013n006904_2d_reference_Spectrum.nxs.md5 @@ -0,0 +1 @@ +40cbe1f8039e80cb2fe5701db27b261f \ No newline at end of file diff --git a/Code/Mantid/Testing/SystemTests/tests/analysis/reference/poldi2013n006904_reference.nxs.md5 b/Code/Mantid/Testing/SystemTests/tests/analysis/reference/poldi2013n006904_reference.nxs.md5 new file mode 100644 index 000000000000..4b794204b9d4 --- /dev/null +++ b/Code/Mantid/Testing/SystemTests/tests/analysis/reference/poldi2013n006904_reference.nxs.md5 @@ -0,0 +1 @@ +1f795439408e2e0e34655c9a93dee98a \ No newline at end of file diff --git a/Code/Mantid/Testing/SystemTests/tests/analysis/reference/poldi2013n006904_reference_1DFit.nxs.md5 b/Code/Mantid/Testing/SystemTests/tests/analysis/reference/poldi2013n006904_reference_1DFit.nxs.md5 new file mode 100644 index 000000000000..536fc2ed9ad4 --- /dev/null +++ b/Code/Mantid/Testing/SystemTests/tests/analysis/reference/poldi2013n006904_reference_1DFit.nxs.md5 @@ -0,0 +1 @@ +f2f0a31a5eefcea028155ef98d1b5b32 \ No newline at end of file diff --git a/Code/Mantid/Testing/SystemTests/tests/analysis/reference/poldi2013n006904_reference_Peaks.nxs.md5 b/Code/Mantid/Testing/SystemTests/tests/analysis/reference/poldi2013n006904_reference_Peaks.nxs.md5 new file mode 100644 index 000000000000..2bc978ab0e19 --- /dev/null +++ b/Code/Mantid/Testing/SystemTests/tests/analysis/reference/poldi2013n006904_reference_Peaks.nxs.md5 @@ -0,0 +1 @@ +4ad0e78b54769654207c4e286f19e373 \ No newline at end of file diff --git a/Code/Mantid/Testing/SystemTests/tests/analysis/reference/poldi2014n019874_fortran_fit.nxs.md5 b/Code/Mantid/Testing/SystemTests/tests/analysis/reference/poldi2014n019874_fortran_fit.nxs.md5 new file mode 100644 index 000000000000..e63569b2af2c --- /dev/null +++ b/Code/Mantid/Testing/SystemTests/tests/analysis/reference/poldi2014n019874_fortran_fit.nxs.md5 @@ -0,0 +1 @@ +c6d709560cb9e7ec51ea508364964011 \ No newline at end of file diff --git a/Code/Mantid/Testing/SystemTests/tests/analysis/reference/poldi2014n019874_fortran_residuals.nxs.md5 b/Code/Mantid/Testing/SystemTests/tests/analysis/reference/poldi2014n019874_fortran_residuals.nxs.md5 new file mode 100644 index 000000000000..7de4b525616d --- /dev/null +++ b/Code/Mantid/Testing/SystemTests/tests/analysis/reference/poldi2014n019874_fortran_residuals.nxs.md5 @@ -0,0 +1 @@ +197273fac62d5a7a395189f821676fcd \ No newline at end of file diff --git a/Code/Mantid/Testing/SystemTests/tests/analysis/reference/poldi2014n019874_reference.nxs.md5 b/Code/Mantid/Testing/SystemTests/tests/analysis/reference/poldi2014n019874_reference.nxs.md5 new file mode 100644 index 000000000000..587728dfe218 --- /dev/null +++ b/Code/Mantid/Testing/SystemTests/tests/analysis/reference/poldi2014n019874_reference.nxs.md5 @@ -0,0 +1 @@ +2aecbb348f625e560a09b92a05c2e795 \ No newline at end of file diff --git a/Code/Mantid/Testing/SystemTests/tests/analysis/reference/poldi2014n019881_reference.nxs.md5 b/Code/Mantid/Testing/SystemTests/tests/analysis/reference/poldi2014n019881_reference.nxs.md5 new file mode 100644 index 000000000000..caf448726a11 --- /dev/null +++ b/Code/Mantid/Testing/SystemTests/tests/analysis/reference/poldi2014n019881_reference.nxs.md5 @@ -0,0 +1 @@ +3cc8095148f05529c00e21ef34e2537d \ No newline at end of file diff --git a/Code/Mantid/Testing/SystemTests/tests/analysis/reference/poldi_2_phases_theoretical_reference.nxs.md5 b/Code/Mantid/Testing/SystemTests/tests/analysis/reference/poldi_2_phases_theoretical_reference.nxs.md5 new file mode 100644 index 000000000000..1c99f5f58024 --- /dev/null +++ b/Code/Mantid/Testing/SystemTests/tests/analysis/reference/poldi_2_phases_theoretical_reference.nxs.md5 @@ -0,0 +1 @@ +6a7e396f28bfafe450366396e3227fa9 \ No newline at end of file diff --git a/Code/Mantid/Testing/SystemTests/tests/analysis/reference/poldi_2_phases_theoretical_reference_1DFit.nxs.md5 b/Code/Mantid/Testing/SystemTests/tests/analysis/reference/poldi_2_phases_theoretical_reference_1DFit.nxs.md5 new file mode 100644 index 000000000000..8b0b9b600f39 --- /dev/null +++ b/Code/Mantid/Testing/SystemTests/tests/analysis/reference/poldi_2_phases_theoretical_reference_1DFit.nxs.md5 @@ -0,0 +1 @@ +b783dc1b55be2a072cbbc9082f84d273 \ No newline at end of file diff --git a/Code/Mantid/Testing/SystemTests/tests/analysis/reference/poldi_sum_6903_6904_reference.nxs.md5 b/Code/Mantid/Testing/SystemTests/tests/analysis/reference/poldi_sum_6903_6904_reference.nxs.md5 new file mode 100644 index 000000000000..400cd641952b --- /dev/null +++ b/Code/Mantid/Testing/SystemTests/tests/analysis/reference/poldi_sum_6903_6904_reference.nxs.md5 @@ -0,0 +1 @@ +3cb663de1a4a8cd79ea4271db197d553 \ No newline at end of file diff --git a/Code/Mantid/Testing/SystemTests/tests/analysis/utils.py b/Code/Mantid/Testing/SystemTests/tests/analysis/utils.py new file mode 100644 index 000000000000..d009a6f64974 --- /dev/null +++ b/Code/Mantid/Testing/SystemTests/tests/analysis/utils.py @@ -0,0 +1,296 @@ +''' SVN Info: The variables below will only get subsituted at svn checkout if + the repository is configured for variable subsitution. + + $Id$ + $HeadURL$ +|=============================================================================|=======| +1 80 +''' +import sys, os +import dis, inspect, opcode +def ls(): + print os.getcwd() + files=os.listdir(os.getcwd()) + for i in range(0,len(files)): + + print files[i] +def pwd(): + print os.getcwd() +def cd(dir_str): + os.chdir(dir_str) +def lineno(): + """ + call signature(s):: + lineno() + + Returns the current line number in our program. + + No Arguments. + + + Working example + >>> print "This is the line number ",lineno(),"\n" + + """ + return inspect.currentframe().f_back.f_lineno + +def decompile(code_object): + ''' taken from http://thermalnoise.wordpress.com/2007/12/30/exploring-python-bytecode/ + + decompile extracts dissasembly information from the byte code and stores it in a + list for further use. + + call signature(s):: + instructions=decompile(f.f_code) + + Required arguments: + ========= ===================================================================== + f.f_code A bytecode object ectracted with inspect.currentframe() + or anyother mechanism that returns byte code. + + Optional keyword arguments: NONE + + Outputs: + ========= ===================================================================== + instructions a list of offsets, op_codes, names, arguments, argument_type, + argument_value which can be deconstructed to find out various things + about a function call. + + Examples: + + f = inspect.currentframe().f_back.f_back + i = f.f_lasti # index of the last attempted instruction in byte code + ins=decompile(f.f_code) + pretty_print(ins) + + + ''' + code = code_object.co_code + variables = code_object.co_cellvars + code_object.co_freevars + instructions = [] + n = len(code) + i = 0 + e = 0 + while i < n: + i_offset = i + i_opcode = ord(code[i]) + i = i + 1 + if i_opcode >= opcode.HAVE_ARGUMENT: + i_argument = ord(code[i]) + (ord(code[i+1]) << (4*2)) + e + i = i +2 + if i_opcode == opcode.EXTENDED_ARG: + e = iarg << 16 + else: + e = 0 + if i_opcode in opcode.hasconst: + i_arg_value = repr(code_object.co_consts[i_argument]) + i_arg_type = 'CONSTANT' + elif i_opcode in opcode.hasname: + i_arg_value = code_object.co_names[i_argument] + i_arg_type = 'GLOBAL VARIABLE' + elif i_opcode in opcode.hasjrel: + i_arg_value = repr(i + i_argument) + i_arg_type = 'RELATIVE JUMP' + elif i_opcode in opcode.haslocal: + i_arg_value = code_object.co_varnames[i_argument] + i_arg_type = 'LOCAL VARIABLE' + elif i_opcode in opcode.hascompare: + i_arg_value = opcode.cmp_op[i_argument] + i_arg_type = 'COMPARE OPERATOR' + elif i_opcode in opcode.hasfree: + i_arg_value = variables[i_argument] + i_arg_type = 'FREE VARIABLE' + else: + i_arg_value = i_argument + i_arg_type = 'OTHER' + else: + i_argument = None + i_arg_value = None + i_arg_type = None + instructions.append( (i_offset, i_opcode, opcode.opname[i_opcode], i_argument, i_arg_type, i_arg_value) ) + return instructions + +# Print the byte code in a human readable format +def pretty_print(instructions): + print '%5s %-20s %3s %5s %-20s %s' % ('OFFSET', 'INSTRUCTION', 'OPCODE', 'ARG', 'TYPE', 'VALUE') + for (offset, op, name, argument, argtype, argvalue) in instructions: + print '%5d %-20s (%3d) ' % (offset, name, op), + if argument != None: + print '%5d %-20s (%s)' % (argument, argtype, argvalue), + print + +def expecting(): + #{{{ + ''' + call signature(s):: + + + Return how many values the caller is expecting + + Required arguments: NONE + + Optional keyword arguments: NONE + + + Outputs: + ========= ===================================================================== + numReturns Number of return values on expected on the left of the equal sign. + + Examples: + + This function is not designed for cammand line use. Using in a function can + follow the form below. + + + def test1(): + def f(): + r = expecting() + print r + if r == 0: + return None + if r == 1: + return 0 + return range(r) + + f() + print "---" + a = f() + print "---", a + a, b = f() + print "---", a,b + a, b = c = f() + print "---", a,b,c + a, b = c = d = f() + print "---", a,b,c + a = b = f() + print "---", a,b + a = b, c = f() + print "---", a,b,c + a = b = c, d = f() + print "---", a,b,c,d + a = b, c = d = f() + print "---", a,b,c,d + a, b = c, d = f() + print "---", a,b,c,d + ''' + #}}} + + """ Developers Notes: + + Now works with an multiple assigments correctly. This is verified by + test() and test1() below + """ + f = inspect.currentframe().f_back.f_back + i = f.f_lasti # index of the last attempted instruction in byte code + ins=decompile(f.f_code) + #pretty_print(ins) + for (offset, op, name, argument, argtype, argvalue) in ins: + if offset > i: + if name == 'POP_TOP': + return 0 + if name == 'UNPACK_SEQUENCE': + return argument + if name == 'CALL_FUNCTION': + return 1 + +def lhs(output='names'): + ''' + call signature(s):: + + Return how many values the caller is expecting + + Required arguments: NONE + + Optional keyword arguments: NONE + + + Outputs: + ========= ===================================================================== + numReturns Number of return values on expected on the left of the equal sign. + + Examples: + + This function is not designed for cammand line use. Using in a function can + follow the form below. + + ''' + """ Developers Notes: + """ + f = inspect.currentframe().f_back.f_back + i = f.f_lasti # index of the last attempted instruction in byte code + ins=decompile(f.f_code) + #pretty_print(ins) + + CallFunctionLocation={} + first=False; StartIndex=0; StartOffset=0 + # we must list all of the operators that behave like a function call in byte-code + OperatorNames=set(['CALL_FUNCTION','UNARY_POSITIVE','UNARY_NEGATIVE','UNARY_NOT','UNARY_CONVERT','UNARY_INVERT','GET_ITER', 'BINARY_POWER','BINARY_MULTIPLY','BINARY_DIVIDE', 'BINARY_FLOOR_DIVIDE', 'BINARY_TRUE_DIVIDE', 'BINARY_MODULO','BINARY_ADD','BINARY_SUBTRACT','BINARY_SUBSCR','BINARY_LSHIFT','BINARY_RSHIFT','BINARY_AND','BINARY_XOR','BINARY_OR']) + + for index in range(len(ins)): + (offset, op, name, argument, argtype, argvalue) = ins[index] + if name in OperatorNames: + if not first: + CallFunctionLocation[StartOffset] = (StartIndex,index) + StartIndex=index + StartOffset = offset + + (offset, op, name, argument, argtype, argvalue) = ins[-1] + CallFunctionLocation[StartOffset]=(StartIndex,len(ins)-1) # append the index of the last entry to form the last boundary + + #print CallFunctionLocation + #pretty_print( ins[CallFunctionLocation[i][0]:CallFunctionLocation[i][1]] ) + # In our case i should always be the offset of a Call_Function instruction. We can use this to baracket + # the bit which we are interested in + + OutputVariableNames=[] + (offset, op, name, argument, argtype, argvalue) = ins[CallFunctionLocation[i][0] + 1] + if name == 'POP_TOP': # no Return Values + pass + #return OutputVariableNames + if name == 'STORE_FAST' or name == 'STORE_NAME': # One Return Value + OutputVariableNames.append(argvalue) + if name == 'UNPACK_SEQUENCE': # Many Return Values, One equal sign + for index in range(argvalue): + (offset_, op_, name_, argument_, argtype_, argvalue_) = ins[CallFunctionLocation[i][0] + 1 + 1 +index] + OutputVariableNames.append(argvalue_) + maxReturns = len(OutputVariableNames) + if name == 'DUP_TOP': # Many Return Values, Many equal signs + # The output here should be a multi-dim list which mimics the variable unpacking sequence. + # For instance a,b=c,d=f() => [ ['a','b'] , ['c','d'] ] + # a,b=c=d=f() => [ ['a','b'] , 'c','d' ] So on and so forth. + + # put this in a loop and stack the results in an array. + count = 0; maxReturns = 0 # Must count the maxReturns ourselves in this case + while count < len(ins[CallFunctionLocation[i][0] :CallFunctionLocation[i][1]]): + (offset_, op_, name_, argument_, argtype_, argvalue_) = ins[CallFunctionLocation[i][0]+count] + #print 'i= ',i,'count = ', count, 'maxReturns = ',maxReturns + if name_ == 'UNPACK_SEQUENCE': # Many Return Values, One equal sign + hold=[] + #print 'argvalue_ = ', argvalue_, 'count = ',count + if argvalue_ > maxReturns: + maxReturns=argvalue_ + for index in range(argvalue_): + (_offset_, _op_, _name_, _argument_, _argtype_, _argvalue_) = ins[CallFunctionLocation[i][0] + count+1+index] + hold.append(_argvalue_) + count = count + argvalue_ + OutputVariableNames.append(hold) + # Need to now skip the entries we just appended with the for loop. + if name_ == 'STORE_FAST' or name_ == 'STORE_NAME': # One Return Value + if 1 > maxReturns: + maxReturns = 1 + OutputVariableNames.append(argvalue_) + count = count + 1 + + + # Now that OutputVariableNames is filled with the right stuff we need to output the correct thing. Either the maximum number of + # variables to unpack in the case of multiple ='s or just the length of the array or just the naames of the variables. + + if output== 'names': + return OutputVariableNames + elif output == 'number': + return maxReturns + elif output == 'both': + return (maxReturns,OutputVariableNames) + + return 0 # Should never get to here + diff --git a/Code/Mantid/Vates/ParaviewPlugins/ParaViewFilters/CMakeLists.txt b/Code/Mantid/Vates/ParaviewPlugins/ParaViewFilters/CMakeLists.txt index 3ff128f17415..aabeadb41010 100644 --- a/Code/Mantid/Vates/ParaviewPlugins/ParaViewFilters/CMakeLists.txt +++ b/Code/Mantid/Vates/ParaviewPlugins/ParaViewFilters/CMakeLists.txt @@ -1,4 +1,2 @@ -add_subdirectory( MDEWRebinningCutterOperator ) -add_subdirectory( RebinningTransformOperator ) add_subdirectory( SplatterPlot ) add_subdirectory( ScaleWorkspace ) diff --git a/Code/Mantid/Vates/ParaviewPlugins/ParaViewFilters/MDEWRebinningCutterOperator/CMakeLists.txt b/Code/Mantid/Vates/ParaviewPlugins/ParaViewFilters/MDEWRebinningCutterOperator/CMakeLists.txt deleted file mode 100644 index 605bc5c0a1e6..000000000000 --- a/Code/Mantid/Vates/ParaviewPlugins/ParaViewFilters/MDEWRebinningCutterOperator/CMakeLists.txt +++ /dev/null @@ -1,21 +0,0 @@ -cmake_minimum_required( VERSION 2.8.12 ) -project( MantidParaViewMDEWRebinningCutter ) - -add_paraview_plugin( MantidParaViewMDEWRebinningCutterSMPlugin "1.0" - SERVER_MANAGER_XML MDEWRebinningCutter.xml - SERVER_MANAGER_SOURCES vtkMDEWRebinningCutter.cxx - GUI_RESOURCES MDEWRebinningCutter.qrc - GUI_RESOURCE_FILES MDEWRebinningCutterGUI.xml -) - -# Add to the 'VatesParaViewPlugins' group in VS -set_property( TARGET MantidParaViewMDEWRebinningCutterSMPlugin PROPERTY FOLDER "MantidVatesParaViewPlugins" ) - -target_link_libraries( MantidParaViewMDEWRebinningCutterSMPlugin -${MANTID_SUBPROJECT_LIBS} ) - -# Put library into subfolder. -SET_TARGET_OUTPUT_DIRECTORY(MantidParaViewMDEWRebinningCutterSMPlugin ${CMAKE_LIBRARY_OUTPUT_DIRECTORY}/${CMAKE_CFG_INTDIR}/${PVPLUGINS_DIR}/${PVPLUGINS_SUBDIR}) - -install( TARGETS MantidParaViewMDEWRebinningCutterSMPlugin ${SYSTEM_PACKAGE_TARGET} DESTINATION ${PVPLUGINS_DIR}/${PVPLUGINS_SUBDIR} ) - diff --git a/Code/Mantid/Vates/ParaviewPlugins/ParaViewFilters/MDEWRebinningCutterOperator/MDEWRebinningCutter.qrc b/Code/Mantid/Vates/ParaviewPlugins/ParaViewFilters/MDEWRebinningCutterOperator/MDEWRebinningCutter.qrc deleted file mode 100644 index 5d7d11b0049a..000000000000 --- a/Code/Mantid/Vates/ParaviewPlugins/ParaViewFilters/MDEWRebinningCutterOperator/MDEWRebinningCutter.qrc +++ /dev/null @@ -1,5 +0,0 @@ - - - RebinningCutter.png - - diff --git a/Code/Mantid/Vates/ParaviewPlugins/ParaViewFilters/MDEWRebinningCutterOperator/MDEWRebinningCutter.xml b/Code/Mantid/Vates/ParaviewPlugins/ParaViewFilters/MDEWRebinningCutterOperator/MDEWRebinningCutter.xml deleted file mode 100644 index 957ff1acc045..000000000000 --- a/Code/Mantid/Vates/ParaviewPlugins/ParaViewFilters/MDEWRebinningCutterOperator/MDEWRebinningCutter.xml +++ /dev/null @@ -1,104 +0,0 @@ - - - - - - - - - - - - - - - - - Available timestep values. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/Code/Mantid/Vates/ParaviewPlugins/ParaViewFilters/MDEWRebinningCutterOperator/MDEWRebinningCutterGUI.xml b/Code/Mantid/Vates/ParaviewPlugins/ParaViewFilters/MDEWRebinningCutterOperator/MDEWRebinningCutterGUI.xml deleted file mode 100644 index 5f4ea51eb512..000000000000 --- a/Code/Mantid/Vates/ParaviewPlugins/ParaViewFilters/MDEWRebinningCutterOperator/MDEWRebinningCutterGUI.xml +++ /dev/null @@ -1,6 +0,0 @@ - - - - /> - - \ No newline at end of file diff --git a/Code/Mantid/Vates/ParaviewPlugins/ParaViewFilters/MDEWRebinningCutterOperator/RebinningCutter.png b/Code/Mantid/Vates/ParaviewPlugins/ParaViewFilters/MDEWRebinningCutterOperator/RebinningCutter.png deleted file mode 100644 index f97c7801c6d5..000000000000 Binary files a/Code/Mantid/Vates/ParaviewPlugins/ParaViewFilters/MDEWRebinningCutterOperator/RebinningCutter.png and /dev/null differ diff --git a/Code/Mantid/Vates/ParaviewPlugins/ParaViewFilters/MDEWRebinningCutterOperator/vtkMDEWRebinningCutter.cxx b/Code/Mantid/Vates/ParaviewPlugins/ParaViewFilters/MDEWRebinningCutterOperator/vtkMDEWRebinningCutter.cxx deleted file mode 100644 index 8fa8ec34b017..000000000000 --- a/Code/Mantid/Vates/ParaviewPlugins/ParaViewFilters/MDEWRebinningCutterOperator/vtkMDEWRebinningCutter.cxx +++ /dev/null @@ -1,547 +0,0 @@ -#include "MantidVatesAPI/MDEWRebinningPresenter.h" -#include "MantidVatesAPI/NullRebinningPresenter.h" - -#include "vtkMDEWRebinningCutter.h" -#include "vtkInformation.h" -#include "vtkInformationVector.h" -#include "vtkObjectFactory.h" -#include "vtkAlgorithm.h" -#include "vtkPVClipDataSet.h" -#include "vtkSmartPointer.h" -#include "vtkStreamingDemandDrivenPipeline.h" -#include "vtkImplicitFunction.h" -#include "vtkPointData.h" -#include "vtkPlane.h" - -#include "MantidKernel/Exception.h" -#include "MantidAPI/IMDEventWorkspace.h" -#include "MantidVatesAPI/ADSWorkspaceProvider.h" -#include "MantidVatesAPI/EscalatingRebinningActionManager.h" -#include "MantidVatesAPI/RebinningCutterXMLDefinitions.h" -#include "MantidVatesAPI/vtkMDHistoHex4DFactory.h" -#include "MantidVatesAPI/vtkMDHistoHexFactory.h" -#include "MantidVatesAPI/vtkMDHistoQuadFactory.h" -#include "MantidVatesAPI/vtkMDHistoLineFactory.h" -#include "MantidVatesAPI/vtkMDLineFactory.h" -#include "MantidVatesAPI/vtkMDQuadFactory.h" -#include "MantidVatesAPI/vtkMDHexFactory.h" -#include "MantidVatesAPI/TimeToTimeStep.h" -#include "MantidVatesAPI/FilteringUpdateProgressAction.h" -#include "MantidVatesAPI/Common.h" -#include "MantidVatesAPI/vtkDataSetToGeometry.h" -#include "MantidVatesAPI/UserDefinedThresholdRange.h" -#include "MantidVatesAPI/NoThresholdRange.h" -#include "MantidVatesAPI/IgnoreZerosThresholdRange.h" -#include "MantidVatesAPI/MedianAndBelowThresholdRange.h" -#include "MantidVatesAPI/ADSWorkspaceProvider.h" -#include "MantidVatesAPI/MDRebinningViewAdapter.h" -#include "MantidGeometry/MDGeometry/MDGeometryXMLParser.h" -#include "MantidGeometry/MDGeometry/MDGeometryXMLBuilder.h" - -#include -#include - -#include "MantidVatesAPI/Clipper.h" -#include - -class ClipperAdapter : public Mantid::VATES::Clipper -{ -private: - vtkPVClipDataSet* m_clipper; -public: - - ClipperAdapter(vtkPVClipDataSet* pClipper) : m_clipper(pClipper) - { - } - - void SetInput(vtkDataSet* input) - { - m_clipper->SetInputData(input); - } - - void SetClipFunction(vtkImplicitFunction* func) - { - m_clipper->SetClipFunction(func); - } - - void SetInsideOut(bool insideout) - { - m_clipper->SetInsideOut(insideout); - } - - void SetRemoveWholeCells(bool) - { - } - - void SetOutput(vtkUnstructuredGrid* out_ds) - { - m_clipper->SetOutput(out_ds); - } - - void Update() - { - m_clipper->Update(); - } - - void Delete() - { - delete this; - } - - ~ClipperAdapter() - { - m_clipper->Delete(); - } - - vtkDataSet* GetOutput() - { - return m_clipper->GetOutput(); - } - -}; - - -/** Plugin for ParaView. Performs simultaneous rebinning and slicing of Mantid data. - -@author Owen Arnold, Tessella plc -@date 14/03/2011 - -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: -*/ - -/** Getter for the max threshold -@return max threshold -*/ -double vtkMDEWRebinningCutter::getMaxThreshold() const -{ - return m_thresholdMax; -} - -/** Getter for the min threshold -@return min threshold -*/ -double vtkMDEWRebinningCutter::getMinThreshold() const -{ - return m_thresholdMin; -} - -/** Getter flag indicating wheter clipping is applied. -*/ -bool vtkMDEWRebinningCutter::getApplyClip() const -{ - return m_clip == ApplyClipping; -} - -/** Getter for the timestep -@return timestep value -*/ -double vtkMDEWRebinningCutter::getTimeStep() const -{ - return m_timestep; -} - -/** Getter for applied geometry xml. -@return ptr to applied geometry string. -*/ -const char* vtkMDEWRebinningCutter::getAppliedGeometryXML() const -{ - return m_appliedGeometryXML.c_str(); -} - -bool vtkMDEWRebinningCutter::getOutputHistogramWS() const -{ - return m_bOutputHistogramWS; -} - -/** Setter for the algorithm progress.. -@param progress : the current progress value -@param message : progress message -*/ -void vtkMDEWRebinningCutter::updateAlgorithmProgress(double progress, const std::string& message) -{ - progressMutex.lock(); - this->SetProgressText(message.c_str()); - this->UpdateProgress(progress); - progressMutex.unlock(); -} - -vtkStandardNewMacro(vtkMDEWRebinningCutter); - -using namespace Mantid::VATES; - -///Constructor. -vtkMDEWRebinningCutter::vtkMDEWRebinningCutter() : -m_presenter(new NullRebinningPresenter()), - m_clipFunction(NULL), - m_clip(IgnoreClipping), - m_originalExtents(IgnoreOriginal), - m_setup(Pending), - m_timestep(0), - m_thresholdMax(1e9), - m_thresholdMin(0), - m_thresholdMethodIndex(0), - m_bOutputHistogramWS(true) -{ - this->SetNumberOfInputPorts(1); - this->SetNumberOfOutputPorts(1); -} - -///Destructor. -vtkMDEWRebinningCutter::~vtkMDEWRebinningCutter() -{ -} - -/* -Determine the threshold range strategy to use. -*/ -void vtkMDEWRebinningCutter::configureThresholdRangeMethod() -{ - switch(m_thresholdMethodIndex) - { - case 0: - m_ThresholdRange = ThresholdRange_scptr(new IgnoreZerosThresholdRange()); - break; - case 1: - m_ThresholdRange = ThresholdRange_scptr(new NoThresholdRange()); - break; - case 2: - m_ThresholdRange = ThresholdRange_scptr(new MedianAndBelowThresholdRange()); - break; - case 3: - m_ThresholdRange = ThresholdRange_scptr(new UserDefinedThresholdRange(m_thresholdMin, m_thresholdMax)); - break; - } -} - -int vtkMDEWRebinningCutter::RequestData(vtkInformation* vtkNotUsed(request), vtkInformationVector**, - vtkInformationVector *outputVector) -{ - using namespace Mantid::VATES; - - //Setup is not complete until metadata has been correctly provided. - if(SetupDone == m_setup) - { - configureThresholdRangeMethod(); - - //Updating again at this point is the only way to pick-up changes to clipping. - m_presenter->updateModel(); - - FilterUpdateProgressAction rebinningActionReporting(this, "Rebinning..."); - FilterUpdateProgressAction drawingActionReporting(this, "Drawing..."); - - vtkInformation *outInfo = outputVector->GetInformationObject(0); - vtkUnstructuredGrid *output = vtkUnstructuredGrid::SafeDownCast(outInfo->Get( - vtkDataObject::DATA_OBJECT())); - - if (outInfo->Has(vtkStreamingDemandDrivenPipeline::UPDATE_TIME_STEP())) - { - // usually only one actual step requested - m_timestep = outInfo->Get(vtkStreamingDemandDrivenPipeline::UPDATE_TIME_STEP()); - } - - std::string scalarName = XMLDefinitions::signalName(); - - //Create Factory Object for chain. Chain-of-responsibility for translating imdworkspaces. - vtkMDLineFactory* p_1dMDFactory = new vtkMDLineFactory(m_ThresholdRange, scalarName); - vtkMDQuadFactory* p_2dMDFactory = new vtkMDQuadFactory(m_ThresholdRange, scalarName); - vtkMDHexFactory* p_3dMDFactory = new vtkMDHexFactory(m_ThresholdRange, scalarName); - vtkMDHistoLineFactory* p_1dHistoFactory = new vtkMDHistoLineFactory(m_ThresholdRange, scalarName); - vtkMDHistoQuadFactory* p_2dHistoFactory = new vtkMDHistoQuadFactory(m_ThresholdRange,scalarName); - vtkMDHistoHexFactory* p_3dHistoFactory = new vtkMDHistoHexFactory(m_ThresholdRange,scalarName); - vtkMDHistoHex4DFactory* p_4dHistoFactory = new vtkMDHistoHex4DFactory(m_ThresholdRange,scalarName, m_timestep); - - //Assemble Chain-of-Reponsibility - p_1dMDFactory->SetSuccessor(p_2dMDFactory); - p_2dMDFactory->SetSuccessor(p_3dMDFactory); - p_3dMDFactory->SetSuccessor(p_1dHistoFactory); - p_1dHistoFactory->SetSuccessor(p_2dHistoFactory); - p_2dHistoFactory->SetSuccessor(p_3dHistoFactory); - p_3dHistoFactory->SetSuccessor(p_4dHistoFactory); - - - vtkDataSet* outData = m_presenter->execute(p_1dMDFactory, rebinningActionReporting, drawingActionReporting); - m_thresholdMax = m_ThresholdRange->getMaximum(); - m_thresholdMin = m_ThresholdRange->getMinimum(); - delete p_1dMDFactory; - - output->ShallowCopy(outData); - try - { - m_presenter->makeNonOrthogonal(output); - } - catch (std::invalid_argument &e) - { - std::string error = e.what(); - vtkDebugMacro(<< "Workspace does not have correct information to " - << "plot non-orthogonal axes. " << error); - } - - m_presenter->setAxisLabels(output); - } - return 1; -} - -int vtkMDEWRebinningCutter::RequestInformation(vtkInformation* vtkNotUsed(request), vtkInformationVector **inputVector, - vtkInformationVector *outputVector) -{ - using namespace Mantid::VATES; - - enum Status{Bad=0, Good=1}; - Status status=Good; - if (Pending == m_setup) - { - vtkInformation * inputInf = inputVector[0]->GetInformationObject(0); - vtkDataSet * inputDataset = vtkDataSet::SafeDownCast(inputInf->Get(vtkDataObject::DATA_OBJECT())); - - using namespace Mantid::VATES; - - //Try to use another type of presenter with this view. One for MDEWs. - ADSWorkspaceProvider wsProvider; - MDRebinningPresenter_sptr temp= MDRebinningPresenter_sptr(new MDEWRebinningPresenter(inputDataset, new EscalatingRebinningActionManager(RecalculateAll), new MDRebinningViewAdapter(this), wsProvider)); - m_presenter = temp; - - m_appliedGeometryXML = m_presenter->getAppliedGeometryXML(); - m_setup = SetupDone; - - } - setTimeRange(outputVector); - return status; -} - -int vtkMDEWRebinningCutter::RequestUpdateExtent(vtkInformation* vtkNotUsed(info), vtkInformationVector** vtkNotUsed(inputVector), - vtkInformationVector* vtkNotUsed(outputVector)) -{ - return 1; -} -; - -int vtkMDEWRebinningCutter::FillInputPortInformation(int vtkNotUsed(port), vtkInformation* info) -{ - info->Set(vtkAlgorithm::INPUT_REQUIRED_DATA_TYPE(), "vtkDataSet"); - return 1; -} - -void vtkMDEWRebinningCutter::PrintSelf(ostream& os, vtkIndent indent) -{ - this->Superclass::PrintSelf(os, indent); -} - -void vtkMDEWRebinningCutter::SetOutputHistogramWS(bool bOutputHistogramWS) -{ - if(bOutputHistogramWS != m_bOutputHistogramWS) - { - m_bOutputHistogramWS = bOutputHistogramWS; - this->Modified(); - } -} - -void vtkMDEWRebinningCutter::SetMaxThreshold(double maxThreshold) -{ - if (maxThreshold != m_thresholdMax) - { - this->m_thresholdMax = maxThreshold; - this->Modified(); - } -} - -void vtkMDEWRebinningCutter::SetMinThreshold(double minThreshold) -{ - if (minThreshold != m_thresholdMin) - { - this->m_thresholdMin = minThreshold; - this->Modified(); - } -} - - -void vtkMDEWRebinningCutter::SetAppliedGeometryXML(std::string appliedGeometryXML) -{ - if(SetupDone == m_setup) - { - m_appliedGeometryXML = appliedGeometryXML; - this->Modified(); - } -} - -void vtkMDEWRebinningCutter::SetThresholdRangeStrategyIndex(std::string selectedStrategyIndex) -{ - int index = atoi(selectedStrategyIndex.c_str()); - if(index != m_thresholdMethodIndex) - { - m_thresholdMethodIndex = index; - this->Modified(); - } -} - -const char* vtkMDEWRebinningCutter::GetInputGeometryXML() -{ - try - { - return this->m_presenter->getAppliedGeometryXML().c_str(); //TODO, check xml lives beyond function call. - } - catch(std::runtime_error&) - { - return ""; - } -} - -double vtkMDEWRebinningCutter::GetInputMinThreshold() -{ - return m_thresholdMin; -} - -double vtkMDEWRebinningCutter::GetInputMaxThreshold() -{ - return m_thresholdMax; -} - -unsigned long vtkMDEWRebinningCutter::GetMTime() -{ - unsigned long mTime = this->Superclass::GetMTime(); - - if (this->m_clipFunction != NULL) - { - unsigned long time; - time = this->m_clipFunction->GetMTime(); - if(time > mTime) - { - mTime = time; - } - } - - return mTime; -} - -void vtkMDEWRebinningCutter::setTimeRange(vtkInformationVector* outputVector) -{ - if(SetupDone == m_setup) - { - if(m_presenter->hasTDimensionAvailable()) - { - vtkInformation *outInfo = outputVector->GetInformationObject(0); - outInfo->Set(vtkStreamingDemandDrivenPipeline::TIME_LABEL_ANNOTATION(), - m_presenter->getTimeStepLabel().c_str()); - std::vector timeStepValues = m_presenter->getTimeStepValues(); - outInfo->Set(vtkStreamingDemandDrivenPipeline::TIME_STEPS(), &timeStepValues[0], - static_cast (timeStepValues.size())); - double timeRange[2]; - timeRange[0] = timeStepValues.front(); - timeRange[1] = timeStepValues.back(); - - outInfo->Set(vtkStreamingDemandDrivenPipeline::TIME_RANGE(), timeRange, 2); - } - } -} - -/** - * Gets the minimum value of the data associated with the - * workspace. - * @return The minimum value of the workspace data. - */ -double vtkMDEWRebinningCutter::GetMinValue() const -{ - if (NULL == m_presenter) - { - return 0.0; - } - try - { - return m_presenter->getMinValue(); - } - catch (std::runtime_error &) - { - return 0; - } -} - -/** - * Gets the maximum value of the data associated with the - * workspace. - * @return The maximum value of the workspace data. - */ -double vtkMDEWRebinningCutter::GetMaxValue() const -{ - if (NULL == m_presenter) - { - return 0.0; - } - try - { - return m_presenter->getMaxValue(); - } - catch (std::runtime_error &) - { - return 0; - } -} - -/** - * Gets the (first) instrument which is associated with the workspace. - * @return The name of the instrument. - */ -const char* vtkMDEWRebinningCutter::GetInstrument() const -{ - if (NULL == m_presenter) - { - return ""; - } - try - { - return m_presenter->getInstrument().c_str(); - } - catch (std::runtime_error &) - { - return ""; - } -} - - -Mantid::Kernel::V3D vtkMDEWRebinningCutter::getOrigin() -{ - throw std::runtime_error("Not implemented on vtkMDEWRebinningCutter."); -} - -Mantid::Kernel::V3D vtkMDEWRebinningCutter::getB1() -{ - throw std::runtime_error("Not implemented on vtkMDEWRebinningCutter."); -} - -Mantid::Kernel::V3D vtkMDEWRebinningCutter::getB2() -{ - throw std::runtime_error("Not implemented on vtkMDEWRebinningCutter."); -} - -double vtkMDEWRebinningCutter::getLengthB1() const -{ - throw std::runtime_error("Not implemented on vtkMDEWRebinningCutter."); -} - -double vtkMDEWRebinningCutter::getLengthB2() const -{ - throw std::runtime_error("Not implemented on vtkMDEWRebinningCutter."); -} - -double vtkMDEWRebinningCutter::getLengthB3() const -{ - throw std::runtime_error("Not implemented on vtkMDEWRebinningCutter."); -} - - diff --git a/Code/Mantid/Vates/ParaviewPlugins/ParaViewFilters/MDEWRebinningCutterOperator/vtkMDEWRebinningCutter.h b/Code/Mantid/Vates/ParaviewPlugins/ParaViewFilters/MDEWRebinningCutterOperator/vtkMDEWRebinningCutter.h deleted file mode 100644 index 03315a012f70..000000000000 --- a/Code/Mantid/Vates/ParaviewPlugins/ParaViewFilters/MDEWRebinningCutterOperator/vtkMDEWRebinningCutter.h +++ /dev/null @@ -1,156 +0,0 @@ -#ifndef _vtkMDEWRebinningCutter_h -#define _vtkMDEWRebinningCutter_h -#include -#include "vtkUnstructuredGridAlgorithm.h" -#include "MantidVatesAPI/ThresholdRange.h" -#include "MantidGeometry/MDGeometry/MDTypes.h" -#include "MantidKernel/MultiThreaded.h" -#include "MantidKernel/V3D.h" -#include - -/** - * - * Paraview Filter implementing rebinning/cutting operations. - - @author Owen Arnold, RAL ISIS - @date 18/03/2011 - - Copyright © 2007-10 ISIS Rutherford Appleton Laboratory, NScD Oak Ridge National Laboratory & European Spallation Source - - This file is part of Mantid. - - Mantid is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - Mantid is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . - - File change history is stored at: . - Code Documentation is available at: -*/ - -namespace Mantid -{ - namespace VATES - { - class MDRebinningPresenter; - class RebinningActionManager; - } -} - - -enum SetupStatus{ Pending, SetupDone}; -///Type marks wheter clipping is to be applied or ignored -enum Clipping{ ApplyClipping, IgnoreClipping}; -///Type marks wheter original extents should be used over box extents. -enum OrignalExtents{ ApplyOriginal, IgnoreOriginal}; - -class vtkImplicitFunction; -// cppcheck-suppress class_X_Y -class VTK_EXPORT vtkMDEWRebinningCutter : public vtkUnstructuredGridAlgorithm//, public Mantid::VATES::MDRebinningView -{ -public: - static vtkMDEWRebinningCutter *New(); - vtkTypeMacro(vtkMDEWRebinningCutter, vtkUnstructuredGridAlgorithm); - void PrintSelf(ostream& os, vtkIndent indent); - - /// Paraview Related Commands. See *.xml proxy/property file -------------------------------- - void SetMaxThreshold(double maxThreshold); - void SetMinThreshold(double minThreshold); - void SetAppliedGeometryXML(std::string xml); - const char* GetInputGeometryXML(); - void SetThresholdRangeStrategyIndex(std::string selectedStrategyIndex); - void SetOutputHistogramWS(bool value); - double GetInputMinThreshold(); - double GetInputMaxThreshold(); - /// Paraview Related Commands. See *.xml proxy/property file -------------------------------- - - /// Called by presenter to force progress information updating. - void updateAlgorithmProgress(double progress, const std::string& message); - virtual double getMaxThreshold() const; - virtual double getMinThreshold() const; - virtual bool getApplyClip() const; - virtual double getTimeStep() const; - virtual const char* getAppliedGeometryXML() const; - virtual Mantid::Kernel::V3D getOrigin(); - virtual Mantid::Kernel::V3D getB1(); - virtual Mantid::Kernel::V3D getB2(); - virtual double getLengthB1() const; - virtual double getLengthB2() const; - virtual double getLengthB3() const; - virtual bool getForceOrthogonal() const { throw std::runtime_error("Not implemented"); } - virtual bool getOutputHistogramWS() const; - virtual double GetMinValue() const; - virtual double GetMaxValue() const; - virtual const char* GetInstrument() const; - -protected: - - ///Constructor - vtkMDEWRebinningCutter(); - - ///Destructor - ~vtkMDEWRebinningCutter(); - - ///Request information prior to execution. - int RequestInformation(vtkInformation *, vtkInformationVector **, vtkInformationVector *); - - ///Execution. - int RequestData(vtkInformation *, vtkInformationVector **, vtkInformationVector *); - - ///Update extents. - int RequestUpdateExtent(vtkInformation*, - vtkInformationVector**, vtkInformationVector* ); - - ///Handle time variation. - unsigned long GetMTime(); - - ///Overriden fill imports so that vtkDataSets may be specified. - int FillInputPortInformation(int port, vtkInformation* info); - -private: - - boost::shared_ptr m_presenter; - std::string m_appliedGeometryXML; - - vtkMDEWRebinningCutter(const vtkMDEWRebinningCutter&); - void operator = (const vtkMDEWRebinningCutter&); - - void configureThresholdRangeMethod(); - - /// handles overwriting of time ranges. - void setTimeRange(vtkInformationVector* outputVector); - - /// Clip function provided by ClipFunction ProxyProperty - vtkImplicitFunction * m_clipFunction; - /// Cached vtkDataSet. Enables fast visualization where possible. - - /// Flag indicating that the clip boundaries should be use to construct the rebinning region. - Clipping m_clip; - /// Original extents should be used. - OrignalExtents m_originalExtents; - /// Flag indicating whether set up has occurred or not - SetupStatus m_setup; - /// Flag containing the timestep. - double m_timestep; - /// Threshold max value. - Mantid::signal_t m_thresholdMax; - /// Threhsold min value. - Mantid::signal_t m_thresholdMin; - /// Threshold range calculator. - Mantid::VATES::ThresholdRange_scptr m_ThresholdRange; - /// Method of thresholding to use. - int m_thresholdMethodIndex; - /// Mutex for progress updates - Mantid::Kernel::Mutex progressMutex; - /// Flag indicating that a histogram workspace should be exported. - bool m_bOutputHistogramWS; -}; -#endif diff --git a/Code/Mantid/Vates/ParaviewPlugins/ParaViewFilters/RebinningTransformOperator/CMakeLists.txt b/Code/Mantid/Vates/ParaviewPlugins/ParaViewFilters/RebinningTransformOperator/CMakeLists.txt deleted file mode 100644 index 64ab4736f89e..000000000000 --- a/Code/Mantid/Vates/ParaviewPlugins/ParaViewFilters/RebinningTransformOperator/CMakeLists.txt +++ /dev/null @@ -1,20 +0,0 @@ -project( MantidParaViewMDEWRebinningCutter ) - -add_paraview_plugin( MantidParaViewRebinningTransformSMPlugin "1.0" - SERVER_MANAGER_XML RebinningTransformOperator.xml - SERVER_MANAGER_SOURCES vtkRebinningTransformOperator.cxx - GUI_RESOURCES RebinningTransformOperator.qrc - GUI_RESOURCE_FILES RebinningTransformOperatorGUI.xml -) - -# Add to the 'VatesParaViewPlugins' group in VS -set_property( TARGET MantidParaViewRebinningTransformSMPlugin PROPERTY FOLDER "MantidVatesParaViewPlugins" ) - -target_link_libraries( MantidParaViewRebinningTransformSMPlugin -${MANTID_SUBPROJECT_LIBS} ) - -# Put library into subfolder. -SET_TARGET_OUTPUT_DIRECTORY(MantidParaViewRebinningTransformSMPlugin ${CMAKE_LIBRARY_OUTPUT_DIRECTORY}/${CMAKE_CFG_INTDIR}/${PVPLUGINS_DIR}/${PVPLUGINS_SUBDIR}) - -install( TARGETS MantidParaViewRebinningTransformSMPlugin ${SYSTEM_PACKAGE_TARGET} DESTINATION ${PVPLUGINS_DIR}/${PVPLUGINS_SUBDIR} ) - diff --git a/Code/Mantid/Vates/ParaviewPlugins/ParaViewFilters/RebinningTransformOperator/RebinningTransformOperator.png b/Code/Mantid/Vates/ParaviewPlugins/ParaViewFilters/RebinningTransformOperator/RebinningTransformOperator.png deleted file mode 100644 index f97c7801c6d5..000000000000 Binary files a/Code/Mantid/Vates/ParaviewPlugins/ParaViewFilters/RebinningTransformOperator/RebinningTransformOperator.png and /dev/null differ diff --git a/Code/Mantid/Vates/ParaviewPlugins/ParaViewFilters/RebinningTransformOperator/RebinningTransformOperator.qrc b/Code/Mantid/Vates/ParaviewPlugins/ParaViewFilters/RebinningTransformOperator/RebinningTransformOperator.qrc deleted file mode 100644 index 8bee991395c2..000000000000 --- a/Code/Mantid/Vates/ParaviewPlugins/ParaViewFilters/RebinningTransformOperator/RebinningTransformOperator.qrc +++ /dev/null @@ -1,5 +0,0 @@ - - - RebinningTransformOperator.png - - diff --git a/Code/Mantid/Vates/ParaviewPlugins/ParaViewFilters/RebinningTransformOperator/RebinningTransformOperator.xml b/Code/Mantid/Vates/ParaviewPlugins/ParaViewFilters/RebinningTransformOperator/RebinningTransformOperator.xml deleted file mode 100644 index 80a685aea8cd..000000000000 --- a/Code/Mantid/Vates/ParaviewPlugins/ParaViewFilters/RebinningTransformOperator/RebinningTransformOperator.xml +++ /dev/null @@ -1,150 +0,0 @@ - - - - - - - - - - - - - - - - - Available timestep values. - - - - - - Output a histogram workspace or a full MD workspace. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/Code/Mantid/Vates/ParaviewPlugins/ParaViewFilters/RebinningTransformOperator/RebinningTransformOperatorGUI.xml b/Code/Mantid/Vates/ParaviewPlugins/ParaViewFilters/RebinningTransformOperator/RebinningTransformOperatorGUI.xml deleted file mode 100644 index 45ca4beab229..000000000000 --- a/Code/Mantid/Vates/ParaviewPlugins/ParaViewFilters/RebinningTransformOperator/RebinningTransformOperatorGUI.xml +++ /dev/null @@ -1,6 +0,0 @@ - - - - /> - - \ No newline at end of file diff --git a/Code/Mantid/Vates/ParaviewPlugins/ParaViewFilters/RebinningTransformOperator/vtkRebinningTransformOperator.cxx b/Code/Mantid/Vates/ParaviewPlugins/ParaViewFilters/RebinningTransformOperator/vtkRebinningTransformOperator.cxx deleted file mode 100644 index bb1703d838fb..000000000000 --- a/Code/Mantid/Vates/ParaviewPlugins/ParaViewFilters/RebinningTransformOperator/vtkRebinningTransformOperator.cxx +++ /dev/null @@ -1,598 +0,0 @@ -#include "MantidVatesAPI/MDEWRebinningPresenter.h" -#include "MantidVatesAPI/NullRebinningPresenter.h" - -#include "vtkRebinningTransformOperator.h" -#include "vtkInformation.h" -#include "vtkInformationVector.h" -#include "vtkObjectFactory.h" -#include "vtkAlgorithm.h" -#include "vtkPVClipDataSet.h" -#include "vtkSmartPointer.h" -#include "vtkStreamingDemandDrivenPipeline.h" -#include "vtkPointData.h" - -#include "MantidKernel/Exception.h" -#include "MantidAPI/IMDEventWorkspace.h" -#include "MantidVatesAPI/ADSWorkspaceProvider.h" -#include "MantidGeometry/MDGeometry/NullImplicitFunction.h" -#include "MantidVatesAPI/EscalatingRebinningActionManager.h" -#include "MantidVatesAPI/RebinningCutterXMLDefinitions.h" -#include "MantidVatesAPI/vtkMDQuadFactory.h" -#include "MantidVatesAPI/vtkMDLineFactory.h" -#include "MantidVatesAPI/vtkMDHexFactory.h" -#include "MantidVatesAPI/vtkMDHistoHex4DFactory.h" -#include "MantidVatesAPI/vtkMDHistoHexFactory.h" -#include "MantidVatesAPI/vtkMDHistoQuadFactory.h" -#include "MantidVatesAPI/vtkMDHistoLineFactory.h" -#include "MantidVatesAPI/TimeToTimeStep.h" -#include "MantidVatesAPI/FilteringUpdateProgressAction.h" -#include "MantidVatesAPI/Common.h" -#include "MantidVatesAPI/vtkDataSetToGeometry.h" -#include "MantidVatesAPI/UserDefinedThresholdRange.h" -#include "MantidVatesAPI/NoThresholdRange.h" -#include "MantidVatesAPI/IgnoreZerosThresholdRange.h" -#include "MantidVatesAPI/MedianAndBelowThresholdRange.h" -#include "MantidVatesAPI/ADSWorkspaceProvider.h" -#include "MantidVatesAPI/MDRebinningViewAdapter.h" -#include "MantidGeometry/MDGeometry/MDGeometryXMLParser.h" -#include "MantidGeometry/MDGeometry/MDGeometryXMLBuilder.h" - - -#include -#include - - -#include "MantidVatesAPI/Clipper.h" -#include - -class ClipperAdapter : public Mantid::VATES::Clipper -{ -private: - vtkPVClipDataSet* m_clipper; -public: - - ClipperAdapter(vtkPVClipDataSet* pClipper) : m_clipper(pClipper) - { - } - - void SetInput(vtkDataSet* input) - { - m_clipper->SetInputData(input); - } - - void SetClipFunction(vtkImplicitFunction* func) - { - m_clipper->SetClipFunction(func); - } - - void SetInsideOut(bool insideout) - { - m_clipper->SetInsideOut(insideout); - } - - void SetRemoveWholeCells(bool) - { - } - - void SetOutput(vtkUnstructuredGrid* out_ds) - { - m_clipper->SetOutput(out_ds); - } - - void Update() - { - m_clipper->Update(); - } - - void Delete() - { - delete this; - } - - ~ClipperAdapter() - { - m_clipper->Delete(); - } - - vtkDataSet* GetOutput() - { - return m_clipper->GetOutput(); - } - -}; - - -/** Plugin for ParaView. Performs simultaneous rebinning and slicing of Mantid data. - -@author Owen Arnold, Tessella plc -@date 14/03/2011 - -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: -*/ - - -/** Getter for the max threshold -@return max threshold -*/ -double vtkRebinningTransformOperator::getMaxThreshold() const -{ - return m_thresholdMax; -} - -/** Getter for the min threshold -@return min threshold -*/ -double vtkRebinningTransformOperator::getMinThreshold() const -{ - return m_thresholdMin; -} - -/** Getter flag indicating wheter clipping is applied. -*/ -bool vtkRebinningTransformOperator::getApplyClip() const -{ - return m_clip == ApplyClipping; -} - -/** Getter for the timestep -@return timestep value -*/ -double vtkRebinningTransformOperator::getTimeStep() const -{ - return m_timestep; -} - -/** Getter for applied geometry xml. -@return ptr to applied geometry string. -*/ -const char* vtkRebinningTransformOperator::getAppliedGeometryXML() const -{ - return m_appliedGeometryXML.c_str(); -} - -/** Setter for the algorithm progress.. -@param progress : The current progress value -@param message : Progress message -*/ -void vtkRebinningTransformOperator::updateAlgorithmProgress(double progress, const std::string& message) -{ - progressMutex.lock(); - this->SetProgressText(message.c_str()); - this->UpdateProgress(progress); - progressMutex.unlock(); -} - -bool vtkRebinningTransformOperator::getOutputHistogramWS() const -{ - return m_bOutputHistogramWS; -} - -vtkStandardNewMacro(vtkRebinningTransformOperator); - -using namespace Mantid::VATES; - -///Constructor. -vtkRebinningTransformOperator::vtkRebinningTransformOperator() : -m_presenter(new NullRebinningPresenter()), - m_clip(ApplyClipping), - m_originalExtents(IgnoreOriginal), - m_setup(Pending), - m_timestep(0), - m_thresholdMax(1e9), - m_thresholdMin(0), - m_thresholdMethodIndex(0), - m_origin(0, 0, 0), - m_lengthB1(1), - m_lengthB2(1), - m_lengthB3(1), - m_ForceOrthogonal(true), - m_bOutputHistogramWS(true) -{ - this->SetNumberOfInputPorts(1); - this->SetNumberOfOutputPorts(1); -} - -///Destructor. -vtkRebinningTransformOperator::~vtkRebinningTransformOperator() -{ -} - -/* -Determine the threshold range strategy to use. -*/ -void vtkRebinningTransformOperator::configureThresholdRangeMethod() -{ - switch(m_thresholdMethodIndex) - { - case 0: - m_ThresholdRange = ThresholdRange_scptr(new IgnoreZerosThresholdRange()); - break; - case 1: - m_ThresholdRange = ThresholdRange_scptr(new NoThresholdRange()); - break; - case 2: - m_ThresholdRange = ThresholdRange_scptr(new MedianAndBelowThresholdRange()); - break; - case 3: - m_ThresholdRange = ThresholdRange_scptr(new UserDefinedThresholdRange(m_thresholdMin, m_thresholdMax)); - break; - } -} - -int vtkRebinningTransformOperator::RequestData(vtkInformation* vtkNotUsed(request), vtkInformationVector**, - vtkInformationVector *outputVector) -{ - using namespace Mantid::VATES; - - //Setup is not complete until metadata has been correctly provided. - if(SetupDone == m_setup) - { - configureThresholdRangeMethod(); - - //Updating again at this point is the only way to pick-up changes to clipping. - m_presenter->updateModel(); - - FilterUpdateProgressAction rebinningProgressUpdate(this, "Rebinning..."); - FilterUpdateProgressAction drawingProgressUpdate(this, "Drawing..."); - - vtkInformation *outInfo = outputVector->GetInformationObject(0); - vtkUnstructuredGrid *output = vtkUnstructuredGrid::SafeDownCast(outInfo->Get( - vtkDataObject::DATA_OBJECT())); - - if (outInfo->Has(vtkStreamingDemandDrivenPipeline::UPDATE_TIME_STEP())) - { - // usually only one actual step requested - m_timestep = outInfo->Get(vtkStreamingDemandDrivenPipeline::UPDATE_TIME_STEP()); - } - - std::string scalarName = XMLDefinitions::signalName(); - - //Create Factory Object for chain. Chain-of-responsibility for translating imdworkspaces. - vtkMDLineFactory* p_1dMDFactory = new vtkMDLineFactory(m_ThresholdRange, scalarName); - vtkMDQuadFactory* p_2dMDFactory = new vtkMDQuadFactory(m_ThresholdRange, scalarName); - vtkMDHexFactory* p_3dMDFactory = new vtkMDHexFactory(m_ThresholdRange, scalarName); - vtkMDHistoLineFactory* p_1dHistoFactory = new vtkMDHistoLineFactory(m_ThresholdRange, scalarName); - vtkMDHistoQuadFactory* p_2dHistoFactory = new vtkMDHistoQuadFactory(m_ThresholdRange,scalarName); - vtkMDHistoHexFactory* p_3dHistoFactory = new vtkMDHistoHexFactory(m_ThresholdRange,scalarName); - vtkMDHistoHex4DFactory* p_4dHistoFactory = new vtkMDHistoHex4DFactory(m_ThresholdRange,scalarName, m_timestep); - - //Assemble Chain-of-Reponsibility - p_1dMDFactory->SetSuccessor(p_2dMDFactory); - p_2dMDFactory->SetSuccessor(p_3dMDFactory); - p_3dMDFactory->SetSuccessor(p_1dHistoFactory); - p_1dHistoFactory->SetSuccessor(p_2dHistoFactory); - p_2dHistoFactory->SetSuccessor(p_3dHistoFactory); - p_3dHistoFactory->SetSuccessor(p_4dHistoFactory); - - vtkDataSet* outData = m_presenter->execute(p_1dMDFactory, rebinningProgressUpdate, drawingProgressUpdate); - m_thresholdMax = m_ThresholdRange->getMaximum(); - m_thresholdMin = m_ThresholdRange->getMinimum(); - delete p_1dMDFactory; - - output->ShallowCopy(outData); - m_presenter->setAxisLabels(output); - } - return 1; -} - -int vtkRebinningTransformOperator::RequestInformation(vtkInformation* vtkNotUsed(request), vtkInformationVector **inputVector, - vtkInformationVector *outputVector) -{ - using namespace Mantid::VATES; - - enum Status{Bad=0, Good=1}; - Status status=Good; - if (Pending == m_setup) - { - vtkInformation * inputInf = inputVector[0]->GetInformationObject(0); - vtkDataSet * inputDataset = vtkDataSet::SafeDownCast(inputInf->Get(vtkDataObject::DATA_OBJECT())); - - using namespace Mantid::VATES; - - //Try to use another type of presenter with this view. One for MDEWs. - ADSWorkspaceProvider wsProvider; - MDRebinningPresenter_sptr temp= MDRebinningPresenter_sptr(new MDEWRebinningPresenter(inputDataset, new EscalatingRebinningActionManager(RecalculateAll), new MDRebinningViewAdapter(this), wsProvider)); - m_presenter = temp; - - m_appliedGeometryXML = m_presenter->getAppliedGeometryXML(); - m_setup = SetupDone; - } - setTimeRange(outputVector); - return status; -} - -int vtkRebinningTransformOperator::RequestUpdateExtent(vtkInformation* vtkNotUsed(info), vtkInformationVector** vtkNotUsed(inputVector), - vtkInformationVector* vtkNotUsed(outputVector)) -{ - return 1; -} -; - -int vtkRebinningTransformOperator::FillInputPortInformation(int vtkNotUsed(port), vtkInformation* info) -{ - info->Set(vtkAlgorithm::INPUT_REQUIRED_DATA_TYPE(), "vtkDataSet"); - return 1; -} - -void vtkRebinningTransformOperator::PrintSelf(ostream& os, vtkIndent indent) -{ - this->Superclass::PrintSelf(os, indent); -} - -void vtkRebinningTransformOperator::SetMaxThreshold(double maxThreshold) -{ - if (maxThreshold != m_thresholdMax) - { - this->m_thresholdMax = maxThreshold; - this->Modified(); - } -} - -void vtkRebinningTransformOperator::SetMinThreshold(double minThreshold) -{ - if (minThreshold != m_thresholdMin) - { - this->m_thresholdMin = minThreshold; - this->Modified(); - } -} - -void vtkRebinningTransformOperator::SetOutputHistogramWS(bool bOutputHistogramWS) -{ - if(bOutputHistogramWS != m_bOutputHistogramWS) - { - m_bOutputHistogramWS = bOutputHistogramWS; - this->Modified(); - } -} - - -void vtkRebinningTransformOperator::SetAppliedGeometryXML(std::string appliedGeometryXML) -{ - if(SetupDone == m_setup) - { - m_appliedGeometryXML = appliedGeometryXML; - this->Modified(); - } -} - -void vtkRebinningTransformOperator::SetThresholdRangeStrategyIndex(std::string selectedStrategyIndex) -{ - int index = atoi(selectedStrategyIndex.c_str()); - if(index != m_thresholdMethodIndex) - { - m_thresholdMethodIndex = index; - this->Modified(); - } -} - -const char* vtkRebinningTransformOperator::GetInputGeometryXML() -{ - try - { - return this->m_presenter->getAppliedGeometryXML().c_str(); //TODO, check xml lives beyond function call. - } - catch(std::runtime_error&) - { - return ""; - } -} - -double vtkRebinningTransformOperator::GetInputMinThreshold() -{ - return m_thresholdMin; -} - -double vtkRebinningTransformOperator::GetInputMaxThreshold() -{ - return m_thresholdMax; -} - -unsigned long vtkRebinningTransformOperator::GetMTime() -{ - return vtkUnstructuredGridAlgorithm::GetMTime(); -} - - - -void vtkRebinningTransformOperator::setTimeRange(vtkInformationVector* outputVector) -{ - if(SetupDone == m_setup) - { - if(m_presenter->hasTDimensionAvailable()) - { - vtkInformation *outInfo = outputVector->GetInformationObject(0); - outInfo->Set(vtkStreamingDemandDrivenPipeline::TIME_LABEL_ANNOTATION(), - m_presenter->getTimeStepLabel().c_str()); - std::vector timeStepValues = m_presenter->getTimeStepValues(); - outInfo->Set(vtkStreamingDemandDrivenPipeline::TIME_STEPS(), &timeStepValues[0], - static_cast (timeStepValues.size())); - double timeRange[2]; - timeRange[0] = timeStepValues.front(); - timeRange[1] = timeStepValues.back(); - - outInfo->Set(vtkStreamingDemandDrivenPipeline::TIME_RANGE(), timeRange, 2); - } - } -} - -void vtkRebinningTransformOperator::SetB1(double a, double b, double c) -{ - Mantid::Kernel::V3D temp(a, b, c); - if(m_b1 != temp) - { - m_b1 = temp; - this->Modified(); - } -} - -void vtkRebinningTransformOperator::SetB2(double a, double b, double c) -{ - Mantid::Kernel::V3D temp(a, b, c); - if(m_b2 != temp) - { - m_b2 = temp; - this->Modified(); - } -} - -void vtkRebinningTransformOperator::SetLengthB1(double length) -{ - if(length != m_lengthB1) - { - m_lengthB1 = length; - this->Modified(); - } -} - -void vtkRebinningTransformOperator::SetLengthB2(double length) -{ - if(length != m_lengthB2) - { - m_lengthB2 = length; - this->Modified(); - } -} - -void vtkRebinningTransformOperator::SetLengthB3(double length) -{ - if(length != m_lengthB3) - { - m_lengthB3 = length; - this->Modified(); - } -} - -void vtkRebinningTransformOperator::SetOrigin(double originX, double originY, double originZ) -{ - Mantid::Kernel::V3D temp(originX, originY, originZ); - if(temp != m_origin) - { - m_origin = temp; - this->Modified(); - } -} - -void vtkRebinningTransformOperator::SetForceOrthogonal(bool temp) -{ - if(temp != m_ForceOrthogonal) - { - m_ForceOrthogonal = temp; - this->Modified(); - } -} - - -Mantid::Kernel::V3D vtkRebinningTransformOperator::getOrigin() -{ - return m_origin; -} - -Mantid::Kernel::V3D vtkRebinningTransformOperator::getB1() -{ - return m_b1; -} - -Mantid::Kernel::V3D vtkRebinningTransformOperator::getB2() -{ - return m_b2; -} - -double vtkRebinningTransformOperator::getLengthB1() const -{ - return m_lengthB1; -} - -double vtkRebinningTransformOperator::getLengthB2() const -{ - return m_lengthB2; -} - -double vtkRebinningTransformOperator::getLengthB3() const -{ - return m_lengthB3; -} -bool vtkRebinningTransformOperator::getForceOrthogonal() const -{ - return m_ForceOrthogonal; -} - -/** - * Gets the minimum value of the data associated with the - * workspace. - * @return The minimum value of the workspace data. - */ -double vtkRebinningTransformOperator::GetMinValue() const -{ - if (NULL == m_presenter) - { - return 0.0; - } - try - { - return m_presenter->getMinValue(); - } - catch (std::runtime_error &) - { - return 0; - } -} - -/** - * Gets the maximum value of the data associated with the - * workspace. - * @return The maximum value of the workspace data. - */ -double vtkRebinningTransformOperator::GetMaxValue() const -{ - if (NULL == m_presenter) - { - return 0.0; - } - try - { - return m_presenter->getMaxValue(); - } - catch (std::runtime_error &) - { - return 0; - } -} - -/** - * Gets the (first) instrument which is associated with the workspace. - * @return The name of the instrument. - */ -const char* vtkRebinningTransformOperator::GetInstrument() const -{ - if (NULL == m_presenter) - { - return ""; - } - try - { - return m_presenter->getInstrument().c_str(); - } - catch (std::runtime_error &) - { - return ""; - } -} diff --git a/Code/Mantid/Vates/ParaviewPlugins/ParaViewFilters/RebinningTransformOperator/vtkRebinningTransformOperator.h b/Code/Mantid/Vates/ParaviewPlugins/ParaViewFilters/RebinningTransformOperator/vtkRebinningTransformOperator.h deleted file mode 100644 index 309e7c3d3d6e..000000000000 --- a/Code/Mantid/Vates/ParaviewPlugins/ParaViewFilters/RebinningTransformOperator/vtkRebinningTransformOperator.h +++ /dev/null @@ -1,182 +0,0 @@ -#ifndef _vtkRebinningTransformOperator_h -#define _vtkRebinningTransformOperator_h -#include -#include "vtkUnstructuredGridAlgorithm.h" -#include "MantidVatesAPI/MetadataJsonManager.h" -#include "MantidVatesAPI/ThresholdRange.h" -#include "MantidVatesAPI/VatesConfigurations.h" -#include "MantidGeometry/MDGeometry/MDTypes.h" -#include "MantidKernel/MultiThreaded.h" -#include "MantidKernel/V3D.h" -#include -#include - -/** - * - * Paraview Filter implementing rebinning/cutting operations. - - @author Owen Arnold, RAL ISIS - @date 18/03/2011 - - Copyright © 2007-10 ISIS Rutherford Appleton Laboratory, NScD Oak Ridge National Laboratory & European Spallation Source - - This file is part of Mantid. - - Mantid is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - Mantid is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . - - File change history is stored at: . - Code Documentation is available at: -*/ - -namespace Mantid -{ - namespace MDAlgorithms - { - //Forward declaration - class BoxImplicitFunction; - } - namespace VATES - { - class MDRebinningPresenter; - class RebinningActionManager; - } -} - - -enum SetupStatus{ Pending, SetupDone}; -///Type marks wheter clipping is to be applied or ignored -enum Clipping{ ApplyClipping, IgnoreClipping}; -///Type marks wheter original extents should be used over box extents. -enum OrignalExtents{ ApplyOriginal, IgnoreOriginal}; - -// cppcheck-suppress class_X_Y -class VTK_EXPORT vtkRebinningTransformOperator : public vtkUnstructuredGridAlgorithm//, public Mantid::VATES::MDRebinningView -{ -public: - static vtkRebinningTransformOperator *New(); - vtkTypeMacro(vtkRebinningTransformOperator, vtkUnstructuredGridAlgorithm); - void PrintSelf(ostream& os, vtkIndent indent); - - /// Paraview Related Commands. See *.xml proxy/property file -------------------------------- - void SetMaxThreshold(double maxThreshold); - void SetMinThreshold(double minThreshold); - void SetAppliedGeometryXML(std::string xml); - void SetB1(double a, double b, double c); - void SetB2(double a, double b, double c); - void SetLengthB1(double length); - void SetLengthB2(double length); - void SetLengthB3(double length); - void SetOrigin(double originX, double originY, double originZ); - void SetForceOrthogonal(bool value); - void SetOutputHistogramWS(bool value); - - const char* GetInputGeometryXML(); - void SetThresholdRangeStrategyIndex(std::string selectedStrategyIndex); - double GetInputMinThreshold(); - double GetInputMaxThreshold(); - /// Paraview Related Commands. See *.xml proxy/property file -------------------------------- - - /// Called by presenter to force progress information updating. - void updateAlgorithmProgress(double progress, const std::string& message); - - virtual double getMaxThreshold() const; - virtual double getMinThreshold() const; - virtual bool getApplyClip() const; - virtual double getTimeStep() const; - virtual const char* getAppliedGeometryXML() const; - virtual Mantid::Kernel::V3D getOrigin(); - virtual Mantid::Kernel::V3D getB1(); - virtual Mantid::Kernel::V3D getB2(); - virtual double getLengthB1() const; - virtual double getLengthB2() const; - virtual double getLengthB3() const; - virtual bool getForceOrthogonal() const; - virtual bool getOutputHistogramWS() const; - virtual double GetMinValue() const; - virtual double GetMaxValue() const; - virtual const char* GetInstrument() const; - -protected: - - ///Constructor - vtkRebinningTransformOperator(); - - ///Destructor - ~vtkRebinningTransformOperator(); - - ///Request information prior to execution. - int RequestInformation(vtkInformation *, vtkInformationVector **, vtkInformationVector *); - - ///Execution. - int RequestData(vtkInformation *, vtkInformationVector **, vtkInformationVector *); - - ///Update extents. - int RequestUpdateExtent(vtkInformation*, - vtkInformationVector**, vtkInformationVector* ); - - ///Handle time variation. - unsigned long GetMTime(); - - ///Overriden fill imports so that vtkDataSets may be specified. - int FillInputPortInformation(int port, vtkInformation* info); - -private: - - boost::shared_ptr m_presenter; - std::string m_appliedGeometryXML; - - vtkRebinningTransformOperator(const vtkRebinningTransformOperator&); - void operator = (const vtkRebinningTransformOperator&); - - void configureThresholdRangeMethod(); - - /// handles overwriting of time ranges. - void setTimeRange(vtkInformationVector* outputVector); - - /// Flag indicating that the clip boundaries should be use to construct the rebinning region. - Clipping m_clip; - /// Original extents should be used. - OrignalExtents m_originalExtents; - /// Flag indicating whether set up has occurred or not - SetupStatus m_setup; - /// Flag containing the timestep. - double m_timestep; - /// Threshold max value. - Mantid::signal_t m_thresholdMax; - /// Threhsold min value. - Mantid::signal_t m_thresholdMin; - /// Threshold range calculator. - Mantid::VATES::ThresholdRange_scptr m_ThresholdRange; - /// Method of thresholding to use. - int m_thresholdMethodIndex; - /// Mutex for progress updates - Mantid::Kernel::Mutex progressMutex; - /// Origin - Mantid::Kernel::V3D m_origin; - /// b1 direction vector - Mantid::Kernel::V3D m_b1; - /// b2 direction vector - Mantid::Kernel::V3D m_b2; - /// length b1 - double m_lengthB1; - /// length b2 - double m_lengthB2; - /// length b3 - double m_lengthB3; - /// Do we force the basis vectors to be orthogonal? - bool m_ForceOrthogonal; - /// Flag indicating that a histogram workspace should be provided. - bool m_bOutputHistogramWS; -}; -#endif diff --git a/Code/Mantid/Vates/ParaviewPlugins/ParaViewFilters/SplatterPlot/vtkSplatterPlot.cxx b/Code/Mantid/Vates/ParaviewPlugins/ParaViewFilters/SplatterPlot/vtkSplatterPlot.cxx index 10113d1ccb9d..8556d6c34de2 100644 --- a/Code/Mantid/Vates/ParaviewPlugins/ParaViewFilters/SplatterPlot/vtkSplatterPlot.cxx +++ b/Code/Mantid/Vates/ParaviewPlugins/ParaViewFilters/SplatterPlot/vtkSplatterPlot.cxx @@ -11,7 +11,7 @@ #include "MantidVatesAPI/FieldDataToMetadata.h" #include "MantidVatesAPI/FilteringUpdateProgressAction.h" #include "MantidVatesAPI/NoThresholdRange.h" -#include "MantidVatesAPI/RebinningCutterXMLDefinitions.h" +#include "MantidVatesAPI/VatesXMLDefinitions.h" #include "MantidVatesAPI/vtkDataSetToNonOrthogonalDataSet.h" #include "MantidVatesAPI/vtkDataSetToWsName.h" #include "MantidVatesAPI/vtkSplatterPlotFactory.h" diff --git a/Code/Mantid/Vates/ParaviewPlugins/ParaViewSources/MDEWSource/vtkMDEWSource.cxx b/Code/Mantid/Vates/ParaviewPlugins/ParaViewSources/MDEWSource/vtkMDEWSource.cxx index fb147413c482..638613a7b129 100644 --- a/Code/Mantid/Vates/ParaviewPlugins/ParaViewSources/MDEWSource/vtkMDEWSource.cxx +++ b/Code/Mantid/Vates/ParaviewPlugins/ParaViewSources/MDEWSource/vtkMDEWSource.cxx @@ -22,7 +22,7 @@ using namespace Mantid::VATES; vtkStandardNewMacro(vtkMDEWSource); /// Constructor -vtkMDEWSource::vtkMDEWSource() : m_wsName(""), m_depth(1000), m_time(0), m_presenter(NULL) +vtkMDEWSource::vtkMDEWSource() : m_wsName(""), m_depth(1000), m_time(0), m_presenter(NULL), m_isStartup(true), m_startupTimeValue(0) { this->SetNumberOfInputPorts(0); this->SetNumberOfOutputPorts(1); @@ -173,8 +173,16 @@ int vtkMDEWSource::RequestData(vtkInformation *, vtkInformationVector **, vtkInf //get the info objects vtkInformation *outInfo = outputVector->GetInformationObject(0); - - if (outInfo->Has(vtkStreamingDemandDrivenPipeline::UPDATE_TIME_STEP())) + if (m_isStartup) + { + // This is part of a workaround for ParaView time steps. The time we get + // is the first time point for all sources, and not necessarily of this source. + // This causes problems when getting the time slice and we end up with an empty + // data set. We therefore feed m_time the first time step of this source at + // start up. + m_time = m_startupTimeValue; + } + else if (outInfo->Has(vtkStreamingDemandDrivenPipeline::UPDATE_TIME_STEP())) { // usually only one actual step requested m_time =outInfo->Get(vtkStreamingDemandDrivenPipeline::UPDATE_TIME_STEP()); @@ -256,6 +264,9 @@ void vtkMDEWSource::setTimeRange(vtkInformationVector* outputVector) timeRange[0] = timeStepValues.front(); timeRange[1] = timeStepValues.back(); + // This is part of a workaround to get the first time value of the current source. + m_startupTimeValue = timeRange[0]; + outInfo->Set(vtkStreamingDemandDrivenPipeline::TIME_RANGE(), timeRange, 2); } } diff --git a/Code/Mantid/Vates/ParaviewPlugins/ParaViewSources/MDEWSource/vtkMDEWSource.h b/Code/Mantid/Vates/ParaviewPlugins/ParaViewSources/MDEWSource/vtkMDEWSource.h index abe5da855e30..f2f7a3e1b19a 100644 --- a/Code/Mantid/Vates/ParaviewPlugins/ParaViewSources/MDEWSource/vtkMDEWSource.h +++ b/Code/Mantid/Vates/ParaviewPlugins/ParaViewSources/MDEWSource/vtkMDEWSource.h @@ -97,6 +97,17 @@ class VTK_EXPORT vtkMDEWSource : public vtkUnstructuredGridAlgorithm /// Cached typename. std::string typeName; + + // This is part of a workaround for a ParaView providing not the start time of + // of current data set. + ///Startup flag + bool m_isStartup; + + // This is part of a workaround for a ParaView providing not the start time of + // of current data set. + /// Startup time value + double m_startupTimeValue; + vtkMDEWSource(const vtkMDEWSource&); void operator = (const vtkMDEWSource&); void setTimeRange(vtkInformationVector* outputVector); diff --git a/Code/Mantid/Vates/ParaviewPlugins/ParaViewWidgets/CMakeLists.txt b/Code/Mantid/Vates/ParaviewPlugins/ParaViewWidgets/CMakeLists.txt index 0c2dbb93920f..361eb758b333 100644 --- a/Code/Mantid/Vates/ParaviewPlugins/ParaViewWidgets/CMakeLists.txt +++ b/Code/Mantid/Vates/ParaviewPlugins/ParaViewWidgets/CMakeLists.txt @@ -1,6 +1,4 @@ # Use Qt4 as system package to avoid compiler warnings include ( UseSystemQt4 ) -add_subdirectory( RebinningCutterObjectPanel ) -add_subdirectory( RebinningTransformObjectPanel ) add_subdirectory( QtWidgets ) diff --git a/Code/Mantid/Vates/ParaviewPlugins/ParaViewWidgets/RebinningCutterObjectPanel/CMakeLists.txt b/Code/Mantid/Vates/ParaviewPlugins/ParaViewWidgets/RebinningCutterObjectPanel/CMakeLists.txt deleted file mode 100644 index 0bc36bdbecb4..000000000000 --- a/Code/Mantid/Vates/ParaviewPlugins/ParaViewWidgets/RebinningCutterObjectPanel/CMakeLists.txt +++ /dev/null @@ -1,30 +0,0 @@ -# Include Qt widgets -include_directories( ${CMAKE_CURRENT_SOURCE_DIR}/../QtWidgets ) - -# So that source file shows in VS. -set( INCLUDE_FILES RebinningCutterObjectPanel.h ) -set( SRC_FILES RebinningCutterObjectPanel.cxx ) - -qt4_wrap_cpp( MOC_SRCS RebinningCutterObjectPanel.h ) -add_paraview_object_panel( IFACES IFACE_SRCS - CLASS_NAME RebinningCutterObjectPanel - XML_NAME MDEWRebinningCutter XML_GROUP filters) -# Deal with Intel compiler warnings in generated files -if ( ${CMAKE_CXX_COMPILER_ID} MATCHES "Intel" ) - set_source_files_properties ( ${IFACES} ${IFACE_SRCS} PROPERTIES COMPILE_FLAGS -wd1170 ) -endif () -add_paraview_plugin( MantidParaViewRebinningCutterObjectPanel "1.0" - GUI_INTERFACES ${IFACES} - SOURCES ${MOC_SRCS} ${IFACE_SRCS} ${INCLUDE_FILES} - ${SRC_FILES} ) -# Add to the 'VatesParaViewPlugins' group in VS -set_property( TARGET MantidParaViewRebinningCutterObjectPanel PROPERTY FOLDER "MantidVatesParaViewPlugins" ) -target_link_libraries( MantidParaViewRebinningCutterObjectPanel -MantidParaViewQtWidgets ) - -# Put library into subfolder. -SET_TARGET_OUTPUT_DIRECTORY( MantidParaViewRebinningCutterObjectPanel ${CMAKE_LIBRARY_OUTPUT_DIRECTORY}/${CMAKE_CFG_INTDIR}/${PVPLUGINS_DIR}/${PVPLUGINS_SUBDIR}) - -install( TARGETS MantidParaViewRebinningCutterObjectPanel ${SYSTEM_PACKAGE_TARGET} DESTINATION ${PVPLUGINS_DIR}/${PVPLUGINS_SUBDIR} ) - - diff --git a/Code/Mantid/Vates/ParaviewPlugins/ParaViewWidgets/RebinningCutterObjectPanel/RebinningCutterObjectPanel.cxx b/Code/Mantid/Vates/ParaviewPlugins/ParaViewWidgets/RebinningCutterObjectPanel/RebinningCutterObjectPanel.cxx deleted file mode 100644 index 83899793858c..000000000000 --- a/Code/Mantid/Vates/ParaviewPlugins/ParaViewWidgets/RebinningCutterObjectPanel/RebinningCutterObjectPanel.cxx +++ /dev/null @@ -1,192 +0,0 @@ -#include "RebinningCutterObjectPanel.h" - -#include "GeometryWidget.h" -#include "ThresholdRangeWidget.h" -#include "MantidGeometry/MDGeometry/MDGeometryXMLParser.h" -#include "MantidVatesAPI/SynchronisingGeometryPresenter.h" - -// Have to deal with ParaView warnings and Intel compiler the hard way. -#if defined(__INTEL_COMPILER) - #pragma warning disable 1170 -#endif - -#include -#include -#include -#include -#include -#include - -#if defined(__INTEL_COMPILER) - #pragma warning enable 1170 -#endif - -#include -#include -#include -#include - -using namespace Mantid::VATES; -using namespace Mantid::Geometry; - -RebinningCutterObjectPanel::RebinningCutterObjectPanel(pqProxy* pxy, QWidget* p) : -pqAutoGeneratedObjectPanel(pxy, p), m_cachedMinThreshold(0), m_cachedMaxThreshold(0), m_geometryXMLString(""), m_geometryWidget(NULL), m_thresholdWidget(NULL), m_geomBinDisplayMode(Simple) -{ - //Auto generated widgets are replaced by Custom Widgets. Autogenerated ones need to be removed. - removeAutoGeneratedWidgets(); -} - -/// Event handler for framework event. -void RebinningCutterObjectPanel::updateInformationAndDomains() -{ - this->proxy()->UpdatePropertyInformation(); - QGridLayout* gLayout = dynamic_cast(this->layout()); - try - { - this->constructThresholdRanges(gLayout); - this->constructGeometry(gLayout); - } - catch(std::exception& ex) - { - UNUSED_ARG(ex); - QMessageBox::information(NULL, "Setup Not possible.", - "Could not interpret metadata. Are you using a rebinning source? Check field data."); - } -} - -void RebinningCutterObjectPanel::constructGeometry(QGridLayout* gLayout) -{ - vtkSMStringVectorProperty* inputGeometryProperty = vtkSMStringVectorProperty::SafeDownCast( - this->proxy()->GetProperty("InputGeometryXML")); - - std::string geometryXMLString = inputGeometryProperty->GetElement(0); - - if(m_geometryXMLString != geometryXMLString) //Only attempt to reconstruct the geometry widget if the xml has changed. - { - MDGeometryXMLParser xmlParser(geometryXMLString); - xmlParser.execute(); - - //Empty geometry widget added to layout. - if(m_geometryWidget != NULL) - { - m_geomBinDisplayMode = m_geometryWidget->getBinDisplayMode(); - this->layout()->removeWidget(m_geometryWidget); - delete m_geometryWidget; - } - - // Construct custom widget instance. - m_geometryWidget = new GeometryWidget(new SynchronisingGeometryPresenter(xmlParser), m_geomBinDisplayMode); - gLayout->addWidget(m_geometryWidget, gLayout->rowCount() + 1, 0, Qt::AlignLeft); - - // Property used as setter. - vtkSMProperty * appliedGeometryXML = this->proxy()->GetProperty("AppliedGeometryXML"); - - connect(m_geometryWidget, SIGNAL(valueChanged()), this, SLOT(onGeometryChanged())); - - //Hook up geometry change event to listener on filter. - this->propertyManager()->registerLink(m_geometryWidget, "GeometryXML", - SIGNAL(valueChanged()), this->proxy(), appliedGeometryXML); - - m_geometryXMLString = geometryXMLString; - } -} - -void RebinningCutterObjectPanel::constructThresholdRanges(QGridLayout* gLayout) -{ - // Access getter property to extract original input max threshold value. - vtkSMDoubleVectorProperty* inputMaxThresholdProperty = vtkSMDoubleVectorProperty::SafeDownCast( - this->proxy()->GetProperty("InputMaxThreshold")); - double inputMaxThreshold = inputMaxThresholdProperty->GetElement(0); - - // Access getter property to extract original input min threshold value. - vtkSMDoubleVectorProperty* inputMinThresholdProperty = vtkSMDoubleVectorProperty::SafeDownCast( - this->proxy()->GetProperty("InputMinThreshold")); - double inputMinThreshold = inputMinThresholdProperty->GetElement(0); - - //vtkSMProperty* prop = this->proxy()->GetProperty("ClipFunction"); - //vtkSMProxyProperty* clipFunc = vtkSMProxyProperty::SafeDownCast(this->proxy()->GetProperty("ClipFunction")); - - - if(inputMaxThreshold != m_cachedMaxThreshold || inputMinThreshold != m_cachedMinThreshold) - { - - if(m_thresholdWidget == NULL) - { - m_thresholdWidget = new ThresholdRangeWidget(inputMinThreshold, inputMaxThreshold); - gLayout->addWidget(m_thresholdWidget, gLayout->rowCount() + 1, 0, Qt::AlignCenter); - - // Property used as setter - vtkSMProperty * minThreshold = this->proxy()->GetProperty("MinThreshold"); - - // Property used as setter - vtkSMProperty * maxThreshold = this->proxy()->GetProperty("MaxThreshold"); - - // Property used as setter - vtkSMProperty * rangeStrategy = this->proxy()->GetProperty("ThresholdRangeStrategyIndex"); - - // Hook-up events to PV properties. - this->propertyManager()->registerLink(m_thresholdWidget, "MinSignal", - SIGNAL(minChanged()), this->proxy(), minThreshold); - - // Hook-up events to PV properties. - this->propertyManager()->registerLink(m_thresholdWidget, "MaxSignal", - SIGNAL(maxChanged()), this->proxy(), maxThreshold); - - // Hook-up events to PV properties. - this->propertyManager()->registerLink(m_thresholdWidget, "ChosenStrategy", - SIGNAL(chosenStrategyChanged()), this->proxy(), rangeStrategy); - - } - else - { - m_thresholdWidget->setMaximum(inputMaxThreshold); - m_thresholdWidget->setMinimum(inputMinThreshold); - } - - m_cachedMaxThreshold = inputMaxThreshold; - m_cachedMinThreshold = inputMinThreshold; - } -} - -/// Direct removal of autogenerated widgets. -void RebinningCutterObjectPanel::removeAutoGeneratedWidgets() -{ - popWidget(); // Autogenerated Geometry QLineEdit - popWidget(); // Autogenerated Geometry QLabel - popWidget(); // Autogenerated Max threshold QLineEdit - popWidget(); // Autogenerated Max threshold QLabel - popWidget(); // Autogenerated Min threshold QLineEdit - popWidget(); // Autogenerated Min threshold QLabel - popWidget(); // Autogenerated User defined ComboBox. - popWidget(); // Autogenerated User defined ComboBox. -} - -/// Pop widgets off the layout and hide them. -void RebinningCutterObjectPanel::popWidget() -{ - unsigned int size = layout()->count(); - if(size >= 1) - { - //Pop the last widget off the layout and hide it. - QLayoutItem* pLayoutItem = layout()->itemAt(size - 1); - QWidget* pWidget = pLayoutItem->widget(); - if (NULL == pWidget) - { - throw std::domain_error( - "Error ::popWidget(). Attempting to pop a non-widget object off the layout!"); - } - else - { - pWidget->setHidden(true); - this->layout()->removeItem(pLayoutItem); - } - } -} - -void RebinningCutterObjectPanel::onGeometryChanged() -{ - if(m_geometryWidget) - { - m_geomBinDisplayMode = m_geometryWidget->getBinDisplayMode(); - } -} diff --git a/Code/Mantid/Vates/ParaviewPlugins/ParaViewWidgets/RebinningCutterObjectPanel/RebinningCutterObjectPanel.h b/Code/Mantid/Vates/ParaviewPlugins/ParaViewWidgets/RebinningCutterObjectPanel/RebinningCutterObjectPanel.h deleted file mode 100644 index a071c5996b09..000000000000 --- a/Code/Mantid/Vates/ParaviewPlugins/ParaViewWidgets/RebinningCutterObjectPanel/RebinningCutterObjectPanel.h +++ /dev/null @@ -1,79 +0,0 @@ -#include "pqAutoGeneratedObjectPanel.h" -#include "MantidVatesAPI/DimensionView.h" -#include "MantidKernel/System.h" - -/** - - Adds and removes from Paraview's autogenerated object panel for the Rebinning Cutting filter. - - @author Owen Arnold, Tessella plc - @date 17/03/2011 - - Copyright © 2010 ISIS Rutherford Appleton Laboratory, NScD Oak Ridge National Laboratory & European Spallation Source - - This file is part of Mantid. - - Mantid is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - Mantid is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . - - File change history is stored at: - Code Documentation is available at: - */ - -//Forward declarations -class GeometryWidget; -class ThresholdRangeWidget; - -// cppcheck-suppress class_X_Y -class DLLExport RebinningCutterObjectPanel: public pqAutoGeneratedObjectPanel -{ -Q_OBJECT -private: - /// cached min threshold. - double m_cachedMinThreshold; - /// cached max threshold. - double m_cachedMaxThreshold; - /// cached geometry xml string. - std::string m_geometryXMLString; - /// Pointer to custom geometry widget. - GeometryWidget* m_geometryWidget; - /// Pointer to custom threshold range widget. - ThresholdRangeWidget* m_thresholdWidget; - /// Cached bin display mode from the geometry widget. - Mantid::VATES::BinDisplay m_geomBinDisplayMode; - -private slots: - - void onGeometryChanged(); - -public: - - /// Constructor - RebinningCutterObjectPanel(pqProxy* pxy, QWidget* p); - - /// Framework overriden method. - void updateInformationAndDomains(); - - /// Remove selected auto-generated widgets - void removeAutoGeneratedWidgets(); - - /// Pop the widget off the layout - void popWidget(); - - /// Construct threshold ranges and link-up with properties - void constructThresholdRanges(QGridLayout* gLayout); - - /// Construct geometry widgets and link-up with properties - void constructGeometry(QGridLayout* gLayout); - -}; diff --git a/Code/Mantid/Vates/ParaviewPlugins/ParaViewWidgets/RebinningTransformObjectPanel/CMakeLists.txt b/Code/Mantid/Vates/ParaviewPlugins/ParaViewWidgets/RebinningTransformObjectPanel/CMakeLists.txt deleted file mode 100644 index 058be1a3e034..000000000000 --- a/Code/Mantid/Vates/ParaviewPlugins/ParaViewWidgets/RebinningTransformObjectPanel/CMakeLists.txt +++ /dev/null @@ -1,30 +0,0 @@ -# Include Qt widgets -include_directories( ${CMAKE_CURRENT_SOURCE_DIR}/../QtWidgets ) - -# So that source file shows in VS. -set( INCLUDE_FILES RebinningTransformObjectPanel.h ) -set( SRC_FILES RebinningTransformObjectPanel.cxx ) - -qt4_wrap_cpp( MOC_SRCS RebinningTransformObjectPanel.h ) -add_paraview_object_panel( IFACES IFACE_SRCS - CLASS_NAME RebinningTransformObjectPanel - XML_NAME RebinningTransformOperator XML_GROUP filters) -# Deal with Intel compiler warnings in generated files -if ( ${CMAKE_CXX_COMPILER_ID} MATCHES "Intel" ) - set_source_files_properties ( ${IFACES} ${IFACE_SRCS} PROPERTIES COMPILE_FLAGS -wd1170 ) -endif () -add_paraview_plugin( MantidParaViewRebinningTransformObjectPanel "1.0" - GUI_INTERFACES ${IFACES} - SOURCES ${MOC_SRCS} ${IFACE_SRCS} ${INCLUDE_FILES} - ${SRC_FILES} ) -# Add to the 'VatesParaViewPlugins' group in VS -set_property( TARGET MantidParaViewRebinningTransformObjectPanel PROPERTY FOLDER "MantidVatesParaViewPlugins" ) -target_link_libraries( MantidParaViewRebinningTransformObjectPanel -MantidParaViewQtWidgets ) - -# Put library into subfolder. -SET_TARGET_OUTPUT_DIRECTORY( MantidParaViewRebinningTransformObjectPanel ${CMAKE_LIBRARY_OUTPUT_DIRECTORY}/${CMAKE_CFG_INTDIR}/${PVPLUGINS_DIR}/${PVPLUGINS_SUBDIR}) - -install( TARGETS MantidParaViewRebinningTransformObjectPanel ${SYSTEM_PACKAGE_TARGET} DESTINATION ${PVPLUGINS_DIR}/${PVPLUGINS_SUBDIR} ) - - diff --git a/Code/Mantid/Vates/ParaviewPlugins/ParaViewWidgets/RebinningTransformObjectPanel/RebinningTransformObjectPanel.cxx b/Code/Mantid/Vates/ParaviewPlugins/ParaViewWidgets/RebinningTransformObjectPanel/RebinningTransformObjectPanel.cxx deleted file mode 100644 index d7874ac49ca8..000000000000 --- a/Code/Mantid/Vates/ParaviewPlugins/ParaViewWidgets/RebinningTransformObjectPanel/RebinningTransformObjectPanel.cxx +++ /dev/null @@ -1,180 +0,0 @@ -#include "RebinningTransformObjectPanel.h" - -#include "GeometryWidget.h" -#include "ThresholdRangeWidget.h" -#include "MantidGeometry/MDGeometry/MDGeometryXMLParser.h" -#include "MantidVatesAPI/SynchronisingGeometryPresenter.h" - -// Have to deal with ParaView warnings and Intel compiler the hard way. -#if defined(__INTEL_COMPILER) - #pragma warning disable 1170 -#endif - -#include -#include -#include -#include -#include -#include - -#if defined(__INTEL_COMPILER) - #pragma warning enable 1170 -#endif - -#include -#include -#include -#include - -using namespace Mantid::VATES; -using namespace Mantid::Geometry; - -RebinningTransformObjectPanel::RebinningTransformObjectPanel(pqProxy* pxy, QWidget* p) : -pqAutoGeneratedObjectPanel(pxy, p), m_cachedMinThreshold(0), m_cachedMaxThreshold(0), m_geometryXMLString(""), m_geometryWidget(NULL), m_thresholdWidget(NULL) -{ - //Auto generated widgets are replaced by Custom Widgets. Autogenerated ones need to be removed. - removeAutoGeneratedWidgets(); -} - -/// Event handler for framework event. -void RebinningTransformObjectPanel::updateInformationAndDomains() -{ - this->proxy()->UpdatePropertyInformation(); - QGridLayout* gLayout = dynamic_cast(this->layout()); - try - { - this->constructThresholdRanges(gLayout); - this->constructGeometry(gLayout); - } - catch(std::exception& ex) - { - UNUSED_ARG(ex); - QMessageBox::information(NULL, "Setup Not possible.", - "Could not interpret metadata. Are you using a rebinning source? Check field data."); - } -} - -void RebinningTransformObjectPanel::constructGeometry(QGridLayout* gLayout) -{ - vtkSMStringVectorProperty* inputGeometryProperty = vtkSMStringVectorProperty::SafeDownCast( - this->proxy()->GetProperty("InputGeometryXML")); - - std::string geometryXMLString = inputGeometryProperty->GetElement(0); - - if(m_geometryXMLString != geometryXMLString) //Only attempt to reconstruct the geometry widget if the xml has changed. - { - MDGeometryXMLParser xmlParser(geometryXMLString); - xmlParser.execute(); - - //Empty geometry widget added to layout. - if(m_geometryWidget != NULL) - { - this->layout()->removeWidget(m_geometryWidget); - delete m_geometryWidget; - } - - // Construct custom widget instance. - m_geometryWidget = new GeometryWidget(new SynchronisingGeometryPresenter(xmlParser), Mantid::VATES::Simple); - gLayout->addWidget(m_geometryWidget, gLayout->rowCount() + 1, 0, 1, 2, Qt::AlignLeft); - - // Property used as setter. - vtkSMProperty * appliedGeometryXML = this->proxy()->GetProperty("AppliedGeometryXML"); - - //Hook up geometry change event to listener on filter. - this->propertyManager()->registerLink(m_geometryWidget, "GeometryXML", - SIGNAL(valueChanged()), this->proxy(), appliedGeometryXML); - - m_geometryXMLString = geometryXMLString; - } -} - -void RebinningTransformObjectPanel::constructThresholdRanges(QGridLayout* gLayout) -{ - // Access getter property to extract original input max threshold value. - vtkSMDoubleVectorProperty* inputMaxThresholdProperty = vtkSMDoubleVectorProperty::SafeDownCast( - this->proxy()->GetProperty("InputMaxThreshold")); - double inputMaxThreshold = inputMaxThresholdProperty->GetElement(0); - - // Access getter property to extract original input min threshold value. - vtkSMDoubleVectorProperty* inputMinThresholdProperty = vtkSMDoubleVectorProperty::SafeDownCast( - this->proxy()->GetProperty("InputMinThreshold")); - double inputMinThreshold = inputMinThresholdProperty->GetElement(0); - - //vtkSMProperty* prop = this->proxy()->GetProperty("ClipFunction"); - //vtkSMProxyProperty* clipFunc = vtkSMProxyProperty::SafeDownCast(this->proxy()->GetProperty("ClipFunction")); - - - if(inputMaxThreshold != m_cachedMaxThreshold || inputMinThreshold != m_cachedMinThreshold) - { - - if(m_thresholdWidget == NULL) - { - m_thresholdWidget = new ThresholdRangeWidget(inputMinThreshold, inputMaxThreshold); - gLayout->addWidget(m_thresholdWidget, gLayout->rowCount() + 1, 0, 1, 2, Qt::AlignCenter); - - // Property used as setter - vtkSMProperty * minThreshold = this->proxy()->GetProperty("MinThreshold"); - - // Property used as setter - vtkSMProperty * maxThreshold = this->proxy()->GetProperty("MaxThreshold"); - - // Property used as setter - vtkSMProperty * rangeStrategy = this->proxy()->GetProperty("ThresholdRangeStrategyIndex"); - - // Hook-up events to PV properties. - this->propertyManager()->registerLink(m_thresholdWidget, "MinSignal", - SIGNAL(minChanged()), this->proxy(), minThreshold); - - // Hook-up events to PV properties. - this->propertyManager()->registerLink(m_thresholdWidget, "MaxSignal", - SIGNAL(maxChanged()), this->proxy(), maxThreshold); - - // Hook-up events to PV properties. - this->propertyManager()->registerLink(m_thresholdWidget, "ChosenStrategy", - SIGNAL(chosenStrategyChanged()), this->proxy(), rangeStrategy); - } - else - { - m_thresholdWidget->setMaximum(inputMaxThreshold); - m_thresholdWidget->setMinimum(inputMinThreshold); - } - - m_cachedMaxThreshold = inputMaxThreshold; - m_cachedMinThreshold = inputMinThreshold; - } -} - -/// Direct removal of autogenerated widgets. -void RebinningTransformObjectPanel::removeAutoGeneratedWidgets() -{ - popWidget(); // Autogenerated Geometry QLineEdit - popWidget(); // Autogenerated Geometry QLabel - popWidget(); // Autogenerated Max threshold QLineEdit - popWidget(); // Autogenerated Max threshold QLabel - popWidget(); // Autogenerated Min threshold QLineEdit - popWidget(); // Autogenerated Min threshold QLabel - popWidget(); // Autogenerated User defined ComboBox. - popWidget(); // Autogenerated User defined ComboBox. -} - -/// Pop widgets off the layout and hide them. -void RebinningTransformObjectPanel::popWidget() -{ - unsigned int size = layout()->count(); - if(size >= 1) - { - //Pop the last widget off the layout and hide it. - QLayoutItem* pLayoutItem = layout()->itemAt(size - 1); - QWidget* pWidget = pLayoutItem->widget(); - if (NULL == pWidget) - { - throw std::domain_error( - "Error ::popWidget(). Attempting to pop a non-widget object off the layout!"); - } - else - { - pWidget->setHidden(true); - this->layout()->removeItem(pLayoutItem); - } - } -} diff --git a/Code/Mantid/Vates/ParaviewPlugins/ParaViewWidgets/RebinningTransformObjectPanel/RebinningTransformObjectPanel.h b/Code/Mantid/Vates/ParaviewPlugins/ParaViewWidgets/RebinningTransformObjectPanel/RebinningTransformObjectPanel.h deleted file mode 100644 index 11f0955d50ea..000000000000 --- a/Code/Mantid/Vates/ParaviewPlugins/ParaViewWidgets/RebinningTransformObjectPanel/RebinningTransformObjectPanel.h +++ /dev/null @@ -1,75 +0,0 @@ -#include "pqAutoGeneratedObjectPanel.h" - -#include "MantidKernel/System.h" - -/** - - Adds and removes from Paraview's autogenerated object panel for the Rebinning Cutting filter. - - @author Owen Arnold, Tessella plc - @date 17/03/2011 - - Copyright © 2010 ISIS Rutherford Appleton Laboratory, NScD Oak Ridge National Laboratory & European Spallation Source - - This file is part of Mantid. - - Mantid is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - Mantid is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . - - File change history is stored at: - Code Documentation is available at: - */ - -//Forward declarations -class GeometryWidget; -class ThresholdRangeWidget; - -// cppcheck-suppress class_X_Y -class DLLExport RebinningTransformObjectPanel: public pqAutoGeneratedObjectPanel -{ -Q_OBJECT -private: - /// cached min threshold. - double m_cachedMinThreshold; - /// cached max threshold. - double m_cachedMaxThreshold; - /// cached geometry xml string. - std::string m_geometryXMLString; - /// Pointer to custom geometry widget. - GeometryWidget* m_geometryWidget; - /// Pointer to custom threshold range widget. - ThresholdRangeWidget* m_thresholdWidget; - -private slots: - -public: - - /// Constructor - RebinningTransformObjectPanel(pqProxy* pxy, QWidget* p); - - /// Framework overriden method. - void updateInformationAndDomains(); - - /// Remove selected auto-generated widgets - void removeAutoGeneratedWidgets(); - - /// Pop the widget off the layout - void popWidget(); - - /// Construct threshold ranges and link-up with properties - void constructThresholdRanges(QGridLayout* gLayout); - - /// Construct geometry widgets and link-up with properties - void constructGeometry(QGridLayout* gLayout); - -}; diff --git a/Code/Mantid/Vates/VatesAPI/CMakeLists.txt b/Code/Mantid/Vates/VatesAPI/CMakeLists.txt index 8384d524d947..15c608a0266f 100644 --- a/Code/Mantid/Vates/VatesAPI/CMakeLists.txt +++ b/Code/Mantid/Vates/VatesAPI/CMakeLists.txt @@ -5,17 +5,14 @@ project( VatesAPI ) set( SRC_FILES src/ADSWorkspaceProvider.cpp -src/Clipper.cpp src/Common.cpp src/DimensionPresenter.cpp -src/EscalatingRebinningActionManager.cpp src/EventNexusLoadingPresenter.cpp src/FieldDataToMetadata.cpp src/IgnoreZerosThresholdRange.cpp src/IMDDimensionComparitor.cpp src/LoadVTK.cpp src/MDEWEventNexusLoadingPresenter.cpp -src/MDEWRebinningPresenter.cpp src/MDEWInMemoryLoadingPresenter.cpp src/MDEWLoadingPresenter.cpp src/MDHWInMemoryLoadingPresenter.cpp @@ -26,15 +23,14 @@ src/MetadataToFieldData.cpp src/MetaDataExtractorUtils.cpp src/MetadataJsonManager.cpp src/NoThresholdRange.cpp -src/NullRebinningPresenter.cpp src/ProgressAction.cpp -src/RebinningCutterXMLDefinitions.cpp -src/RebinningKnowledgeSerializer.cpp src/SynchronisingGeometryPresenter.cpp src/TimeStepToTimeStep.cpp src/TimeToTimeStep.cpp src/UserDefinedThresholdRange.cpp +src/VatesXMLDefinitions.cpp src/VatesConfigurations.cpp +src/VatesKnowledgeSerializer.cpp src/vtkDataSetFactory.cpp src/vtkDataSetToGeometry.cpp src/vtkDataSetToImplicitFunction.cpp @@ -44,6 +40,7 @@ src/vtkDataSetToWsName.cpp src/vtkDataSetToWsLocation.cpp src/vtkMDLineFactory.cpp src/vtkMDQuadFactory.cpp +src/vtkNullUnstructuredGrid.cpp src/vtkSplatterPlotFactory.cpp src/vtkMDHexFactory.cpp src/vtkPeakMarkerFactory.cpp @@ -56,12 +53,10 @@ src/SQWLoadingPresenter.cpp set( INC_FILES inc/MantidVatesAPI/ADSWorkspaceProvider.h -inc/MantidVatesAPI/Clipper.h inc/MantidVatesAPI/Common.h inc/MantidVatesAPI/DimensionPresenter.h inc/MantidVatesAPI/DimensionView.h inc/MantidVatesAPI/DimensionViewFactory.h -inc/MantidVatesAPI/EscalatingRebinningActionManager.h inc/MantidVatesAPI/EventNexusLoadingPresenter.h inc/MantidVatesAPI/FieldDataToMetadata.h inc/MantidVatesAPI/FilteringUpdateProgressAction.h @@ -71,16 +66,12 @@ inc/MantidVatesAPI/LoadVTK.h inc/MantidVatesAPI/MDEWEventNexusLoadingPresenter.h inc/MantidVatesAPI/MDEWLoadingPresenter.h inc/MantidVatesAPI/MDEWInMemoryLoadingPresenter.h -inc/MantidVatesAPI/MDEWRebinningPresenter.h inc/MantidVatesAPI/MDHWInMemoryLoadingPresenter.h inc/MantidVatesAPI/MDHWLoadingPresenter.h inc/MantidVatesAPI/MDHWNexusLoadingPresenter.h inc/MantidVatesAPI/MDLoadingPresenter.h inc/MantidVatesAPI/MDLoadingView.h inc/MantidVatesAPI/MDLoadingViewAdapter.h -inc/MantidVatesAPI/MDRebinningPresenter.h -inc/MantidVatesAPI/MDRebinningView.h -inc/MantidVatesAPI/MDRebinningViewAdapter.h inc/MantidVatesAPI/MedianAndBelowThresholdRange.h inc/MantidVatesAPI/MetaDataExtractorUtils.h inc/MantidVatesAPI/MetadataJsonManager.h @@ -88,18 +79,16 @@ inc/MantidVatesAPI/IgnoreZerosThresholdRange.h inc/MantidVatesAPI/IMDDimensionComparitor.h inc/MantidVatesAPI/MetadataToFieldData.h inc/MantidVatesAPI/NoThresholdRange.h -inc/MantidVatesAPI/NullRebinningPresenter.h inc/MantidVatesAPI/ProgressAction.h -inc/MantidVatesAPI/RebinningActionManager.h -inc/MantidVatesAPI/RebinningCutterXMLDefinitions.h -inc/MantidVatesAPI/RebinningKnowledgeSerializer.h inc/MantidVatesAPI/SQWLoadingPresenter.h inc/MantidVatesAPI/SynchronisingGeometryPresenter.h inc/MantidVatesAPI/ThresholdRange.h inc/MantidVatesAPI/TimeStepToTimeStep.h inc/MantidVatesAPI/TimeToTimeStep.h inc/MantidVatesAPI/UserDefinedThresholdRange.h +inc/MantidVatesAPI/VatesXMLDefinitions.h inc/MantidVatesAPI/VatesConfigurations.h +inc/MantidVatesAPI/VatesKnowledgeSerializer.h inc/MantidVatesAPI/vtkDataSetFactory.h inc/MantidVatesAPI/vtkDataSetToGeometry.h inc/MantidVatesAPI/vtkDataSetToImplicitFunction.h @@ -110,6 +99,7 @@ inc/MantidVatesAPI/vtkDataSetToWsLocation.h inc/MantidVatesAPI/vtkMDLineFactory.h inc/MantidVatesAPI/vtkMDQuadFactory.h inc/MantidVatesAPI/vtkMDHexFactory.h +inc/MantidVatesAPI/vtkNullUnstructuredGrid.h inc/MantidVatesAPI/vtkSplatterPlotFactory.h inc/MantidVatesAPI/vtkPeakMarkerFactory.h inc/MantidVatesAPI/vtkMDHistoHexFactory.h @@ -125,7 +115,6 @@ test/vtkDataSetToWsNameTest.h test/vtkDataSetToWsLocationTest.h test/ADSWorkspaceProviderTest.h test/DimensionPresenterTest.h -test/EscalatingRebinningActionManagerTest.h test/EventNexusLoadingPresenterTest.h test/vtkDataSetFactoryTest.h test/vtkDataSetToGeometryTest.h @@ -142,19 +131,15 @@ test/FieldDataToMetadataTest.h test/FilteringUpdateProgressActionTest.h test/LoadVTKTest.h test/MDLoadingViewAdapterTest.h -test/MDRebinningViewAdapterTest.h test/MDEWEventNexusLoadingPresenterTest.h test/MDEWInMemoryLoadingPresenterTest.h test/MDEWLoadingPresenterTest.h -test/MDEWRebinningPresenterTest.h test/MDHWInMemoryLoadingPresenterTest.h test/MDHWLoadingPresenterTest.h test/MDHWNexusLoadingPresenterTest.h test/MetaDataExtractorUtilsTest.h test/MetadataJsonManagerTest.h -test/NullRebinningPresenterTest.h test/MetadataToFieldDataTest.h -test/RebinningKnowledgeSerializerTest.h test/SQWLoadingPresenterTest.h test/SynchronisingGeometryPresenterTest.h test/TimeStepToTimeStepTest.h @@ -163,8 +148,10 @@ test/UserDefinedThresholdRangeTest.h test/MedianAndBelowThresholdRangeTest.h test/NoThresholdRangeTest.h test/IgnoreZerosThresholdRangeTest.h +test/VatesKnowledgeSerializerTest.h test/vtkDataSetToScaledDataSetTest.h test/vtkDataSetToNonOrthogonalDataSetTest.h +test/vtkNullUnstructuredGridTest.h ) include_directories( inc ) diff --git a/Code/Mantid/Vates/VatesAPI/inc/MantidVatesAPI/Clipper.h b/Code/Mantid/Vates/VatesAPI/inc/MantidVatesAPI/Clipper.h deleted file mode 100644 index 9aecf2c88b20..000000000000 --- a/Code/Mantid/Vates/VatesAPI/inc/MantidVatesAPI/Clipper.h +++ /dev/null @@ -1,68 +0,0 @@ -#ifndef ABSTRACT_CLIPPER_H -#define ABSTRACT_CLIPPER_H -#include "MantidKernel/System.h" - -//Forward declarations -class vtkDataSet; -class vtkUnstructuredGrid; -class vtkImplicitFunction; - -namespace Mantid -{ -namespace VATES -{ - - /** Abstract clipper type. Allows full separation of vendor specific vtk technology from back end. - - @author Owen Arnold, Tessella plc - @date 07/02/2011 - - Copyright © 2010 ISIS Rutherford Appleton Laboratory, NScD Oak Ridge National Laboratory & European Spallation Source - - This file is part of Mantid. - - Mantid is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - Mantid is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . - - File change history is stored at: - Code Documentation is available at: - */ - -class DLLExport Clipper -{ -public: - - virtual void SetInput(vtkDataSet* in_ds) =0; - - virtual void SetClipFunction(vtkImplicitFunction* func) =0; - - virtual void SetInsideOut(bool insideout) =0; - - virtual void SetRemoveWholeCells(bool removeWholeCells) =0; - - virtual void SetOutput(vtkUnstructuredGrid* out_ds) =0; - - virtual void Update() = 0; - - virtual ~Clipper() =0; - - virtual void Delete() = 0; - - virtual vtkDataSet* GetOutput() =0; -}; - -} -} - - -#endif diff --git a/Code/Mantid/Vates/VatesAPI/inc/MantidVatesAPI/Common.h b/Code/Mantid/Vates/VatesAPI/inc/MantidVatesAPI/Common.h index 6f2c94cef288..453c98865e08 100644 --- a/Code/Mantid/Vates/VatesAPI/inc/MantidVatesAPI/Common.h +++ b/Code/Mantid/Vates/VatesAPI/inc/MantidVatesAPI/Common.h @@ -25,14 +25,6 @@ typedef boost::shared_ptr Dimension_sptr; /// IMDDimension as const shared pointer. Note that IMDDimension is pure virtual. typedef boost::shared_ptr Dimension_const_sptr; -/// Flags what should be done on the current iteration. -enum RebinningIterationAction { - UseCache, //There is no delta here. Use a cached vtkDataSet. - RecalculateVisualDataSetOnly, // 4D data set has not altered so create a new visual 3D slice only. - RecalculateAll, // Rebin and create 3D visualisation slice from 4D dataset. - ReloadAndRecalculateAll // Reload the original workspace and then Rebin it. -}; - std::string makeAxisTitle(Dimension_const_sptr dim); void setAxisLabel(std::string metadataLabel, diff --git a/Code/Mantid/Vates/VatesAPI/inc/MantidVatesAPI/EscalatingRebinningActionManager.h b/Code/Mantid/Vates/VatesAPI/inc/MantidVatesAPI/EscalatingRebinningActionManager.h deleted file mode 100644 index e037b2eed3d7..000000000000 --- a/Code/Mantid/Vates/VatesAPI/inc/MantidVatesAPI/EscalatingRebinningActionManager.h +++ /dev/null @@ -1,56 +0,0 @@ -#ifndef ESCALATING_REBINNINGACTIONMANAGER_H_ -#define ESCALATING_REBINNINGACTIONMANAGER_H_ - -/** - * Encapsulates knowledge about switching between rebinning action states. - * Knows when to escalate a decision to a higher level (i.e, from effectivley do nothing to - * trigger a full rebin based on the current state and the request made). - * Simple stragegy pattern, may be one of may used. - * - @author Owen Arnold, Tessella ISIS - @date 16/04/2011 - - Copyright © 2007-10 ISIS Rutherford Appleton Laboratory, NScD Oak Ridge National Laboratory & European Spallation Source - - This file is part of Mantid. - - Mantid is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - Mantid is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . - - File change history is stored at: . - Code Documentation is available at: - */ - -#include "MantidVatesAPI/RebinningActionManager.h" -namespace Mantid -{ - namespace VATES - { - class DLLExport EscalatingRebinningActionManager : public RebinningActionManager - { - private: - RebinningIterationAction m_currentAction; - public: - EscalatingRebinningActionManager(RebinningIterationAction action=UseCache); - virtual ~EscalatingRebinningActionManager(); - virtual void ask(RebinningIterationAction requestedAction); - virtual RebinningIterationAction action() const; - virtual void reset(); - private: - EscalatingRebinningActionManager(const EscalatingRebinningActionManager&); - EscalatingRebinningActionManager& operator=(const EscalatingRebinningActionManager&); - }; - } -} - -#endif diff --git a/Code/Mantid/Vates/VatesAPI/inc/MantidVatesAPI/MDEWRebinningPresenter.h b/Code/Mantid/Vates/VatesAPI/inc/MantidVatesAPI/MDEWRebinningPresenter.h deleted file mode 100644 index 159b93f49c5c..000000000000 --- a/Code/Mantid/Vates/VatesAPI/inc/MantidVatesAPI/MDEWRebinningPresenter.h +++ /dev/null @@ -1,142 +0,0 @@ -#ifndef MDEW_REBINNING_PRESENTER_H -#define MDEW_REBINNING_PRESENTER_H - -#include "MantidVatesAPI/MDRebinningPresenter.h" -#include "MantidGeometry/MDGeometry/MDImplicitFunction.h" -#include "MantidVatesAPI/MetadataJsonManager.h" -#include "MantidVatesAPI/RebinningKnowledgeSerializer.h" -#include "MantidVatesAPI/VatesConfigurations.h" -#include "MantidVatesAPI/vtkDataSetToGeometry.h" -#include -#include "MantidKernel/VMD.h" - -class vtkPlane; -namespace Mantid -{ - - namespace VATES - { - - /** - @class MDEWRebinningPresenter - Concrete MDRebinningPresenter using centre piece rebinning directly on MDEWs producing Histogrammed MDWs. - @author Owen Arnold, Tessella plc - @date 10/08/2011 - - Copyright © 2010 ISIS Rutherford Appleton Laboratory, NScD Oak Ridge National Laboratory & European Spallation Source - - This file is part of Mantid. - - Mantid is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - Mantid is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . - - File change history is stored at: - Code Documentation is available at: - */ - - class MDRebinningView; - class RebinningActionManager; - class WorkspaceProvider; - - class DLLExport MDEWRebinningPresenter : public MDRebinningPresenter - { - public: - - /*----------------------------------- MDRebinningPresenter methods -------------------------------------*/ - - virtual void updateModel(); - - virtual vtkDataSet* execute(vtkDataSetFactory* factory, ProgressAction& rebinningProgressUpdate, ProgressAction& drawingProgressUpdate); - - virtual const std::string& getAppliedGeometryXML() const; - - bool hasTDimensionAvailable() const; - - std::vector getTimeStepValues() const; - - std::string getTimeStepLabel() const; - - virtual void makeNonOrthogonal(vtkDataSet* visualDataSet); - - virtual void setAxisLabels(vtkDataSet* visualDataSet); - - virtual const std::string& getInstrument() const; - - virtual double getMaxValue() const; - - virtual double getMinValue() const; - - /*-----------------------------------End MDRebinningPresenter methods -------------------------------------*/ - - MDEWRebinningPresenter(vtkDataSet* input, RebinningActionManager* request, MDRebinningView* view, const WorkspaceProvider& wsProvider); - - virtual ~MDEWRebinningPresenter(); - - private: - - void persistReductionKnowledge(vtkDataSet* out_ds, const RebinningKnowledgeSerializer& xmlGenerator, const char* id); - std::string extractFormattedPropertyFromDimension(Mantid::Geometry::IMDDimension_sptr dimension) const; - std::string extractFormattedPropertyFromDimension(const Mantid::Kernel::V3D& basis, const size_t totalNDims, double length, Mantid::Geometry::IMDDimension_sptr dimension) const; - void addFunctionKnowledge(); - - ///Parser used to process input vtk to extract metadata. - vtkDataSetToGeometry m_inputParser; - ///Input vtk dataset. - vtkDataSet* m_input; - ///Request, encapsulating priorisation of requests made for rebinning/redrawing. - boost::scoped_ptr m_request; - ///The view of this MVP pattern. - MDRebinningView* m_view; - ///Maximum threshold - signal_t m_maxThreshold; - ///Minimum threshold - signal_t m_minThreshold; - ///The current timestep. - double m_timestep; - ///The workspace geometry. Cached value. - mutable std::string m_wsGeometry; - ///Serializer of rebinning - RebinningKnowledgeSerializer m_serializer; - /// Function - Mantid::Geometry::MDImplicitFunction_sptr m_function; - /// Flag indicating that clipping should be used. - bool m_applyClipping; - /// Origin - Mantid::Kernel::V3D m_origin; - /// b1 direction vector - Mantid::Kernel::V3D m_b1; - /// b2 direction vector - Mantid::Kernel::V3D m_b2; - /// length b1 - double m_lengthB1; - /// length b2 - double m_lengthB2; - /// length b3 - double m_lengthB3; - /// ForceOrthogonal coords - bool m_ForceOrthogonal; - /// Force output in terms of a histogram workspace. Decides which rebinning algorithm to use. - bool m_bOutputHistogramWS; - /// Tag for the rebinned workspace - static const std::string rb_tag; - /// Store for the instrument - mutable std::string m_instrument; - /// Pointer to the manager for json metadata - boost::scoped_ptr m_metadataJsonManager; - /// Pointer to the vates configuration object - boost::scoped_ptr m_vatesConfigurations; - }; - } -} - -#endif diff --git a/Code/Mantid/Vates/VatesAPI/inc/MantidVatesAPI/MDRebinningPresenter.h b/Code/Mantid/Vates/VatesAPI/inc/MantidVatesAPI/MDRebinningPresenter.h deleted file mode 100644 index e73dc31f5f0c..000000000000 --- a/Code/Mantid/Vates/VatesAPI/inc/MantidVatesAPI/MDRebinningPresenter.h +++ /dev/null @@ -1,64 +0,0 @@ -#ifndef MANTID_VATES_MD_REBINNING_PRESENTER -#define MANTID_VATES_MD_REBINNING_PRESENTER - -#include "MantidKernel/System.h" -#include -#include -#include "vtkDataSet.h" -#include - -class vtkUnstructuredGrid; -namespace Mantid -{ - namespace VATES - { - class ProgressAction; - class vtkDataSetFactory; - /** - @class MDRebinningPresenter - Abstract presenters for multi-dimensional rebinning of various types. - @author Owen Arnold, Tessella plc - @date 03/06/2011 - - Copyright © 2010 ISIS Rutherford Appleton Laboratory, NScD Oak Ridge National Laboratory & European Spallation Source - - This file is part of Mantid. - - Mantid is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - Mantid is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . - - File change history is stored at: - Code Documentation is available at: - */ - class DLLExport MDRebinningPresenter - { - public: - virtual void updateModel() = 0; - virtual vtkDataSet* execute(vtkDataSetFactory* factory, ProgressAction& rebinningActionReporting, ProgressAction& drawingActionReporting ) = 0; - virtual const std::string& getAppliedGeometryXML() const = 0; - virtual bool hasTDimensionAvailable() const = 0; - virtual std::vector getTimeStepValues() const = 0; - virtual std::string getTimeStepLabel() const = 0; - virtual void makeNonOrthogonal(vtkDataSet* visualDataSet) = 0; - virtual void setAxisLabels(vtkDataSet* visualDataSet) = 0; - virtual ~MDRebinningPresenter(){} - virtual const std::string& getInstrument() const = 0; - virtual double getMaxValue() const = 0; - virtual double getMinValue() const = 0; - }; - - typedef boost::shared_ptr MDRebinningPresenter_sptr; - } -} - -#endif diff --git a/Code/Mantid/Vates/VatesAPI/inc/MantidVatesAPI/MDRebinningView.h b/Code/Mantid/Vates/VatesAPI/inc/MantidVatesAPI/MDRebinningView.h deleted file mode 100644 index 9cdd6b42bbb5..000000000000 --- a/Code/Mantid/Vates/VatesAPI/inc/MantidVatesAPI/MDRebinningView.h +++ /dev/null @@ -1,61 +0,0 @@ -#ifndef MANTID_VATES_MD_REBINNING_VIEW -#define MANTID_VATES_MD_REBINNING_VIEW - -#include "MantidKernel/System.h" -#include "MantidKernel/V3D.h" - -class vtkImplicitFunction; -namespace Mantid -{ - namespace VATES - { - - /** - @class MDRebinningView - Abstract view for controlling multi-dimensional rebinning. - @author Owen Arnold, Tessella plc - @date 03/06/2011 - - Copyright © 2010 ISIS Rutherford Appleton Laboratory, NScD Oak Ridge National Laboratory & European Spallation Source - - This file is part of Mantid. - - Mantid is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - Mantid is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . - - File change history is stored at: - Code Documentation is available at: - */ - class DLLExport MDRebinningView - { - public: - virtual double getMaxThreshold() const = 0; - virtual double getMinThreshold() const = 0; - virtual bool getApplyClip() const = 0; - virtual double getTimeStep() const = 0; - virtual Mantid::Kernel::V3D getOrigin() const = 0; - virtual Mantid::Kernel::V3D getB1() const = 0; - virtual Mantid::Kernel::V3D getB2() const = 0; - virtual double getLengthB1() const = 0; - virtual double getLengthB2() const = 0; - virtual double getLengthB3() const = 0; - virtual bool getForceOrthogonal() const = 0; - virtual bool getOutputHistogramWS() const = 0; - virtual const char* getAppliedGeometryXML() const = 0; - virtual void updateAlgorithmProgress(double, const std::string&) = 0; - virtual ~MDRebinningView(){} - }; - } -} - -#endif diff --git a/Code/Mantid/Vates/VatesAPI/inc/MantidVatesAPI/MDRebinningViewAdapter.h b/Code/Mantid/Vates/VatesAPI/inc/MantidVatesAPI/MDRebinningViewAdapter.h deleted file mode 100644 index 56d8d89f46ad..000000000000 --- a/Code/Mantid/Vates/VatesAPI/inc/MantidVatesAPI/MDRebinningViewAdapter.h +++ /dev/null @@ -1,129 +0,0 @@ -#ifndef MANTID_VATES_MD_REBINNING_VIEW_ADAPTER_H -#define MANTID_VATES_MD_REBINNING_VIEW_ADAPTER_H - -#include "MantidVatesAPI/MDRebinningView.h" - -class vtkImplicitFunction; -namespace Mantid -{ - namespace VATES - { - - /** - @class MDRebinningViewAdapter - Adapter for non-MDRebinningView types that need to be used as MDRebinningViews. See Adapter pattern. - @author Owen Arnold, Tessella plc - @date 07/09/2011 - - Copyright © 2010 ISIS Rutherford Appleton Laboratory, NScD Oak Ridge National Laboratory & European Spallation Source - - This file is part of Mantid. - - Mantid is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - Mantid is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . - - File change history is stored at: - Code Documentation is available at: - */ - template - class DLLExport MDRebinningViewAdapter : public MDRebinningView - { - private: - - ViewType* m_adaptee; - - public: - - MDRebinningViewAdapter(ViewType* adaptee) : m_adaptee(adaptee) - { - } - - virtual bool getForceOrthogonal() const - { - return m_adaptee->getForceOrthogonal(); - } - - virtual Mantid::Kernel::V3D getOrigin() const - { - return m_adaptee->getOrigin(); - } - - virtual Mantid::Kernel::V3D getB1() const - { - return m_adaptee->getB1(); - } - - virtual Mantid::Kernel::V3D getB2() const - { - return m_adaptee->getB2(); - } - - virtual double getLengthB1() const - { - return m_adaptee->getLengthB1(); - } - - virtual double getLengthB2() const - { - return m_adaptee->getLengthB2(); - } - - virtual double getLengthB3() const - { - return m_adaptee->getLengthB3(); - } - - virtual double getMaxThreshold() const - { - return m_adaptee->getMaxThreshold(); - } - - virtual double getMinThreshold() const - { - return m_adaptee->getMinThreshold(); - } - - virtual bool getApplyClip() const - { - return m_adaptee->getApplyClip(); - } - - virtual double getTimeStep() const - { - return m_adaptee->getTimeStep(); - } - - virtual const char* getAppliedGeometryXML() const - { - return m_adaptee->getAppliedGeometryXML(); - } - - virtual void updateAlgorithmProgress(double progress, const std::string& message) - { - return m_adaptee->updateAlgorithmProgress(progress, message); - } - - virtual bool getOutputHistogramWS() const - { - return m_adaptee->getOutputHistogramWS(); - } - - virtual ~MDRebinningViewAdapter() - { - //Do not delete adaptee. - } - }; - } -} - -#endif diff --git a/Code/Mantid/Vates/VatesAPI/inc/MantidVatesAPI/NullRebinningPresenter.h b/Code/Mantid/Vates/VatesAPI/inc/MantidVatesAPI/NullRebinningPresenter.h deleted file mode 100644 index 33313ff473fe..000000000000 --- a/Code/Mantid/Vates/VatesAPI/inc/MantidVatesAPI/NullRebinningPresenter.h +++ /dev/null @@ -1,48 +0,0 @@ -#ifndef MANTID_VATES_NULL_REBINNING_PRESENTER -#define MANTID_VATES_NULL_REBINNING_PRESENTER -#include "MantidVatesAPI/MDRebinningPresenter.h" -namespace Mantid -{ - namespace VATES - { - class DLLExport NullRebinningPresenter : public MDRebinningPresenter - { - public: - - NullRebinningPresenter(); - - virtual void updateModel(); - - virtual vtkDataSet* execute(vtkDataSetFactory*, ProgressAction&, ProgressAction&); - - virtual const std::string& getAppliedGeometryXML() const; - - virtual std::vector getTimeStepValues() const; - - virtual std::string getTimeStepLabel() const; - - virtual bool hasTDimensionAvailable() const; - - virtual void makeNonOrthogonal(vtkDataSet *visualDataSet); - - virtual void setAxisLabels(vtkDataSet* visualDataSet); - - virtual const std::string& getInstrument() const; - - virtual double getMaxValue() const; - - virtual double getMinValue() const; - - virtual ~NullRebinningPresenter(); - - private: - - NullRebinningPresenter(const NullRebinningPresenter&); - - NullRebinningPresenter& operator=(const NullRebinningPresenter&); - - }; - } -} - -#endif diff --git a/Code/Mantid/Vates/VatesAPI/inc/MantidVatesAPI/RebinningActionManager.h b/Code/Mantid/Vates/VatesAPI/inc/MantidVatesAPI/RebinningActionManager.h deleted file mode 100644 index 25bfe125e5b3..000000000000 --- a/Code/Mantid/Vates/VatesAPI/inc/MantidVatesAPI/RebinningActionManager.h +++ /dev/null @@ -1,31 +0,0 @@ -/* - * RebinningActionManager.h - * - * Created on: 17 Apr 2011 - * Author: owen - */ - -#ifndef REBINNINGACTIONMANAGER_H_ -#define REBINNINGACTIONMANAGER_H_ - -#include "MantidVatesAPI/Common.h" -#include "MantidKernel/System.h" - -namespace Mantid -{ -namespace VATES -{ -class DLLExport RebinningActionManager -{ -public: - virtual void ask(RebinningIterationAction requestedAction) = 0; - virtual RebinningIterationAction action() const = 0; - virtual void reset() = 0; - virtual ~RebinningActionManager() - { - } -}; -} -} - -#endif /* REBINNINGACTIONMANAGER_H_ */ diff --git a/Code/Mantid/Vates/VatesAPI/inc/MantidVatesAPI/RebinningKnowledgeSerializer.h b/Code/Mantid/Vates/VatesAPI/inc/MantidVatesAPI/VatesKnowledgeSerializer.h similarity index 88% rename from Code/Mantid/Vates/VatesAPI/inc/MantidVatesAPI/RebinningKnowledgeSerializer.h rename to Code/Mantid/Vates/VatesAPI/inc/MantidVatesAPI/VatesKnowledgeSerializer.h index 65a38176f462..9d8d4eb8e09f 100644 --- a/Code/Mantid/Vates/VatesAPI/inc/MantidVatesAPI/RebinningKnowledgeSerializer.h +++ b/Code/Mantid/Vates/VatesAPI/inc/MantidVatesAPI/VatesKnowledgeSerializer.h @@ -1,5 +1,5 @@ -#ifndef VATES_REBINNING_KNOWLEDGE_SERIALIZER_H -#define VATES_REBINNING_KNOWLEDGE_SERIALIZER_H +#ifndef VATES_KNOWLEDGE_SERIALIZER_H +#define VATES_KNOWLEDGE_SERIALIZER_H #include #include @@ -24,8 +24,7 @@ enum LocationPolicy{LocationMandatory, LocationNotRequired}; /** - This type assists with the generation of well-formed xml meeting the xsd scehema layed-out for - Rebinning/cutting type operations. The individual components utilised here may not be able to form well-formed + This type assists with the generation of well-formed xml meeting the xsd scehema. The individual components utilised here may not be able to form well-formed xml in their own right and therefore do not have a toXMLString method. This implementation is based on a builder pattern using the create mechanism for xml string generation. @@ -53,7 +52,7 @@ enum LocationPolicy{LocationMandatory, LocationNotRequired}; File change history is stored at: Code Documentation is available at: */ -class DLLExport RebinningKnowledgeSerializer +class DLLExport VatesKnowledgeSerializer { private: @@ -66,7 +65,7 @@ class DLLExport RebinningKnowledgeSerializer LocationPolicy m_locationPolicy; public: - RebinningKnowledgeSerializer(LocationPolicy locationPolicy=LocationMandatory); + VatesKnowledgeSerializer(LocationPolicy locationPolicy=LocationMandatory); /// Set the implicit function to use called. void setImplicitFunction(boost::shared_ptr spFunction); diff --git a/Code/Mantid/Vates/VatesAPI/inc/MantidVatesAPI/RebinningCutterXMLDefinitions.h b/Code/Mantid/Vates/VatesAPI/inc/MantidVatesAPI/VatesXMLDefinitions.h similarity index 96% rename from Code/Mantid/Vates/VatesAPI/inc/MantidVatesAPI/RebinningCutterXMLDefinitions.h rename to Code/Mantid/Vates/VatesAPI/inc/MantidVatesAPI/VatesXMLDefinitions.h index 37f72a9e3625..acc7112d1dc6 100644 --- a/Code/Mantid/Vates/VatesAPI/inc/MantidVatesAPI/RebinningCutterXMLDefinitions.h +++ b/Code/Mantid/Vates/VatesAPI/inc/MantidVatesAPI/VatesXMLDefinitions.h @@ -1,5 +1,5 @@ -#ifndef REBINNINGCUTTERXMLDEFINITIONS_H_ -#define REBINNINGCUTTERXMLDEFINITIONS_H_ +#ifndef VATESXMLDEFINITIONS_H_ +#define VATESXMLDEFINITIONS_H_ #include #include "MantidKernel/System.h" @@ -10,7 +10,7 @@ namespace VATES /** - This type contains definitions that will be found in the xml schema for the rebinning instructions, but must be used in + This type contains definitions that will be found in the xml schema of VATES, but must be used in code as part of the peristance/fetching routines. This file provides a single location for definitions to aid future maintenance. @author Owen Arnold, Tessella plc diff --git a/Code/Mantid/Vates/VatesAPI/inc/MantidVatesAPI/vtkNullUnstructuredGrid.h b/Code/Mantid/Vates/VatesAPI/inc/MantidVatesAPI/vtkNullUnstructuredGrid.h new file mode 100644 index 000000000000..c797b599f630 --- /dev/null +++ b/Code/Mantid/Vates/VatesAPI/inc/MantidVatesAPI/vtkNullUnstructuredGrid.h @@ -0,0 +1,50 @@ +#ifndef VATES_VTK_NULL_DATA_SET +#define VATES_VTK_NULL_DATA_SET + +#include "MantidKernel/System.h" + +class vtkUnstructuredGrid; + +namespace Mantid { +namespace VATES { + +/** Generates a vtkUnstructuredGrid with a single point. Note that this is not a + Null + Object for a vtkDataSet. + + @date 25/02/2015 + + Copyright © 2012 ISIS Rutherford Appleton Laboratory, NScD Oak Ridge + National Laboratory & European Spallation Source + + This file is part of Mantid. + + Mantid is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + Mantid is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + + File change history is stored at: + Code Documentation is available at: +*/ + +class DLLExport vtkNullUnstructuredGrid { + +public: + vtkNullUnstructuredGrid(); + + ~vtkNullUnstructuredGrid(); + + vtkUnstructuredGrid *createNullData(); +}; +} +} +#endif \ No newline at end of file diff --git a/Code/Mantid/Vates/VatesAPI/src/Clipper.cpp b/Code/Mantid/Vates/VatesAPI/src/Clipper.cpp deleted file mode 100644 index 7aa867cbf750..000000000000 --- a/Code/Mantid/Vates/VatesAPI/src/Clipper.cpp +++ /dev/null @@ -1,13 +0,0 @@ -#include "MantidVatesAPI/Clipper.h" - -namespace Mantid -{ -namespace VATES -{ - -Clipper::~Clipper() -{ -} - -} -} diff --git a/Code/Mantid/Vates/VatesAPI/src/EscalatingRebinningActionManager.cpp b/Code/Mantid/Vates/VatesAPI/src/EscalatingRebinningActionManager.cpp deleted file mode 100644 index 4e2ba4abe03f..000000000000 --- a/Code/Mantid/Vates/VatesAPI/src/EscalatingRebinningActionManager.cpp +++ /dev/null @@ -1,49 +0,0 @@ -#include "MantidVatesAPI/EscalatingRebinningActionManager.h" - -namespace Mantid -{ -namespace VATES -{ - - -/* -Constructor -@param action : optional starting action. -*/ -EscalatingRebinningActionManager::EscalatingRebinningActionManager(RebinningIterationAction action) : - m_currentAction(action) -{ -} - - /** Request that some level of action is peformed. - * @param requestedAction */ -void EscalatingRebinningActionManager::ask(RebinningIterationAction requestedAction) -{ - //Very simply, only allow escalation if the requested action is more 'severe' than the current one. - if (requestedAction > m_currentAction) - { - m_currentAction = requestedAction; - } -} - -/** Get the selected action. - * @return the selected action - */ -RebinningIterationAction EscalatingRebinningActionManager::action() const -{ - return m_currentAction; -} - -///Reset the escalation path to the minimum level. -void EscalatingRebinningActionManager::reset() -{ - m_currentAction = UseCache; -} - -///Destructor -EscalatingRebinningActionManager::~EscalatingRebinningActionManager() -{ -} - -} -} diff --git a/Code/Mantid/Vates/VatesAPI/src/MDEWLoadingPresenter.cpp b/Code/Mantid/Vates/VatesAPI/src/MDEWLoadingPresenter.cpp index c104b6ffbf12..b0e7cb9bdd5c 100644 --- a/Code/Mantid/Vates/VatesAPI/src/MDEWLoadingPresenter.cpp +++ b/Code/Mantid/Vates/VatesAPI/src/MDEWLoadingPresenter.cpp @@ -3,12 +3,12 @@ #include "MantidAPI/FrameworkManager.h" #include "MantidGeometry/MDGeometry/NullImplicitFunction.h" -#include "MantidVatesAPI/RebinningKnowledgeSerializer.h" +#include "MantidVatesAPI/VatesKnowledgeSerializer.h" #include "MantidVatesAPI/MetaDataExtractorUtils.h" #include "MantidVatesAPI/MetadataJsonManager.h" #include "MantidVatesAPI/MetadataToFieldData.h" +#include "MantidVatesAPI/VatesXMLDefinitions.h" #include "MantidVatesAPI/VatesConfigurations.h" -#include "MantidVatesAPI/RebinningCutterXMLDefinitions.h" #include "MantidVatesAPI/Common.h" #include @@ -155,7 +155,7 @@ namespace Mantid vtkFieldData* outputFD = vtkFieldData::New(); //Serialize metadata - RebinningKnowledgeSerializer serializer(LocationNotRequired); + VatesKnowledgeSerializer serializer(LocationNotRequired); serializer.setWorkspaceName(wsName); serializer.setGeometryXML(xmlBuilder.create()); serializer.setImplicitFunction( Mantid::Geometry::MDImplicitFunction_sptr(new Mantid::Geometry::NullImplicitFunction())); diff --git a/Code/Mantid/Vates/VatesAPI/src/MDEWRebinningPresenter.cpp b/Code/Mantid/Vates/VatesAPI/src/MDEWRebinningPresenter.cpp deleted file mode 100644 index 851019910bc1..000000000000 --- a/Code/Mantid/Vates/VatesAPI/src/MDEWRebinningPresenter.cpp +++ /dev/null @@ -1,532 +0,0 @@ -#include "MantidVatesAPI/MDEWRebinningPresenter.h" -#include "MantidVatesAPI/MDRebinningView.h" -#include "MantidGeometry/MDGeometry/MDGeometryXMLDefinitions.h" -#include "MantidGeometry/MDGeometry/MDGeometryXMLBuilder.h" -#include "MantidGeometry/MDGeometry/CompositeImplicitFunction.h" -#include "MantidGeometry/MDGeometry/NullImplicitFunction.h" -#include "MantidVatesAPI/RebinningActionManager.h" -#include "MantidVatesAPI/ProgressAction.h" -#include "MantidVatesAPI/vtkDataSetToGeometry.h" -#include "MantidVatesAPI/RebinningCutterXMLDefinitions.h" -#include "MantidVatesAPI/FieldDataToMetadata.h" -#include "MantidVatesAPI/MetadataToFieldData.h" -#include "MantidVatesAPI/MetadataJsonManager.h" -#include "MantidVatesAPI/vtkDataSetFactory.h" -#include "MantidVatesAPI/WorkspaceProvider.h" -#include "MantidVatesAPI/vtkDataSetToImplicitFunction.h" -#include "MantidVatesAPI/vtkDataSetToNonOrthogonalDataSet.h" -#include "MantidVatesAPI/vtkDataSetToWsLocation.h" -#include "MantidVatesAPI/vtkDataSetToWsName.h" -#include "MantidVatesAPI/VatesConfigurations.h" -#include "MantidVatesAPI/Common.h" -#include "MantidAPI/AlgorithmManager.h" -#include "MantidAPI/ImplicitFunctionFactory.h" -#include "MantidKernel/VMD.h" -#include -#include -#include - -using namespace Mantid::API; -using namespace Mantid::Kernel; - -namespace Mantid -{ - namespace VATES - { - const std::string MDEWRebinningPresenter::rb_tag = "_visual_md"; - - /** - Constructor. - @param input : input vtk dataset containing existing metadata. - @param request : object performing decision making on what rebinning action to take. - @param view : mvp view handle to use. - @param wsProvider : ref to object used to determine the availability of the correct ws for this prsenter to work on. - */ - MDEWRebinningPresenter::MDEWRebinningPresenter(vtkDataSet* input, RebinningActionManager* request, MDRebinningView* view, const WorkspaceProvider& wsProvider) : - m_inputParser(input), - m_input(input), - m_request(request), - m_view(view), - m_maxThreshold(0), - m_minThreshold(0), - m_timestep(0), - m_wsGeometry(""), - m_serializer(LocationNotRequired), - m_function(Mantid::Geometry::MDImplicitFunction_sptr(new Mantid::Geometry::NullImplicitFunction())), - m_applyClipping(false), - m_lengthB1(1), - m_lengthB2(1), - m_lengthB3(1), - m_ForceOrthogonal(true), - m_bOutputHistogramWS(true), - m_instrument(""), - m_metadataJsonManager(new MetadataJsonManager()), - m_vatesConfigurations(new VatesConfigurations()) - { - using namespace Mantid::API; - vtkFieldData* fd = input->GetFieldData(); - if(NULL == fd || NULL == fd->GetArray(XMLDefinitions::metaDataId().c_str())) - { - throw std::logic_error("Rebinning operations require Rebinning Metadata"); - } - std::string wsName = vtkDataSetToWsName::exec(m_input); - if(!wsProvider.canProvideWorkspace(wsName)) - { - throw std::invalid_argument("Wrong type of Workspace stored. Cannot handle with this presenter"); - } - - vtkDataSetToGeometry parser(input); - parser.execute(); - - using Mantid::Geometry::MDGeometryBuilderXML; - using Mantid::Geometry::NoDimensionPolicy; - MDGeometryBuilderXML xmlBuilder; - - Mantid::Geometry::VecIMDDimension_sptr dimensions =parser.getAllDimensions(); - DimensionVec::iterator it = dimensions.begin(); - for(;it != dimensions.end(); ++it) - { - xmlBuilder.addOrdinaryDimension(*it); - } - if(parser.hasXDimension()) - { - xmlBuilder.addXDimension(parser.getXDimension()); - } - if(parser.hasYDimension()) - { - xmlBuilder.addYDimension(parser.getYDimension()); - } - if(parser.hasZDimension()) - { - xmlBuilder.addZDimension(parser.getZDimension()); - } - if(parser.hasTDimension()) - { - xmlBuilder.addTDimension(parser.getTDimension()); - } - - //Apply the geometry. - m_serializer.setGeometryXML(xmlBuilder.create()); - //Apply the workspace name after extraction from the input xml. - m_serializer.setWorkspaceName( wsName); - - // Extract Json metadata from the field data - if(NULL == fd || NULL == fd->GetArray(m_vatesConfigurations->getMetadataIdJson().c_str())) - { - throw std::logic_error("Rebinning operations require Rebinning Json Metadata"); - } - - FieldDataToMetadata fieldDataToMetadata; - - std::string jsonString = fieldDataToMetadata(fd, m_vatesConfigurations->getMetadataIdJson()); - m_metadataJsonManager->readInSerializedJson(jsonString); - - m_instrument = m_metadataJsonManager->getInstrument(); - } - - /// Destructor - MDEWRebinningPresenter::~MDEWRebinningPresenter() - { - delete m_view; - } - - /* - Records and accumulates function knowledge so that it can be seralized to xml later. - */ - void MDEWRebinningPresenter::addFunctionKnowledge() - { - //Add existing functions. - Mantid::Geometry::CompositeImplicitFunction* compFunction = new Mantid::Geometry::CompositeImplicitFunction; - compFunction->addFunction(m_function); - Mantid::Geometry::MDImplicitFunction* existingFunctions = vtkDataSetToImplicitFunction::exec(m_input); - if (existingFunctions != NULL) - { - compFunction->addFunction(Mantid::Geometry::MDImplicitFunction_sptr(existingFunctions)); - } - //Apply the implicit function. - m_serializer.setImplicitFunction(Mantid::Geometry::MDImplicitFunction_sptr(compFunction)); - } - - /** - Uses the state of the MVP view to determine what rebinning action to take next. Also updates the internal - members according to the state of the view so that the 'Delta' between the view and this presenter can - be compared and determined again at a later point. - */ - void MDEWRebinningPresenter::updateModel() - { - if(m_view->getTimeStep() != m_timestep) - { - m_request->ask(RecalculateVisualDataSetOnly); - } - if(m_view->getMaxThreshold() != m_maxThreshold) - { - m_request->ask(RecalculateVisualDataSetOnly); - } - if(m_view->getMinThreshold() != m_minThreshold) - { - m_request->ask(RecalculateVisualDataSetOnly); - } - const bool bOutputHistogramWS = m_view->getOutputHistogramWS(); - if(bOutputHistogramWS != m_bOutputHistogramWS) - { - m_request->ask(RecalculateAll); - } - - bool hasAppliedClipping = m_view->getApplyClip(); - - //Recalculation is always required if this property is toggled. - if(m_applyClipping != hasAppliedClipping) - { - m_applyClipping = hasAppliedClipping; - m_request->ask(RecalculateAll); - } - - //Should always do clipping comparison if clipping has been set to on. - if(m_applyClipping == true) - { - using Mantid::Kernel::V3D; - //Check all parameters, which define the clipping. - V3D temp_origin = m_view->getOrigin(); - V3D temp_b1 = m_view->getB1(); - V3D temp_b2 = m_view->getB2(); - double temp_length_b1 = m_view->getLengthB1(); - double temp_length_b2 = m_view->getLengthB2(); - double temp_length_b3 = m_view->getLengthB3(); - - if(temp_origin != m_origin) - { - m_request->ask(RecalculateAll); - } - if(temp_b1 != m_b1) - { - m_request->ask(RecalculateAll); - } - if(temp_b2 != m_b2) - { - m_request->ask(RecalculateAll); - } - if(temp_length_b1 != m_lengthB1) - { - m_request->ask(RecalculateAll); - } - if(temp_length_b2 != m_lengthB2) - { - m_request->ask(RecalculateAll); - } - if(temp_length_b3 != m_lengthB3) - { - m_request->ask(RecalculateAll); - } - if(m_view->getForceOrthogonal() != m_ForceOrthogonal) - { - m_request->ask(RecalculateAll); - } - //Update coord transform fields. - m_origin = temp_origin; - m_b1 = temp_b1; - m_b2 = temp_b2; - m_lengthB1 = temp_length_b1; - m_lengthB2 = temp_length_b2; - m_lengthB3 = temp_length_b3; - m_ForceOrthogonal = m_view->getForceOrthogonal(); - m_bOutputHistogramWS = m_view->getOutputHistogramWS(); - } - - if(m_view->getAppliedGeometryXML() != m_serializer.getWorkspaceGeometry()) - { - m_request->ask(RecalculateAll); - } - - //Update the presenter fields. - m_timestep = m_view->getTimeStep(); - m_maxThreshold = m_view->getMaxThreshold(); - m_minThreshold = m_view->getMinThreshold(); - m_applyClipping = hasAppliedClipping; - m_bOutputHistogramWS = bOutputHistogramWS; - addFunctionKnowledge(); //calls m_serializer.setImplicitFunction() - m_serializer.setGeometryXML( m_view->getAppliedGeometryXML() ); - } - - /** Mantid properties for rebinning algorithm require formatted information. - * This is for the AlignedDim0... props - @param dimension : dimension to extract property value for. - @return true available, false otherwise. - */ - std::string MDEWRebinningPresenter::extractFormattedPropertyFromDimension(Mantid::Geometry::IMDDimension_sptr dimension) const - { - double min = dimension->getMinimum(); - double max = dimension->getMaximum(); - size_t nbins = dimension->getNBins(); - std::string id = dimension->getDimensionId(); - return boost::str(boost::format("%s, %f, %f, %d") %id %min %max % nbins); - } - - /** Mantid properties for rebinning algorithm require formatted information. - * This is for the BasisVector0... parameters - * - @param basis : basis vector. - @param totalNDims : total number of dimensions. - @param length : length of vector? - @param dimension : dimension to extract property value for. - @return true available, false otherwise. - */ - std::string MDEWRebinningPresenter::extractFormattedPropertyFromDimension(const Mantid::Kernel::V3D& basis, const size_t totalNDims, double length, Mantid::Geometry::IMDDimension_sptr dimension) const - { - UNUSED_ARG(length); - - MantidVec localBasis(3); - localBasis[0] = basis.X(); - localBasis[1] = basis.Y(); - localBasis[2] = basis.Z(); - size_t nAdditionalDimensions = totalNDims - 3; - if(nAdditionalDimensions >= 1) - { - for(size_t i = 0; i < nAdditionalDimensions; ++i) - { - localBasis.push_back(0); - } - } - - std::string units = dimension->getUnits(); - std::string id = dimension->getDimensionId(); - return boost::str(boost::format("%s, %s, %s") %id %units %VMD(localBasis).toString(",") ); - } - - /** - Direct Mantid Algorithms and Workspaces to produce a visual dataset. - @param factory : Factory, or chain of factories used for Workspace to VTK dataset conversion. - @param rebinningProgressUpdate : Handler for GUI updates while algorithm progresses. - @param drawingProgressUpdate : Handler for GUI updates while vtkDataSetFactory::create occurs. - */ - vtkDataSet* MDEWRebinningPresenter::execute(vtkDataSetFactory* factory, ProgressAction& rebinningProgressUpdate, ProgressAction& drawingProgressUpdate) - { - std::string wsName = m_serializer.getWorkspaceName(); - - std::string outWsName = wsName + rb_tag; - - using namespace Mantid::API; - if(RecalculateAll == m_request->action()) - { - Mantid::Geometry::MDGeometryXMLParser sourceGeometry(m_view->getAppliedGeometryXML()); - sourceGeometry.execute(); - - IAlgorithm_sptr binningAlg = m_bOutputHistogramWS ? AlgorithmManager::Instance().create("BinMD") : AlgorithmManager::Instance().create("SliceMD"); - binningAlg->initialize(); - binningAlg->setPropertyValue("InputWorkspace", wsName); - if(!m_bOutputHistogramWS) - { - //SliceMD only! This means that iterators will only go through top-level boxes. So iterators will always hit boxes worth visualising. - binningAlg->setProperty("TakeMaxRecursionDepthFromInput", false); - binningAlg->setProperty("MaxRecursionDepth", 1) ; - } - - if(m_view->getApplyClip()) - { - using namespace Mantid::Kernel; - const size_t totalNDims = sourceGeometry.getAllDimensions().size(); - V3D b3 = m_b1.cross_prod(m_b2); - binningAlg->setPropertyValue("Translation", VMD(m_origin).toString(",") ); - binningAlg->setProperty("AxisAligned", false); - binningAlg->setProperty("ForceOrthogonal", m_ForceOrthogonal ); - std::vector OutputBins; - std::vector OutputExtents; - if(sourceGeometry.hasXDimension()) - { - binningAlg->setPropertyValue("BasisVector0", extractFormattedPropertyFromDimension(m_b1, totalNDims, m_lengthB1, sourceGeometry.getXDimension())); - OutputExtents.push_back(0); - OutputExtents.push_back(m_lengthB1); - OutputBins.push_back(int(sourceGeometry.getXDimension()->getNBins())); - } - if(sourceGeometry.hasYDimension()) - { - binningAlg->setPropertyValue("BasisVector1", extractFormattedPropertyFromDimension(m_b2, totalNDims, m_lengthB2, sourceGeometry.getYDimension())); - OutputExtents.push_back(0); - OutputExtents.push_back(m_lengthB2); - OutputBins.push_back(int(sourceGeometry.getYDimension()->getNBins())); - } - if(sourceGeometry.hasZDimension()) - { - binningAlg->setPropertyValue("BasisVector2", extractFormattedPropertyFromDimension(b3, totalNDims, m_lengthB3, sourceGeometry.getZDimension())); - OutputExtents.push_back(0); - OutputExtents.push_back(m_lengthB3); - OutputBins.push_back(int(sourceGeometry.getYDimension()->getNBins())); - } - if(sourceGeometry.hasTDimension()) - { - // Create a basis vector parallel to the current time vector. - auto dimT = sourceGeometry.getTDimension(); - std::string units = dimT->getUnits(); - std::string id = dimT->getDimensionId(); - std::string formattedTInput = boost::str(boost::format("%s, %s, 0,0,0,1") %id %units); - binningAlg->setPropertyValue("BasisVector3", formattedTInput); - - // Set up extents and bins for this dimension. - OutputExtents.push_back(dimT->getMinimum()); - OutputExtents.push_back(dimT->getMaximum()); - OutputBins.push_back(int(dimT->getNBins())); - - // Overwrite the translation. - binningAlg->setPropertyValue("Translation", boost::str(boost::format("%s, 0") %VMD(m_origin).toString(",")) ); - } - binningAlg->setProperty("OutputExtents", OutputExtents); - binningAlg->setProperty("OutputBins", OutputBins); - } - else - { - binningAlg->setProperty("AxisAligned", true); - if(sourceGeometry.hasXDimension()) - { - binningAlg->setPropertyValue("AlignedDim0", extractFormattedPropertyFromDimension(sourceGeometry.getXDimension())); - } - if(sourceGeometry.hasYDimension()) - { - binningAlg->setPropertyValue("AlignedDim1", extractFormattedPropertyFromDimension(sourceGeometry.getYDimension())); - } - if(sourceGeometry.hasZDimension()) - { - binningAlg->setPropertyValue("AlignedDim2", extractFormattedPropertyFromDimension(sourceGeometry.getZDimension())); - } - if(sourceGeometry.hasTDimension()) - { - binningAlg->setPropertyValue("AlignedDim3", extractFormattedPropertyFromDimension(sourceGeometry.getTDimension())); - } - } - - binningAlg->setPropertyValue("OutputWorkspace", outWsName); - Poco::NObserver observer(rebinningProgressUpdate, &ProgressAction::handler); - //Add observer. - binningAlg->addObserver(observer); - //Run the rebinning algorithm. - binningAlg->setRethrows(true); - binningAlg->execute(); - //Remove observer - binningAlg->removeObserver(observer); - } - - Mantid::API::Workspace_sptr result=Mantid::API::AnalysisDataService::Instance().retrieve(outWsName); - - vtkDataSet* temp = factory->oneStepCreate(result, drawingProgressUpdate); - - // Extract min and max range of the data set and update the json store - double* range = temp->GetScalarRange(); - - if (range) - { - m_metadataJsonManager->setMinValue(range[0]); - m_metadataJsonManager->setMaxValue(range[1]); - } - - persistReductionKnowledge(temp, this->m_serializer, XMLDefinitions::metaDataId().c_str()); - - m_request->reset(); - return temp; - } - - const std::string& MDEWRebinningPresenter::getAppliedGeometryXML() const - { - return m_serializer.getWorkspaceGeometry(); - } - - bool MDEWRebinningPresenter::hasTDimensionAvailable() const - { - Mantid::Geometry::MDGeometryXMLParser sourceGeometry(m_view->getAppliedGeometryXML()); - sourceGeometry.execute(); - return sourceGeometry.hasTDimension(); - } - - std::vector MDEWRebinningPresenter::getTimeStepValues() const - { - Mantid::Geometry::MDGeometryXMLParser sourceGeometry(m_view->getAppliedGeometryXML()); - sourceGeometry.execute(); - - double min = sourceGeometry.getTDimension()->getMinimum(); - double max = sourceGeometry.getTDimension()->getMaximum(); - unsigned int nBins = static_cast(sourceGeometry.getTDimension()->getNBins() ); - double increment = (max - min) / nBins; - std::vector timeStepValues(nBins); - for (unsigned int i = 0; i < nBins; i++) - { - timeStepValues[i] = min + (i * increment); - } - return timeStepValues; - } - - /** - * Create a label for the "time" coordinate - * @return the "time" coordinate label - */ - std::string MDEWRebinningPresenter::getTimeStepLabel() const - { - Mantid::Geometry::MDGeometryXMLParser sourceGeometry(m_view->getAppliedGeometryXML()); - sourceGeometry.execute(); - std::string label = sourceGeometry.getTDimension()->getName(); - label += " ("; - label += sourceGeometry.getTDimension()->getUnits(); - label += ")"; - return label; - } - - void MDEWRebinningPresenter::makeNonOrthogonal(vtkDataSet *visualDataSet) - { - std::string wsName = m_serializer.getWorkspaceName() + rb_tag; - vtkDataSetToNonOrthogonalDataSet converter(visualDataSet, wsName); - converter.execute(); - } - - void MDEWRebinningPresenter::setAxisLabels(vtkDataSet *visualDataSet) - { - Mantid::Geometry::MDGeometryXMLParser sourceGeometry(m_view->getAppliedGeometryXML()); - sourceGeometry.execute(); - vtkFieldData* fieldData = visualDataSet->GetFieldData(); - setAxisLabel("AxisTitleForX", - makeAxisTitle(sourceGeometry.getXDimension()), fieldData); - setAxisLabel("AxisTitleForY", - makeAxisTitle(sourceGeometry.getYDimension()), fieldData); - setAxisLabel("AxisTitleForZ", - makeAxisTitle(sourceGeometry.getZDimension()), fieldData); - } - - void MDEWRebinningPresenter::persistReductionKnowledge(vtkDataSet* out_ds, const - RebinningKnowledgeSerializer& xmlGenerator, const char* id) - { - vtkFieldData* fd = vtkFieldData::New(); - - MetadataToFieldData convert; - convert(fd, xmlGenerator.createXMLString().c_str(), id); - - // Add second entry for Json metadata - std::string jsonMetadata = m_metadataJsonManager->getSerializedJson(); - convert(fd, jsonMetadata, m_vatesConfigurations->getMetadataIdJson()); - - out_ds->SetFieldData(fd); - fd->Delete(); - } - - /** - * Get the maximum value of the data range. - * @returns The maximum value. - */ - double MDEWRebinningPresenter::getMaxValue() const - { - return this->m_metadataJsonManager->getMaxValue(); - } - - /** - * Get the minimum value of the data range. - * @returns The maximum value of the data range. - */ - double MDEWRebinningPresenter::getMinValue() const - { - return this->m_metadataJsonManager->getMinValue(); - } - - /**getM - * Get the instrument associated with the workspace - * @returns The instrument - */ - const std::string& MDEWRebinningPresenter::getInstrument() const - { - return m_instrument; - } - } -} diff --git a/Code/Mantid/Vates/VatesAPI/src/MDHWLoadingPresenter.cpp b/Code/Mantid/Vates/VatesAPI/src/MDHWLoadingPresenter.cpp index 7087e9bc783d..eb113bb20a1d 100644 --- a/Code/Mantid/Vates/VatesAPI/src/MDHWLoadingPresenter.cpp +++ b/Code/Mantid/Vates/VatesAPI/src/MDHWLoadingPresenter.cpp @@ -4,11 +4,11 @@ #include "MantidGeometry/MDGeometry/MDHistoDimension.h" #include "MantidGeometry/MDGeometry/NullImplicitFunction.h" -#include "MantidVatesAPI/RebinningKnowledgeSerializer.h" +#include "MantidVatesAPI/VatesKnowledgeSerializer.h" #include "MantidVatesAPI/MetaDataExtractorUtils.h" #include "MantidVatesAPI/MetadataJsonManager.h" #include "MantidVatesAPI/MetadataToFieldData.h" -#include "MantidVatesAPI/RebinningCutterXMLDefinitions.h" +#include "MantidVatesAPI/VatesXMLDefinitions.h" #include "MantidVatesAPI/VatesConfigurations.h" #include "MantidVatesAPI/vtkDataSetToNonOrthogonalDataSet.h" #include "MantidVatesAPI/vtkDataSetToWsName.h" @@ -150,7 +150,7 @@ namespace Mantid vtkFieldData* outputFD = vtkFieldData::New(); //Serialize metadata - RebinningKnowledgeSerializer serializer(LocationNotRequired); + VatesKnowledgeSerializer serializer(LocationNotRequired); serializer.setWorkspaceName(wsName); serializer.setGeometryXML(xmlBuilder.create()); serializer.setImplicitFunction( Mantid::Geometry::MDImplicitFunction_sptr(new Mantid::Geometry::NullImplicitFunction())); diff --git a/Code/Mantid/Vates/VatesAPI/src/NullRebinningPresenter.cpp b/Code/Mantid/Vates/VatesAPI/src/NullRebinningPresenter.cpp deleted file mode 100644 index b313d1c3ef40..000000000000 --- a/Code/Mantid/Vates/VatesAPI/src/NullRebinningPresenter.cpp +++ /dev/null @@ -1,73 +0,0 @@ -#include "MantidVatesAPI/NullRebinningPresenter.h" -#include -#include - -namespace Mantid -{ - namespace VATES - { - NullRebinningPresenter::NullRebinningPresenter() - { - } - - void NullRebinningPresenter::updateModel() - { - } - - vtkDataSet* NullRebinningPresenter::execute(vtkDataSetFactory*, ProgressAction&, ProgressAction&) - { - throw std::runtime_error("NullRebinningPresenter does not implement this method. Misused"); - } - - const std::string& NullRebinningPresenter::getAppliedGeometryXML() const - { - throw std::runtime_error("NullRebinningPresenter does not implement this method. Misused"); - } - - NullRebinningPresenter::~NullRebinningPresenter() - { - } - - std::vector NullRebinningPresenter::getTimeStepValues() const - { - throw std::runtime_error("NullRebinningPresenter does not implement this method. Misused"); - } - - bool NullRebinningPresenter::hasTDimensionAvailable() const - { - throw std::runtime_error("NullRebinningPresenter does not implement this method. Misused"); - } - - std::string NullRebinningPresenter::getTimeStepLabel() const - { - throw std::runtime_error("NullRebinningPresenter does not implement this method. Misused"); - } - - void NullRebinningPresenter::makeNonOrthogonal(vtkDataSet *visualDataSet) - { - UNUSED_ARG(visualDataSet); - throw std::runtime_error("NullRebinningPresenter does not implement this method. Misused"); - } - - void NullRebinningPresenter::setAxisLabels(vtkDataSet *visualDataSet) - { - UNUSED_ARG(visualDataSet); - throw std::runtime_error("NullRebinningPresenter does not implement this method. Misused"); - } - - const std::string& NullRebinningPresenter::getInstrument() const - { - throw std::runtime_error("NullRebinningPresenter does not implement this method. Misused"); - } - - double NullRebinningPresenter::getMaxValue() const - { - throw std::runtime_error("NullRebinningPresenter does not implement this method. Misused"); - } - - double NullRebinningPresenter::getMinValue() const - { - throw std::runtime_error("NullRebinningPresenter does not implement this method. Misused"); - } - } -} diff --git a/Code/Mantid/Vates/VatesAPI/src/RebinningCutterXMLDefinitions.cpp b/Code/Mantid/Vates/VatesAPI/src/RebinningCutterXMLDefinitions.cpp deleted file mode 100644 index 735d83185fd4..000000000000 --- a/Code/Mantid/Vates/VatesAPI/src/RebinningCutterXMLDefinitions.cpp +++ /dev/null @@ -1,9 +0,0 @@ -#include "MantidVatesAPI/RebinningCutterXMLDefinitions.h" - -namespace Mantid -{ -namespace VATES -{ - -} -} diff --git a/Code/Mantid/Vates/VatesAPI/src/RebinningKnowledgeSerializer.cpp b/Code/Mantid/Vates/VatesAPI/src/VatesKnowledgeSerializer.cpp similarity index 71% rename from Code/Mantid/Vates/VatesAPI/src/RebinningKnowledgeSerializer.cpp rename to Code/Mantid/Vates/VatesAPI/src/VatesKnowledgeSerializer.cpp index 760d78723160..b9e9dcd60006 100644 --- a/Code/Mantid/Vates/VatesAPI/src/RebinningKnowledgeSerializer.cpp +++ b/Code/Mantid/Vates/VatesAPI/src/VatesKnowledgeSerializer.cpp @@ -4,8 +4,8 @@ #include #include #include "MantidGeometry/MDGeometry/MDGeometryXMLDefinitions.h" -#include "MantidVatesAPI/RebinningKnowledgeSerializer.h" -#include "MantidVatesAPI/RebinningCutterXMLDefinitions.h" +#include "MantidVatesAPI/VatesKnowledgeSerializer.h" +#include "MantidVatesAPI/VatesXMLDefinitions.h" using Mantid::Geometry::MDGeometryXMLDefinitions; namespace Mantid @@ -13,7 +13,7 @@ namespace Mantid namespace VATES { -RebinningKnowledgeSerializer::RebinningKnowledgeSerializer(LocationPolicy locationPolicy) : +VatesKnowledgeSerializer::VatesKnowledgeSerializer(LocationPolicy locationPolicy) : m_wsLocationXML(""), m_wsNameXML(""), m_wsName(""), @@ -22,13 +22,13 @@ RebinningKnowledgeSerializer::RebinningKnowledgeSerializer(LocationPolicy locati { } -void RebinningKnowledgeSerializer::setImplicitFunction(boost::shared_ptr spFunction) +void VatesKnowledgeSerializer::setImplicitFunction(boost::shared_ptr spFunction) { this->m_spFunction = spFunction; } /// Set the workspace name to apply. -void RebinningKnowledgeSerializer::setWorkspace(boost::shared_ptr workspace) +void VatesKnowledgeSerializer::setWorkspace(boost::shared_ptr workspace) { this->m_wsNameXML = MDGeometryXMLDefinitions::workspaceNameXMLTagStart() + workspace->getName() + MDGeometryXMLDefinitions::workspaceNameXMLTagEnd(); @@ -36,19 +36,19 @@ void RebinningKnowledgeSerializer::setWorkspace(boost::shared_ptrm_geomXML = workspace->getGeometryXML(); } -void RebinningKnowledgeSerializer::setWorkspaceName(std::string wsName) +void VatesKnowledgeSerializer::setWorkspaceName(std::string wsName) { this->m_wsName = wsName; this->m_wsNameXML = std::string(MDGeometryXMLDefinitions::workspaceNameXMLTagStart() + wsName + MDGeometryXMLDefinitions::workspaceNameXMLTagEnd()); } -void RebinningKnowledgeSerializer::setGeometryXML(std::string geomXML) +void VatesKnowledgeSerializer::setGeometryXML(std::string geomXML) { this->m_geomXML = geomXML; } /// Create the xml string correponding to the set values. -std::string RebinningKnowledgeSerializer::createXMLString() const +std::string VatesKnowledgeSerializer::createXMLString() const { if(true == this->m_geomXML.empty()) @@ -72,22 +72,22 @@ std::string RebinningKnowledgeSerializer::createXMLString() const } } -const std::string& RebinningKnowledgeSerializer::getWorkspaceName() const +const std::string& VatesKnowledgeSerializer::getWorkspaceName() const { return this->m_wsName; } -const std::string& RebinningKnowledgeSerializer::getWorkspaceGeometry() const +const std::string& VatesKnowledgeSerializer::getWorkspaceGeometry() const { return this->m_geomXML; } - bool RebinningKnowledgeSerializer::hasFunctionInfo() const + bool VatesKnowledgeSerializer::hasFunctionInfo() const { return NULL != m_spFunction.get(); } - bool RebinningKnowledgeSerializer::hasGeometryInfo() const + bool VatesKnowledgeSerializer::hasGeometryInfo() const { return !m_geomXML.empty() && !m_wsName.empty(); } diff --git a/Code/Mantid/Vates/VatesAPI/src/VatesXMLDefinitions.cpp b/Code/Mantid/Vates/VatesAPI/src/VatesXMLDefinitions.cpp new file mode 100644 index 000000000000..294fa91ac2ed --- /dev/null +++ b/Code/Mantid/Vates/VatesAPI/src/VatesXMLDefinitions.cpp @@ -0,0 +1,9 @@ +#include "MantidVatesAPI/VatesXMLDefinitions.h" + +namespace Mantid +{ +namespace VATES +{ + +} +} diff --git a/Code/Mantid/Vates/VatesAPI/src/vtkDataSetToGeometry.cpp b/Code/Mantid/Vates/VatesAPI/src/vtkDataSetToGeometry.cpp index 38c18916e0f1..b4f3849d0ab3 100644 --- a/Code/Mantid/Vates/VatesAPI/src/vtkDataSetToGeometry.cpp +++ b/Code/Mantid/Vates/VatesAPI/src/vtkDataSetToGeometry.cpp @@ -1,6 +1,6 @@ #include "MantidVatesAPI/vtkDataSetToGeometry.h" #include "MantidVatesAPI/FieldDataToMetadata.h" -#include "MantidVatesAPI/RebinningCutterXMLDefinitions.h" +#include "MantidVatesAPI/VatesXMLDefinitions.h" #include "MantidGeometry/MDGeometry/MDGeometryXMLDefinitions.h" #include "vtkDataSet.h" diff --git a/Code/Mantid/Vates/VatesAPI/src/vtkDataSetToImplicitFunction.cpp b/Code/Mantid/Vates/VatesAPI/src/vtkDataSetToImplicitFunction.cpp index b950806172a2..628a229023f4 100644 --- a/Code/Mantid/Vates/VatesAPI/src/vtkDataSetToImplicitFunction.cpp +++ b/Code/Mantid/Vates/VatesAPI/src/vtkDataSetToImplicitFunction.cpp @@ -1,6 +1,6 @@ #include "MantidVatesAPI/vtkDataSetToImplicitFunction.h" #include "MantidVatesAPI/FieldDataToMetadata.h" -#include "MantidVatesAPI/RebinningCutterXMLDefinitions.h" +#include "MantidVatesAPI/VatesXMLDefinitions.h" #include "MantidGeometry/MDGeometry/MDGeometryXMLDefinitions.h" #include "MantidAPI/ImplicitFunctionFactory.h" #include "MantidGeometry/MDGeometry/NullImplicitFunction.h" diff --git a/Code/Mantid/Vates/VatesAPI/src/vtkDataSetToScaledDataSet.cpp b/Code/Mantid/Vates/VatesAPI/src/vtkDataSetToScaledDataSet.cpp index e3855b0940f0..21f05328c4f5 100644 --- a/Code/Mantid/Vates/VatesAPI/src/vtkDataSetToScaledDataSet.cpp +++ b/Code/Mantid/Vates/VatesAPI/src/vtkDataSetToScaledDataSet.cpp @@ -68,6 +68,7 @@ namespace VATES } vtkPoints *points = m_inputData->GetPoints(); + double *point; vtkPoints* newPoints = vtkPoints::New(); newPoints->Allocate(points->GetNumberOfPoints()); diff --git a/Code/Mantid/Vates/VatesAPI/src/vtkDataSetToWsLocation.cpp b/Code/Mantid/Vates/VatesAPI/src/vtkDataSetToWsLocation.cpp index 7f0335d50d4a..0644a617dc96 100644 --- a/Code/Mantid/Vates/VatesAPI/src/vtkDataSetToWsLocation.cpp +++ b/Code/Mantid/Vates/VatesAPI/src/vtkDataSetToWsLocation.cpp @@ -1,6 +1,6 @@ #include "MantidVatesAPI/vtkDataSetToWsLocation.h" #include "MantidVatesAPI/FieldDataToMetadata.h" -#include "MantidVatesAPI/RebinningCutterXMLDefinitions.h" +#include "MantidVatesAPI/VatesXMLDefinitions.h" #include "MantidGeometry/MDGeometry/MDGeometryXMLDefinitions.h" #include #include diff --git a/Code/Mantid/Vates/VatesAPI/src/vtkDataSetToWsName.cpp b/Code/Mantid/Vates/VatesAPI/src/vtkDataSetToWsName.cpp index 8ac49785e715..52b2387ac143 100644 --- a/Code/Mantid/Vates/VatesAPI/src/vtkDataSetToWsName.cpp +++ b/Code/Mantid/Vates/VatesAPI/src/vtkDataSetToWsName.cpp @@ -1,6 +1,6 @@ #include "MantidVatesAPI/vtkDataSetToWsName.h" #include "MantidVatesAPI/FieldDataToMetadata.h" -#include "MantidVatesAPI/RebinningCutterXMLDefinitions.h" +#include "MantidVatesAPI/VatesXMLDefinitions.h" #include "MantidGeometry/MDGeometry/MDGeometryXMLDefinitions.h" #include #include diff --git a/Code/Mantid/Vates/VatesAPI/src/vtkMDHexFactory.cpp b/Code/Mantid/Vates/VatesAPI/src/vtkMDHexFactory.cpp index 7ef697daefa3..dff61fc73ff6 100644 --- a/Code/Mantid/Vates/VatesAPI/src/vtkMDHexFactory.cpp +++ b/Code/Mantid/Vates/VatesAPI/src/vtkMDHexFactory.cpp @@ -4,6 +4,7 @@ #include "MantidVatesAPI/vtkMDHexFactory.h" #include "MantidVatesAPI/Common.h" #include "MantidVatesAPI/ProgressAction.h" +#include "MantidVatesAPI/vtkNullUnstructuredGrid.h" #include #include #include @@ -184,6 +185,15 @@ namespace Mantid //Add scalars visualDataSet->GetCellData()->SetScalars(signals); + // Hedge against empty data sets + if (visualDataSet->GetNumberOfPoints() <= 0) + { + visualDataSet->Delete(); + vtkNullUnstructuredGrid nullGrid; + visualDataSet = nullGrid.createNullData(); + this->dataSet = visualDataSet; + } + if (VERBOSE) std::cout << tim << " to create " << imageSizeActual << " hexahedrons." << std::endl; } diff --git a/Code/Mantid/Vates/VatesAPI/src/vtkMDHistoHexFactory.cpp b/Code/Mantid/Vates/VatesAPI/src/vtkMDHistoHexFactory.cpp index 4de4177dd39b..9f2c33f23574 100644 --- a/Code/Mantid/Vates/VatesAPI/src/vtkMDHistoHexFactory.cpp +++ b/Code/Mantid/Vates/VatesAPI/src/vtkMDHistoHexFactory.cpp @@ -4,6 +4,7 @@ #include "MantidVatesAPI/vtkMDHistoHexFactory.h" #include "MantidVatesAPI/Common.h" #include "MantidVatesAPI/ProgressAction.h" +#include "MantidVatesAPI/vtkNullUnstructuredGrid.h" #include "MantidAPI/NullCoordTransform.h" #include "MantidKernel/ReadLock.h" @@ -280,6 +281,15 @@ namespace VATES delete [] pointIDs; delete [] voxelShown; delete [] pointNeeded; + + // Hedge against empty data sets + if (visualDataSet->GetNumberOfPoints() <= 0) + { + visualDataSet->Delete(); + vtkNullUnstructuredGrid nullGrid; + visualDataSet = nullGrid.createNullData(); + } + return visualDataSet; } diff --git a/Code/Mantid/Vates/VatesAPI/src/vtkMDHistoLineFactory.cpp b/Code/Mantid/Vates/VatesAPI/src/vtkMDHistoLineFactory.cpp index d8223d1e008b..58679343101f 100644 --- a/Code/Mantid/Vates/VatesAPI/src/vtkMDHistoLineFactory.cpp +++ b/Code/Mantid/Vates/VatesAPI/src/vtkMDHistoLineFactory.cpp @@ -1,6 +1,7 @@ #include "MantidVatesAPI/vtkMDHistoLineFactory.h" #include "MantidVatesAPI/Common.h" #include "MantidVatesAPI/ProgressAction.h" +#include "MantidVatesAPI/vtkNullUnstructuredGrid.h" #include "vtkCellArray.h" #include "vtkCellData.h" #include "vtkFloatArray.h" @@ -150,6 +151,15 @@ namespace Mantid points->Delete(); signal->Delete(); visualDataSet->Squeeze(); + + // Hedge against empty data sets + if (visualDataSet->GetNumberOfPoints() <= 0) + { + visualDataSet->Delete(); + vtkNullUnstructuredGrid nullGrid; + visualDataSet = nullGrid.createNullData(); + } + return visualDataSet; } } diff --git a/Code/Mantid/Vates/VatesAPI/src/vtkMDHistoQuadFactory.cpp b/Code/Mantid/Vates/VatesAPI/src/vtkMDHistoQuadFactory.cpp index 2341a57fe072..5199a36414ae 100644 --- a/Code/Mantid/Vates/VatesAPI/src/vtkMDHistoQuadFactory.cpp +++ b/Code/Mantid/Vates/VatesAPI/src/vtkMDHistoQuadFactory.cpp @@ -5,6 +5,7 @@ #include "MantidVatesAPI/vtkMDHistoQuadFactory.h" #include "MantidVatesAPI/Common.h" #include "MantidVatesAPI/ProgressAction.h" +#include "MantidVatesAPI/vtkNullUnstructuredGrid.h" #include "vtkCellArray.h" #include "vtkCellData.h" #include "vtkFloatArray.h" @@ -211,6 +212,14 @@ namespace Mantid delete [] voxelShown; delete [] pointNeeded; + // Hedge against empty data sets + if (visualDataSet->GetNumberOfPoints() <= 0) + { + visualDataSet->Delete(); + vtkNullUnstructuredGrid nullGrid; + visualDataSet = nullGrid.createNullData(); + } + return visualDataSet; } } diff --git a/Code/Mantid/Vates/VatesAPI/src/vtkMDLineFactory.cpp b/Code/Mantid/Vates/VatesAPI/src/vtkMDLineFactory.cpp index 071d6aaa09c0..fdf2398d98de 100644 --- a/Code/Mantid/Vates/VatesAPI/src/vtkMDLineFactory.cpp +++ b/Code/Mantid/Vates/VatesAPI/src/vtkMDLineFactory.cpp @@ -1,6 +1,7 @@ #include "MantidVatesAPI/vtkMDLineFactory.h" #include "MantidVatesAPI/Common.h" #include "MantidVatesAPI/ProgressAction.h" +#include "MantidVatesAPI/vtkNullUnstructuredGrid.h" #include "MantidAPI/IMDWorkspace.h" #include "MantidAPI/IMDEventWorkspace.h" #include "MantidAPI/IMDIterator.h" @@ -165,6 +166,14 @@ namespace Mantid points->Delete(); linePointList->Delete(); + // Hedge against empty data sets + if (visualDataSet->GetNumberOfPoints() <= 0) + { + visualDataSet->Delete(); + vtkNullUnstructuredGrid nullGrid; + visualDataSet = nullGrid.createNullData(); + } + return visualDataSet; } } diff --git a/Code/Mantid/Vates/VatesAPI/src/vtkMDQuadFactory.cpp b/Code/Mantid/Vates/VatesAPI/src/vtkMDQuadFactory.cpp index a5d24df5f1d3..e894c7ac25ec 100644 --- a/Code/Mantid/Vates/VatesAPI/src/vtkMDQuadFactory.cpp +++ b/Code/Mantid/Vates/VatesAPI/src/vtkMDQuadFactory.cpp @@ -1,6 +1,7 @@ #include "MantidVatesAPI/vtkMDQuadFactory.h" #include "MantidVatesAPI/Common.h" #include "MantidVatesAPI/ProgressAction.h" +#include "MantidVatesAPI/vtkNullUnstructuredGrid.h" #include "MantidAPI/IMDWorkspace.h" #include "MantidAPI/IMDEventWorkspace.h" #include "MantidAPI/IMDIterator.h" @@ -163,6 +164,14 @@ namespace Mantid points->Delete(); quadPointList->Delete(); + // Hedge against empty data sets + if (visualDataSet->GetNumberOfPoints() <= 0) + { + visualDataSet->Delete(); + vtkNullUnstructuredGrid nullGrid; + visualDataSet = nullGrid.createNullData(); + } + return visualDataSet; } } diff --git a/Code/Mantid/Vates/VatesAPI/src/vtkNullUnstructuredGrid.cpp b/Code/Mantid/Vates/VatesAPI/src/vtkNullUnstructuredGrid.cpp new file mode 100644 index 000000000000..5c4ce44d5c6a --- /dev/null +++ b/Code/Mantid/Vates/VatesAPI/src/vtkNullUnstructuredGrid.cpp @@ -0,0 +1,45 @@ +#include "MantidVatesAPI/vtkNullUnstructuredGrid.h" + +#include +#include +#include +#include +#include +namespace Mantid { +namespace VATES { + +/// Constructor +vtkNullUnstructuredGrid::vtkNullUnstructuredGrid() {} + +/// Destructor +vtkNullUnstructuredGrid::~vtkNullUnstructuredGrid() {} + +/** + * Creates a default vtkDataSet. + *@returns A pointer to the default vtkDataSet + */ +vtkUnstructuredGrid *vtkNullUnstructuredGrid::createNullData() { + + vtkUnstructuredGrid *dataSet = vtkUnstructuredGrid::New(); + dataSet->Allocate(1); + + vtkSmartPointer points = vtkSmartPointer::New(); + vtkSmartPointer vertex = vtkSmartPointer::New(); + + double p[3]; + p[0] = 0.0; + p[1] = 0.0; + p[2] = 0.0; + + points->InsertPoint(0, p); + + vertex->GetPointIds()->SetId(0, 0); + + dataSet->InsertNextCell(VTK_VERTEX, vertex->GetPointIds()); + dataSet->SetPoints(points); + dataSet->Squeeze(); + + return dataSet; +} +} +} \ No newline at end of file diff --git a/Code/Mantid/Vates/VatesAPI/test/EscalatingRebinningActionManagerTest.h b/Code/Mantid/Vates/VatesAPI/test/EscalatingRebinningActionManagerTest.h deleted file mode 100644 index a143182d3499..000000000000 --- a/Code/Mantid/Vates/VatesAPI/test/EscalatingRebinningActionManagerTest.h +++ /dev/null @@ -1,76 +0,0 @@ -#ifndef ESCALATINGREBINNINGACTIONMANAGERTEST_H_ -#define ESCALATINGREBINNINGACTIONMANAGERTEST_H_ - -#include -#include -#include -#include "MantidVatesAPI/EscalatingRebinningActionManager.h" - -using namespace Mantid::VATES; - -class EscalatingRebinningActionManagerTest : public CxxTest::TestSuite -{ - -public: - - void testDefaultConstruction() - { - EscalatingRebinningActionManager escManager; - TSM_ASSERT_EQUALS("Wrong default level. Should be lowest escalation level.", UseCache, escManager.action()); - } - - void testConstructor() - { - EscalatingRebinningActionManager escManager(RecalculateAll); - TSM_ASSERT_EQUALS("Constructor/initalized value does not reflect result of action(). Not wired-up properly.", RecalculateAll, escManager.action()); - } - - void testExpecedEscalationTypes() - { - //This ordering is fundamental to the operation of the EscalatingRebinningManagerTest. - - TS_ASSERT(RecalculateVisualDataSetOnly > UseCache); - TS_ASSERT(RecalculateAll > RecalculateVisualDataSetOnly); - TS_ASSERT(ReloadAndRecalculateAll > RecalculateAll) - } - - void testEscalation() - { - EscalatingRebinningActionManager escManager; - RebinningActionManager& manager = escManager; - - manager.ask(RecalculateVisualDataSetOnly); - TSM_ASSERT_EQUALS("Should have escalated to RecalculateVisualDataSetOnly", RecalculateVisualDataSetOnly, manager.action()); - - manager.ask(RecalculateAll); - TSM_ASSERT_EQUALS("Should have escalated to RecalculateAll", RecalculateAll, manager.action()); - } - - void testNoEscalation() - { - EscalatingRebinningActionManager escManager; - RebinningActionManager& manager = escManager; - manager.ask(RecalculateAll); - - manager.ask(RecalculateVisualDataSetOnly); - TSM_ASSERT_EQUALS("Should not have de-escalated to RecalculateVisualDataSetOnly", RecalculateAll, manager.action()); - - manager.ask(RecalculateAll); - TSM_ASSERT_EQUALS("Should have de-escalated to UseCache", RecalculateAll, manager.action()); - - } - - void testReset() - { - EscalatingRebinningActionManager escManager; - RebinningActionManager& manager = escManager; - - manager.ask(RecalculateAll); - manager.reset(); - - TSM_ASSERT_EQUALS("Should have reset to lowest level.", UseCache, manager.action()); - } - -}; - -#endif /* ESCALATINGREBINNINGACTIONMANAGERTEST_H_ */ diff --git a/Code/Mantid/Vates/VatesAPI/test/MDEWRebinningPresenterTest.h b/Code/Mantid/Vates/VatesAPI/test/MDEWRebinningPresenterTest.h deleted file mode 100644 index e92aae121b13..000000000000 --- a/Code/Mantid/Vates/VatesAPI/test/MDEWRebinningPresenterTest.h +++ /dev/null @@ -1,636 +0,0 @@ -#ifndef MDEW_REBINNING_PRESENTER_TEST_H_ -#define MDEW_REBINNING_PRESENTER_TEST_H_ - -#include -#include -#include -#include -#include "MockObjects.h" - -#include "MantidVatesAPI/MDEWRebinningPresenter.h" -#include "MantidVatesAPI/MetadataToFieldData.h" -#include "MantidVatesAPI/RebinningKnowledgeSerializer.h" -#include "MantidVatesAPI/VatesConfigurations.h" -#include "MantidVatesAPI/ADSWorkspaceProvider.h" -#include "MantidVatesAPI/vtkMDHistoHexFactory.h" -#include "MantidVatesAPI/vtkMDHistoHex4DFactory.h" -#include "MantidVatesAPI/NoThresholdRange.h" -#include "MantidVatesAPI/TimeToTimeStep.h" -#include "MantidVatesAPI/EscalatingRebinningActionManager.h" -#include "MantidVatesAPI/vtkDataSetToGeometry.h" -#include "MantidTestHelpers/MDEventsTestHelper.h" - -using namespace testing; -using namespace Mantid::VATES; -using namespace Mantid::MDEvents; - -//===================================================================================== -// Functional tests -//===================================================================================== -class MDEWRebinningPresenterTest : public CxxTest::TestSuite -{ -private: - - vtkFieldData* generateFieldData(std::string testData) - { - // Create mock object - vtkFieldData* fieldData = createFieldDataWithCharArray(testData); - - // Generate metadata - MetadataJsonManager manager; - manager.setInstrument("OSIRIS"); - - VatesConfigurations config; - - std::string jsonString = manager.getSerializedJson(); - - // Add additional json metadata to the field data - MetadataToFieldData convert; - convert(fieldData, jsonString, config.getMetadataIdJson().c_str()); - - return fieldData; - } - -public: - - void testConstructorThrowsWithoutFieldData() - { - MockRebinningActionManager actionManager; - - MockWorkspaceProvider wsProvider; - EXPECT_CALL(wsProvider, canProvideWorkspace(_)).Times(0); - - TSM_ASSERT_THROWS("Should throw if no FieldData", MDEWRebinningPresenter(vtkUnstructuredGrid::New(), new MockRebinningActionManager, new MockMDRebinningView, wsProvider), std::logic_error); - } - - void testConstructorThrowsWhenCannotProvideWorkspace() - { - MockRebinningActionManager actionManager; - - vtkUnstructuredGrid* dataset = vtkUnstructuredGrid::New(); - dataset->SetFieldData(generateFieldData(constructXML("qx", "qy", "qz", "en"))); - - MockWorkspaceProvider wsProvider; - EXPECT_CALL(wsProvider, canProvideWorkspace(_)).WillOnce(Return(false)); - - TSM_ASSERT_THROWS("Should throw if cannot provide workspace", MDEWRebinningPresenter(dataset, new MockRebinningActionManager, new MockMDRebinningView, wsProvider), std::invalid_argument); - } - - void testConstruction() - { - MockRebinningActionManager* pRequest = new MockRebinningActionManager; - MockWorkspaceProvider wsProvider; - EXPECT_CALL(wsProvider, canProvideWorkspace(_)).WillRepeatedly(Return(true)); - - vtkUnstructuredGrid* dataSet = vtkUnstructuredGrid::New(); - dataSet->SetFieldData(generateFieldData(constructXML("qx", "qy", "qz", "en"))); - - MDEWRebinningPresenter presenter(dataSet, pRequest, new MockMDRebinningView, wsProvider); - TSM_ASSERT("Geometry should be available immediately after construction.", !presenter.getAppliedGeometryXML().empty()); - } - - void testUpdateModelWithNoChanges() - { - MockMDRebinningView* view = new MockMDRebinningView; - EXPECT_CALL(*view, getOutputHistogramWS()).WillRepeatedly(Return(true)); - EXPECT_CALL(*view, getTimeStep()).WillRepeatedly(Return(0)); - EXPECT_CALL(*view, getMaxThreshold()).WillRepeatedly(Return(0)); - EXPECT_CALL(*view, getMinThreshold()).WillRepeatedly(Return(0)); - EXPECT_CALL(*view, getApplyClip()).WillRepeatedly(Return(false)); - std::string viewXML = constrctGeometryOnlyXML("qx", "qy", "qz", "en"); - EXPECT_CALL(*view, getAppliedGeometryXML()).WillRepeatedly(Return(viewXML.c_str())); - - MockRebinningActionManager* pRequest = new MockRebinningActionManager; - EXPECT_CALL(*pRequest, ask(RecalculateAll)).Times(0); //Since nothing has changed, no requests should be made. - - MockWorkspaceProvider wsProvider; - EXPECT_CALL(wsProvider, canProvideWorkspace(_)).WillRepeatedly(Return(true)); - - vtkUnstructuredGrid* dataSet = vtkUnstructuredGrid::New(); - dataSet->SetFieldData(generateFieldData(constructXML("qx", "qy", "qz", "en"))); - - MDEWRebinningPresenter presenter(dataSet, pRequest, view, wsProvider); - presenter.updateModel(); - - TS_ASSERT(Mock::VerifyAndClearExpectations(view)); - TS_ASSERT(Mock::VerifyAndClearExpectations(pRequest)); - } - - void testUpdateModelWithDifferentMaxThreshold() - { - MockMDRebinningView* view = new MockMDRebinningView; - EXPECT_CALL(*view, getOutputHistogramWS()).WillRepeatedly(Return(true)); - EXPECT_CALL(*view, getTimeStep()).WillRepeatedly(Return(0)); - EXPECT_CALL(*view, getMaxThreshold()).WillRepeatedly(Return(1)); //Maxthreshold non-zero - EXPECT_CALL(*view, getMinThreshold()).WillRepeatedly(Return(0)); - EXPECT_CALL(*view, getApplyClip()).WillRepeatedly(Return(false)); - std::string viewXML = constrctGeometryOnlyXML("qx", "qy", "qz", "en"); - EXPECT_CALL(*view, getAppliedGeometryXML()).WillRepeatedly(Return(viewXML.c_str())); - - MockRebinningActionManager* pRequest = new MockRebinningActionManager; - EXPECT_CALL(*pRequest, ask(RecalculateVisualDataSetOnly)).Times(1); //Maxthreshold updated should reflect on request. - - MockWorkspaceProvider wsProvider; - EXPECT_CALL(wsProvider, canProvideWorkspace(_)).WillRepeatedly(Return(true)); - - vtkUnstructuredGrid* dataSet = vtkUnstructuredGrid::New(); - dataSet->SetFieldData(generateFieldData(constructXML("qx", "qy", "qz", "en"))); - - MDEWRebinningPresenter presenter(dataSet, pRequest, view, wsProvider); - presenter.updateModel(); - - TS_ASSERT(Mock::VerifyAndClearExpectations(view)); - TS_ASSERT(Mock::VerifyAndClearExpectations(pRequest)); - } - - void testUpdateModelWithDifferentMinThreshold() - { - MockMDRebinningView* view = new MockMDRebinningView; - EXPECT_CALL(*view, getOutputHistogramWS()).WillRepeatedly(Return(true)); - EXPECT_CALL(*view, getTimeStep()).WillRepeatedly(Return(0)); - EXPECT_CALL(*view, getMaxThreshold()).WillRepeatedly(Return(0)); - EXPECT_CALL(*view, getMinThreshold()).WillRepeatedly(Return(1)); //Minthreshold non-zero - EXPECT_CALL(*view, getApplyClip()).WillRepeatedly(Return(false)); - std::string viewXML = constrctGeometryOnlyXML("qx", "qy", "qz", "en"); - EXPECT_CALL(*view, getAppliedGeometryXML()).WillRepeatedly(Return(viewXML.c_str())); - - MockRebinningActionManager* pRequest = new MockRebinningActionManager; - EXPECT_CALL(*pRequest, ask(RecalculateVisualDataSetOnly)).Times(1); //Minthreshold updated should reflect on request. - - MockWorkspaceProvider wsProvider; - EXPECT_CALL(wsProvider, canProvideWorkspace(_)).WillRepeatedly(Return(true)); - - vtkUnstructuredGrid* dataSet = vtkUnstructuredGrid::New(); - dataSet->SetFieldData(generateFieldData(constructXML("qx", "qy", "qz", "en"))); - - MDEWRebinningPresenter presenter(dataSet, pRequest, view, wsProvider); - presenter.updateModel(); - - TS_ASSERT(Mock::VerifyAndClearExpectations(view)); - TS_ASSERT(Mock::VerifyAndClearExpectations(pRequest)); - } - - void testUpdateModelWithDifferentTimestep() - { - MockMDRebinningView* view = new MockMDRebinningView; - EXPECT_CALL(*view, getOutputHistogramWS()).WillRepeatedly(Return(true)); - EXPECT_CALL(*view, getTimeStep()).Times(2).WillRepeatedly(Return(1)); //Timestep updated - EXPECT_CALL(*view, getMaxThreshold()).WillRepeatedly(Return(0)); - EXPECT_CALL(*view, getMinThreshold()).WillRepeatedly(Return(0)); - EXPECT_CALL(*view, getApplyClip()).WillRepeatedly(Return(false)); - std::string viewXML = constrctGeometryOnlyXML("qx", "qy", "qz", "en"); - EXPECT_CALL(*view, getAppliedGeometryXML()).WillRepeatedly(Return(viewXML.c_str())); - - MockRebinningActionManager* pRequest = new MockRebinningActionManager; - EXPECT_CALL(*pRequest, ask(RecalculateVisualDataSetOnly)).Times(1); //Timestep updated should reflect on request. - - MockWorkspaceProvider wsProvider; - EXPECT_CALL(wsProvider, canProvideWorkspace(_)).WillRepeatedly(Return(true)); - - vtkUnstructuredGrid* dataSet = vtkUnstructuredGrid::New(); - dataSet->SetFieldData(generateFieldData(constructXML("qx", "qy", "qz", "en"))); - - MDEWRebinningPresenter presenter(dataSet, pRequest, view, wsProvider); - presenter.updateModel(); - - TS_ASSERT(Mock::VerifyAndClearExpectations(view)); - TS_ASSERT(Mock::VerifyAndClearExpectations(pRequest)); - } - - void testUpdateModelWithMoreXBins() - { - MockMDRebinningView* view = new MockMDRebinningView; - EXPECT_CALL(*view, getOutputHistogramWS()).WillRepeatedly(Return(true)); - EXPECT_CALL(*view, getTimeStep()).WillRepeatedly(Return(0)); - EXPECT_CALL(*view, getMaxThreshold()).WillRepeatedly(Return(0)); - EXPECT_CALL(*view, getMinThreshold()).WillRepeatedly(Return(0)); - EXPECT_CALL(*view, getApplyClip()).WillRepeatedly(Return(false)); - std::string viewXML = constrctGeometryOnlyXML("qx", "qy", "qz", "en", "11"); - EXPECT_CALL(*view, getAppliedGeometryXML()).Times(2).WillRepeatedly(Return(viewXML.c_str())); //Geometry (4D) should reflect on request. - - MockRebinningActionManager* pRequest = new MockRebinningActionManager; - EXPECT_CALL(*pRequest, ask(RecalculateAll)).Times(1); //Nxbins changed, requires rebin request. - - MockWorkspaceProvider wsProvider; - EXPECT_CALL(wsProvider, canProvideWorkspace(_)).WillRepeatedly(Return(true)); - - vtkUnstructuredGrid* dataSet = vtkUnstructuredGrid::New(); - dataSet->SetFieldData(generateFieldData(constructXML("qx", "qy", "qz", "en"))); - - MDEWRebinningPresenter presenter(dataSet, pRequest, view, wsProvider); - presenter.updateModel(); - - TS_ASSERT(Mock::VerifyAndClearExpectations(view)); - TS_ASSERT(Mock::VerifyAndClearExpectations(pRequest)); - } - - void testUpdateModelWithMoreXYBins() - { - MockMDRebinningView* view = new MockMDRebinningView; - EXPECT_CALL(*view, getOutputHistogramWS()).WillRepeatedly(Return(true)); - EXPECT_CALL(*view, getTimeStep()).WillRepeatedly(Return(0)); - EXPECT_CALL(*view, getMaxThreshold()).WillRepeatedly(Return(0)); - EXPECT_CALL(*view, getMinThreshold()).WillRepeatedly(Return(0)); - EXPECT_CALL(*view, getApplyClip()).WillRepeatedly(Return(false)); - std::string viewXML = constrctGeometryOnlyXML("qx", "qy", "qz", "en", "11", "11"); - EXPECT_CALL(*view, getAppliedGeometryXML()).Times(2).WillRepeatedly(Return(viewXML.c_str())); - - MockRebinningActionManager* pRequest = new MockRebinningActionManager; - EXPECT_CALL(*pRequest, ask(RecalculateAll)).Times(1); //Nxbins & Nybins changed, requires rebin request. - - MockWorkspaceProvider wsProvider; - EXPECT_CALL(wsProvider, canProvideWorkspace(_)).WillRepeatedly(Return(true)); - - vtkUnstructuredGrid* dataSet = vtkUnstructuredGrid::New(); - dataSet->SetFieldData(generateFieldData(constructXML("qx", "qy", "qz", "en"))); - - MDEWRebinningPresenter presenter(dataSet, pRequest, view, wsProvider); - presenter.updateModel(); - - TS_ASSERT(Mock::VerifyAndClearExpectations(view)); - TS_ASSERT(Mock::VerifyAndClearExpectations(pRequest)); - } - - - void testUpdateModelWithMoreXYZBins() - { - MockMDRebinningView* view = new MockMDRebinningView; - EXPECT_CALL(*view, getOutputHistogramWS()).WillRepeatedly(Return(true)); - EXPECT_CALL(*view, getTimeStep()).WillRepeatedly(Return(0)); - EXPECT_CALL(*view, getMaxThreshold()).WillRepeatedly(Return(0)); - EXPECT_CALL(*view, getMinThreshold()).WillRepeatedly(Return(0)); - EXPECT_CALL(*view, getApplyClip()).WillRepeatedly(Return(false)); - std::string viewXML = constrctGeometryOnlyXML("qx", "qy", "qz", "en", "11", "11", "11"); - EXPECT_CALL(*view, getAppliedGeometryXML()).Times(2).WillRepeatedly(Return(viewXML.c_str())); - - MockRebinningActionManager* pRequest = new MockRebinningActionManager; - EXPECT_CALL(*pRequest, ask(RecalculateAll)).Times(1); //Nxbins & Nybins & Nzbins changed, requires rebin request. - - MockWorkspaceProvider wsProvider; - EXPECT_CALL(wsProvider, canProvideWorkspace(_)).WillRepeatedly(Return(true)); - - vtkUnstructuredGrid* dataSet = vtkUnstructuredGrid::New(); - dataSet->SetFieldData(generateFieldData(constructXML("qx", "qy", "qz", "en"))); - - MDEWRebinningPresenter presenter(dataSet, pRequest, view, wsProvider); - presenter.updateModel(); - - TS_ASSERT(Mock::VerifyAndClearExpectations(view)); - TS_ASSERT(Mock::VerifyAndClearExpectations(pRequest)); - } - - void testUpdateModelWithDifferentOutputType() - { - MockMDRebinningView* view = new MockMDRebinningView; - EXPECT_CALL(*view, getOutputHistogramWS()).WillRepeatedly(Return(false)); //Output a full MDEW workspace via SliceMD - EXPECT_CALL(*view, getTimeStep()).WillRepeatedly(Return(0)); - EXPECT_CALL(*view, getMaxThreshold()).WillRepeatedly(Return(0)); - EXPECT_CALL(*view, getMinThreshold()).WillRepeatedly(Return(0)); - EXPECT_CALL(*view, getApplyClip()).WillRepeatedly(Return(false)); - std::string viewXML = constrctGeometryOnlyXML("qx", "qy", "qz", "en"); - EXPECT_CALL(*view, getAppliedGeometryXML()).WillRepeatedly(Return(viewXML.c_str())); - - MockRebinningActionManager* pRequest = new MockRebinningActionManager; - EXPECT_CALL(*pRequest, ask(RecalculateAll)).Times(1); //Output type changed. Requires re-execution. - - MockWorkspaceProvider wsProvider; - EXPECT_CALL(wsProvider, canProvideWorkspace(_)).WillRepeatedly(Return(true)); - - vtkUnstructuredGrid* dataSet = vtkUnstructuredGrid::New(); - dataSet->SetFieldData(generateFieldData(constructXML("qx", "qy", "qz", "en"))); - - MDEWRebinningPresenter presenter(dataSet, pRequest, view, wsProvider); - presenter.updateModel(); - - TS_ASSERT(Mock::VerifyAndClearExpectations(view)); - TS_ASSERT(Mock::VerifyAndClearExpectations(pRequest)); - } - - void testUpdateModelWithApplyClipping() - { - - MockMDRebinningView* view = new MockMDRebinningView; - EXPECT_CALL(*view, getOutputHistogramWS()).WillRepeatedly(Return(true)); - EXPECT_CALL(*view, getTimeStep()).WillRepeatedly(Return(0)); - EXPECT_CALL(*view, getMaxThreshold()).WillRepeatedly(Return(0)); - EXPECT_CALL(*view, getMinThreshold()).WillRepeatedly(Return(0)); - EXPECT_CALL(*view, getApplyClip()).WillRepeatedly(Return(true)); // Clipping applied. - EXPECT_CALL(*view, getOrigin()).WillRepeatedly(Return(Mantid::Kernel::V3D(0, 0, 0))); - EXPECT_CALL(*view, getB1()).Times(AtLeast(1)).WillRepeatedly(Return(Mantid::Kernel::V3D(1, 0, 0))); - EXPECT_CALL(*view, getB2()).Times(AtLeast(1)).WillRepeatedly(Return(Mantid::Kernel::V3D(0, 1, 0))); - EXPECT_CALL(*view, getLengthB1()).Times(AtLeast(1)).WillRepeatedly(Return(1)); - EXPECT_CALL(*view, getLengthB2()).Times(AtLeast(1)).WillRepeatedly(Return(1)); - EXPECT_CALL(*view, getLengthB3()).Times(AtLeast(1)).WillRepeatedly(Return(1)); - EXPECT_CALL(*view, getForceOrthogonal()).WillRepeatedly(Return(false)); - - std::string viewXML = constrctGeometryOnlyXML("qx", "qy", "qz", "en"); - EXPECT_CALL(*view, getAppliedGeometryXML()).Times(AtLeast(1)).WillRepeatedly(Return(viewXML.c_str())); - - MockRebinningActionManager* pRequest = new MockRebinningActionManager; - EXPECT_CALL(*pRequest, ask(RecalculateAll)).Times(AtLeast(1)); //Clipping changed so should rebin. - - MockWorkspaceProvider wsProvider; - EXPECT_CALL(wsProvider, canProvideWorkspace(_)).WillRepeatedly(Return(true)); - - vtkUnstructuredGrid* dataSet = vtkUnstructuredGrid::New(); - dataSet->SetFieldData(generateFieldData(constructXML("qx", "qy", "qz", "en"))); - - MDEWRebinningPresenter presenter(dataSet, pRequest, view, wsProvider); - presenter.updateModel(); - - TS_ASSERT(Mock::VerifyAndClearExpectations(view)); - TS_ASSERT(Mock::VerifyAndClearExpectations(pRequest)); - } - - void testUpdateModelWithSameClipping() - { - MockMDRebinningView* view = new MockMDRebinningView; - EXPECT_CALL(*view, getOutputHistogramWS()).WillRepeatedly(Return(true)); - EXPECT_CALL(*view, getTimeStep()).WillRepeatedly(Return(0)); - EXPECT_CALL(*view, getMaxThreshold()).WillRepeatedly(Return(0)); - EXPECT_CALL(*view, getMinThreshold()).WillRepeatedly(Return(0)); - EXPECT_CALL(*view, getApplyClip()).WillRepeatedly(Return(true)); // Clipping applied. - EXPECT_CALL(*view, getOrigin()).WillRepeatedly(Return(Mantid::Kernel::V3D(0, 0, 0))); - EXPECT_CALL(*view, getB1()).Times(AtLeast(1)).WillRepeatedly(Return(Mantid::Kernel::V3D(1, 0, 0))); - EXPECT_CALL(*view, getB2()).Times(AtLeast(1)).WillRepeatedly(Return(Mantid::Kernel::V3D(0, 1, 0))); - EXPECT_CALL(*view, getLengthB1()).Times(AtLeast(1)).WillRepeatedly(Return(1)); - EXPECT_CALL(*view, getLengthB2()).Times(AtLeast(1)).WillRepeatedly(Return(1)); - EXPECT_CALL(*view, getLengthB3()) - .Times(AtLeast(1)) - .WillOnce(Return(1)) - .WillOnce(Return(1)); - EXPECT_CALL(*view, getForceOrthogonal()).WillRepeatedly(Return(false)); - - //Should now need to fetch the implicit function - std::string viewXML = constrctGeometryOnlyXML("qx", "qy", "qz", "en"); - EXPECT_CALL(*view, getAppliedGeometryXML()).Times(AtLeast(1)).WillRepeatedly(Return(viewXML.c_str())); - - MockRebinningActionManager* pRequest = new MockRebinningActionManager; - - EXPECT_CALL(*pRequest, ask(RecalculateAll)).Times(AtLeast(1)); //Should ask on first pass, but not for secondClipping as is identical to first. - - MockWorkspaceProvider wsProvider; - EXPECT_CALL(wsProvider, canProvideWorkspace(_)).WillRepeatedly(Return(true)); - - vtkUnstructuredGrid* dataSet = vtkUnstructuredGrid::New(); - dataSet->SetFieldData(generateFieldData(constructXML("qx", "qy", "qz", "en"))); - - MDEWRebinningPresenter presenter(dataSet, pRequest, view, wsProvider); - presenter.updateModel(); - presenter.updateModel(); - - TS_ASSERT(Mock::VerifyAndClearExpectations(view)); - TS_ASSERT(Mock::VerifyAndClearExpectations(pRequest)); - } - - void testUpdateModelWithDifferentClipping() - { - MockMDRebinningView* view = new MockMDRebinningView; - EXPECT_CALL(*view, getOutputHistogramWS()).WillRepeatedly(Return(true)); - EXPECT_CALL(*view, getTimeStep()).WillRepeatedly(Return(0)); - EXPECT_CALL(*view, getMaxThreshold()).WillRepeatedly(Return(0)); - EXPECT_CALL(*view, getMinThreshold()).WillRepeatedly(Return(0)); - EXPECT_CALL(*view, getApplyClip()).WillRepeatedly(Return(true)); // Clipping applied. - EXPECT_CALL(*view, getOrigin()).WillRepeatedly(Return(Mantid::Kernel::V3D(0, 0, 0))); - EXPECT_CALL(*view, getB1()).Times(AtLeast(1)).WillRepeatedly(Return(Mantid::Kernel::V3D(1, 0, 0))); - EXPECT_CALL(*view, getB2()).Times(AtLeast(1)).WillRepeatedly(Return(Mantid::Kernel::V3D(0, 1, 0))); - EXPECT_CALL(*view, getLengthB1()).Times(AtLeast(1)).WillRepeatedly(Return(1)); - EXPECT_CALL(*view, getLengthB2()).Times(AtLeast(1)).WillRepeatedly(Return(1)); - EXPECT_CALL(*view, getLengthB3()) - .Times(AtLeast(1)) - .WillOnce(Return(1)) - .WillOnce(Return(2)); - EXPECT_CALL(*view, getForceOrthogonal()).WillRepeatedly(Return(false)); - - //Should now need to fetch the implicit function - std::string viewXML = constrctGeometryOnlyXML("qx", "qy", "qz", "en"); - EXPECT_CALL(*view, getAppliedGeometryXML()).Times(AtLeast(1)).WillRepeatedly(Return(viewXML.c_str())); - - MockRebinningActionManager* pRequest = new MockRebinningActionManager; - - EXPECT_CALL(*pRequest, ask(RecalculateAll)).Times(AtLeast(1)); //Should ask on first pass, but not for secondClipping as is identical to first. - - MockWorkspaceProvider wsProvider; - EXPECT_CALL(wsProvider, canProvideWorkspace(_)).WillRepeatedly(Return(true)); - - vtkUnstructuredGrid* dataSet = vtkUnstructuredGrid::New(); - dataSet->SetFieldData(generateFieldData(constructXML("qx", "qy", "qz", "en"))); - - MDEWRebinningPresenter presenter(dataSet, pRequest, view, wsProvider); - presenter.updateModel(); - presenter.updateModel(); - - TS_ASSERT(Mock::VerifyAndClearExpectations(view)); - TS_ASSERT(Mock::VerifyAndClearExpectations(pRequest)); - } - - void testExecute() - { - // Create a MDWorkspace and put it into the ADS. - const std::string wsName = "TestMDEW"; - auto someMDEW = Mantid::MDEvents::MDEventsTestHelper::makeAnyMDEW,3>(10,0,10,0,wsName); - - // Generate xml relating to the dimensionality etc. by querying this workspace. - RebinningKnowledgeSerializer serializer(LocationNotRequired); - serializer.setWorkspace(someMDEW); - std::string creationalXML = serializer.createXMLString(); - - // Create an empty dataset and attach that xml as field data. - vtkUnstructuredGrid* dataSet = vtkUnstructuredGrid::New(); - dataSet->SetFieldData(generateFieldData(creationalXML)); - - /* - The vtkFilter is the view in our MVP set up. - We can't actually create an instance of the vtkFilter for testing, which would otherwise make it impossible to test any of this functionality. - - However, we can mock a View, because both the real filter and our Mock inherite from MDRebinningView. Using this view we 'simulate' real user inputs. - */ - MockMDRebinningView* view = new MockMDRebinningView; - EXPECT_CALL(*view, getOutputHistogramWS()).WillRepeatedly(Return(true)); - EXPECT_CALL(*view, getTimeStep()).WillRepeatedly(Return(0)); - EXPECT_CALL(*view, getMaxThreshold()).WillRepeatedly(Return(0)); - EXPECT_CALL(*view, getMinThreshold()).WillRepeatedly(Return(0)); - EXPECT_CALL(*view, getApplyClip()).WillRepeatedly(Return(false)); - /* - The following is the critical method. It returns the xml from the current state of the view. - At the moment, the view is going to return the same xml as it was originally given. However, we can override this behaviour and provide - any xml we wish. So for example, simulating that the user has increased the number of bins. - */ - std::string viewXML = serializer.getWorkspaceGeometry(); - EXPECT_CALL(*view, getAppliedGeometryXML()).WillRepeatedly(Return(viewXML.c_str())); - - // The workspace provider is a proxy to the Analysis Data Service. - ADSWorkspaceProvider workspaceProvider; - - // The request is the way that the rebinner stores what action to take when the user hits 'Apply'/ - RebinningActionManager* pRequest = new EscalatingRebinningActionManager; - - // Create a presenter which binds the Model and the View together. - MDEWRebinningPresenter presenter(dataSet, pRequest, view, workspaceProvider); - pRequest->ask(Mantid::VATES::RecalculateAll); // Force it to rebin. Usually we call updateModel first, which figures out what action needs to be taken (rebin, just redraw e.t.c). - - // A progress action is the mechanism by which progress is reported. - NiceMock progressAction; - // Create a factory for visualising the output workspace after rebinning. We only provide one here, because we know that it's going to be a 3D MDHistoWorkspace from BinMD. - auto vtkFactory = new vtkMDHistoHexFactory(ThresholdRange_scptr(new NoThresholdRange), "signal"); - vtkDataSet* product = presenter.execute(vtkFactory, progressAction, progressAction); - - // Now we can read the xml off the product data set. For example.. - vtkDataSetToGeometry parser(product); - parser.execute(); - TS_ASSERT_EQUALS(3, parser.getAllDimensions().size()); // Simple test here. but there are loads of other properties on the parser to test. - - // NOTE. if you wanted to Extract the field data. You could do that here by fetching it off output product vtkDataSet. - } - - void testTimeLabelAfterRebinFor4DData() - { - const std::string wsName = "TestMDEW"; - auto someMDEW = Mantid::MDEvents::MDEventsTestHelper::makeAnyMDEW,4>(10,0,10,0,wsName); - - RebinningKnowledgeSerializer serializer(LocationNotRequired); - serializer.setWorkspace(someMDEW); - std::string creationalXML = serializer.createXMLString(); - - vtkUnstructuredGrid* dataSet = vtkUnstructuredGrid::New(); - dataSet->SetFieldData(generateFieldData(creationalXML)); - - MockMDRebinningView* view = new MockMDRebinningView; - EXPECT_CALL(*view, getOutputHistogramWS()).WillRepeatedly(Return(true)); - EXPECT_CALL(*view, getTimeStep()).WillRepeatedly(Return(0)); - EXPECT_CALL(*view, getMaxThreshold()).WillRepeatedly(Return(0)); - EXPECT_CALL(*view, getMinThreshold()).WillRepeatedly(Return(0)); - EXPECT_CALL(*view, getApplyClip()).WillRepeatedly(Return(false)); - - std::string viewXML = constructGeometryOnlyXMLForMDEvHelperData("Axis3", - "Axis2", - "Axis1", - "Axis0"); - EXPECT_CALL(*view, getAppliedGeometryXML()).WillRepeatedly(Return(viewXML.c_str())); - - ADSWorkspaceProvider workspaceProvider; - - RebinningActionManager* pRequest = new EscalatingRebinningActionManager; - - MDEWRebinningPresenter presenter(dataSet, pRequest, view, workspaceProvider); - pRequest->ask(Mantid::VATES::RecalculateAll); - - TSM_ASSERT_EQUALS("Time label should be exact.", - presenter.getTimeStepLabel(), "Axis0 (m)") - } - - void testAxisLabelsAfterRebinFor3DData() - { - const std::string wsName = "TestMDEW"; - auto someMDEW = Mantid::MDEvents::MDEventsTestHelper::makeAnyMDEW,3>(10,0,10,0,wsName); - - RebinningKnowledgeSerializer serializer(LocationNotRequired); - serializer.setWorkspace(someMDEW); - std::string creationalXML = serializer.createXMLString(); - - vtkUnstructuredGrid* dataSet = vtkUnstructuredGrid::New(); - dataSet->SetFieldData(generateFieldData(creationalXML)); - - MockMDRebinningView* view = new MockMDRebinningView; - EXPECT_CALL(*view, getOutputHistogramWS()).WillRepeatedly(Return(true)); - EXPECT_CALL(*view, getTimeStep()).WillRepeatedly(Return(0)); - EXPECT_CALL(*view, getMaxThreshold()).WillRepeatedly(Return(0)); - EXPECT_CALL(*view, getMinThreshold()).WillRepeatedly(Return(0)); - EXPECT_CALL(*view, getApplyClip()).WillRepeatedly(Return(false)); - - std::string viewXML = constructGeometryOnlyXMLForMDEvHelperData("Axis2", - "Axis0", - "Axis1", - ""); - EXPECT_CALL(*view, getAppliedGeometryXML()).WillRepeatedly(Return(viewXML.c_str())); - - ADSWorkspaceProvider workspaceProvider; - - RebinningActionManager* pRequest = new EscalatingRebinningActionManager; - - MDEWRebinningPresenter presenter(dataSet, pRequest, view, workspaceProvider); - pRequest->ask(Mantid::VATES::RecalculateAll); - - NiceMock progressAction; - - auto vtkFactory = new vtkMDHistoHexFactory(ThresholdRange_scptr(new NoThresholdRange), "signal"); - vtkDataSet* product = presenter.execute(vtkFactory, progressAction, progressAction); - - TSM_ASSERT_THROWS_NOTHING("Should pass", presenter.setAxisLabels(product)); - TSM_ASSERT_EQUALS("X Label should match exactly", - getStringFieldDataValue(product, "AxisTitleForX"), - "Axis2 (m)"); - TSM_ASSERT_EQUALS("Y Label should match exactly", - getStringFieldDataValue(product, "AxisTitleForY"), - "Axis0 (m)"); - TSM_ASSERT_EQUALS("Z Label should match exactly", - getStringFieldDataValue(product, "AxisTitleForZ"), - "Axis1 (m)"); - } - - void testAxisLabelsAfterRebinFor4DData() - { - const std::string wsName = "TestMDEW"; - auto someMDEW = Mantid::MDEvents::MDEventsTestHelper::makeAnyMDEW,4>(10,0,10); - Mantid::API::AnalysisDataService::Instance().addOrReplace(wsName, someMDEW); - - RebinningKnowledgeSerializer serializer(LocationNotRequired); - serializer.setWorkspace(someMDEW); - std::string creationalXML = serializer.createXMLString(); - - vtkUnstructuredGrid* dataSet = vtkUnstructuredGrid::New(); - dataSet->SetFieldData(generateFieldData(creationalXML)); - - MockMDRebinningView* view = new MockMDRebinningView; - EXPECT_CALL(*view, getOutputHistogramWS()).WillRepeatedly(Return(true)); - EXPECT_CALL(*view, getTimeStep()).WillRepeatedly(Return(0)); - EXPECT_CALL(*view, getMaxThreshold()).WillRepeatedly(Return(0)); - EXPECT_CALL(*view, getMinThreshold()).WillRepeatedly(Return(0)); - EXPECT_CALL(*view, getApplyClip()).WillRepeatedly(Return(false)); - - std::string viewXML = constructGeometryOnlyXMLForMDEvHelperData("Axis3", - "Axis2", - "Axis1", - "Axis0"); - EXPECT_CALL(*view, getAppliedGeometryXML()).WillRepeatedly(Return(viewXML.c_str())); - - ADSWorkspaceProvider workspaceProvider; - - RebinningActionManager* pRequest = new EscalatingRebinningActionManager; - - MDEWRebinningPresenter presenter(dataSet, pRequest, view, workspaceProvider); - pRequest->ask(Mantid::VATES::RecalculateAll); - - NiceMock progressAction; - - auto vtkFactory = new vtkMDHistoHex4DFactory(ThresholdRange_scptr(new NoThresholdRange), "signal", 0.0); - vtkDataSet* product = presenter.execute(vtkFactory, progressAction, progressAction); - - TSM_ASSERT_THROWS_NOTHING("Should pass", presenter.setAxisLabels(product)); - TSM_ASSERT_EQUALS("X Label should match exactly", - getStringFieldDataValue(product, "AxisTitleForX"), - "Axis3 (s)"); - TSM_ASSERT_EQUALS("Y Label should match exactly", - getStringFieldDataValue(product, "AxisTitleForY"), - "Axis2 (m)"); - TSM_ASSERT_EQUALS("Z Label should match exactly", - getStringFieldDataValue(product, "AxisTitleForZ"), - "Axis1 (m)"); - } - - void testJsonMetadataExtractionFromRebinnedDataSet() - { - MockRebinningActionManager* pRequest = new MockRebinningActionManager; - MockWorkspaceProvider wsProvider; - EXPECT_CALL(wsProvider, canProvideWorkspace(_)).WillRepeatedly(Return(true)); - - vtkUnstructuredGrid* dataSet = vtkUnstructuredGrid::New(); - dataSet->SetFieldData(generateFieldData(constructXML("qx", "qy", "qz", "en"))); - - MDEWRebinningPresenter presenter(dataSet, pRequest, new MockMDRebinningView, wsProvider); - TSM_ASSERT("Instrument should be available immediately after construction.", !presenter.getInstrument().empty()); - TSM_ASSERT("Instrument should be read out correctly.", presenter.getInstrument() == "OSIRIS"); - } -}; - -#endif diff --git a/Code/Mantid/Vates/VatesAPI/test/MDRebinningViewAdapterTest.h b/Code/Mantid/Vates/VatesAPI/test/MDRebinningViewAdapterTest.h deleted file mode 100644 index 578effe3d912..000000000000 --- a/Code/Mantid/Vates/VatesAPI/test/MDRebinningViewAdapterTest.h +++ /dev/null @@ -1,67 +0,0 @@ -#ifndef MD_REBINNING_VIEW_ADAPTER_TEST_H -#define MD_REBINNING_VIEW_ADAPTER_TEST_H - -#include "MantidKernel/V3D.h" -#include "MantidVatesAPI/MDRebinningViewAdapter.h" -#include -#include -#include -#include "MockObjects.h" - -using namespace testing; -using namespace Mantid::VATES; - -class MDRebinningViewAdapterTest : public CxxTest::TestSuite -{ - -public: - - void testWireUp() - { - Mantid::Kernel::V3D v; - //Set expectations on adaptee - MockMDRebinningView view; - EXPECT_CALL(view, getMaxThreshold()).Times(1); - EXPECT_CALL(view, getMinThreshold()).Times(1); - EXPECT_CALL(view, getApplyClip()).Times(1); - EXPECT_CALL(view, getTimeStep()).Times(1); - EXPECT_CALL(view, getAppliedGeometryXML()).Times(1); - EXPECT_CALL(view, updateAlgorithmProgress(_,_)).Times(1); - EXPECT_CALL(view, getOrigin()).Times(1).WillOnce(Return(v)); - EXPECT_CALL(view, getB1()).Times(1).WillOnce(Return(v)); - EXPECT_CALL(view, getB2()).Times(1).WillOnce(Return(v)); - EXPECT_CALL(view, getLengthB1()).Times(1); - EXPECT_CALL(view, getLengthB2()).Times(1); - EXPECT_CALL(view, getLengthB3()).Times(1); - EXPECT_CALL(view, getForceOrthogonal()).Times(1); - EXPECT_CALL(view, getOutputHistogramWS()).Times(1); - - //Create adapter using adaptee - MDRebinningViewAdapter view_adapter(&view); - - //Use an alias to ensure that adapting to the right type. - MDRebinningView& alias = view_adapter; - - //Test running adaptees invokes expecations and exits cleanly - TS_ASSERT_THROWS_NOTHING(alias.getMaxThreshold()); - TS_ASSERT_THROWS_NOTHING(alias.getMinThreshold()); - TS_ASSERT_THROWS_NOTHING(alias.getApplyClip()); - TS_ASSERT_THROWS_NOTHING(alias.getTimeStep()); - TS_ASSERT_THROWS_NOTHING(alias.getAppliedGeometryXML()); - TS_ASSERT_THROWS_NOTHING(alias.updateAlgorithmProgress(0,"")); - TS_ASSERT_THROWS_NOTHING(alias.getLengthB1()); - TS_ASSERT_THROWS_NOTHING(alias.getLengthB2()); - TS_ASSERT_THROWS_NOTHING(alias.getLengthB3()); - TS_ASSERT_THROWS_NOTHING(alias.getB1()); - TS_ASSERT_THROWS_NOTHING(alias.getB2()); - TS_ASSERT_THROWS_NOTHING(alias.getOrigin()); - TS_ASSERT_THROWS_NOTHING(alias.getForceOrthogonal()); - TS_ASSERT_THROWS_NOTHING(alias.getOutputHistogramWS()); - - //Check the expectations. - TSM_ASSERT("Not wired-up correctly", Mock::VerifyAndClearExpectations(&view)); - } - -}; - -#endif \ No newline at end of file diff --git a/Code/Mantid/Vates/VatesAPI/test/MockObjects.h b/Code/Mantid/Vates/VatesAPI/test/MockObjects.h index 46fd81113642..aa8be83dfa11 100644 --- a/Code/Mantid/Vates/VatesAPI/test/MockObjects.h +++ b/Code/Mantid/Vates/VatesAPI/test/MockObjects.h @@ -13,14 +13,11 @@ #include "MantidKernel/UnitLabel.h" #include "MantidMDEvents/MDHistoWorkspace.h" #include "MantidVatesAPI/MDLoadingView.h" -#include "MantidVatesAPI/Clipper.h" #include "MantidVatesAPI/Common.h" -#include "MantidVatesAPI/MDRebinningView.h" #include "MantidVatesAPI/vtkDataSetFactory.h" #include "MantidVatesAPI/MDLoadingView.h" #include "MantidVatesAPI/ProgressAction.h" -#include "MantidVatesAPI/RebinningActionManager.h" -#include "MantidVatesAPI/RebinningCutterXMLDefinitions.h" +#include "MantidVatesAPI/VatesXMLDefinitions.h" #include "MantidVatesAPI/WorkspaceProvider.h" #include "MantidAPI/NullCoordTransform.h" #include "MantidAPI/FrameworkManager.h" @@ -29,7 +26,6 @@ #include #include -using Mantid::VATES::MDRebinningView; using Mantid::Geometry::MDHistoDimension; using Mantid::Geometry::MDHistoDimension_sptr; using Mantid::coord_t; @@ -147,56 +143,6 @@ class MockMDLoadingView : public Mantid::VATES::MDLoadingView ~MockMDLoadingView(){} }; -class MockMDRebinningView : public MDRebinningView -{ -public: - MOCK_CONST_METHOD0(getMaxThreshold, - double()); - MOCK_CONST_METHOD0(getMinThreshold, - double()); - MOCK_CONST_METHOD0(getApplyClip, - bool()); - MOCK_CONST_METHOD0(getTimeStep, - double()); - MOCK_CONST_METHOD0(getAppliedGeometryXML, - const char*()); - MOCK_METHOD2(updateAlgorithmProgress, - void(double, const std::string&)); - MOCK_CONST_METHOD0(getOrigin, Mantid::Kernel::V3D()); - MOCK_CONST_METHOD0(getB1, Mantid::Kernel::V3D()); - MOCK_CONST_METHOD0(getB2, Mantid::Kernel::V3D()); - MOCK_CONST_METHOD0(getLengthB1, double()); - MOCK_CONST_METHOD0(getLengthB2, double()); - MOCK_CONST_METHOD0(getLengthB3, double()); - MOCK_CONST_METHOD0(getForceOrthogonal, bool()); - MOCK_CONST_METHOD0(getOutputHistogramWS, bool()); -}; - -class MockClipper: public Mantid::VATES::Clipper -{ -public: - MOCK_METHOD1(SetInput, void(vtkDataSet* in_ds)); - MOCK_METHOD1(SetClipFunction, void(vtkImplicitFunction* func)); - MOCK_METHOD1(SetInsideOut, void(bool insideout)); - MOCK_METHOD1(SetRemoveWholeCells, void(bool removeWholeCells)); - MOCK_METHOD1(SetOutput, void(vtkUnstructuredGrid* out_ds)); - MOCK_METHOD0(Update, void()); - MOCK_METHOD0(Delete,void()); - MOCK_METHOD0(GetOutput, vtkDataSet*()); - MOCK_METHOD0(die, void()); - virtual ~MockClipper(){} -}; - -class MockRebinningActionManager : public Mantid::VATES::RebinningActionManager -{ -public: - MOCK_METHOD1(ask, void(Mantid::VATES::RebinningIterationAction)); - MOCK_CONST_METHOD0(action, Mantid::VATES::RebinningIterationAction()); - MOCK_METHOD0(reset, void()); - virtual ~MockRebinningActionManager(){} -}; - - class MockWorkspaceProvider : public Mantid::VATES::WorkspaceProvider { public: diff --git a/Code/Mantid/Vates/VatesAPI/test/NullRebinningPresenterTest.h b/Code/Mantid/Vates/VatesAPI/test/NullRebinningPresenterTest.h deleted file mode 100644 index 1344bda8b2a1..000000000000 --- a/Code/Mantid/Vates/VatesAPI/test/NullRebinningPresenterTest.h +++ /dev/null @@ -1,89 +0,0 @@ -#ifndef NULL_REBINNING_PRESENTER_TEST_H_ -#define NULL_REBINNING_PRESENTER_TEST_H_ - -#include -#include "MantidVatesAPI/NullRebinningPresenter.h" -#include "MantidVatesAPI/ProgressAction.h" -#include "MantidVatesAPI/vtkDataSetFactory.h" -#include -#include -#include -#include "MantidAPI/Workspace.h" - -using namespace Mantid::VATES; - -class NullRebinningPresenterTest : public CxxTest::TestSuite -{ -private: - - class FakeProgressAction : public ProgressAction - { - virtual void eventRaised(double){} - }; - - class FakeDataSetFactory : public Mantid::VATES::vtkDataSetFactory - { - public: - virtual ~FakeDataSetFactory(){ } - private: - - virtual vtkDataSet* create(ProgressAction&) const{ throw std::runtime_error("Not implemented on test type");} - virtual void initialize(boost::shared_ptr){throw std::runtime_error("Not implemented on test type");} - virtual void SetSuccessor(vtkDataSetFactory*){ throw std::runtime_error("Not implemented on test type");} - virtual bool hasSuccessor() const{ throw std::runtime_error("Not implemented on test type");} - virtual std::string getFactoryTypeName() const{ throw std::runtime_error("Not implemented on test type");} - virtual void validate() const{ throw std::runtime_error("Not implemented on test type");} - }; - -public: - - void testUpdateModelDoewNothing() - { - NullRebinningPresenter nullObject; - TS_ASSERT_THROWS_NOTHING(nullObject.updateModel()); - } - - void executeThrows() - { - NullRebinningPresenter nullObject; - FakeProgressAction progressAction; - FakeDataSetFactory* pFactory = new FakeDataSetFactory; - TS_ASSERT_THROWS(nullObject.execute(pFactory, progressAction, progressAction), std::runtime_error); - delete pFactory; - } - - void getAppliedGeometryXMLThrows() - { - NullRebinningPresenter nullObject; - TS_ASSERT_THROWS(nullObject.getAppliedGeometryXML(), std::runtime_error); - } - - void hasTDimensionAvailableThrows() - { - NullRebinningPresenter nullObject; - TS_ASSERT_THROWS(nullObject.hasTDimensionAvailable(), std::runtime_error); - } - - void getTimeStepValuesThrows() - { - NullRebinningPresenter nullObject; - TS_ASSERT_THROWS(nullObject.getTimeStepValues(), std::runtime_error); - } - - void getTimeStepLabelThows() - { - NullRebinningPresenter nullObject; - TS_ASSERT_THROWS(nullObject.getTimeStepLabel(), std::runtime_error); - } - - void setAxisLabelsThrows() - { - NullRebinningPresenter nullObject; - vtkDataSet *ds = vtkUnstructuredGrid::New(); - TS_ASSERT_THROWS(nullObject.setAxisLabels(ds), std::runtime_error); - ds->Delete(); - } - -}; - -#endif diff --git a/Code/Mantid/Vates/VatesAPI/test/RebinningKnowledgeSerializerTest.h b/Code/Mantid/Vates/VatesAPI/test/VatesKnowledgeSerializerTest.h similarity index 88% rename from Code/Mantid/Vates/VatesAPI/test/RebinningKnowledgeSerializerTest.h rename to Code/Mantid/Vates/VatesAPI/test/VatesKnowledgeSerializerTest.h index 8dd93b1472b9..6100f48902c0 100644 --- a/Code/Mantid/Vates/VatesAPI/test/RebinningKnowledgeSerializerTest.h +++ b/Code/Mantid/Vates/VatesAPI/test/VatesKnowledgeSerializerTest.h @@ -5,7 +5,7 @@ #include #include #include -#include "MantidVatesAPI/RebinningKnowledgeSerializer.h" +#include "MantidVatesAPI/VatesKnowledgeSerializer.h" #include "MantidAPI/IMDWorkspace.h" #include "MantidGeometry/MDGeometry/MDImplicitFunction.h" #include "MantidKernel/System.h" @@ -15,7 +15,7 @@ using namespace Mantid::VATES; -class RebinningKnowledgeSerializerTest: public CxxTest::TestSuite +class VatesKnowledgeSerializerTest: public CxxTest::TestSuite { private: @@ -39,7 +39,7 @@ class RebinningKnowledgeSerializerTest: public CxxTest::TestSuite void testNoWorkspaceThrows() { - RebinningKnowledgeSerializer generator; + VatesKnowledgeSerializer generator; Mantid::Geometry::MDImplicitFunction_sptr impFunction(new MockImplicitFunction); generator.setImplicitFunction(impFunction); TSM_ASSERT_THROWS("Cannot generate the xml without the workspace", generator.createXMLString(), std::runtime_error); @@ -55,7 +55,7 @@ void testNoLocationDoesNotThrow() EXPECT_CALL(*pImpFunction, toXMLString()).Times(1).WillRepeatedly(testing::Return("")); Mantid::Geometry::MDImplicitFunction_sptr impFunction(pImpFunction); - RebinningKnowledgeSerializer generator(LocationNotRequired); //Location is not required. + VatesKnowledgeSerializer generator(LocationNotRequired); //Location is not required. generator.setImplicitFunction(impFunction); generator.setWorkspace(workspace); @@ -68,7 +68,7 @@ void testNoNameThrows() Mantid::Geometry::MDImplicitFunction_sptr impFunction(new MockImplicitFunction); MockIMDWorkspace* pWorkspace = new MockIMDWorkspace; boost::shared_ptr workspace(pWorkspace); - RebinningKnowledgeSerializer generator; + VatesKnowledgeSerializer generator; generator.setImplicitFunction(impFunction); generator.setWorkspace(workspace); @@ -83,7 +83,7 @@ void testCreateXMLWithComponents() //Uses individual setters for geometry, locat EXPECT_CALL(*pImpFunction, toXMLString()).Times(1).WillRepeatedly(testing::Return("")); Mantid::Geometry::MDImplicitFunction_sptr impFunction(pImpFunction); - RebinningKnowledgeSerializer generator; + VatesKnowledgeSerializer generator; //Apply setters. generator.setImplicitFunction(impFunction); generator.setWorkspaceName("name"); @@ -96,7 +96,7 @@ void testCreateXMLWithComponents() //Uses individual setters for geometry, locat void testCreateXMLWithoutFunction() { - RebinningKnowledgeSerializer generator; + VatesKnowledgeSerializer generator; //Apply setters. generator.setWorkspaceName("name"); generator.setGeometryXML(""); @@ -107,7 +107,7 @@ void testCreateXMLWithoutFunction() void testGetGeometryXML() { - RebinningKnowledgeSerializer generator; + VatesKnowledgeSerializer generator; generator.setWorkspaceName("name"); std::string dimensionXMLString = ""; generator.setGeometryXML(dimensionXMLString); @@ -118,8 +118,8 @@ void testGetGeometryXML() void testHasFunction() { - RebinningKnowledgeSerializer withoutFunction; - RebinningKnowledgeSerializer withFunction; + VatesKnowledgeSerializer withoutFunction; + VatesKnowledgeSerializer withFunction; Mantid::Geometry::MDImplicitFunction_sptr impFunction(new MockImplicitFunction); withFunction.setImplicitFunction(impFunction); @@ -130,21 +130,21 @@ void testHasFunction() void testHasGeometryInfoWithoutGeometry() { //Note that functions do not apply to this test set. - RebinningKnowledgeSerializer withoutGeometry; + VatesKnowledgeSerializer withoutGeometry; withoutGeometry.setWorkspaceName("-"); TSM_ASSERT_EQUALS("No Geometry provided. ::hasGeometryInfo() should return false.", false, withoutGeometry.hasGeometryInfo()); } void testHasGeometryInfoWithoutWSName() { - RebinningKnowledgeSerializer withoutWSName; + VatesKnowledgeSerializer withoutWSName; withoutWSName.setGeometryXML("-"); TSM_ASSERT_EQUALS("No WS name provided. ::hasGeometryInfo() should return false.", false, withoutWSName.hasGeometryInfo()); } void testHasGeometryAndWSInfo() { - RebinningKnowledgeSerializer withFullGeometryAndWSInfo; + VatesKnowledgeSerializer withFullGeometryAndWSInfo; withFullGeometryAndWSInfo.setGeometryXML("-"); withFullGeometryAndWSInfo.setWorkspaceName("-"); TSM_ASSERT_EQUALS("All geometry and ws information has been provided. ::hasGeometryInfo() should return true.", true, withFullGeometryAndWSInfo.hasGeometryInfo()); diff --git a/Code/Mantid/Vates/VatesAPI/test/vtkDataSetToGeometryTest.h b/Code/Mantid/Vates/VatesAPI/test/vtkDataSetToGeometryTest.h index fa12994629a1..66c7e23ade2a 100644 --- a/Code/Mantid/Vates/VatesAPI/test/vtkDataSetToGeometryTest.h +++ b/Code/Mantid/Vates/VatesAPI/test/vtkDataSetToGeometryTest.h @@ -10,7 +10,7 @@ #include "vtkCharArray.h" #include "MantidVatesAPI/vtkRectilinearGrid_Silent.h" -#include "MantidVatesAPI/RebinningCutterXMLDefinitions.h" +#include "MantidVatesAPI/VatesXMLDefinitions.h" class vtkDataSetToGeometryTest : public CxxTest::TestSuite { diff --git a/Code/Mantid/Vates/VatesAPI/test/vtkMDHistoHex4DFactoryTest.h b/Code/Mantid/Vates/VatesAPI/test/vtkMDHistoHex4DFactoryTest.h index b415f478277d..75307ce3110e 100644 --- a/Code/Mantid/Vates/VatesAPI/test/vtkMDHistoHex4DFactoryTest.h +++ b/Code/Mantid/Vates/VatesAPI/test/vtkMDHistoHex4DFactoryTest.h @@ -50,8 +50,11 @@ class vtkMDHistoHex4DFactoryTest: public CxxTest::TestSuite vtkUnstructuredGrid* aboveProduct = dynamic_cast(above.create(progressAction)); TS_ASSERT_EQUALS((10*10*10), insideProduct->GetNumberOfCells()); - TS_ASSERT_EQUALS(0, belowProduct->GetNumberOfCells()); - TS_ASSERT_EQUALS(0, aboveProduct->GetNumberOfCells()); + + // This has changed, in order to ensure that we do not pass on empty + // workspaces. A single point is created in the center by the vtkNullUnstructuredGrid + TS_ASSERT_EQUALS(1, belowProduct->GetNumberOfCells()); + TS_ASSERT_EQUALS(1, aboveProduct->GetNumberOfCells()); } void testProgressUpdating() diff --git a/Code/Mantid/Vates/VatesAPI/test/vtkMDHistoHexFactoryTest.h b/Code/Mantid/Vates/VatesAPI/test/vtkMDHistoHexFactoryTest.h index 7035784d6f68..73e800f03bad 100644 --- a/Code/Mantid/Vates/VatesAPI/test/vtkMDHistoHexFactoryTest.h +++ b/Code/Mantid/Vates/VatesAPI/test/vtkMDHistoHexFactoryTest.h @@ -48,8 +48,11 @@ class vtkMDHistoHexFactoryTest: public CxxTest::TestSuite vtkUnstructuredGrid* aboveProduct = dynamic_cast(above.create(progressUpdate)); TS_ASSERT_EQUALS((10*10*10), insideProduct->GetNumberOfCells()); - TS_ASSERT_EQUALS(0, belowProduct->GetNumberOfCells()); - TS_ASSERT_EQUALS(0, aboveProduct->GetNumberOfCells()); + + // This has changed, in order to ensure that we do not pass on empty + // workspaces. A single point is created in the center by the vtkNullUnstructuredGrid + TS_ASSERT_EQUALS(1, belowProduct->GetNumberOfCells()); + TS_ASSERT_EQUALS(1, aboveProduct->GetNumberOfCells()); } void testSignalAspects() diff --git a/Code/Mantid/Vates/VatesAPI/test/vtkMDHistoQuadFactoryTest.h b/Code/Mantid/Vates/VatesAPI/test/vtkMDHistoQuadFactoryTest.h index afee56fcfeae..612edc4c54c6 100644 --- a/Code/Mantid/Vates/VatesAPI/test/vtkMDHistoQuadFactoryTest.h +++ b/Code/Mantid/Vates/VatesAPI/test/vtkMDHistoQuadFactoryTest.h @@ -81,9 +81,10 @@ class vtkMDHistoQuadFactoryTest: public CxxTest::TestSuite above.initialize(ws_sptr); vtkUnstructuredGrid* aboveProduct = dynamic_cast(above.create(progressUpdate)); - // No points nor cells are created if nothing is within range - TS_ASSERT_EQUALS(0, aboveProduct->GetNumberOfCells()); - TS_ASSERT_EQUALS(0, aboveProduct->GetNumberOfPoints()); + // This changed from previously, in order to ensure that we do not pass on empty + // workspaces. A single point is created in the center by the vtkNullUnstructuredGrid + TS_ASSERT_EQUALS(1, aboveProduct->GetNumberOfCells()); + TS_ASSERT_EQUALS(1, aboveProduct->GetNumberOfPoints()); } void testBelowThreshold() @@ -99,9 +100,10 @@ class vtkMDHistoQuadFactoryTest: public CxxTest::TestSuite below.initialize(ws_sptr); vtkUnstructuredGrid* belowProduct = dynamic_cast(below.create(progressUpdate)); - // No points nor cells are created if nothing is within range - TS_ASSERT_EQUALS(0, belowProduct->GetNumberOfCells()); - TS_ASSERT_EQUALS(0, belowProduct->GetNumberOfPoints()); + // This changed from previously, in order to ensure that we do not pass on empty + // workspaces. A single point is created in the center by the vtkNullUnstructuredGrid + TS_ASSERT_EQUALS(1, belowProduct->GetNumberOfCells()); + TS_ASSERT_EQUALS(1, belowProduct->GetNumberOfPoints()); } void testInitializationDelegates() diff --git a/Code/Mantid/Vates/VatesAPI/test/vtkNullUnstructuredGridTest.h b/Code/Mantid/Vates/VatesAPI/test/vtkNullUnstructuredGridTest.h new file mode 100644 index 000000000000..82327106c416 --- /dev/null +++ b/Code/Mantid/Vates/VatesAPI/test/vtkNullUnstructuredGridTest.h @@ -0,0 +1,36 @@ +#ifndef VTKNULLUNSTRUCTUREDGRID_TEST_H_ +#define VTKNULLUNSTRUCTUREDGRID_TEST_H_ + +#include "MantidVatesAPI/vtkNullUnstructuredGrid.h" +#include "MockObjects.h" +#include +#include +#include + +#include +#include + +using namespace Mantid::VATES; + +class vtkNullUnstructuredGridTest : public CxxTest::TestSuite { +public: + void testCorrectVtkDataSetIsReturned() { + vtkNullUnstructuredGrid grid; + + vtkUnstructuredGrid *ugrid = NULL; + + TSM_ASSERT_THROWS_NOTHING( + "Should create the unstructured grid without problems.", + ugrid = grid.createNullData()); + TSM_ASSERT("Should have exactly one point", + ugrid->GetNumberOfPoints() == 1); + TSM_ASSERT("Should have exactly one cell", ugrid->GetNumberOfCells() == 1); + vtkPoints *p = ugrid->GetPoints(); + double coord[3]; + p->GetPoint(0, coord); + TSM_ASSERT("X should be in the center", coord[0] == 0.0); + TSM_ASSERT("X should be in the center", coord[1] == 0.0); + TSM_ASSERT("X should be in the center", coord[2] == 0.0); + } +}; +#endif diff --git a/Code/Mantid/Vates/VatesAPI/test/vtkPeakMarkerFactoryTest.h b/Code/Mantid/Vates/VatesAPI/test/vtkPeakMarkerFactoryTest.h index 5e4fb59411a2..78406aba6e0e 100644 --- a/Code/Mantid/Vates/VatesAPI/test/vtkPeakMarkerFactoryTest.h +++ b/Code/Mantid/Vates/VatesAPI/test/vtkPeakMarkerFactoryTest.h @@ -29,7 +29,7 @@ class MockPeaksWorkspace : public PeaksWorkspace { public: MOCK_METHOD1(setInstrument, void (Mantid::Geometry::Instrument_const_sptr inst)); - MOCK_METHOD0(getInstrument, Mantid::Geometry::Instrument_const_sptr ()); + MOCK_CONST_METHOD0(getInstrument, Mantid::Geometry::Instrument_const_sptr ()); MOCK_CONST_METHOD0(clone, Mantid::DataObjects::PeaksWorkspace*()); MOCK_CONST_METHOD0(getNumberPeaks, int()); MOCK_METHOD1(removePeak, void (int peakNum) ); diff --git a/Code/Mantid/Vates/VatesSimpleGui/QtWidgets/CMakeLists.txt b/Code/Mantid/Vates/VatesSimpleGui/QtWidgets/CMakeLists.txt index df8c97093ef2..9d3d7a37cd72 100644 --- a/Code/Mantid/Vates/VatesSimpleGui/QtWidgets/CMakeLists.txt +++ b/Code/Mantid/Vates/VatesSimpleGui/QtWidgets/CMakeLists.txt @@ -36,7 +36,8 @@ qt4_wrap_ui( UI_BUILT_SOURCES include_directories( inc ${CMAKE_CURRENT_BINARY_DIR} - ${QWT_INCLUDE_DIR} + ${QWT_INCLUDE_DIR} + ${CMAKE_SOURCE_DIR}/MantidQt/API/inc ) set( ALL_FILES @@ -61,6 +62,7 @@ ${POCO_LIBRARIES} ${QT_LIBRARIES} ${QWT_LIBRARIES} ${MANTID_SUBPROJECT_LIBS} +MantidQtAPI ) install( TARGETS VatesSimpleGuiQtWidgets ${SYSTEM_PACKAGE_TARGET} DESTINATION ${PVPLUGINS_DIR} ) diff --git a/Code/Mantid/Vates/VatesSimpleGui/QtWidgets/inc/MantidVatesSimpleGuiQtWidgets/ModeControlWidget.h b/Code/Mantid/Vates/VatesSimpleGui/QtWidgets/inc/MantidVatesSimpleGuiQtWidgets/ModeControlWidget.h index fd40735a3838..a25cc3bfac1e 100644 --- a/Code/Mantid/Vates/VatesSimpleGui/QtWidgets/inc/MantidVatesSimpleGuiQtWidgets/ModeControlWidget.h +++ b/Code/Mantid/Vates/VatesSimpleGui/QtWidgets/inc/MantidVatesSimpleGuiQtWidgets/ModeControlWidget.h @@ -6,6 +6,7 @@ #include #include +#include namespace Mantid { @@ -74,7 +75,7 @@ public slots: void setToSelectedView(ModeControlWidget::Views view); /// Convert a string into an enum - ModeControlWidget::Views getViewFromString(std::string view); + ModeControlWidget::Views getViewFromString(QString view); signals: /** @@ -107,7 +108,7 @@ protected slots: private: Ui::ModeControlWidgetClass ui; ///< The mode control widget's UI form - std::map mapFromStringToView; //< Holds the mapping from the a string to an associated enum + std::map mapFromStringToView; //< Holds the mapping from the a string to an associated enum }; } diff --git a/Code/Mantid/Vates/VatesSimpleGui/QtWidgets/src/ModeControlWidget.cpp b/Code/Mantid/Vates/VatesSimpleGui/QtWidgets/src/ModeControlWidget.cpp index 06f8683498a4..24494dd8077e 100644 --- a/Code/Mantid/Vates/VatesSimpleGui/QtWidgets/src/ModeControlWidget.cpp +++ b/Code/Mantid/Vates/VatesSimpleGui/QtWidgets/src/ModeControlWidget.cpp @@ -1,5 +1,6 @@ #include "MantidVatesSimpleGuiQtWidgets/ModeControlWidget.h" #include "MantidKernel/Logger.h" +#include "MantidQtAPI/MdConstants.h" #include #include @@ -30,10 +31,11 @@ ModeControlWidget::ModeControlWidget(QWidget *parent) : QWidget(parent) this, SLOT(onSplatterPlotViewButtonClicked())); // Add the mapping from string to the view enum - mapFromStringToView.insert(std::pair("STANDARD", ModeControlWidget::STANDARD)); - mapFromStringToView.insert(std::pair("THREESLICE", ModeControlWidget::THREESLICE)); - mapFromStringToView.insert(std::pair("MULTISLICE", ModeControlWidget::MULTISLICE)); - mapFromStringToView.insert(std::pair("SPLATTERPLOT", ModeControlWidget::SPLATTERPLOT)); + MantidQt::API::MdConstants mdConstants; + mapFromStringToView.insert(std::pair(mdConstants.getStandardView(), ModeControlWidget::STANDARD)); + mapFromStringToView.insert(std::pair(mdConstants.getThreeSliceView(), ModeControlWidget::THREESLICE)); + mapFromStringToView.insert(std::pair(mdConstants.getMultiSliceView(), ModeControlWidget::MULTISLICE)); + mapFromStringToView.insert(std::pair(mdConstants.getSplatterPlotView(), ModeControlWidget::SPLATTERPLOT)); } ModeControlWidget::~ModeControlWidget() @@ -192,11 +194,9 @@ void ModeControlWidget::enableViewButton(ModeControlWidget::Views mode, * @param view A selected view. * @returns The selected view as enum or the standard view. */ -ModeControlWidget::Views ModeControlWidget::getViewFromString(std::string view) +ModeControlWidget::Views ModeControlWidget::getViewFromString(QString view) { - std::transform(view.begin(), view.end(), view.begin(), toupper); - - if (!view.empty() && mapFromStringToView.count(view) == 1) + if (!view.isEmpty() && mapFromStringToView.count(view) == 1) { return mapFromStringToView[view]; } diff --git a/Code/Mantid/Vates/VatesSimpleGui/StandAloneExec/CMakeLists.txt b/Code/Mantid/Vates/VatesSimpleGui/StandAloneExec/CMakeLists.txt index 0b35b412adfe..f2af04d6f4fd 100644 --- a/Code/Mantid/Vates/VatesSimpleGui/StandAloneExec/CMakeLists.txt +++ b/Code/Mantid/Vates/VatesSimpleGui/StandAloneExec/CMakeLists.txt @@ -9,6 +9,8 @@ include_directories( ${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_CURRENT_BINARY_DIR}/../QtWidgets ${CMAKE_CURRENT_BINARY_DIR}/../ViewWidgets + ${CMAKE_SOURCE_DIR}/MantidQt/MantidWidgets/inc + ${CMAKE_BINARY_DIR}/MantidQt/MantidWidgets ) # These are the C++ files to be compiled. diff --git a/Code/Mantid/Vates/VatesSimpleGui/ViewWidgets/CMakeLists.txt b/Code/Mantid/Vates/VatesSimpleGui/ViewWidgets/CMakeLists.txt index df45ab427a9f..01b95a20f3fd 100644 --- a/Code/Mantid/Vates/VatesSimpleGui/ViewWidgets/CMakeLists.txt +++ b/Code/Mantid/Vates/VatesSimpleGui/ViewWidgets/CMakeLists.txt @@ -3,12 +3,16 @@ project( MantidVatesSimpleGuiViewWidgets ) # These are the C++ files to be compiled. set( INCLUDE_FILES inc/MantidVatesSimpleGuiViewWidgets/AutoScaleRangeGenerator.h + inc/MantidVatesSimpleGuiViewWidgets/BackgroundRgbProvider.h + inc/MantidVatesSimpleGuiViewWidgets/ColorMapManager.h inc/MantidVatesSimpleGuiViewWidgets/ColorSelectionWidget.h inc/MantidVatesSimpleGuiViewWidgets/ColorUpdater.h inc/MantidVatesSimpleGuiViewWidgets/LibHelper.h inc/MantidVatesSimpleGuiViewWidgets/MdViewerWidget.h inc/MantidVatesSimpleGuiViewWidgets/MultisliceView.h + inc/MantidVatesSimpleGuiViewWidgets/RebinAlgorithmDialogProvider.h inc/MantidVatesSimpleGuiViewWidgets/SaveScreenshotReaction.h + inc/MantidVatesSimpleGuiViewWidgets/RebinnedSourcesManager.h inc/MantidVatesSimpleGuiViewWidgets/StandardView.h inc/MantidVatesSimpleGuiViewWidgets/SplatterPlotView.h inc/MantidVatesSimpleGuiViewWidgets/ThreesliceView.h @@ -19,11 +23,15 @@ set( INCLUDE_FILES set( SOURCE_FILES src/AutoScaleRangeGenerator.cpp + src/BackgroundRgbProvider.cpp + src/ColorMapManager.cpp src/ColorSelectionWidget.cpp src/ColorUpdater.cpp src/MdViewerWidget.cpp src/MultisliceView.cpp + src/RebinAlgorithmDialogProvider.cpp src/SaveScreenshotReaction.cpp + src/RebinnedSourcesManager.cpp src/StandardView.cpp src/SplatterPlotView.cpp src/ThreesliceView.cpp @@ -31,6 +39,10 @@ set( SOURCE_FILES src/ViewBase.cpp ) +set( TEST_FILES + test/unitTests/ColorMapManagerTest.h +) + # These are the headers to be preprocessed using # Qt's moc preprocessor. qt4_wrap_cpp( MOC_SOURCES @@ -38,6 +50,7 @@ qt4_wrap_cpp( MOC_SOURCES inc/MantidVatesSimpleGuiViewWidgets/MdViewerWidget.h inc/MantidVatesSimpleGuiViewWidgets/MultisliceView.h inc/MantidVatesSimpleGuiViewWidgets/SaveScreenshotReaction.h + inc/MantidVatesSimpleGuiViewWidgets/RebinnedSourcesManager.h inc/MantidVatesSimpleGuiViewWidgets/StandardView.h inc/MantidVatesSimpleGuiViewWidgets/SplatterPlotView.h inc/MantidVatesSimpleGuiViewWidgets/ThreesliceView.h @@ -65,6 +78,7 @@ include_directories( inc ${CMAKE_SOURCE_DIR}/MantidQt/API/inc ${CMAKE_SOURCE_DIR}/MantidQt/MantidWidgets/inc + ${CMAKE_BINARY_DIR}/MantidQt/MantidWidgets ${CMAKE_SOURCE_DIR}/MantidQt/SliceViewer/inc ${CMAKE_BINARY_DIR}/MantidQt/SliceViewer ${CMAKE_SOURCE_DIR}/MantidQt/Factory/inc @@ -105,8 +119,25 @@ VatesAPI ${MANTID_SUBPROJECT_LIBS} MantidQtSliceViewer MantidQtFactory +MantidWidgets ) +# Create test file projects +if( CXXTEST_FOUND AND GMOCK_FOUND AND GTEST_FOUND ) + include_directories ( SYSTEM ${CXXTEST_INCLUDE_DIR} ${GMOCK_INCLUDE_DIR} ${GTEST_INCLUDE_DIR} ) + + include_directories( inc ../../../Framework/TestHelpers/inc ../../../Framework/DataHandling/inc ../../../Framework/DataObjects/inc) + set ( TESTHELPER_SRCS ../../../Framework/TestHelpers/src/ComponentCreationHelper.cpp + ../../../Framework/TestHelpers/src/WorkspaceCreationHelper.cpp + ../../../Framework/TestHelpers/src/MDEventsTestHelper.cpp + ../../../Framework/TestHelpers/src/StartFrameworkManager.cpp ) + cxxtest_add_test( VatesSimpleGuiViewWidgetsTest ${TEST_FILES} ) + target_link_libraries( VatesSimpleGuiViewWidgetsTest VatesSimpleGuiViewWidgets DataHandling Kernel DataObjects ${GMOCK_LIBRARIES} ${GTEST_LIBRARIES} ) + add_dependencies( AllTests VatesSimpleGuiViewWidgetsTest ) + # Add to the 'UnitTests' group in VS + set_property ( TARGET VatesSimpleGuiViewWidgetsTest PROPERTY FOLDER "UnitTests" ) +endif() + configure_file ( ${CMAKE_CURRENT_SOURCE_DIR}/inc/MantidVatesSimpleGuiViewWidgets/LibHelper.h.in ${CMAKE_CURRENT_SOURCE_DIR}/inc/MantidVatesSimpleGuiViewWidgets/LibHelper.h ) diff --git a/Code/Mantid/Vates/VatesSimpleGui/ViewWidgets/inc/MantidVatesSimpleGuiViewWidgets/BackgroundRgbProvider.h b/Code/Mantid/Vates/VatesSimpleGui/ViewWidgets/inc/MantidVatesSimpleGuiViewWidgets/BackgroundRgbProvider.h new file mode 100644 index 000000000000..4aa78d305fba --- /dev/null +++ b/Code/Mantid/Vates/VatesSimpleGui/ViewWidgets/inc/MantidVatesSimpleGuiViewWidgets/BackgroundRgbProvider.h @@ -0,0 +1,111 @@ +#ifndef BACKGROUNDRGB_PROVIDER_H_ +#define BACKGROUNDRGB_PROVIDER_H_ + +#include "MantidVatesSimpleGuiViewWidgets/WidgetDllOption.h" +#include "MantidQtAPI/MdSettings.h" +#include +#include +#include + +#if defined(__INTEL_COMPILER) + #pragma warning disable 1170 +#endif + +#include + +#if defined(__INTEL_COMPILER) + #pragma warning enable 1170 +#endif + +class vtkObject; + +namespace Mantid +{ + namespace Vates + { + namespace SimpleGui + { + /** + * + This class gets the default color values for the background of the view. + + @date 10/12/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 EXPORT_OPT_MANTIDVATES_SIMPLEGUI_VIEWWIDGETS BackgroundRgbProvider + { + public: + BackgroundRgbProvider(); + + ~BackgroundRgbProvider(); + + /** + * Set the Rgb values for the color of the view's background. + * @param viewSwitched Is this the initial loading or were the views switched? + * @param view The view which has its background color set. + */ + void setBackgroundColor(pqRenderView* view, bool viewSwitched); + + /** + * Listen to a change in the background color + *@param view The view which we want to listen to. + */ + void observe(pqRenderView* view); + + /** + * Update the last session background color. + */ + void update(); + + private: + /** + * Get the Rgb values for the color of the view's background from the user setting. + * @param viewSwitched Is this the initial loading or were the views switched? + * @returns A vector with the RGB values + */ + std::vector getRgbFromSetting(bool viewSwitched); + + /** + * Get the Rgb values for the color of the view's background + * @param viewSwitched Is this the initial loading or were the views switched? + * @returns A vector with the RGB values + */ + std::vector getRgb(bool viewSwitched); + + /** + * Callback function for background color changing events + *@param caller Calling object. + *@param eventId Not used. + *@param clientData Not used. + *@parma callData Not used. + */ + static void backgroundColorChangeCallbackFunction(vtkObject* caller, long unsigned int vtkNotUsed(eventId), void* vtkNotUsed(clientData), void* vtkNotUsed(callData)); + + static QColor currentBackgroundColor; + + MantidQt::API::MdSettings m_mdSettings; + }; + } + } +} +#endif \ No newline at end of file diff --git a/Code/Mantid/Vates/VatesSimpleGui/ViewWidgets/inc/MantidVatesSimpleGuiViewWidgets/ColorMapManager.h b/Code/Mantid/Vates/VatesSimpleGui/ViewWidgets/inc/MantidVatesSimpleGuiViewWidgets/ColorMapManager.h new file mode 100644 index 000000000000..ac9824a7e764 --- /dev/null +++ b/Code/Mantid/Vates/VatesSimpleGui/ViewWidgets/inc/MantidVatesSimpleGuiViewWidgets/ColorMapManager.h @@ -0,0 +1,93 @@ +#ifndef COLORMAP_MANAGER_H_ +#define COLORMAP_MANAGER_H_ + +#include "MantidVatesSimpleGuiViewWidgets/WidgetDllOption.h" +#include "MantidQtAPI/MdSettings.h" +#include +#include + + +namespace Mantid +{ + namespace Vates + { + namespace SimpleGui + { + /** + * + This class handles the colormaps which are loaded into the + + @date 10/12/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 EXPORT_OPT_MANTIDVATES_SIMPLEGUI_VIEWWIDGETS ColorMapManager + { + public: + ColorMapManager(); + + virtual ~ColorMapManager(); + + /** + * Get default color map + * @param viewSwitched If the view has switched or not. + * @returns index The index of the default color map in the list of color maps. + */ + int getDefaultColorMapIndex(bool viewSwitched); + + /** + * Read in and store the available color maps + * @param xml The path to the colormap. + */ + void readInColorMap(std::string xml); + + /** + * Get index for colormap + * @param colorMap The name of the color map. + * @returns The index of the colormap in the Paraview store. + */ + int getColorMapIndex(std::string colorMap); + + /** + * Check if a color map already has been recorded. + * @param colorMap The name of the color map. + * @returns True if the name already exists + */ + bool isRecordedColorMap(std::string colorMap); + + /** + * Record the new active color map when the user selected a new one. + * @param index The index of the color map in the color map list. + */ + void setNewActiveColorMap(int index); + + private: + int m_indexCounter; + std::map m_nameToIndex; + std::map m_indexToName; + + MantidQt::API::MdSettings m_mdSettings; + }; + } + } +} +#endif \ No newline at end of file diff --git a/Code/Mantid/Vates/VatesSimpleGui/ViewWidgets/inc/MantidVatesSimpleGuiViewWidgets/ColorSelectionWidget.h b/Code/Mantid/Vates/VatesSimpleGui/ViewWidgets/inc/MantidVatesSimpleGuiViewWidgets/ColorSelectionWidget.h index 1499fd57a988..87216f222ddf 100644 --- a/Code/Mantid/Vates/VatesSimpleGui/ViewWidgets/inc/MantidVatesSimpleGuiViewWidgets/ColorSelectionWidget.h +++ b/Code/Mantid/Vates/VatesSimpleGui/ViewWidgets/inc/MantidVatesSimpleGuiViewWidgets/ColorSelectionWidget.h @@ -4,6 +4,8 @@ #include "ui_ColorSelectionWidget.h" #include "MantidVatesSimpleGuiViewWidgets/WidgetDllOption.h" #include "MantidQtAPI/MdConstants.h" +#include "boost/scoped_ptr.hpp" +#include "MantidVatesSimpleGuiViewWidgets/ColorMapManager.h" #include class pqColorMapModel; @@ -63,6 +65,8 @@ class EXPORT_OPT_MANTIDVATES_SIMPLEGUI_VIEWWIDGETS ColorSelectionWidget : public double getMinRange(); /// Get the maximum color range value double getMaxRange(); + /// Load the default color map + void loadColorMap(bool viewSwitched); public slots: /// Set state for all control widgets. @@ -122,9 +126,10 @@ protected slots: /// Set min smaller max void setMinSmallerMax(double& min, double& max); + boost::scoped_ptr colorMapManager; ///< Keeps track of the available color maps. + QDoubleValidator* m_minValidator; QDoubleValidator* m_maxValidator; - double m_minHistoric; double m_maxHistoric; diff --git a/Code/Mantid/Vates/VatesSimpleGui/ViewWidgets/inc/MantidVatesSimpleGuiViewWidgets/MdViewerWidget.h b/Code/Mantid/Vates/VatesSimpleGui/ViewWidgets/inc/MantidVatesSimpleGuiViewWidgets/MdViewerWidget.h index 2ea0f5bd9198..425e7c132853 100644 --- a/Code/Mantid/Vates/VatesSimpleGui/ViewWidgets/inc/MantidVatesSimpleGuiViewWidgets/MdViewerWidget.h +++ b/Code/Mantid/Vates/VatesSimpleGui/ViewWidgets/inc/MantidVatesSimpleGuiViewWidgets/MdViewerWidget.h @@ -3,12 +3,19 @@ #include "ui_MdViewerWidget.h" #include "MantidVatesSimpleGuiViewWidgets/WidgetDllOption.h" +#include "MantidVatesSimpleGuiViewWidgets/RebinAlgorithmDialogProvider.h" +#include "MantidVatesSimpleGuiViewWidgets/RebinnedSourcesManager.h" #include "MantidQtAPI/VatesViewerInterface.h" #include "MantidQtAPI/WorkspaceObserver.h" +#include "boost/shared_ptr.hpp" +#include "MantidQtAPI/MdConstants.h" +#include "MantidQtAPI/MdSettings.h" +#include "MantidVatesSimpleGuiViewWidgets/BackgroundRgbProvider.h" #include #include +#include class pqLoadDataReaction; class pqPipelineSource; @@ -31,7 +38,7 @@ namespace SimpleGui class RotationPointDialog; class SaveScreenshotReaction; class ViewBase; - +class RebinDialog; /** * This class represents the central widget for handling VATES visualization @@ -101,6 +108,12 @@ protected slots: void renderingDone(); /// Execute view switch. void switchViews(ModeControlWidget::Views v); + /// On rebin + void onRebin(std::string algorithmType); + /// On unbin + void onUnbin(); + /// On switching an MDEvent source to a temporary source. + void onSwitchSoures(std::string rebinnedWorkspaceName, std::string sourceType); protected: /// Handle workspace preDeletion tasks. @@ -127,7 +140,11 @@ protected slots: pqViewSettingsReaction *viewSettings; ///< Holder for the view settings reaction bool viewSwitched; ModeControlWidget::Views initialView; ///< Holds the initial view - + MantidQt::API::MdSettings mdSettings;///& techniques, const std::string& keyword) const; /// Reset the current view to the appropriate initial view. void resetCurrentView(int workspaceType, const std::string& instrumentName); + /// Render rebinned workspace + void prepareRebinnedWorkspace(const std::string rebinnedWorkspaceName, std::string sourceType); /// Set visibility listener void setVisibilityListener(); + /// Set up the default color for the background of the view. + void setColorForBackground(); + /// Render the original workspace + void renderOriginalWorkspace(const std::string originalWorkspaceName); + /// Delete a specific workspace + void deleteSpecificSource(std::string workspaceName); + /// Remove the rebinning when switching views or otherwise. + void removeRebinning(pqPipelineSource* source, bool forced, ModeControlWidget::Views view = ModeControlWidget::STANDARD); + /// Remove all rebinned sources + void removeAllRebinning(ModeControlWidget::Views view); + /// Sets a listener for when sources are being destroyed + void setDestroyedListener(); }; } // SimpleGui diff --git a/Code/Mantid/Vates/VatesSimpleGui/ViewWidgets/inc/MantidVatesSimpleGuiViewWidgets/RebinAlgorithmDialogProvider.h b/Code/Mantid/Vates/VatesSimpleGui/ViewWidgets/inc/MantidVatesSimpleGuiViewWidgets/RebinAlgorithmDialogProvider.h new file mode 100644 index 000000000000..5d9768accfc6 --- /dev/null +++ b/Code/Mantid/Vates/VatesSimpleGui/ViewWidgets/inc/MantidVatesSimpleGuiViewWidgets/RebinAlgorithmDialogProvider.h @@ -0,0 +1,77 @@ +#ifndef REBINALGORITHMDIALOGPROVIDER_H_ +#define REBINALGORITHMDIALOGPROVIDER_H_ + +#include "MantidVatesSimpleGuiViewWidgets/WidgetDllOption.h" + +#include "MantidVatesAPI/ADSWorkspaceProvider.h" +#include "MantidAPI/IMDEventWorkspace.h" +#include "MantidAPI/Algorithm.h" +#include "MantidQtAPI/AlgorithmDialog.h" +#include "MantidQtMantidWidgets/SlicingAlgorithmDialog.h" + +namespace Mantid +{ + namespace Vates + { + namespace SimpleGui + { + /** + * + This class coordinates the rebinning of a workspace and updates the pipeline and view to make the changes of the + underlying workspace visible. + + @date 15/01/2015 + + Copyright © 2011 ISIS Rutherford Appleton Laboratory, NScD Oak Ridge National Laboratory & European Spallation Source + + This file is part of Mantid. + + Mantid is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + Mantid is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + + File change history is stored at: + Code Documentation is available at: + */ + class EXPORT_OPT_MANTIDVATES_SIMPLEGUI_VIEWWIDGETS RebinAlgorithmDialogProvider + { + public: + RebinAlgorithmDialogProvider(QWidget* parent); + + ~RebinAlgorithmDialogProvider(); + + void showDialog(std::string inputWorkspace, std::string outputWorkspace, std::string algorithmType); + + private: + MantidQt::API::AlgorithmDialog* createDialog(Mantid::API::IAlgorithm_sptr algorithm, std::string inputWorkspace, std::string outputWorkspace, std::string algorithmType); + + void getPresetsForSliceMDAlgorithmDialog( std::string inputWorkspace, std::string outputWorkspace, QHash& presets); + + void setAxisDimensions(MantidQt::MantidWidgets::SlicingAlgorithmDialog* dialog, std::string inputWorkspace); + + Mantid::API::IMDEventWorkspace_sptr getWorkspace(std::string workspaceName); + + Mantid::API::IAlgorithm_sptr createAlgorithm(const std::string& algName, int version); + + Mantid::VATES::ADSWorkspaceProvider m_adsWorkspaceProvider; + + QString m_lblInputWorkspace; + QString m_lblOutputWorkspace; + size_t m_binCutOffValue; + QWidget* m_parent; + }; + + } // SimpleGui + } // Vates +} // Mantid + +#endif diff --git a/Code/Mantid/Vates/VatesSimpleGui/ViewWidgets/inc/MantidVatesSimpleGuiViewWidgets/RebinnedSourcesManager.h b/Code/Mantid/Vates/VatesSimpleGui/ViewWidgets/inc/MantidVatesSimpleGuiViewWidgets/RebinnedSourcesManager.h new file mode 100644 index 000000000000..039006502c62 --- /dev/null +++ b/Code/Mantid/Vates/VatesSimpleGui/ViewWidgets/inc/MantidVatesSimpleGuiViewWidgets/RebinnedSourcesManager.h @@ -0,0 +1,128 @@ +#ifndef REBINNEDSOURCESMANAGER_H_ +#define REBINNEDSOURCESMANAGER_H_ + +#include "MantidVatesSimpleGuiViewWidgets/WidgetDllOption.h" +#include "MantidQtAPI/WorkspaceObserver.h" +#include "MantidAPI/Workspace.h" + +// Have to deal with ParaView warnings and Intel compiler the hard way. +#if defined(__INTEL_COMPILER) + #pragma warning disable 1170 +#endif + +#include +#include +#include + +#if defined(__INTEL_COMPILER) + #pragma warning enable 1170 +#endif + +#include +#include +#include + +namespace Mantid +{ + namespace Vates + { + namespace SimpleGui + { + /** + * + This class keeps track of the MDEvent workspaces and associated rebinned workspaces. Rebinning requires temporary workspaces instead of + the original MDEvent workspaces. This class switches between these types of sources. + + @date 21/01/2015 + + Copyright © 2011 ISIS Rutherford Appleton Laboratory, NScD Oak Ridge National Laboratory & European Spallation Source + + This file is part of Mantid. + + Mantid is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + Mantid is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + + File change history is stored at: + Code Documentation is available at: + */ + class EXPORT_OPT_MANTIDVATES_SIMPLEGUI_VIEWWIDGETS RebinnedSourcesManager :public QWidget, MantidQt::API::WorkspaceObserver + { + Q_OBJECT + public: + RebinnedSourcesManager(QWidget* parent = 0); + + ~RebinnedSourcesManager(); + + void checkSource(pqPipelineSource* source, std::string& inputWorkspace, std::string& outputWorkspace, std::string algorithmType); + + void repipeRebinnedSource(std::string rebinnedSource, std::string& sourceToBeDeleted); + + void repipeOriginalSource(std::string rebinnedSource, std::string originalSource); + + void getStoredWorkspaceNames(pqPipelineSource* source, std::string& originalWorkspaceName, std::string& rebinnedWorkspaceName); + + void registerRebinnedSource(pqPipelineSource* source); + + bool isRebinnedSource(std::string name); + + signals: + void switchSources(std::string rebinnedWorkspaceName, std::string sourceType); + + void triggerAcceptForNewFilters(); + protected: + void addHandle(const std::string &workspaceName, const boost::shared_ptr workspace); + + void preDeleteHandle(const std::string &wsName, const boost::shared_ptr ); + + private slots: + void onRebinnedSourceDestroyed(); + + private: + std::map m_originalWorkspaceToRebinnedWorkspace; ///< Holds the mapping from the original source to the rebinned source + + std::map m_rebinnedWorkspaceToOriginalWorkspace; ///< Holds the mapping from the rebinned source to the original source + + std::map m_rebinnedWorkspaceToRebinnedWorkspace; ///< Holds information from a rebinned source to another temproary source which replaces it. + + std::string m_tempPostfix; + + std::string m_tempPrefix; + + pqPipelineSource* getSourceForWorkspace(std::string workspaceName); + + void swapSources(std::string source1, std::string source2); + + void rebuildPipeline(pqPipelineSource* source1, pqPipelineSource* source2); + + void processWorkspaceNames(std::string& inputWorkspace, std::string& outputWorkspace, std::string workspaceName, std::string algorithmType); + + void removeUnusedRebinnedWorkspaces(); + + void untrackWorkspaces(std::string rebinnedSource); + + void removeRebinnedWorkspace(std::string rebinnedWorkspace); + + void compareToSources(std::string workspaceName); + + void copyProperties(pqPipelineFilter* filter1, pqPipelineFilter* filter2); + + static void copySafe(vtkSMProxy* dest, vtkSMProxy* source); + + void getWorkspaceInfo(pqPipelineSource* source, std::string& workspaceName, std::string& workSpaceType); + }; + + } // SimpleGui + } // Vates +} // Mantid + +#endif diff --git a/Code/Mantid/Vates/VatesSimpleGui/ViewWidgets/inc/MantidVatesSimpleGuiViewWidgets/StandardView.h b/Code/Mantid/Vates/VatesSimpleGui/ViewWidgets/inc/MantidVatesSimpleGuiViewWidgets/StandardView.h index 204d6735d9e8..403df62c7576 100644 --- a/Code/Mantid/Vates/VatesSimpleGui/ViewWidgets/inc/MantidVatesSimpleGuiViewWidgets/StandardView.h +++ b/Code/Mantid/Vates/VatesSimpleGui/ViewWidgets/inc/MantidVatesSimpleGuiViewWidgets/StandardView.h @@ -10,6 +10,7 @@ class pqPipelineSource; class pqRenderView; +class QAction; namespace Mantid { @@ -70,27 +71,46 @@ class EXPORT_OPT_MANTIDVATES_SIMPLEGUI_VIEWWIDGETS StandardView : public ViewBas void updateUI(); /// @see ViewBase::updateView() void updateView(); + /// @see ViewBase::closeSubWindows + void closeSubWindows(); + +public slots: + /// React when the visibility of a representation changes + void onSourceDestroyed(); + /// Listen to a change in the active source. + void activeSourceChangeListener(pqPipelineSource* source); protected slots: /// Add a slice to the current dataset. void onCutButtonClicked(); - /// Check for a rebinning source being destroyed. - void onDestroyingSource(pqPipelineSource *src); - /// Invoke the RebinnerCutter on the current dataset. - void onRebinButtonClicked(); /// Perform operations when rendering is done. void onRenderDone(); /// Invoke the ScaleWorkspace on the current dataset. void onScaleButtonClicked(); + /// On BinMD button clicked + void onBinMD(); + /// On SliceMD button clicked + void onSliceMD(); + /// On CutMD button clicked + void onCutMD(); private: Q_DISABLE_COPY(StandardView) bool cameraReset; - QPointer rebinCut; ///< Holder for the RebinnerCutter QPointer scaler; ///< Holder for the ScaleWorkspace Ui::StandardView ui; ///< The standard view's UI form QPointer view; ///< The main view + + /// Set the rebin and unbin button visibility + void setRebinAndUnbinButtons(); + /// Set up the buttons + void setupViewButtons(); + + QAction* m_binMDAction; + QAction* m_sliceMDAction; + QAction* m_cutMDAction; + QAction* m_unbinAction; }; } // SimpleGui diff --git a/Code/Mantid/Vates/VatesSimpleGui/ViewWidgets/inc/MantidVatesSimpleGuiViewWidgets/StandardView.ui b/Code/Mantid/Vates/VatesSimpleGui/ViewWidgets/inc/MantidVatesSimpleGuiViewWidgets/StandardView.ui index 05625fe2c6f1..c3c83e587838 100644 --- a/Code/Mantid/Vates/VatesSimpleGui/ViewWidgets/inc/MantidVatesSimpleGuiViewWidgets/StandardView.ui +++ b/Code/Mantid/Vates/VatesSimpleGui/ViewWidgets/inc/MantidVatesSimpleGuiViewWidgets/StandardView.ui @@ -30,10 +30,34 @@ - + + + + 0 + 0 + + + + + 75 + 23 + + + + Select a rebin algorithm for MDEvent data + Rebin + + Qt::ToolButtonTextBesideIcon + + + false + + + Qt::NoArrow + diff --git a/Code/Mantid/Vates/VatesSimpleGui/ViewWidgets/inc/MantidVatesSimpleGuiViewWidgets/ViewBase.h b/Code/Mantid/Vates/VatesSimpleGui/ViewWidgets/inc/MantidVatesSimpleGuiViewWidgets/ViewBase.h index 0d955541fa8f..51a5607306f8 100644 --- a/Code/Mantid/Vates/VatesSimpleGui/ViewWidgets/inc/MantidVatesSimpleGuiViewWidgets/ViewBase.h +++ b/Code/Mantid/Vates/VatesSimpleGui/ViewWidgets/inc/MantidVatesSimpleGuiViewWidgets/ViewBase.h @@ -1,9 +1,9 @@ #ifndef VIEWBASE_H_ #define VIEWBASE_H_ +#include "MantidVatesSimpleGuiViewWidgets/BackgroundRgbProvider.h" #include "MantidVatesSimpleGuiViewWidgets/ColorUpdater.h" #include "MantidVatesSimpleGuiViewWidgets/WidgetDllOption.h" - #include "MantidVatesSimpleGuiQtWidgets/ModeControlWidget.h" #include @@ -97,6 +97,8 @@ class EXPORT_OPT_MANTIDVATES_SIMPLEGUI_VIEWWIDGETS ViewBase : public QWidget virtual bool hasWorkspaceType(const QString &wsTypeName); /// Check if file/workspace is a MDHistoWorkspace. virtual bool isMDHistoWorkspace(pqPipelineSource *src); + /// Check if file/workspace is a temporary workspace + virtual bool isTemporaryWorkspace(pqPipelineSource* src); /// Check if file/workspace is a Peaks one. virtual bool isPeaksWorkspace(pqPipelineSource *src); /// Prints properties for given source. @@ -112,14 +114,21 @@ class EXPORT_OPT_MANTIDVATES_SIMPLEGUI_VIEWWIDGETS ViewBase : public QWidget /// Set the current color scale state virtual void setColorScaleState(ColorSelectionWidget *cs); /// Create source for plugin mode. - virtual void setPluginSource(QString pluginName, QString wsName); + virtual pqPipelineSource* setPluginSource(QString pluginName, QString wsName); /// Determines if source has timesteps (4D). virtual bool srcHasTimeSteps(pqPipelineSource *src); + /// Set the the background color for the view + virtual void setColorForBackground(bool viewSwitched); + /// Sets the splatterplot button to the desired visibility. + virtual void setSplatterplot(bool visibility); /// Initializes the settings of the color scale virtual void initializeColorScale(); - + /// Sets the standard veiw button to the desired visibility. + virtual void setStandard(bool visibility); /// Enumeration for Cartesian coordinates enum Direction {X, Y, Z}; + /// Update settings + virtual void updateSettings(); QPointer origSrc; ///< The original source QPointer origRep; ///< The original source representation @@ -149,6 +158,7 @@ public slots: virtual void updateView(); /// React when the visibility of a representation changes virtual void onVisibilityChanged(pqPipelineSource *source, pqDataRepresentation *representation); + virtual void onSourceDestroyed(); signals: /** @@ -186,10 +196,20 @@ public slots: void setViewStatus(ModeControlWidget::Views mode, bool state); /** * Signal to set the status of the view mode buttons. - * @param view The initial view. + * @param view The initial view. * @param state Whether or not to enable to view mode buttons. */ void setViewsStatus(ModeControlWidget::Views view, bool state); + /** + * Signal to perform a possible rebin. + * @param algorithmType The type of rebinning algorithm. + */ + void rebin(std::string algorithmType); + /** + * Signal to perform a possible unbin on a sources which has been + * rebinned in the VSI. + */ + void unbin(); /** * Singal to tell other elements that the log scale was altered programatically * @param state flag wheter or not to enable the @@ -215,6 +235,10 @@ public slots: void handleTimeInfo(vtkSMDoubleVectorProperty *dvp); ColorUpdater colorUpdater; ///< Handle to the color updating delegator + BackgroundRgbProvider backgroundRgbProvider; /// < Holds the manager for background color related tasks. + const pqColorMapModel* m_currentColorMapModel; + + QString m_temporaryWorkspaceIdentifier; }; } diff --git a/Code/Mantid/Vates/VatesSimpleGui/ViewWidgets/src/AutoScaleRangeGenerator.cpp b/Code/Mantid/Vates/VatesSimpleGui/ViewWidgets/src/AutoScaleRangeGenerator.cpp index 5962e131e2fe..82101590b1be 100644 --- a/Code/Mantid/Vates/VatesSimpleGui/ViewWidgets/src/AutoScaleRangeGenerator.cpp +++ b/Code/Mantid/Vates/VatesSimpleGui/ViewWidgets/src/AutoScaleRangeGenerator.cpp @@ -4,6 +4,7 @@ #if defined(__INTEL_COMPILER) #pragma warning disable 1170 #endif + #include #include #include @@ -17,6 +18,10 @@ #include #include +#if defined(__INTEL_COMPILER) + #pragma warning enable 1170 +#endif + #include #include #include "MantidQtAPI/MdSettings.h" diff --git a/Code/Mantid/Vates/VatesSimpleGui/ViewWidgets/src/BackgroundRgbProvider.cpp b/Code/Mantid/Vates/VatesSimpleGui/ViewWidgets/src/BackgroundRgbProvider.cpp new file mode 100644 index 000000000000..7cba3778ed2e --- /dev/null +++ b/Code/Mantid/Vates/VatesSimpleGui/ViewWidgets/src/BackgroundRgbProvider.cpp @@ -0,0 +1,160 @@ +#include "MantidVatesSimpleGuiViewWidgets/BackgroundRgbProvider.h" +#include "MantidQtAPI/MdSettings.h" +#include "MantidKernel/Logger.h" +#include + +// Have to deal with ParaView warnings and Intel compiler the hard way. +#if defined(__INTEL_COMPILER) + #pragma warning disable 1170 +#endif +#include +#include +#include +#include +#include +#include + +#if defined(__INTEL_COMPILER) + #pragma warning enable 1170 +#endif + +namespace Mantid +{ + namespace Vates + { + namespace SimpleGui + { + + QColor BackgroundRgbProvider::currentBackgroundColor = QColor(84,89,109); + + BackgroundRgbProvider::BackgroundRgbProvider() + { + }; + + BackgroundRgbProvider::~BackgroundRgbProvider() + { + // Need to record the background color + update(); + }; + + std::vector BackgroundRgbProvider::getRgb(bool viewSwitched) + { + // Get the rgb setting from the config file + std::vector userSettingRgb = getRgbFromSetting(viewSwitched); + + // Normalize the entries to 256 + userSettingRgb[0] = userSettingRgb[0]/255.0; + userSettingRgb[1] = userSettingRgb[1]/255.0; + userSettingRgb[2] = userSettingRgb[2]/255.0; + + return userSettingRgb; + } + + std::vector BackgroundRgbProvider::getRgbFromSetting(bool viewSwitched) + { + // Set the mantid default here + std::vector background; + QColor userBackground; + + if (viewSwitched) + { + // Update the settings + update(); + + userBackground = m_mdSettings.getLastSessionBackgroundColor(); + } + else + { + if (m_mdSettings.getUsageLastSession()) + { + userBackground = m_mdSettings.getLastSessionBackgroundColor(); + } + else + { + // Select the user setting as the background color and make the user setting the last session color + userBackground= m_mdSettings.getUserSettingBackgroundColor(); + + m_mdSettings.setLastSessionBackgroundColor(userBackground); + } + + // Need to make sure that the static variable is initialized correctly, else it will show a black background + currentBackgroundColor = userBackground; + } + + // Get the background + int rVal; + int gVal; + int bVal; + + if (userBackground.isValid()) + { + rVal = userBackground.red(); + gVal = userBackground.green(); + bVal = userBackground.blue(); + } + else + { + // Set the default + QColor defaultBackgroundColor = m_mdSettings.getDefaultBackgroundColor(); + rVal = defaultBackgroundColor.red(); + gVal = defaultBackgroundColor.green(); + bVal = defaultBackgroundColor.blue(); + } + + background.push_back(static_cast(rVal)); + background.push_back(static_cast(gVal)); + background.push_back(static_cast(bVal)); + + return background; + } + + void BackgroundRgbProvider::update() + { + m_mdSettings.setLastSessionBackgroundColor(currentBackgroundColor); + } + + void BackgroundRgbProvider::setBackgroundColor(pqRenderView* view, bool viewSwitched) + { + std::vector backgroundRgb = getRgb(viewSwitched); + + vtkSMDoubleVectorProperty* background = vtkSMDoubleVectorProperty::SafeDownCast(view->getViewProxy()->GetProperty("Background")); + + background->SetElements3(backgroundRgb[0],backgroundRgb[1],backgroundRgb[2]); + + view->resetCamera(); + } + + void BackgroundRgbProvider::observe(pqRenderView* view) + { + // For more information http://www.vtk.org/Wiki/VTK/Tutorials/Callbacks + vtkSmartPointer backgroundColorChangeCallback = vtkSmartPointer::New(); + + backgroundColorChangeCallback->SetCallback(backgroundColorChangeCallbackFunction); + + view->getViewProxy()->GetProperty("Background")->AddObserver(vtkCommand::ModifiedEvent, backgroundColorChangeCallback); + } + + void BackgroundRgbProvider::backgroundColorChangeCallbackFunction(vtkObject* caller, long unsigned int vtkNotUsed(eventId), void* vtkNotUsed(clientData), void* vtkNotUsed(callData)) + { + // Extract the background color and persist it + vtkSMDoubleVectorProperty* background =vtkSMDoubleVectorProperty::SafeDownCast(caller); + + int numberOfElements = background->GetNumberOfElements(); + double* elements = background->GetElements(); + + if (numberOfElements >= 3) + { + double r = elements[0]*255.0; + double g = elements[1]*255.0; + double b = elements[2]*255.0; + + int red = static_cast(r); + int green = static_cast(g); + int blue = static_cast(b); + + currentBackgroundColor = QColor(red,green,blue); + } + } + } + } +} \ No newline at end of file diff --git a/Code/Mantid/Vates/VatesSimpleGui/ViewWidgets/src/ColorMapManager.cpp b/Code/Mantid/Vates/VatesSimpleGui/ViewWidgets/src/ColorMapManager.cpp new file mode 100644 index 000000000000..c32a2a542948 --- /dev/null +++ b/Code/Mantid/Vates/VatesSimpleGui/ViewWidgets/src/ColorMapManager.cpp @@ -0,0 +1,110 @@ +#include "MantidVatesSimpleGuiViewWidgets/ColorMapManager.h" +#include "MantidQtAPI/MdSettings.h" +#include "MantidKernel/ConfigService.h" +#include +#include + + +namespace Mantid +{ + namespace Vates + { + namespace SimpleGui + { + ColorMapManager::ColorMapManager() : m_indexCounter(0) + { + } + + ColorMapManager::~ColorMapManager() + { + } + + int ColorMapManager::getDefaultColorMapIndex(bool viewSwitched) + { + QString defaultColorMap; + + // If the view has switched use the last color map index + if (viewSwitched) + { + defaultColorMap = m_mdSettings.getLastSessionColorMap(); + } + else + { + // Check if the user wants a general MD color map + if (m_mdSettings.getUsageGeneralMdColorMap()) + { + // The name is sufficient for the VSI to find the color map + defaultColorMap = m_mdSettings.getGeneralMdColorMapName(); + } + else + { + // Check if the user wants to use the last session + if (m_mdSettings.getUsageLastSession()) + { + defaultColorMap = m_mdSettings.getLastSessionColorMap(); + } + else + { + defaultColorMap = m_mdSettings.getUserSettingColorMap(); + } + } + } + + // Set the default colormap + int defaultColorMapIndex = 0; + + if (!defaultColorMap.isEmpty()) + { + m_mdSettings.setLastSessionColorMap(defaultColorMap); + defaultColorMapIndex = this->getColorMapIndex(defaultColorMap.toStdString()); + } + + return defaultColorMapIndex; + } + + void ColorMapManager::readInColorMap(std::string name) + { + // Add the name to the colormap map and increment the index counter + if (!name.empty()) + { + m_nameToIndex.insert(std::pair(name, m_indexCounter)); + m_indexToName.insert(std::pair(m_indexCounter, name)); + m_indexCounter = m_indexCounter + 1; + } + } + + int ColorMapManager::getColorMapIndex(std::string colorMap) + { + if (m_nameToIndex.count(colorMap) == 1 ) + { + return m_nameToIndex[colorMap]; + } + else + { + return 0; + } + } + + bool ColorMapManager::isRecordedColorMap(std::string colorMap) + { + if (m_nameToIndex.count(colorMap) > 0) + { + return true; + } + else + { + return false; + } + } + + void ColorMapManager::setNewActiveColorMap(int index) + { + // Persist the new value of the color map in the QSettings object. + if (m_indexToName.count(index) > 0) + { + m_mdSettings.setLastSessionColorMap(QString::fromStdString(m_indexToName[index])); + } + } + } + } +} \ No newline at end of file diff --git a/Code/Mantid/Vates/VatesSimpleGui/ViewWidgets/src/ColorSelectionWidget.cpp b/Code/Mantid/Vates/VatesSimpleGui/ViewWidgets/src/ColorSelectionWidget.cpp index e18b9656b2b8..fac0e1e004f0 100644 --- a/Code/Mantid/Vates/VatesSimpleGui/ViewWidgets/src/ColorSelectionWidget.cpp +++ b/Code/Mantid/Vates/VatesSimpleGui/ViewWidgets/src/ColorSelectionWidget.cpp @@ -1,16 +1,26 @@ #include "MantidVatesSimpleGuiViewWidgets/ColorSelectionWidget.h" - #include "MantidKernel/ConfigService.h" +#include "MantidVatesSimpleGuiViewWidgets/ColorMapManager.h" #include "MantidQtAPI/MdConstants.h" +// Have to deal with ParaView warnings and Intel compiler the hard way. +#if defined(__INTEL_COMPILER) + #pragma warning disable 1170 +#endif + #include #include #include #include #include + #include #include +#if defined(__INTEL_COMPILER) + #pragma warning enable 1170 +#endif + #include #include #include @@ -31,7 +41,7 @@ namespace SimpleGui * sub-components and connections. * @param parent the parent widget of the mode control widget */ - ColorSelectionWidget::ColorSelectionWidget(QWidget *parent) : QWidget(parent), m_minHistoric(0.01), m_maxHistoric(0.01) + ColorSelectionWidget::ColorSelectionWidget(QWidget *parent) : QWidget(parent), colorMapManager(new ColorMapManager()), m_minHistoric(0.01), m_maxHistoric(0.01) { this->ui.setupUi(this); this->ui.autoColorScaleCheckBox->setChecked(true); @@ -80,18 +90,21 @@ void ColorSelectionWidget::loadBuiltinColorPresets() { pqColorPresetModel *presetModel = this->presets->getModel(); - // get builtin color maps xml - const char *xml = pqComponentsGetColorMapsXML(); + // Associate the colormap value with the index a continuous index // create xml parser vtkPVXMLParser *xmlParser = vtkPVXMLParser::New(); + + + // 1. Get builtinw color maps (Reading fragment requires: InitializeParser, ParseChunk, CleanupParser) + const char *xml = pqComponentsGetColorMapsXML(); xmlParser->InitializeParser(); xmlParser->ParseChunk(xml, static_cast(strlen(xml))); xmlParser->CleanupParser(); - this->addColorMapsFromXML(xmlParser, presetModel); - - // Add color maps from IDL and Matplotlib + + // 2. Add color maps from Slice Viewer, IDL and Matplotlib + this->addColorMapsFromFile("All_slice_viewer_cmaps_for_vsi.xml", xmlParser, presetModel); this->addColorMapsFromFile("All_idl_cmaps.xml", xmlParser, presetModel); this->addColorMapsFromFile("All_mpl_cmaps.xml", xmlParser, presetModel); @@ -99,6 +112,22 @@ void ColorSelectionWidget::loadBuiltinColorPresets() xmlParser->Delete(); } + /** + * Load the default color map + * @param viewSwitched Flag if the view has switched or not. + */ + void ColorSelectionWidget::loadColorMap(bool viewSwitched) + { + int defaultColorMapIndex = this->colorMapManager->getDefaultColorMapIndex(viewSwitched); + + const pqColorMapModel *colorMap = this->presets->getModel()->getColorMap(defaultColorMapIndex); + + if (colorMap) + { + emit this->colorMapChanged(colorMap); + } + } + /** * This function takes color maps from a XML file, parses them and loads and * adds them to the color preset model. @@ -148,8 +177,15 @@ void ColorSelectionWidget::addColorMapsFromXML(vtkPVXMLParser *parser, pqColorPresetManager::createColorMapFromXML(colorMapElement); QString name = colorMapElement->GetAttribute("name"); - // add color map to the model - model->addBuiltinColorMap(colorMap, name); + // Only add the color map if the name does not exist yet + if (!this->colorMapManager->isRecordedColorMap(name.toStdString())) + { + // add color map to the model + model->addBuiltinColorMap(colorMap, name); + + // add color map to the color map manager + this->colorMapManager->readInColorMap(name.toStdString()); + } } } @@ -186,8 +222,11 @@ void ColorSelectionWidget::loadPreset() QItemSelectionModel *selection = this->presets->getSelectionModel(); QModelIndex index = selection->currentIndex(); const pqColorMapModel *colorMap = this->presets->getModel()->getColorMap(index.row()); + if (colorMap) { + // Persist the color map change + this->colorMapManager->setNewActiveColorMap(index.row()); emit this->colorMapChanged(colorMap); } } diff --git a/Code/Mantid/Vates/VatesSimpleGui/ViewWidgets/src/ColorUpdater.cpp b/Code/Mantid/Vates/VatesSimpleGui/ViewWidgets/src/ColorUpdater.cpp index b4f2b3b34e8c..07bdd9179020 100644 --- a/Code/Mantid/Vates/VatesSimpleGui/ViewWidgets/src/ColorUpdater.cpp +++ b/Code/Mantid/Vates/VatesSimpleGui/ViewWidgets/src/ColorUpdater.cpp @@ -74,6 +74,12 @@ void ColorUpdater::colorMapChange(pqPipelineRepresentation *repr, const pqColorMapModel *model) { pqScalarsToColors *lut = repr->getLookupTable(); + if (NULL == lut) + { + // Got a bad proxy, so just return + return; + } + // Need the scalar bounds to calculate the color point settings QPair bounds = lut->getScalarRange(); diff --git a/Code/Mantid/Vates/VatesSimpleGui/ViewWidgets/src/MdViewerWidget.cpp b/Code/Mantid/Vates/VatesSimpleGui/ViewWidgets/src/MdViewerWidget.cpp index e0cb2a036ab4..c03869729a27 100644 --- a/Code/Mantid/Vates/VatesSimpleGui/ViewWidgets/src/MdViewerWidget.cpp +++ b/Code/Mantid/Vates/VatesSimpleGui/ViewWidgets/src/MdViewerWidget.cpp @@ -2,6 +2,7 @@ #include "MantidVatesSimpleGuiQtWidgets/ModeControlWidget.h" #include "MantidVatesSimpleGuiQtWidgets/RotationPointDialog.h" +#include "MantidVatesSimpleGuiViewWidgets/BackgroundRgbProvider.h" #include "MantidVatesSimpleGuiViewWidgets/ColorSelectionWidget.h" #include "MantidVatesSimpleGuiViewWidgets/MultisliceView.h" #include "MantidVatesSimpleGuiViewWidgets/SaveScreenshotReaction.h" @@ -9,18 +10,22 @@ #include "MantidVatesSimpleGuiViewWidgets/StandardView.h" #include "MantidVatesSimpleGuiViewWidgets/ThreesliceView.h" #include "MantidVatesSimpleGuiViewWidgets/TimeControlWidget.h" - #include "MantidQtAPI/InterfaceManager.h" #include "MantidKernel/DynamicFactory.h" #include "MantidKernel/Logger.h" #include "MantidKernel/ConfigService.h" #include "MantidKernel/InstrumentInfo.h" +#include "boost/shared_ptr.hpp" +#include "boost/scoped_ptr.hpp" +#include "MantidQtAPI/MdConstants.h" +#include "MantidQtAPI/MdSettings.h" + // Have to deal with ParaView warnings and Intel compiler the hard way. #if defined(__INTEL_COMPILER) #pragma warning disable 1170 #endif - +#include #include #include #include @@ -30,15 +35,19 @@ #include #include #include +#include #include #include #include +#include +#include #include #include #include #include #include #include +#include #include #include #include @@ -90,6 +99,7 @@ #include #include #include +#include #include #include @@ -118,7 +128,7 @@ REGISTER_VATESGUI(MdViewerWidget) */ MdViewerWidget::MdViewerWidget() : VatesViewerInterface(), currentView(NULL), dataLoader(NULL), hiddenView(NULL), lodAction(NULL), screenShot(NULL), viewLayout(NULL), - viewSettings(NULL) + viewSettings(NULL), m_rebinAlgorithmDialogProvider(this), m_rebinnedWorkspaceIdentifier("_tempvsi") { // Calling workspace observer functions. observeAfterReplace(); @@ -127,15 +137,16 @@ MdViewerWidget::MdViewerWidget() : VatesViewerInterface(), currentView(NULL), this->internalSetup(true); - // Create the mapping from the measurement technique to the view - + // Connect the rebinned sources manager + QObject::connect(&m_rebinnedSourcesManager, SIGNAL(switchSources(std::string, std::string)), + this, SLOT(onSwitchSoures(std::string, std::string))); } /** * This constructor is used in the standalone mode operation of the VSI. * @param parent the parent widget for the main window */ -MdViewerWidget::MdViewerWidget(QWidget *parent) : VatesViewerInterface(parent) +MdViewerWidget::MdViewerWidget(QWidget *parent) : VatesViewerInterface(parent), m_rebinAlgorithmDialogProvider(this) { this->checkEnvSetup(); // We're in the standalone application mode @@ -208,6 +219,13 @@ void MdViewerWidget::setupUiAndConnections() SIGNAL(clicked()), this, SLOT(onRotationPoint())); + + // Connect the rebinned sources manager + QObject::connect(&m_rebinnedSourcesManager, + SIGNAL(triggerAcceptForNewFilters()), + this->ui.propertiesPanel, + SLOT(apply())); + } /** @@ -390,8 +408,10 @@ void MdViewerWidget::setParaViewComponentsForView() pqActiveObjects *activeObjects = &pqActiveObjects::instance(); QObject::connect(activeObjects, SIGNAL(portChanged(pqOutputPort*)), this->ui.propertiesPanel, SLOT(setOutputPort(pqOutputPort*))); + QObject::connect(activeObjects, SIGNAL(representationChanged(pqRepresentation*)), this->ui.propertiesPanel, SLOT(setRepresentation(pqRepresentation*))); + QObject::connect(activeObjects, SIGNAL(viewChanged(pqView*)), this->ui.propertiesPanel, SLOT(setView(pqView*))); @@ -453,6 +473,196 @@ void MdViewerWidget::setParaViewComponentsForView() SIGNAL(toggled(bool)), this->currentView, SLOT(onParallelProjection(bool))); + + // Start listening to a rebinning event + QObject::connect(this->currentView, SIGNAL(rebin(std::string)), + this, SLOT(onRebin(std::string)), Qt::UniqueConnection); + + // Start listening to an unbinning event + QObject::connect(this->currentView, SIGNAL(unbin()), + this, SLOT(onUnbin()), Qt::UniqueConnection); + +} + +/** + * Reaction for a rebin event + * @param algorithmType The type of rebinning algorithm + */ +void MdViewerWidget::onRebin(std::string algorithmType) +{ + pqPipelineSource* source = pqActiveObjects::instance().activeSource(); + + std::string inputWorkspaceName; + std::string outputWorkspaceName; + m_rebinnedSourcesManager.checkSource(source, inputWorkspaceName, outputWorkspaceName, algorithmType); + m_rebinAlgorithmDialogProvider.showDialog(inputWorkspaceName, outputWorkspaceName, algorithmType); +} + +/** + * Switch a source. + * @param rebinnedWorkspaceName The name of the rebinned workspace. + * @param sourceType The type of the source. + */ +void MdViewerWidget::onSwitchSoures(std::string rebinnedWorkspaceName, std::string sourceType) +{ + // Create the rebinned workspace + prepareRebinnedWorkspace(rebinnedWorkspaceName, sourceType); + + try + { + std::string sourceToBeDeleted; + + // Repipe the filters to the rebinned source + m_rebinnedSourcesManager.repipeRebinnedSource(rebinnedWorkspaceName, sourceToBeDeleted); + + // Remove the original source + deleteSpecificSource(sourceToBeDeleted); + + // Update the color scale + this->currentView->onAutoScale(this->ui.colorSelectionWidget); + + // Set the splatterplot button explicitly + this->currentView->setSplatterplot(true); + } + catch (const std::runtime_error& error) + { + g_log.warning() << error.what(); + } +} + +/** + * Creates and renders a rebinned workspace source + * @param rebinnedWorkspaceName The name of the rebinned workspace. + * @param sourceType The name of the source plugin. + */ +void MdViewerWidget::prepareRebinnedWorkspace(const std::string rebinnedWorkspaceName, std::string sourceType) +{ + // Load a new source plugin + pqPipelineSource* newRebinnedSource = this->currentView->setPluginSource(QString::fromStdString(sourceType), QString::fromStdString(rebinnedWorkspaceName)); + + // It seems that the new source gets set as active before it is fully constructed. We therefore reset it. + pqActiveObjects::instance().setActiveSource(NULL); + pqActiveObjects::instance().setActiveSource(newRebinnedSource); + m_rebinnedSourcesManager.registerRebinnedSource(newRebinnedSource); + + this->renderAndFinalSetup(); + + this->currentView->onAutoScale(this->ui.colorSelectionWidget); +} + +/** + * Creates and renders back to the original source + * @param originalWorkspaceName The name of the original workspace + */ +void MdViewerWidget::renderOriginalWorkspace(const std::string originalWorkspaceName) +{ + // Load a new source plugin + QString sourcePlugin = "MDEW Source"; + this->currentView->setPluginSource(sourcePlugin, QString::fromStdString(originalWorkspaceName)); + + // Render and final setup + this->renderAndFinalSetup(); +} + + +/** + * Gets triggered by an unbin event. It removes the rebinning on a workspace + * which has been rebinned from within the VSI. + */ +void MdViewerWidget::onUnbin() +{ + // Force the removal of the rebinning + pqPipelineSource *activeSource = pqActiveObjects::instance().activeSource(); + + removeRebinning(activeSource, true); +} + +/** + * Remove the rebinning. + * @param source The pipeline source for which the rebinning will be removed. + * @param forced If it should be removed under all circumstances. + * @param view If switched, to which view is it being switched + */ +void MdViewerWidget::removeRebinning(pqPipelineSource* source, bool forced, ModeControlWidget::Views view) +{ + if (forced || view == ModeControlWidget::SPLATTERPLOT) + { + std::string originalWorkspaceName; + std::string rebinnedWorkspaceName; + m_rebinnedSourcesManager.getStoredWorkspaceNames(source, originalWorkspaceName, rebinnedWorkspaceName); + + // If the active source has not been rebinned, then send a reminder to the user that only rebinned sources + // can be unbinned + if (originalWorkspaceName.empty() || rebinnedWorkspaceName.empty()) + { + if (forced == true) + { + QMessageBox::warning(this, QApplication::tr("Unbin Warning"), + QApplication::tr("You cannot unbin a source which has not be rebinned. \n"\ + "To unbin, select a rebinned source and \n"\ + "press Remove Rebinning again")); + } + return; + } + + // Create the original source + renderOriginalWorkspace(originalWorkspaceName); + + // Repipe the filters to the original source + try + { + m_rebinnedSourcesManager.repipeOriginalSource(rebinnedWorkspaceName, originalWorkspaceName); + } + catch (const std::runtime_error& error) + { + g_log.warning() << error.what(); + } + + // Remove the rebinned workspace source + deleteSpecificSource(rebinnedWorkspaceName); + + // Render and final setup + pqActiveObjects::instance().activeView()->forceRender(); + + // Set the buttons correctly if we switch to splatterplot + if ( view == ModeControlWidget::SPLATTERPLOT) + { + this->currentView->setSplatterplot(false); + this->currentView->setStandard(true); + } + } +} + +/** + * Remove rebinning from all rebinned sources + * @param view The view mode. + */ +void MdViewerWidget::removeAllRebinning(ModeControlWidget::Views view) +{ + // Iterate over all rebinned sources and remove them + pqServer *server = pqActiveObjects::instance().activeServer(); + pqServerManagerModel *smModel = pqApplicationCore::instance()->getServerManagerModel(); + QList sources = smModel->findItems(server); + + // We need to record all true sources, The filters will be removed in the removeRebinning step + // Hence the iterator will not point to a valid object anymore. + QList sourcesToAlter; + + for (QList::Iterator source = sources.begin(); source != sources.end(); ++source) + { + const QString srcProxyName = (*source)->getProxy()->GetXMLGroup(); + + if (srcProxyName == QString("sources")) + { + sourcesToAlter.push_back(*source); + } + } + + for (QList::Iterator source = sourcesToAlter.begin(); source!= sourcesToAlter.end(); ++source) + { + removeRebinning(*source, false, view); + } + } /** @@ -475,8 +685,9 @@ void MdViewerWidget::renderingDone() { if (this->viewSwitched) { - this->viewSwitched = false; + this->ui.colorSelectionWidget->loadColorMap(this->viewSwitched); // Load the default color map this->currentView->setColorsForView(this->ui.colorSelectionWidget); + this->viewSwitched = false; } } @@ -489,14 +700,16 @@ void MdViewerWidget::renderingDone() */ void MdViewerWidget::renderWorkspace(QString workspaceName, int workspaceType, std::string instrumentName) { + // Workaround: Note that setting to the standard view was part of the eventFilter. This causes the + // VSI window to not close properly. Moving it here ensures that we have the switch, but + // after the window is started again. if (this->currentView->getNumSources() == 0) { - this->ui.modeControlWidget->setToStandardView(); - } + this->setColorForBackground(); + this->ui.colorSelectionWidget->loadColorMap(this->viewSwitched); - // If there are no other sources, then set the required - if (this->currentView->getNumSources() == 0) - { + this->ui.modeControlWidget->setToStandardView(); + this->currentView->hide(); // Set the auto log scale state this->currentView->initializeColorScale(); } @@ -515,6 +728,16 @@ void MdViewerWidget::renderWorkspace(QString workspaceName, int workspaceType, s sourcePlugin = "MDEW Source"; } + // Make sure that we are not loading a rebinned vsi workspace. + if (workspaceName.contains(m_rebinnedWorkspaceIdentifier)) + { + QMessageBox::information(this, QApplication::tr("Loading Source Warning"), + QApplication::tr("You cannot load a rebinned rebinned vsi source. \n "\ + "Please select another source.")); + + return; + } + // Load a new source plugin this->currentView->setPluginSource(sourcePlugin, workspaceName); @@ -526,7 +749,6 @@ void MdViewerWidget::renderWorkspace(QString workspaceName, int workspaceType, s // correct initial after calling renderAndFinalSetup. We first // need to load in the current view and then switch to be inline // with the current architecture. - if (VatesViewerInterface::PEAKS != workspaceType) { resetCurrentView(workspaceType, instrumentName); @@ -580,6 +802,10 @@ void MdViewerWidget::resetCurrentView(int workspaceType, const std::string& inst { this->ui.modeControlWidget->setToSelectedView(initialView); } + else + { + this->currentView->show(); + } this->initialView = initialView; } @@ -596,11 +822,19 @@ void MdViewerWidget::resetCurrentView(int workspaceType, const std::string& inst ModeControlWidget::Views MdViewerWidget::getInitialView(int workspaceType, std::string instrumentName) { // Get the possible initial views - std::string initialViewFromUserProperties = Mantid::Kernel::ConfigService::Instance().getVsiInitialView(); - std::string initialViewFromTechnique = getViewForInstrument(instrumentName); + QString initialViewFromUserProperties = mdSettings.getUserSettingInitialView(); + QString initialViewFromTechnique = getViewForInstrument(instrumentName); - // The user-properties-defined default view takes precedence over the techique-defined default view - std::string initialView = initialViewFromUserProperties.empty() ? initialViewFromTechnique : initialViewFromUserProperties; + // The user-properties-defined default view takes precedence over the technique-defined default view + QString initialView; + if (initialViewFromUserProperties == mdConstants.getTechniqueDependence()) + { + initialView = initialViewFromTechnique; + } + else + { + initialView = initialViewFromUserProperties; + } ModeControlWidget::Views view = this->ui.modeControlWidget->getViewFromString(initialView); @@ -614,12 +848,12 @@ ModeControlWidget::Views MdViewerWidget::getInitialView(int workspaceType, std:: * data was measured. * @returns A view. */ -std::string MdViewerWidget::getViewForInstrument(const std::string& instrumentName) const +QString MdViewerWidget::getViewForInstrument(const std::string& instrumentName) const { // If nothing is specified the standard view is chosen if (instrumentName.empty()) { - return "STANDARD"; + return mdConstants.getStandardView(); } // Check for techniques @@ -629,22 +863,22 @@ std::string MdViewerWidget::getViewForInstrument(const std::string& instrumentNa // 4. Other --> STANDARD const std::set techniques = Mantid::Kernel::ConfigService::Instance().getInstrument(instrumentName).techniques(); - std::string associatedView; + QString associatedView; if (techniques.count("Single Crystal Diffraction") > 0 ) { - associatedView = "SPLATTERPLOT"; + associatedView = mdConstants.getSplatterPlotView(); } else if (techniques.count("Neutron Diffraction") > 0 ) { - associatedView = "SPLATTERPLOT"; + associatedView = mdConstants.getSplatterPlotView(); } else if (checkIfTechniqueContainsKeyword(techniques, "Spectroscopy")) { - associatedView = "MULTISLICE"; + associatedView = mdConstants.getMultiSliceView(); } else { - associatedView = "STANDARD"; + associatedView = mdConstants.getStandardView(); } return associatedView; @@ -729,14 +963,25 @@ void MdViewerWidget::setupPluginMode() */ void MdViewerWidget::renderAndFinalSetup() { + this->setColorForBackground(); this->currentView->render(); + this->ui.colorSelectionWidget->loadColorMap(this->viewSwitched); this->currentView->setColorsForView(this->ui.colorSelectionWidget); this->currentView->checkView(this->initialView); this->currentView->updateAnimationControls(); + this->setDestroyedListener(); this->setVisibilityListener(); this->currentView->onAutoScale(this->ui.colorSelectionWidget); } +/** + * Set the background color for this view. + */ +void MdViewerWidget::setColorForBackground() +{ + this->currentView->setColorForBackground(this->viewSwitched); +} + /** * This function is used during the post-apply process of particular pipeline * filters to check for updates to anything that relies on information from the @@ -751,13 +996,6 @@ void MdViewerWidget::checkForUpdates() } vtkSMProxy *proxy = src->getProxy(); - if (strcmp(proxy->GetXMLName(), "MDEWRebinningCutter") == 0) - { - this->currentView->onAutoScale(this->ui.colorSelectionWidget); - this->currentView->updateAnimationControls(); - this->currentView->updateView(); - this->currentView->updateUI(); - } if (QString(proxy->GetXMLName()).contains("Threshold")) { this->ui.colorSelectionWidget->enableControls(true); @@ -786,6 +1024,7 @@ void MdViewerWidget::checkForUpdates() */ void MdViewerWidget::switchViews(ModeControlWidget::Views v) { + this->removeAllRebinning(v); this->viewSwitched = true; this->currentView->closeSubWindows(); this->disconnectDialogs(); @@ -804,11 +1043,14 @@ void MdViewerWidget::switchViews(ModeControlWidget::Views v) this->hiddenView->close(); this->hiddenView->destroyView(); delete this->hiddenView; + this->setColorForBackground(); this->currentView->render(); this->currentView->setColorsForView(this->ui.colorSelectionWidget); + this->currentView->checkViewOnSwitch(); this->updateAppState(); this->initialView = v; + this->setDestroyedListener(); this->setVisibilityListener(); } @@ -843,11 +1085,16 @@ bool MdViewerWidget::eventFilter(QObject *obj, QEvent *ev) { this->ui.parallelProjButton->toggle(); } + this->ui.colorSelectionWidget->reset(); this->currentView->setColorScaleState(this->ui.colorSelectionWidget); + pqObjectBuilder* builder = pqApplicationCore::instance()->getObjectBuilder(); builder->destroySources(); + this->currentView->updateSettings(); + this->currentView->hide(); + return true; } } @@ -1098,8 +1345,9 @@ void MdViewerWidget::afterReplaceHandle(const std::string &wsName, /** * This function responds to a workspace being deleted. If there are one or - * more PeaksWorkspaces present, the requested one will be deleted. Otherwise, - * if it is an IMDWorkspace, everything goes! + * more PeaksWorkspaces present, the requested one will be deleted. If the + * deleted source is a rebinned source, then we revert back to the +* original source. Otherwise, if it is an IMDWorkspace, everything goes! * @param wsName : Name of workspace being deleted * @param ws : Pointer to workspace being deleted */ @@ -1107,6 +1355,7 @@ void MdViewerWidget::preDeleteHandle(const std::string &wsName, const boost::shared_ptr ws) { UNUSED_ARG(ws); + pqPipelineSource *src = this->currentView->hasWorkspace(wsName.c_str()); if (NULL != src) { @@ -1120,10 +1369,69 @@ void MdViewerWidget::preDeleteHandle(const std::string &wsName, return; } } + + // Check if rebinned source and perform an unbinning + if (m_rebinnedSourcesManager.isRebinnedSource(wsName)) + { + removeRebinning(src, true); + return; + } + emit this->requestClose(); } } +/** + * Delete a specific source and all of its filters. This assumes a linear filter system + * @param workspaceName The workspaceName associated with the source which is to be deleted + */ +void MdViewerWidget::deleteSpecificSource(std::string workspaceName) +{ + pqPipelineSource *source = this->currentView->hasWorkspace(workspaceName.c_str()); + if (NULL != source) + { + // Go to the end of the source and work your way back + pqPipelineSource* tempSource = source; + + while ((tempSource->getAllConsumers()).size() > 0) + { + tempSource = tempSource->getConsumer(0); + } + + // Now delete all filters and the source + pqObjectBuilder *builder = pqApplicationCore::instance()->getObjectBuilder(); + + // Crawl up to the source level + pqPipelineFilter* filter = qobject_cast(tempSource); + + while (filter) + { + tempSource = filter->getInput(0); + builder->destroy(filter); + filter = qobject_cast(tempSource); + } + + builder->destroy(tempSource); + } +} + +/** +* Set the listener for when sources are being destroyed +*/ +void MdViewerWidget::setDestroyedListener() +{ + pqServer *server = pqActiveObjects::instance().activeServer(); + pqServerManagerModel *smModel = pqApplicationCore::instance()->getServerManagerModel(); + QList sources = smModel->findItems(server); + + // Attach the destroyd signal of all sources to the viewbase. + for (QList::iterator source = sources.begin(); source != sources.end(); ++source) + { + QObject::connect((*source), SIGNAL(destroyed()), + this->currentView, SLOT(onSourceDestroyed()), Qt::UniqueConnection); + } +} + /** * Set the listener for the visibility of the representations */ diff --git a/Code/Mantid/Vates/VatesSimpleGui/ViewWidgets/src/MultisliceView.cpp b/Code/Mantid/Vates/VatesSimpleGui/ViewWidgets/src/MultisliceView.cpp index 80a385129599..6a6ea3228523 100644 --- a/Code/Mantid/Vates/VatesSimpleGui/ViewWidgets/src/MultisliceView.cpp +++ b/Code/Mantid/Vates/VatesSimpleGui/ViewWidgets/src/MultisliceView.cpp @@ -5,7 +5,7 @@ #include "MantidGeometry/MDGeometry/MDPlaneImplicitFunction.h" #include "MantidQtSliceViewer/SliceViewerWindow.h" #include "MantidQtFactory/WidgetFactory.h" -#include "MantidVatesAPI/RebinningKnowledgeSerializer.h" +#include "MantidVatesAPI/VatesKnowledgeSerializer.h" // Have to deal with ParaView warnings and Intel compiler the hard way. #if defined(__INTEL_COMPILER) @@ -162,19 +162,14 @@ void MultiSliceView::showCutInSliceViewer(int axisIndex, foreach (pqPipelineSource *src, srcs) { const QString name(src->getProxy()->GetXMLName()); - if (name.contains("MDEWRebinningCutter")) - { - src1 = src; - } + if (name.contains("ScaleWorkspace")) { src2 = src; } } - if (NULL == src1) - { - src1 = smModel->getItemAtIndex(0); - } + + src1 = smModel->getItemAtIndex(0); // Get the current dataset characteristics const char *inGeomXML = vtkSMPropertyHelper(src1->getProxy(), @@ -228,7 +223,7 @@ void MultiSliceView::showCutInSliceViewer(int axisIndex, origin[2] = sliceOffsetOnAxis * orient[2]; // Create the XML holder - VATES::RebinningKnowledgeSerializer rks(VATES::LocationNotRequired); + VATES::VatesKnowledgeSerializer rks(VATES::LocationNotRequired); rks.setWorkspaceName(wsName.toStdString()); rks.setGeometryXML(geomXML); diff --git a/Code/Mantid/Vates/VatesSimpleGui/ViewWidgets/src/RebinAlgorithmDialogProvider.cpp b/Code/Mantid/Vates/VatesSimpleGui/ViewWidgets/src/RebinAlgorithmDialogProvider.cpp new file mode 100644 index 000000000000..346e4f949b46 --- /dev/null +++ b/Code/Mantid/Vates/VatesSimpleGui/ViewWidgets/src/RebinAlgorithmDialogProvider.cpp @@ -0,0 +1,273 @@ +#include "MantidVatesSimpleGuiViewWidgets/RebinAlgorithmDialogProvider.h" +#include "MantidVatesAPI/ADSWorkspaceProvider.h" +#include "MantidAPI/Algorithm.h" +#include "MantidQtAPI/InterfaceManager.h" +#include "MantidQtMantidWidgets/SlicingAlgorithmDialog.h" +#include "MantidAPI/IMDEventWorkspace.h" +#include "MantidAPI/IMDWorkspace.h" +#include "MantidKernel/Logger.h" + +// Have to deal with ParaView warnings and Intel compiler the hard way. +#if defined(__INTEL_COMPILER) + #pragma warning disable 1170 +#endif +#include +#include +#if defined(__INTEL_COMPILER) + #pragma warning enable 1170 +#endif + +#include +#include + +#include +#include +#include +#include "boost/shared_ptr.hpp" + +namespace Mantid +{ + namespace Vates + { + namespace SimpleGui + { + + namespace + { + Mantid::Kernel::Logger g_log("RebinAlgorithmDialogProvider"); + } + + RebinAlgorithmDialogProvider::RebinAlgorithmDialogProvider(QWidget* parent) : + m_lblInputWorkspace("InputWorkspace"), + m_lblOutputWorkspace("OutputWorkspace"), + m_binCutOffValue(50), + m_parent(parent) + { + } + + RebinAlgorithmDialogProvider::~RebinAlgorithmDialogProvider() + { + } + + /** + * Show a Bin MD dialog for rebinning in the VSI + * @param inputWorkspace The name of the input workspace. + * @param outputWorkspace The name of the output workspace. + * @param algorithmType The type of algorithm which is to be used for rebinning. + */ + void RebinAlgorithmDialogProvider::showDialog(std::string inputWorkspace, std::string outputWorkspace, std::string algorithmType) + { + if (inputWorkspace.empty() || outputWorkspace.empty()) + { + return; + } + + // Create the algorithm + Mantid::API::IAlgorithm_sptr algorithm = createAlgorithm(algorithmType, 1); + + if (!algorithm) + { + return; + } + + MantidQt::API::AlgorithmDialog* rebinDialog = createDialog(algorithm, inputWorkspace, outputWorkspace, algorithmType); + + rebinDialog->show(); + rebinDialog->raise(); + rebinDialog->activateWindow(); + } + + /** + * Gets the event workspace + * @param workspaceName The name of the input workspace. + * @returns A pointer to the current event workspace + */ + Mantid::API::IMDEventWorkspace_sptr RebinAlgorithmDialogProvider::getWorkspace(std::string workspaceName) + { + Mantid::API::IMDEventWorkspace_sptr eventWorkspace; + + + if (!m_adsWorkspaceProvider.canProvideWorkspace(workspaceName)) + { + return eventWorkspace; + } + + Mantid::API::Workspace_sptr workspace = m_adsWorkspaceProvider.fetchWorkspace(workspaceName); + + // Make sure it is a and MDEvent + eventWorkspace = boost::dynamic_pointer_cast(workspace); + + return eventWorkspace; + } + + /** + * Creates an algorithm + * @param algorithmName The name of the algorithm. + * @param version The version of the algorithm + * @returns A pointer to the newly created algorithm. + */ + Mantid::API::IAlgorithm_sptr RebinAlgorithmDialogProvider::createAlgorithm(const std::string& algorithmName, int version) + { + Mantid::API::IAlgorithm_sptr alg; + try + { + alg = Mantid::API::AlgorithmManager::Instance().create(algorithmName,version); + } + catch(...) + { + g_log.warning() << "Error: " << algorithmName << " was not created. Version number is " << version; + } + return alg; + } + + /** + * Creates the dialog for the algorithm (see InterfaceManager). + * @param algorithm The algorithm which is to be used. + * @param inputWorkspace The name of the input workspace. + * @param outputWorkspace The name of the output workspace. + * @returns The algorithm dialog + */ + MantidQt::API::AlgorithmDialog* RebinAlgorithmDialogProvider::createDialog(Mantid::API::IAlgorithm_sptr algorithm, + std::string inputWorkspace, + std::string outputWorkspace, + std::string algorithmType) + { + QHash presets; + //Check if a workspace is selected in the dock and set this as a preference for the input workspace + //This is an optional message displayed at the top of the GUI. + QString optional_msg(algorithm->summary().c_str()); + + MantidQt::API::AlgorithmDialog* dialog = NULL; + + // Set the correct algorithm dialog, Add CutMD here once it is ready. + if (algorithmType == "BinMD") + { + dialog = new MantidQt::MantidWidgets::BinMDDialog(m_parent); + getPresetsForSliceMDAlgorithmDialog(inputWorkspace, outputWorkspace, presets); + } + else if (algorithmType == "SliceMD") + { + dialog = new MantidQt::MantidWidgets::SliceMDDialog(m_parent); + getPresetsForSliceMDAlgorithmDialog(inputWorkspace, outputWorkspace, presets); + } + else + { + return dialog; + } + + // The parent so that the dialog appears on top of it + dialog->setParent(m_parent); + dialog->setAttribute(Qt::WA_DeleteOnClose, true); + + // Set the QDialog window flags to ensure the dialog ends up on top + Qt::WindowFlags flags = 0; + flags |= Qt::Dialog; + flags |= Qt::WindowContextHelpButtonHint; + dialog->setWindowFlags(flags); + + dialog->setAlgorithm(algorithm); + dialog->setPresetValues(presets); + dialog->setOptionalMessage(QString(algorithm->summary().c_str())); + + MantidQt::MantidWidgets::BinMDDialog * binDialog = dynamic_cast(dialog); + MantidQt::MantidWidgets::SliceMDDialog * sliceDialog = dynamic_cast(dialog); + + + if (binDialog) + { + binDialog->initializeLayout(); + binDialog->customiseLayoutForVsi(inputWorkspace); + + // Setup the values of the axis dimensions + setAxisDimensions(binDialog, inputWorkspace); + } + else if (sliceDialog) + { + sliceDialog->initializeLayout(); + sliceDialog->customiseLayoutForVsi(inputWorkspace); + + // Setup the values of the axis dimensions + setAxisDimensions(sliceDialog, inputWorkspace); + } + + return dialog; + } + + /** + * Determine the preset values + * @param inputWorkspace The name of the input workspace. + * @param outputWorkspace The name of the output workspace. + * @param presets A container for the preset values. + */ + void RebinAlgorithmDialogProvider::getPresetsForSliceMDAlgorithmDialog(std::string inputWorkspace, std::string outputWorkspace, QHash& presets) + { + // Set the input workspace + presets.insert(QString(m_lblInputWorkspace),QString::fromStdString(inputWorkspace)); + + // Set the output workspace + presets.insert(QString(m_lblOutputWorkspace),QString::fromStdString(outputWorkspace)); + } + + /** + * Resets the aligned dimensions properties in a SlicingAlgorithmDialog. + * @param dialog A pointer to the SliceMDDialog + * @param inputWorkspace The name of the input workspace. + */ + void RebinAlgorithmDialogProvider::setAxisDimensions(MantidQt::MantidWidgets::SlicingAlgorithmDialog* dialog, std::string inputWorkspace) + { + Mantid::API::IMDEventWorkspace_sptr eventWorkspace = getWorkspace(inputWorkspace); + + size_t nDimensions = eventWorkspace->getNumDims(); + + for (size_t index = 0; index < nDimensions; ++index) + { + Mantid::Geometry::IMDDimension_const_sptr dim = eventWorkspace->getDimension(index); + + std::string name = dim->getName(); + std::string dimensionId = dim->getDimensionId(); + coord_t minimum = dim->getMinimum(); + coord_t maximum = dim->getMaximum(); + size_t numberOfBins = dim->getNBins(); + + // Check the bins size + QString newNumberOfBins; + if (numberOfBins < m_binCutOffValue && index < 3) + { + // Only do this for BinMD, it is too costly for SliceMD to have very large cuts + if (dynamic_cast(dialog)) + { + newNumberOfBins = QString::number(static_cast(m_binCutOffValue)); + } + else + { + newNumberOfBins = QString::number(static_cast(numberOfBins)); + } + } + else + { + newNumberOfBins = QString::number(static_cast(numberOfBins)); + } + + // Set the name + std::string identifier; + if (!name.empty()) + { + identifier = name; + } + else + { + identifier = dimensionId; + } + + // Check here if the set bins are OK + QString propertyValue = QString::fromStdString(identifier) + "," + + QString::number(static_cast(minimum)) + "," + + QString::number(static_cast(maximum)) + "," + + newNumberOfBins; + + dialog->resestAlignedDimProperty(index, propertyValue); + } + } + } + } +} diff --git a/Code/Mantid/Vates/VatesSimpleGui/ViewWidgets/src/RebinnedSourcesManager.cpp b/Code/Mantid/Vates/VatesSimpleGui/ViewWidgets/src/RebinnedSourcesManager.cpp new file mode 100644 index 000000000000..f45d0c2f9be9 --- /dev/null +++ b/Code/Mantid/Vates/VatesSimpleGui/ViewWidgets/src/RebinnedSourcesManager.cpp @@ -0,0 +1,655 @@ +#include "MantidVatesSimpleGuiViewWidgets/RebinnedSourcesManager.h" +#include "MantidVatesAPI/ADSWorkspaceProvider.h" +#include "MantidQtAPI/WorkspaceObserver.h" +#include "MantidAPI/AnalysisDataService.h" +#include "MantidAPI/IMDHistoWorkspace.h" +#include "MantidAPI/IMDEventWorkspace.h" +#include "MantidAPI/Workspace.h" +#include "MantidKernel/Logger.h" + +// Have to deal with ParaView warnings and Intel compiler the hard way. +#if defined(__INTEL_COMPILER) + #pragma warning disable 1170 +#endif +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +#if defined(__INTEL_COMPILER) + #pragma warning enable 1170 +#endif +#include +#include "boost/shared_ptr.hpp" +#include + + + +namespace Mantid +{ + namespace Vates + { + namespace SimpleGui + { + + namespace + { + Mantid::Kernel::Logger g_log("RebinnedSourcesManager"); + } + + RebinnedSourcesManager::RebinnedSourcesManager(QWidget* parent) : QWidget(parent), m_tempPostfix("_tempvsi"), m_tempPrefix("__") + { + observeAdd(); + observePreDelete(); + } + + RebinnedSourcesManager::~RebinnedSourcesManager() + { + } + + /** + * Checks if a rebinned MDHisto workspace was added and invokes a replacement procedure + * @param workspaceName Name of the workspace. + * @param workspace A pointer to the added workspace. + */ + void RebinnedSourcesManager::addHandle(const std::string &workspaceName, Mantid::API::Workspace_sptr workspace) + { + if (m_rebinnedWorkspaceToOriginalWorkspace.count(workspaceName) > 0 || m_rebinnedWorkspaceToRebinnedWorkspace.count(workspaceName) > 0) + { + std::string sourceType; + Mantid::API::IMDEventWorkspace_sptr eventWorkspace = boost::dynamic_pointer_cast(workspace); + Mantid::API::IMDHistoWorkspace_sptr histoWorkspace = boost::dynamic_pointer_cast(workspace); + + if(eventWorkspace) + { + sourceType = "MDEW Source"; + } + else if(histoWorkspace) + { + sourceType = "MDHW Source"; + } + else + { + return; + } + + emit switchSources(workspaceName, sourceType); + } + } + + /** + * Catch the deletion of either the rebinned or the original workspace. + * @param wsName The name of the workspace. + * @param ws The handle to the workspace + */ + void RebinnedSourcesManager::preDeleteHandle(const std::string &wsName, const boost::shared_ptr) + { + // If the original workspace has been deleted, then delete the rebinned + // source (and workspace via the listener) + if (m_originalWorkspaceToRebinnedWorkspace.count(wsName)) + { + // Get the rebinned source and destroy the entire pipeline + pqPipelineSource* source = getSourceForWorkspace(m_originalWorkspaceToRebinnedWorkspace[wsName]); + + // Go to the end of the pipeline + while(source->getNumberOfConsumers() > 0) + { + source = source->getConsumer(0); + } + + //Destroy the pipeline from the end + pqObjectBuilder* builder = pqApplicationCore::instance()->getObjectBuilder(); + pqPipelineFilter* filter = qobject_cast(source); + + while (filter) + { + source = filter->getInput(0); + builder->destroy(filter); + filter = qobject_cast(source); + } + + builder->destroy(source); // The listener takes now care of the workspace. + untrackWorkspaces(m_originalWorkspaceToRebinnedWorkspace[wsName]); + } + } + + /** + * Check if the sources are valid. + * @param source The pipeline source. + * @param inputWorkspace Reference for the name of the input workspace. + * @param outputWorkspace Reference for the name of the output workspace. + * @param algorithmType The type of the algorithm which will be used to create the rebinned source. + */ + void RebinnedSourcesManager::checkSource(pqPipelineSource* source, std::string& inputWorkspace, std::string& outputWorkspace, std::string algorithmType) + { + std::string workspaceName; + std::string workspaceType; + + getWorkspaceInfo(source, workspaceName, workspaceType); + + bool isHistoWorkspace = workspaceType.find("MDHistoWorkspace")!=std::string::npos; + bool isEventWorkspace = workspaceType.find("MDEventWorkspace")!=std::string::npos; + + // Check if it is a Histo or Event workspace, if it is neither, then don't do anything + if (isHistoWorkspace || isEventWorkspace) + { + processWorkspaceNames(inputWorkspace, outputWorkspace, workspaceName, algorithmType); + } + } + + /** + * Get workspace name and type + * @param workspaceName Reference to workspace name. + * @param workspaceType Reference to workspace type. + */ + void RebinnedSourcesManager::getWorkspaceInfo(pqPipelineSource* source, std::string& workspaceName, std::string& workspaceType) + { + // Make sure that the input source exists. Note that this can happen when there is no active view + if (!source) + { + return; + } + + // Update the source/filter + vtkSMProxy* proxy = source->getProxy(); + proxy->UpdateVTKObjects(); + proxy->UpdatePropertyInformation(); + source->updatePipeline(); + + // Crawl up to the source level + pqPipelineFilter* filter = qobject_cast(source); + + while (filter) + { + source = filter->getInput(0); + filter = qobject_cast(source); + } + + proxy = source->getProxy(); + + // Ensure that the source is either an MDEvent source or an MDHisto source + if (!QString(proxy->GetXMLName()).contains("MDEW Source") && + !QString(proxy->GetXMLName()).contains("MDHW Source")) + { + return; + } + + // Check if the source has an underlying event workspace or histo workspace + workspaceName = vtkSMPropertyHelper(source->getProxy(), "WorkspaceName", true).GetAsString(); + + workspaceType = vtkSMPropertyHelper(source->getProxy(), "WorkspaceTypeName", true).GetAsString(); + + } + + /** + * Creates the pipeline for the rebinned source. + * @param rebinnedSource The name of the rebinned source. + * @param sourceToBeDeleted The name of the sources which needs to be removed from the pipeline browser. + */ + void RebinnedSourcesManager::repipeRebinnedSource(std::string rebinnedSource, std::string& sourceToBeDeleted) + { + // We need to check if the source from which we receive our filters is the original source or + // a rebinned source. + if (m_rebinnedWorkspaceToRebinnedWorkspace.count(rebinnedSource) == 0) + { + std::string originalSource = m_rebinnedWorkspaceToOriginalWorkspace[rebinnedSource]; + + // Swap with the original source + swapSources(originalSource, rebinnedSource); + + sourceToBeDeleted = originalSource; + } + else + { + std::string oldRebinnedSource = m_rebinnedWorkspaceToRebinnedWorkspace[rebinnedSource]; + std::string originalSource = m_rebinnedWorkspaceToOriginalWorkspace[oldRebinnedSource]; + + // Swap with the other rebinned source + swapSources(oldRebinnedSource, rebinnedSource); + + sourceToBeDeleted = oldRebinnedSource; + + m_originalWorkspaceToRebinnedWorkspace.insert(std::pair(originalSource, rebinnedSource)); + m_rebinnedWorkspaceToOriginalWorkspace.insert(std::pair(rebinnedSource, originalSource)); + + // Unregister the connection between the two rebinned sources. + m_rebinnedWorkspaceToRebinnedWorkspace.erase(rebinnedSource); + } + } + + /** + * Creates the pipeline for the original source. + * @param rebinnedSource The name of the rebinned source. + * @param originalSource The name of the original source. + */ + void RebinnedSourcesManager::repipeOriginalSource(std::string rebinnedSource, std::string originalSource) + { + // Swap source from rebinned source to original source. + swapSources(rebinnedSource, originalSource); + + m_originalWorkspaceToRebinnedWorkspace.erase(originalSource); + m_rebinnedWorkspaceToOriginalWorkspace.erase(rebinnedSource); + } + + /** + * Swap the sources at the bottom level of the pipeline. + * @param source1 First source. + * @param source2 Second source. + */ + void RebinnedSourcesManager::swapSources(std::string source1, std::string source2) + { + pqPipelineSource* src1= getSourceForWorkspace(source1); + pqPipelineSource* src2 = getSourceForWorkspace(source2); + + if (!src1 || !src2) + { + throw std::runtime_error("VSI error: Either the original or rebinned source don't seem to exist."); + } + + // Check that both sources contain non-empty data sets + + // Check if the original source has a filter if such then repipe otherwise we are done + if ((src1->getAllConsumers()).size() <= 0) + { + // Need to press apply to finalize the internal setup of the source. + //emit triggerAcceptForNewFilters(); + return; + } + + // Rebuild pipeline + rebuildPipeline(src1, src2); + + // Render the active view to make the changes visible. + pqActiveObjects::instance().activeView()->render(); + } + + /** + * Get the stored workspace names assoicated with a source. + * @param source The name of the source. + * @param originalWorkspaceName The name of the original workspace. + * @param rebinnedWorkspaceName The name of the rebinned workspace. + */ + void RebinnedSourcesManager::getStoredWorkspaceNames(pqPipelineSource* source, std::string& originalWorkspaceName, std::string& rebinnedWorkspaceName) + { + if (!source) + { + return; + } + + // Get the underlying workspace name and type + std::string workspaceName; + std::string workspaceType; + getWorkspaceInfo(source, workspaceName, workspaceType); + + // The input can either be a rebinned source or a + if (m_rebinnedWorkspaceToOriginalWorkspace.count(workspaceName) > 0) + { + originalWorkspaceName = m_rebinnedWorkspaceToOriginalWorkspace[workspaceName]; + rebinnedWorkspaceName = workspaceName; + } else if (m_originalWorkspaceToRebinnedWorkspace.count(workspaceName) > 0) + { + originalWorkspaceName = workspaceName; + rebinnedWorkspaceName = m_originalWorkspaceToRebinnedWorkspace[workspaceName]; + } + } + + /** + * Get the desired source + * @param workspaceName The workspace name associated with the source. + */ + pqPipelineSource* RebinnedSourcesManager::getSourceForWorkspace(std::string workspaceName) + { + pqServer *server = pqActiveObjects::instance().activeServer(); + pqServerManagerModel *smModel = pqApplicationCore::instance()->getServerManagerModel(); + QList sources; + QList::Iterator source; + sources = smModel->findItems(server); + + for (source = sources.begin(); source != sources.end(); ++source) + { + + pqPipelineFilter* filter = qobject_cast(*source); + + if (!filter) + { + std::string wsName(vtkSMPropertyHelper((*source)->getProxy(), + "WorkspaceName", true).GetAsString()); + if (!wsName.empty()) + { + if (wsName == workspaceName) + { + return (*source); + } + } + } + } + return NULL; + } + + /** + * Process the workspaces names for the original source and the input source + * @param inputWorkspace Reference to the input workpspace. + * @param outputWorkspace Reference to the output workspace. + * @param workspaceName The name of the workspace of the current source. + * @param algorithmType The algorithm which creates the rebinned source. + */ + void RebinnedSourcesManager::processWorkspaceNames(std::string& inputWorkspace, std::string& outputWorkspace, std::string workspaceName, std::string algorithmType) + { + // If the workspace is the original workspace + if (workspaceName.find(m_tempPostfix) == std::string::npos) + { + inputWorkspace = workspaceName; + outputWorkspace = m_tempPrefix + workspaceName + algorithmType + m_tempPostfix; + + // Record the workspace + m_originalWorkspaceToRebinnedWorkspace.insert(std::pair(inputWorkspace, outputWorkspace)); + m_rebinnedWorkspaceToOriginalWorkspace.insert(std::pair(outputWorkspace, inputWorkspace)); + } // If the workspace is rebinned and was created with the same algorithm as the currently selected one. + else if (workspaceName.find(algorithmType) != std::string::npos) + { + if (m_rebinnedWorkspaceToOriginalWorkspace.count(workspaceName) > 0) + { + inputWorkspace = m_rebinnedWorkspaceToOriginalWorkspace[workspaceName]; + outputWorkspace = workspaceName; + } + } + else // If the workspace is rebinned but was not created with the same algorithm as the currently selected one. + { + if (m_rebinnedWorkspaceToOriginalWorkspace.count(workspaceName) > 0) + { + inputWorkspace = m_rebinnedWorkspaceToOriginalWorkspace[workspaceName]; + outputWorkspace = m_tempPrefix + inputWorkspace + algorithmType + m_tempPostfix; + + // Map the new rebinned workspace name to the old rebinned workspace name + m_rebinnedWorkspaceToRebinnedWorkspace.insert(std::pair(outputWorkspace, workspaceName)); + } + } + } + + /** + * Stop keeping tabs on the specific workspace pair + * @param rebinnedWorspace The name of the rebinned workspace. + */ + void RebinnedSourcesManager::untrackWorkspaces(std::string rebinnedWorkspace) + { + std::string originalWorkspace = m_rebinnedWorkspaceToOriginalWorkspace[rebinnedWorkspace]; + + // Remove the mapping ofthe rebinned workspace to the original workspace. + if (m_rebinnedWorkspaceToOriginalWorkspace.count(rebinnedWorkspace) > 0) + { + m_rebinnedWorkspaceToOriginalWorkspace.erase(rebinnedWorkspace); + } + + // Remove the mapping of the original workspace to the rebinned workspace, if the mapping is still intact. + if (m_originalWorkspaceToRebinnedWorkspace.count(originalWorkspace) > 0 && m_originalWorkspaceToRebinnedWorkspace[originalWorkspace] == rebinnedWorkspace) + { + m_originalWorkspaceToRebinnedWorkspace.erase(originalWorkspace); + } + } + + /** + * Register the rebinned source. Specifically, connect to the destroyed signal of the rebinned source. + * @param source The rebinned source. + */ + void RebinnedSourcesManager::registerRebinnedSource(pqPipelineSource* source) + { + if (!source) + { + return; + } + + QObject::connect(source, SIGNAL(destroyed()), + this, SLOT(onRebinnedSourceDestroyed())); + } + + /** + * React to the deletion of a rebinned source. + */ + void RebinnedSourcesManager::onRebinnedSourceDestroyed() + { + removeUnusedRebinnedWorkspaces(); + } + + /** + * Remove unused rebinned workspaces, by comparing the workspaces against the sources. + */ + void RebinnedSourcesManager::removeUnusedRebinnedWorkspaces() + { + // Iterate through all workspaces and check for ones ending with the tempIdentifier + std::set workspaceNames = Mantid::API::AnalysisDataService::Instance().getObjectNamesInclHidden(); + + for (std::set::iterator it = workspaceNames.begin(); it != workspaceNames.end(); ++it) + { + // Only look at the rebinned files + if (it->find(m_tempPostfix) != std::string::npos) + { + compareToSources(*it); + } + } + } + + /** + * Compare if the workspace name exists among the sources. If it doesnt't exist, remove it. + * @param workspaceName The name of the workspace + */ + void RebinnedSourcesManager::compareToSources(std::string workspaceName) + { + pqServer *server = pqActiveObjects::instance().activeServer(); + pqServerManagerModel *smModel = pqApplicationCore::instance()->getServerManagerModel(); + QList sources = smModel->findItems(server); + + for (QList::Iterator source = sources.begin(); source != sources.end(); ++source) + { + const QString srcProxyName = (*source)->getProxy()->GetXMLGroup(); + + if (srcProxyName == QString("sources")) + { + std::string name(vtkSMPropertyHelper((*source)->getProxy(), + "WorkspaceName", true).GetAsString()); + + // If the rebinned workspace has a source equivalent, then exit + if (name==workspaceName) + { + return; + } + } + } + + // There is no source which corresponds to the workspace, hence delete and unregister the workspace. + removeRebinnedWorkspace(workspaceName); + untrackWorkspaces(workspaceName); + } + + /** + * Removes the rebinned workspace from memory. + * @param rebinnedWorkspace The name of the rebinned workspace. + */ + void RebinnedSourcesManager::removeRebinnedWorkspace(std::string rebinnedWorkspace) + { + Mantid::VATES::ADSWorkspaceProvider adsHistoWorkspaceProvider; + Mantid::VATES::ADSWorkspaceProvider adsEventWorkspaceProvider; + + if (adsHistoWorkspaceProvider.canProvideWorkspace(rebinnedWorkspace)) + { + adsHistoWorkspaceProvider.disposeWorkspace(rebinnedWorkspace); + } + else if (adsEventWorkspaceProvider.canProvideWorkspace(rebinnedWorkspace)) + { + adsEventWorkspaceProvider.disposeWorkspace(rebinnedWorkspace); + } + } + + /** + * Rebuild the pipeline for the new source + * @param source1 The old source. + * @param source2 The new source. + */ + void RebinnedSourcesManager::rebuildPipeline(pqPipelineSource* source1, pqPipelineSource* source2) + { + // Step through all the filters in old pipeline and reproduce them + pqObjectBuilder* builder = pqApplicationCore::instance()->getObjectBuilder(); + pqPipelineFilter* filter1 = qobject_cast(source1->getConsumer(0)); + + pqPipelineSource* endOfSource2Pipeline = source2; + + while(filter1) + { + vtkSMProxy* proxy1 = NULL; + proxy1 = filter1->getProxy(); + pqPipelineSource* newPipelineElement = NULL; + pqPipelineFilter* newFilter = NULL; + // Move source2 to its end. + while (endOfSource2Pipeline->getNumberOfConsumers() > 0) + { + endOfSource2Pipeline = endOfSource2Pipeline->getConsumer(0); + } + + if (QString(proxy1->GetXMLName()).contains("ScaleWorkspace")) + { + // Build the source + newPipelineElement = builder->createFilter("filters","MantidParaViewScaleWorkspace", endOfSource2Pipeline); + } else if (QString(proxy1->GetXMLName()).contains("Cut")) + { + newPipelineElement = builder->createFilter("filters", "Cut", endOfSource2Pipeline); + } + + newFilter = qobject_cast(newPipelineElement); + + // Copy the properties from the old filter to the new filter. + copyProperties(filter1, newFilter); + + if (filter1->getNumberOfConsumers() > 0) + { + filter1 = qobject_cast(filter1->getConsumer(0)); + } + else + { + filter1 = NULL; + } + } + emit triggerAcceptForNewFilters(); + } + + /** + * Copy the properties of the old filter to the new filter. + * @param filter1 The old filter. + * @param filter2 The new filter. + */ + void RebinnedSourcesManager::copyProperties(pqPipelineFilter* filter1, pqPipelineFilter* filter2) + { + vtkSMProxy* proxy1 = filter1->getProxy(); + vtkSMProxy* proxy2 = filter2->getProxy(); + + copySafe(proxy2, proxy1); + } + + /** + * This method is taken from a newer version of pqCopyReaction, which contains a bug fix + * for copying CutFilter properties. This is the correct way to copy proxy properties. + * @param dest Destination proxy. + * @param source Source proxy. + */ + void RebinnedSourcesManager::copySafe(vtkSMProxy* dest, vtkSMProxy* source) + { + if (dest && source) + { + BEGIN_UNDO_SET("Copy Properties"); + dest->Copy(source, "vtkSMProxyProperty"); + + // handle proxy properties. + vtkSMPropertyIterator* destIter = dest->NewPropertyIterator(); + for (destIter->Begin(); !destIter->IsAtEnd(); destIter->Next()) + { + if (vtkSMInputProperty::SafeDownCast(destIter->GetProperty())) + { + // skip input properties. + continue; + } + + vtkSMProxyProperty* destPP = vtkSMProxyProperty::SafeDownCast(destIter->GetProperty()); + vtkSMProxyProperty* srcPP = vtkSMProxyProperty::SafeDownCast(source->GetProperty(destIter->GetKey())); + + if (!destPP || !srcPP || srcPP->GetNumberOfProxies() > 1) + { + // skip non-proxy properties since those were already copied. + continue; + } + + vtkSMProxyListDomain* destPLD = vtkSMProxyListDomain::SafeDownCast(destPP->FindDomain("vtkSMProxyListDomain")); + vtkSMProxyListDomain* srcPLD = vtkSMProxyListDomain::SafeDownCast(srcPP->FindDomain("vtkSMProxyListDomain")); + + if (!destPLD || !srcPLD) + { + // we copy proxy properties that have proxy list domains. + continue; + } + + if (srcPP->GetNumberOfProxies() == 0) + { + destPP->SetNumberOfProxies(0); + continue; + } + + vtkSMProxy* srcValue = srcPP->GetProxy(0); + vtkSMProxy* destValue = NULL; + + // find srcValue type in destPLD and that's the proxy to use as destValue. + for (unsigned int cc=0; srcValue != NULL && cc < destPLD->GetNumberOfProxyTypes(); cc++) + { + if (srcValue->GetXMLName() && destPLD->GetProxyName(cc) && + strcmp(srcValue->GetXMLName(), destPLD->GetProxyName(cc)) == 0 && + srcValue->GetXMLGroup() && destPLD->GetProxyGroup(cc) && + strcmp(srcValue->GetXMLGroup(), destPLD->GetProxyGroup(cc)) == 0) + { + destValue = destPLD->GetProxy(cc); + break; + } + } + + if (destValue) + { + Q_ASSERT(srcValue != NULL); + copySafe(destValue, srcValue); + destPP->SetProxy(0, destValue); + } + } + + destIter->Delete(); + dest->UpdateVTKObjects(); + END_UNDO_SET(); + } + } + + /** + * Check if we have a rebinned source + * @param name The source name. + */ + bool RebinnedSourcesManager::isRebinnedSource(std::string name) + { + if (m_rebinnedWorkspaceToOriginalWorkspace.count(name) > 0) + { + return true; + } + else + { + return false; + } + } + + } + } +} diff --git a/Code/Mantid/Vates/VatesSimpleGui/ViewWidgets/src/StandardView.cpp b/Code/Mantid/Vates/VatesSimpleGui/ViewWidgets/src/StandardView.cpp index 6192e0e4dac9..09817b9f5ad9 100644 --- a/Code/Mantid/Vates/VatesSimpleGui/ViewWidgets/src/StandardView.cpp +++ b/Code/Mantid/Vates/VatesSimpleGui/ViewWidgets/src/StandardView.cpp @@ -1,5 +1,4 @@ #include "MantidVatesSimpleGuiViewWidgets/StandardView.h" - // Have to deal with ParaView warnings and Intel compiler the hard way. #if defined(__INTEL_COMPILER) #pragma warning disable 1170 @@ -11,7 +10,10 @@ #include #include #include +#include #include +#include +#include #include #include #include @@ -21,6 +23,8 @@ #endif #include +#include +#include #include #include @@ -36,38 +40,84 @@ namespace SimpleGui * buttons and creates the rendering view. * @param parent the parent widget for the standard view */ -StandardView::StandardView(QWidget *parent) : ViewBase(parent) + StandardView::StandardView(QWidget *parent) : ViewBase(parent),m_binMDAction(NULL), + m_sliceMDAction(NULL), + m_cutMDAction(NULL), + m_unbinAction(NULL) { this->ui.setupUi(this); this->cameraReset = false; + // Set up the buttons + setupViewButtons(); + // Set the cut button to create a slice on the data QObject::connect(this->ui.cutButton, SIGNAL(clicked()), this, SLOT(onCutButtonClicked())); - // Set the rebin button to create the RebinCutter operator - QObject::connect(this->ui.rebinButton, SIGNAL(clicked()), this, - SLOT(onRebinButtonClicked())); + // Listen to a change in the active source, to adapt our rebin buttons + QObject::connect(&pqActiveObjects::instance(), SIGNAL(sourceChanged(pqPipelineSource*)), + this, SLOT(activeSourceChangeListener(pqPipelineSource*))); // Set the scale button to create the ScaleWorkspace operator QObject::connect(this->ui.scaleButton, SIGNAL(clicked()), this, SLOT(onScaleButtonClicked())); - // Check for rebinning source being deleted - pqObjectBuilder *builder = pqApplicationCore::instance()->getObjectBuilder(); - QObject::connect(builder, SIGNAL(destroying(pqPipelineSource*)), - this, SLOT(onDestroyingSource(pqPipelineSource*))); - this->view = this->createRenderView(this->ui.renderFrame); QObject::connect(this->view.data(), SIGNAL(endRender()), this, SLOT(onRenderDone())); + + } StandardView::~StandardView() { } +void StandardView::setupViewButtons() +{ + // Populate the rebin button + QMenu* rebinMenu = new QMenu(this->ui.rebinToolButton); + + m_binMDAction = new QAction("BinMD", rebinMenu); + m_binMDAction->setIconVisibleInMenu(false); + + m_sliceMDAction = new QAction("SliceMD", rebinMenu); + m_sliceMDAction->setIconVisibleInMenu(false); + + m_cutMDAction = new QAction("CutMD", rebinMenu); + m_cutMDAction->setIconVisibleInMenu(false); + + m_unbinAction = new QAction("Remove Rebinning", rebinMenu); + m_unbinAction->setIconVisibleInMenu(false); + + rebinMenu->addAction(m_binMDAction); + rebinMenu->addAction(m_sliceMDAction); + rebinMenu->addAction(m_cutMDAction); + rebinMenu->addAction(m_unbinAction); + + this->ui.rebinToolButton->setPopupMode(QToolButton::InstantPopup); + this->ui.rebinToolButton->setMenu(rebinMenu); + + QObject::connect(m_binMDAction, SIGNAL(triggered()), + this, SLOT(onBinMD()), Qt::QueuedConnection); + QObject::connect(m_sliceMDAction, SIGNAL(triggered()), + this, SLOT(onSliceMD()), Qt::QueuedConnection); + QObject::connect(m_cutMDAction, SIGNAL(triggered()), + this, SLOT(onCutMD()), Qt::QueuedConnection); + // Set the unbinbutton to remove the rebinning on a workspace + // which was binned in the VSI + QObject::connect(m_unbinAction, SIGNAL(triggered()), + this, SIGNAL(unbin()), Qt::QueuedConnection); + + + // Populate the slice button + + // Populate the cut button + +} + void StandardView::destroyView() { pqObjectBuilder *builder = pqApplicationCore::instance()->getObjectBuilder(); @@ -89,13 +139,10 @@ void StandardView::render() } pqObjectBuilder* builder = pqApplicationCore::instance()->getObjectBuilder(); - if (this->isMDHistoWorkspace(this->origSrc)) - { - this->ui.rebinButton->setEnabled(false); - } + //setRebinAndUnbinButtons(); + if (this->isPeaksWorkspace(this->origSrc)) { - this->ui.rebinButton->setEnabled(false); this->ui.cutButton->setEnabled(false); } @@ -123,29 +170,6 @@ void StandardView::onCutButtonClicked() builder->createFilter("filters", "Cut", this->getPvActiveSrc()); } -void StandardView::onRebinButtonClicked() -{ - const QString filterName = "MantidRebinning"; - if (this->hasFilter(filterName)) - { - QMessageBox::warning(this, QApplication::tr("Overplotting Warning"), - QApplication::tr("Please click on the "+filterName+\ - " entry to modify the rebinning "\ - "parameters.")); - return; - } - if (this->origSrc) - { - pqObjectBuilder* builder = pqApplicationCore::instance()->getObjectBuilder(); - this->rebinCut = builder->createFilter("filters", "MDEWRebinningCutter", - this->origSrc); - this->ui.cutButton->setEnabled(false); - // Resulting MDHW can crash VSI when switching to SplatterPlot view, - // so disable that mode. - emit this->setViewStatus(ModeControlWidget::SPLATTERPLOT, false); - } -} - void StandardView::onScaleButtonClicked() { pqObjectBuilder *builder = pqApplicationCore::instance()->getObjectBuilder(); @@ -175,11 +199,13 @@ void StandardView::renderAll() void StandardView::resetDisplay() { this->view->resetDisplay(); + this->view->forceRender(); } void StandardView::resetCamera() { this->view->resetCamera(); + this->view->forceRender(); } /** @@ -195,19 +221,148 @@ void StandardView::updateView() this->cameraReset = true; } +void StandardView::closeSubWindows() +{ +} + +/** + * This function reacts to a destroyed source. + */ +void StandardView::onSourceDestroyed() +{ + //setRebinAndUnbinButtons(); +} + /** - * This function checks a pipeline source that ParaView says is being - * deleted. If the source is a Mantid rebinning filter, the restriction - * on the SplatterPlot view should be lifted. Also, the cut button can - * be enabled. - * @param src : The pipeline source being checked + * Check if the rebin and unbin buttons should be visible + * Note that for a rebin button to be visible there may be no + * MDHisto workspaces present, yet temporary MDHisto workspaces are + * allowed. */ -void StandardView::onDestroyingSource(pqPipelineSource *src) +void StandardView::setRebinAndUnbinButtons() +{ + int numberOfTemporaryWorkspaces = 0; + int numberOfTrueMDHistoWorkspaces = 0; + int numberOfPeakWorkspaces = 0; + + pqServer *server = pqActiveObjects::instance().activeServer(); + pqServerManagerModel *smModel = pqApplicationCore::instance()->getServerManagerModel(); + QList sources = smModel->findItems(server); + + for (QList::iterator source = sources.begin(); source != sources.end(); ++source) + { + if (isTemporaryWorkspace(*source)) + { + numberOfTemporaryWorkspaces++; + } else if (isMDHistoWorkspace(*source)) + { + numberOfTrueMDHistoWorkspaces++; + } + else if (isPeaksWorkspace(*source)) + { + numberOfPeakWorkspaces++; + } + } + + // If there are any true MDHisto workspaces then the rebin button should be disabled + if (numberOfTrueMDHistoWorkspaces > 0 || numberOfPeakWorkspaces > 0) + { + this->m_binMDAction->setEnabled(false); + this->m_sliceMDAction->setEnabled(false); + this->m_cutMDAction->setEnabled(false); + } + else + { + this->m_binMDAction->setEnabled(true); + this->m_sliceMDAction->setEnabled(true); + this->m_cutMDAction->setEnabled(false); + } + + // If there are no temporary workspaces the button should be disabled. + if (numberOfTemporaryWorkspaces == 0) + { + this->m_unbinAction->setEnabled(false); + } + else + { + this->m_unbinAction->setEnabled(true); + } +} + + +/** + * Reacts to the user selecting the BinMD algorithm + */ +void StandardView::onBinMD() +{ + emit rebin("BinMD"); +} + +/** + * Reacts to the user selecting the SliceMD algorithm + */ +void StandardView::onSliceMD() { - if (src->getSMName().contains("MantidRebinning")) + emit rebin("SliceMD"); +} + +/** + * Reacts to the user selecting the CutMD algorithm + */ +void StandardView::onCutMD() +{ + emit rebin("CutMD"); +} + +/** + * Listen for a change of the active source in order to check if the the + * active source is an MDEventSource for which we allow rebinning. + */ +void StandardView::activeSourceChangeListener(pqPipelineSource* source) +{ + // If there is no active source, then we do not allow rebinning + if (!source) + { + this->m_binMDAction->setEnabled(false); + this->m_sliceMDAction->setEnabled(false); + this->m_cutMDAction->setEnabled(false); + this->m_unbinAction->setEnabled(false); + return; + } + + // If it is a filter work your way down + pqPipelineSource* localSource = source; + pqPipelineFilter* filter = qobject_cast(localSource); + + while(filter) + { + localSource = filter->getInput(0); + filter = qobject_cast(localSource); + } + + // Important to first check the temporary source, then for MDEvent source, + // as a temporary source may be an MDEventSource. + std::string workspaceType(localSource->getProxy()->GetXMLName()); + if (isTemporaryWorkspace(localSource)) + { + this->m_binMDAction->setEnabled(true); + this->m_sliceMDAction->setEnabled(true); + this->m_cutMDAction->setEnabled(false); + this->m_unbinAction->setEnabled(true); + } + else if (workspaceType.find("MDEW Source") != std::string::npos) + { + this->m_binMDAction->setEnabled(true); + this->m_sliceMDAction->setEnabled(true); + this->m_cutMDAction->setEnabled(false); + this->m_unbinAction->setEnabled(false); + } + else { - emit this->setViewStatus(ModeControlWidget::SPLATTERPLOT, true); - this->ui.cutButton->setEnabled(true); + this->m_binMDAction->setEnabled(false); + this->m_sliceMDAction->setEnabled(false); + this->m_cutMDAction->setEnabled(false); + this->m_unbinAction->setEnabled(false); } } diff --git a/Code/Mantid/Vates/VatesSimpleGui/ViewWidgets/src/ViewBase.cpp b/Code/Mantid/Vates/VatesSimpleGui/ViewWidgets/src/ViewBase.cpp index d3d0b47a31ea..fc09884575ec 100644 --- a/Code/Mantid/Vates/VatesSimpleGui/ViewWidgets/src/ViewBase.cpp +++ b/Code/Mantid/Vates/VatesSimpleGui/ViewWidgets/src/ViewBase.cpp @@ -1,4 +1,5 @@ #include "MantidVatesSimpleGuiViewWidgets/ViewBase.h" +#include "MantidVatesSimpleGuiViewWidgets/BackgroundRgbProvider.h" #if defined(__INTEL_COMPILER) #pragma warning disable 1170 @@ -45,7 +46,7 @@ namespace SimpleGui * Default constructor. * @param parent the parent widget for the view */ -ViewBase::ViewBase(QWidget *parent) : QWidget(parent) +ViewBase::ViewBase(QWidget *parent) : QWidget(parent), m_currentColorMapModel(NULL), m_temporaryWorkspaceIdentifier("tempvsi") { } @@ -170,6 +171,14 @@ void ViewBase::onColorMapChange(const pqColorMapModel *model) this->colorUpdater.logScale(true); } rep->renderViewEventually(); + + if (this->colorUpdater.isAutoScale()) + { + setAutoColorScale(); + } + + // Workaround for colormap but when changing the visbility of a source + this->m_currentColorMapModel = model; } /** @@ -240,7 +249,7 @@ bool ViewBase::isPeaksWorkspace(pqPipelineSource *src) } QString wsType(vtkSMPropertyHelper(src->getProxy(), "WorkspaceTypeName", true).GetAsString()); - // This must be a Mantid rebinner filter if the property is empty. + if (wsType.isEmpty()) { wsType = src->getSMName(); @@ -265,7 +274,7 @@ pqPipelineRepresentation *ViewBase::getPvActiveRep() * @param pluginName name of the ParaView plugin * @param wsName name of the Mantid workspace to pass to the plugin */ -void ViewBase::setPluginSource(QString pluginName, QString wsName) +pqPipelineSource* ViewBase::setPluginSource(QString pluginName, QString wsName) { // Create the source from the plugin pqObjectBuilder* builder = pqApplicationCore::instance()->getObjectBuilder(); @@ -281,6 +290,8 @@ void ViewBase::setPluginSource(QString pluginName, QString wsName) srcProxy->Modified(); srcProxy->UpdatePipelineInformation(); src->updatePipeline(); + + return src; } /** @@ -316,14 +327,31 @@ void ViewBase::checkView(ModeControlWidget::Views initialView) } } +/** + * This metod sets the status of the splatterplot button explictly to a desired value + * @param visiblity The state of the the splatterplot view button. + */ +void ViewBase::setSplatterplot(bool visibility) +{ + emit this->setViewStatus(ModeControlWidget::SPLATTERPLOT, visibility); +} + +/** + * This metod sets the status of the standard view button explictly to a desired value + * @param visiblity The state of the the standard view button. + */ +void ViewBase::setStandard(bool visibility) +{ + emit this->setViewStatus(ModeControlWidget::STANDARD, visibility); +} + /** * This function sets the status for the view mode control buttons when the * view switches. */ void ViewBase::checkViewOnSwitch() { - if (this->hasWorkspaceType("MDHistoWorkspace") || - this->hasFilter("MantidRebinning")) + if (this->hasWorkspaceType("MDHistoWorkspace")) { emit this->setViewStatus(ModeControlWidget::SPLATTERPLOT, false); } @@ -581,7 +609,7 @@ bool ViewBase::isMDHistoWorkspace(pqPipelineSource *src) } QString wsType(vtkSMPropertyHelper(src->getProxy(), "WorkspaceTypeName", true).GetAsString()); - // This must be a Mantid rebinner filter if the property is empty. + if (wsType.isEmpty()) { wsType = src->getSMName(); @@ -589,6 +617,39 @@ bool ViewBase::isMDHistoWorkspace(pqPipelineSource *src) return wsType.contains("MDHistoWorkspace"); } +/** + * This function checks if a pqPipelineSource is a temporary workspace. + * @return true if the source is a temporary workspace; + */ +bool ViewBase::isTemporaryWorkspace(pqPipelineSource *src) +{ + if (NULL == src) + { + return false; + } + + QString wsType(vtkSMPropertyHelper(src->getProxy(), + "WorkspaceTypeName", true).GetAsString()); + + if (wsType.isEmpty()) + { + wsType = src->getSMName(); + } + + + QString wsName(vtkSMPropertyHelper(src->getProxy(), + "WorkspaceName", true).GetAsString()); + + if (wsName.contains(m_temporaryWorkspaceIdentifier)) + { + return true; + } + else + { + return false; + } +} + /** * This function is where one specifies updates to the UI components for a * view. @@ -604,6 +665,13 @@ void ViewBase::updateView() { } +/// This function is used to update settings, such as background color etc. +void ViewBase::updateSettings() +{ + this->backgroundRgbProvider.update(); +} + + /** * This function checks the current pipeline for a filter with the specified * name. The function works for generic filter names only. @@ -674,7 +742,7 @@ bool ViewBase::hasWorkspaceType(const QString &wsTypeName) { QString wsType(vtkSMPropertyHelper((*source)->getProxy(), "WorkspaceTypeName", true).GetAsString()); - // This must be a Mantid rebinner filter if the property is empty. + if (wsType.isEmpty()) { wsType = (*source)->getSMName(); @@ -688,6 +756,16 @@ bool ViewBase::hasWorkspaceType(const QString &wsTypeName) return hasWsType; } +/** + * This function sets the default colors for the background and connects a tracker for changes of the background color by the user. + * @param viewSwitched If the view was switched or created. + */ +void ViewBase::setColorForBackground(bool viewSwitched) +{ + backgroundRgbProvider.setBackgroundColor(this->getView(), viewSwitched); + backgroundRgbProvider.observe(this->getView()); +} + /** * React to a change of the visibility of a representation of a source. * This can be a change of the status if the "eye" symbol in the PipelineBrowserWidget @@ -700,6 +778,10 @@ void ViewBase::onVisibilityChanged(pqPipelineSource*, pqDataRepresentation*) // Reset the colorscale if it is set to autoscale if (colorUpdater.isAutoScale()) { + // Workaround: A ParaView bug requires us to reload the ColorMap when the visibility changes. + if (m_currentColorMapModel) { + onColorMapChange(m_currentColorMapModel); + } this->setAutoColorScale(); } } @@ -712,6 +794,13 @@ void ViewBase::initializeColorScale() colorUpdater.initializeColorScale(); } +/** + * This function reacts to a destroyed source. + */ +void ViewBase::onSourceDestroyed() +{ +} + } // namespace SimpleGui } // namespace Vates } // namespace Mantid diff --git a/Code/Mantid/Vates/VatesSimpleGui/ViewWidgets/test/unitTests/ColorMapManagerTest.h b/Code/Mantid/Vates/VatesSimpleGui/ViewWidgets/test/unitTests/ColorMapManagerTest.h new file mode 100644 index 000000000000..fa0fb5e0eafc --- /dev/null +++ b/Code/Mantid/Vates/VatesSimpleGui/ViewWidgets/test/unitTests/ColorMapManagerTest.h @@ -0,0 +1,68 @@ +#ifndef BACKGROUND_RGB_PROVIDER_TEST_H_ +#define BACKGROUND_RGB_PROVIDER_TEST_H_ + +#include "MantidVatesSimpleGuiViewWidgets/ColorMapManager.h" +#include + + +using namespace Mantid::Vates::SimpleGui; + +class ColorMapManagerTest : public CxxTest::TestSuite +{ + public: + + void testWriteAndReadIndexForValidElements() + { + // Arrange + ColorMapManager manager; + + // Act + manager.readInColorMap("test1"); + manager.readInColorMap("test2"); + manager.readInColorMap("test3"); + + // Assert + TSM_ASSERT("Should have an index of 0 as it was entered first.", manager.getColorMapIndex("test1") == 0); + TSM_ASSERT("Should have an index of 1 as it was entered second.", manager.getColorMapIndex("test2") == 1); + TSM_ASSERT("Should have an index of 2 as it was entered third.", manager.getColorMapIndex("test3") == 2); + } + + void testGetsFirstIndexForInvalidColorMapRequest() + { + // Arrange + ColorMapManager manager; + + // Act + manager.readInColorMap("test1"); + manager.readInColorMap("test2"); + manager.readInColorMap("test3"); + + // Assert + TSM_ASSERT("Should have an index of 0 if the color map does not exist", manager.getColorMapIndex("wrongMap") == 0); + } + + void testGetsFirstIndexForManagerWithoutRecordings() + { + // Arrange + ColorMapManager manager; + + // Act + + // Assert + TSM_ASSERT("Should have an index of 0 if there are no color maps recorded.", manager.getColorMapIndex("wrongMap") == 0); + } + + void testDetectsValidAndInvalidEntries() + { + //Arrange + ColorMapManager manager; + + // Act + manager.readInColorMap("test1"); + + // Assert + TSM_ASSERT("Should find a recorded color map", manager.isRecordedColorMap("test1")); + TSM_ASSERT("Should not find an unrecorded color map", !manager.isRecordedColorMap("wrongMap")); + } +}; +#endif \ No newline at end of file diff --git a/Code/Mantid/docs/source/algorithms/AlignAndFocusPowder-v1.rst b/Code/Mantid/docs/source/algorithms/AlignAndFocusPowder-v1.rst index 0320223ce49e..2477b9d64b38 100644 --- a/Code/Mantid/docs/source/algorithms/AlignAndFocusPowder-v1.rst +++ b/Code/Mantid/docs/source/algorithms/AlignAndFocusPowder-v1.rst @@ -32,6 +32,11 @@ sub-algorithms as listed below. #. :ref:`algm-EditInstrumentGeometry` (if appropriate) #. :ref:`algm-ConvertUnits` to time-of-flight +Workflow +######## + +.. diagram:: AlignAndFocusPowder-v1_wkflw.dot + Usage ----- @@ -46,15 +51,4 @@ The files needed for this example are not present in our standard usage data dow CalFileName='pg3_mantid_det.cal', Params='100') - - - - - - -.. image:: /images/AlignAndFocusPowderFlowchart.png - .. categories:: - - - diff --git a/Code/Mantid/docs/source/algorithms/CalibrateRectangularDetectors-v1.rst b/Code/Mantid/docs/source/algorithms/CalibrateRectangularDetectors-v1.rst index cd6f78d11504..c95648178cd4 100644 --- a/Code/Mantid/docs/source/algorithms/CalibrateRectangularDetectors-v1.rst +++ b/Code/Mantid/docs/source/algorithms/CalibrateRectangularDetectors-v1.rst @@ -54,4 +54,6 @@ and :math:`fwhm` as the peak's fitted width. Then, .. math:: c_l\times\frac{\Delta(d)}{d} < fwhm < c_h\times\frac{\Delta(d)}{d} +.. seealso :: Algorithm :ref:`algm-EstimateResolutionDiffraction` + .. categories:: diff --git a/Code/Mantid/docs/source/algorithms/CopyDetectorMapping-v1.rst b/Code/Mantid/docs/source/algorithms/CopyDetectorMapping-v1.rst new file mode 100644 index 000000000000..86b8a8df3052 --- /dev/null +++ b/Code/Mantid/docs/source/algorithms/CopyDetectorMapping-v1.rst @@ -0,0 +1,59 @@ +.. algorithm:: + +.. summary:: + +.. alias:: + +.. properties:: + +Description +----------- + +This algorithm will copy the spectra to detector ID mapping form one workspace +to the other, either on a spectrum index or spectrum number basis. + +Typically if both the workspace to be remapped and the workspace being matched +both have their vertical axes in spectrum number then the IndexBySpectrumNumber +option should be considered. With the option disabled the algorithm will copy +the mapping based on the index of the spectrum in the workspace. + +Both workspaces must be a :ref:`MatrixWorkspace` with the same number of +histograms. + +Usage: +------ + +**Example: CopyDetectorMapping on generated workspaces** + +.. testcode:: + + # Create a sample workspace and a workspace to copy mapping to + to_match = CreateSimulationWorkspace(Instrument='IRIS', + BinParams='-0.5,0.05,0.5') + to_remap = CreateSampleWorkspace(NumBanks=10, BankPixelWidth=1) + + # Group the spectra in the sample workspace + grouping_ws = CreateGroupingWorkspace(InstrumentName='IRIS', + FixedGroupCount=10, + ComponentName='graphite') + to_match = GroupDetectors(InputWorkspace=to_match, PreserveEvents=False, + CopyGroupingFromWorkspace='grouping_ws') + + print 'Spectrum 0 detectors before copy: ' + str(to_remap.getSpectrum(0).getDetectorIDs()) + + # Copy the grouping to another workspace + CopyDetectorMapping(WorkspaceToMatch='to_match', + WorkspaceToRemap='to_remap', + IndexBySpectrumNumber=True) + + print 'Spectrum 0 detectors after copy: ' + str(to_remap.getSpectrum(0).getDetectorIDs()) + + +Output: + +.. testoutput:: + + Spectrum 0 detectors before copy: set(1) + Spectrum 0 detectors after copy: set(3,4,5,6,7) + +.. categories:: diff --git a/Code/Mantid/docs/source/algorithms/DgsAbsoluteUnitsReduction-v1.rst b/Code/Mantid/docs/source/algorithms/DgsAbsoluteUnitsReduction-v1.rst index 9fbbcde5bd3c..e563d679de49 100644 --- a/Code/Mantid/docs/source/algorithms/DgsAbsoluteUnitsReduction-v1.rst +++ b/Code/Mantid/docs/source/algorithms/DgsAbsoluteUnitsReduction-v1.rst @@ -65,8 +65,7 @@ with the cross-section units of :math:`millibarns/steradian`. Workflow ######## -.. figure:: /images/DgsAbsoluteUnitsReductionWorkflow.png - :alt: DgsAbsoluteUnitsReductionWorkflow.png +.. diagram:: DgsAbsoluteUnitsReduction-v1_wkflw.dot Usage ----- diff --git a/Code/Mantid/docs/source/algorithms/DgsReduction-v1.rst b/Code/Mantid/docs/source/algorithms/DgsReduction-v1.rst index e5728c4127e5..cd0050dacbad 100644 --- a/Code/Mantid/docs/source/algorithms/DgsReduction-v1.rst +++ b/Code/Mantid/docs/source/algorithms/DgsReduction-v1.rst @@ -22,8 +22,7 @@ They will be detailed in the child algorithm diagrams. Items in parallelograms are output workspaces from their respective algorithms. Not all output workspaces are subsequently used by other algorithms. -.. figure:: /images/DgsReductionWorkflow.png - :alt: DgsReductionWorkflow.png +.. diagram:: DgsReduction-v1_wkflw.dot Usage ----- diff --git a/Code/Mantid/docs/source/algorithms/DgsRemap-v1.rst b/Code/Mantid/docs/source/algorithms/DgsRemap-v1.rst index 5fb5dbefa3ef..8b4887ee8ac1 100644 --- a/Code/Mantid/docs/source/algorithms/DgsRemap-v1.rst +++ b/Code/Mantid/docs/source/algorithms/DgsRemap-v1.rst @@ -16,8 +16,7 @@ then masking. Workflow ######## -.. figure:: /images/DgsRemapWorkflow.png - :alt: DgsRemapWorkflow.png +.. diagram:: DgsRemap-v1_wkflw.dot Usage ----- diff --git a/Code/Mantid/docs/source/algorithms/EstimatePDDetectorResolution-v1.rst b/Code/Mantid/docs/source/algorithms/EstimateResolutionDiffraction-v1.rst similarity index 90% rename from Code/Mantid/docs/source/algorithms/EstimatePDDetectorResolution-v1.rst rename to Code/Mantid/docs/source/algorithms/EstimateResolutionDiffraction-v1.rst index 29b244b92b7a..701da1d9791f 100644 --- a/Code/Mantid/docs/source/algorithms/EstimatePDDetectorResolution-v1.rst +++ b/Code/Mantid/docs/source/algorithms/EstimateResolutionDiffraction-v1.rst @@ -65,7 +65,7 @@ Usage # Load a Nexus file Load(Filename="PG3_2538_2k.nxs", OutputWorkspace="PG3_2538") # Run the algorithm to estimate detector's resolution - EstimatePDDetectorResolution(InputWorkspace="PG3_2538", DeltaTOF=40.0, OutputWorkspace="PG3_Resolution") + EstimateResolutionDiffraction(InputWorkspace="PG3_2538", DeltaTOF=40.0, OutputWorkspace="PG3_Resolution") resws = mtd["PG3_Resolution"] print "Size of workspace 'PG3_Resolution' = ", resws.getNumberHistograms() @@ -86,4 +86,6 @@ Output: Estimated resolution of detector of spectrum 100 = 0.00323608373204 Estimated resolution of detector of spectrum 999 = 0.00354849279137 +.. seealso :: Algorithms :ref:`algm-CalibrateRectangularDetectors` and :ref:`algm-GetDetOffsetsMultiPeaks` + .. categories:: diff --git a/Code/Mantid/docs/source/algorithms/ExportSampleLogsToCSVFile-v1.rst b/Code/Mantid/docs/source/algorithms/ExportSampleLogsToCSVFile-v1.rst index 871e294a225d..a82ed84a8b69 100644 --- a/Code/Mantid/docs/source/algorithms/ExportSampleLogsToCSVFile-v1.rst +++ b/Code/Mantid/docs/source/algorithms/ExportSampleLogsToCSVFile-v1.rst @@ -9,37 +9,63 @@ Description ----------- -Algorithm 'LoadSampleLogsToCSVFile' exports a specified set of sample logs +Algorithm *LoadSampleLogsToCSVFile* exports a specified set of sample logs , which are stored in a MatrixWorkspace, to a CSV file. +The header for the sample log csv file can also +be created by this algorithm in a seperate *header* file. + +CSV File format +=============== + +Sample logs are written to a csv file. +A tab separates any two adjacent values. Each entry of each exported sample log will be an individual entry in the output CSV file, except in the situation that two entries with time stamps within time tolerance. +The output CSV file has 2+n columns, where n is the number of sample logs +to be exported. + +Here is the definition for the columns. + +- Column 1: Absolute time (with respect to the Unix epoch) in seconds +- Column 2: Relative to first log entry's time +- Column 3 to (2 + n): log values in the order determined by input + *SampleLogNames* + +Header file +=========== + +A sample log header file can be generated optionally. +It contains theree lines described as below. + +- Line 1: Test date: [Test date in string] +- Line 2: Test description: [Description of this log file] +- Line 3: Header content given by user via input property *Header*. + Usually it is the column names in the .csv file Time Zone ---------- +========= -The time stamps of sample logs are recorded as UTC time. +The time stamps of sample logs are recorded as UTC time in SNS. Some users wants to see the exported sample log as the neutron facility's local time. So the input property 'TimeZone' is for this purpose. +Property *TimeZone* does not support all the time zones +but only those with facilities that use Mantid. -Header file ------------ - -- Line 0: Test date: [Test date in string] -- Line 1: Test description: [Description of this log file] -- Line 2: Header content given by user via input property *Header*. - Usually it is the column names in the .csv file +Here is the list of all time zones that are allowed by this algorithm. +- UTC +- GMT+0 +- America/New_York +- Asia/Shanghai +- Australia/Sydney +- Europe/London +- Europe/Paris +- Europe/Copenhagen -CSV File format ---------------- -- Column 0: Absolute time in second -- Column 1: Relative to first log entry's time -- Column 2 to (2 + n) - 1: log values in the order determined by input - *SampleLogNames* Usage ----- diff --git a/Code/Mantid/docs/source/algorithms/GetDetOffsetsMultiPeaks-v1.rst b/Code/Mantid/docs/source/algorithms/GetDetOffsetsMultiPeaks-v1.rst index ec1751a5fb98..9c0fde0e1917 100644 --- a/Code/Mantid/docs/source/algorithms/GetDetOffsetsMultiPeaks-v1.rst +++ b/Code/Mantid/docs/source/algorithms/GetDetOffsetsMultiPeaks-v1.rst @@ -265,4 +265,6 @@ Output os.remove( calFilePath ) +.. seealso :: Algorithm :ref:`algm-EstimateResolutionDiffraction` + .. categories:: diff --git a/Code/Mantid/docs/source/algorithms/IndirectILLReduction-v1.rst b/Code/Mantid/docs/source/algorithms/IndirectILLReduction-v1.rst index c1b79eda7c9c..8792ada006a9 100644 --- a/Code/Mantid/docs/source/algorithms/IndirectILLReduction-v1.rst +++ b/Code/Mantid/docs/source/algorithms/IndirectILLReduction-v1.rst @@ -9,7 +9,9 @@ Description ----------- -A workflow algorithm to perform a data reduction for Indirect ILL instruments. Note that currently only IN16B is supported. +A workflow algorithm to perform a data reduction for Indirect ILL instruments. + +Note that currently only IN16B is supported. Usage ----- @@ -18,7 +20,10 @@ Usage .. testcode:: ExIndirectILLReduction - IndirectILLReduction(Run='ILLIN16B_034745.nxs', RawWorkspace='raw_workspace', ReducedWorkspace='reduced_workspace') + IndirectILLReduction(Run='ILLIN16B_034745.nxs', + RawWorkspace='raw_workspace', + ReducedWorkspace='reduced_workspace') + print "Reduced workspace has %d spectra" % mtd['reduced_workspace'].getNumberHistograms() print "Raw workspace has %d spectra" % mtd['raw_workspace'].getNumberHistograms() @@ -33,11 +38,14 @@ Output: .. testcode:: ExIndirectILLReductionMirrorMode - IndirectILLReduction(Run='ILLIN16B_034745.nxs', RawWorkspace='raw_workspace', ReducedWorkspace='reduced_workspace', LeftWorkspace='reduced_workspace_left', - RightWorkspace='reduced_workspace_right', MirrorMode=True) + IndirectILLReduction(Run='ILLIN16B_034745.nxs', + RawWorkspace='raw_workspace', + ReducedWorkspace='reduced_workspace', + LeftWorkspace='reduced_workspace_left', + RightWorkspace='reduced_workspace_right', + MirrorMode=True) print "Raw workspace has %d spectra" % mtd['raw_workspace'].getNumberHistograms() - print "Reduced workspace has %d spectra" % mtd['reduced_workspace'].getNumberHistograms() print "Reduced left workspace has %d spectra" % mtd['reduced_workspace_left'].getNumberHistograms() print "Reduced right workspace has %d spectra" % mtd['reduced_workspace_right'].getNumberHistograms() diff --git a/Code/Mantid/docs/source/algorithms/LoadInstrument-v1.rst b/Code/Mantid/docs/source/algorithms/LoadInstrument-v1.rst index 05ed9d7d2b07..61c8b3720d9f 100644 --- a/Code/Mantid/docs/source/algorithms/LoadInstrument-v1.rst +++ b/Code/Mantid/docs/source/algorithms/LoadInstrument-v1.rst @@ -52,7 +52,7 @@ Usage .. testoutput:: exLoadInstrument Default workspace has instrument: basic_rect with 0 parameters - Modified workspace has instrument: MARI with 72 parameters + Modified workspace has instrument: MARI with 73 parameters Instrument MARI has the following detectors: [1 2 3] diff --git a/Code/Mantid/docs/source/algorithms/LoadMuonNexus-v1.rst b/Code/Mantid/docs/source/algorithms/LoadMuonNexus-v1.rst index cf38f386f1fd..febe794506e9 100644 --- a/Code/Mantid/docs/source/algorithms/LoadMuonNexus-v1.rst +++ b/Code/Mantid/docs/source/algorithms/LoadMuonNexus-v1.rst @@ -15,11 +15,12 @@ be an absolute or relative path and should have the extension .nxs or .NXS. If the file contains data for more than one period, a separate workspace will be generated for each. After the first period the workspace names will have "\_2", "\_3", and so on, appended to the given -workspace name. For single period data, the optional parameters can be +workspace name. The optional parameters can be used to control which spectra are loaded into the workspace. If -spectrum\_min and spectrum\_max are given, then only that range to data -will be loaded. If a spectrum\_list is given than those values will be -loaded. +SpectrumMin and SpectrumMax are given, then only that range of data +will be loaded. If a SpectrumList is given, then those values will be +loaded. If a range and a list are supplied, the algorithm will +load all the specified spectra. - TODO get XML descriptions of Muon instruments. This data is not in existing Muon Nexus files. @@ -78,4 +79,38 @@ The ChildAlgorithms used by LoadMuonNexus are: LoadInstrument fails. As the Nexus file has limited instrument data, this only populates a few fields. +Usage +----- + +.. include:: ../usagedata-note.txt + +**Example - Load ISIS muon MUSR dataset:** + +.. testcode:: LoadMuonNexusOnePeriod + + # Load MUSR dataset + ws = LoadMuonNexus(Filename="MUSR00015189.nxs",EntryNumber=1) + print "Workspace has ", ws[0].getNumberHistograms(), " spectra" + +Output: + +.. testoutput:: LoadMuonNexusOnePeriod + + Workspace has 64 spectra + +**Example - Load event nexus file with time filtering:** + +.. testcode:: ExLoadMuonNexusSomeSpectra + + # Load some spectra + ws = LoadMuonNexus(Filename="MUSR00015189.nxs",SpectrumMin=5,SpectrumMax=10,EntryNumber=1) + print "Workspace has ", ws[0].getNumberHistograms(), " spectra" + +Output: + +.. testoutput:: ExLoadMuonNexusSomeSpectra + + Workspace has 6 spectra + + .. categories:: diff --git a/Code/Mantid/docs/source/algorithms/LoadSavuTomoConfig-v1.rst b/Code/Mantid/docs/source/algorithms/LoadSavuTomoConfig-v1.rst new file mode 100644 index 000000000000..77dba9bb7a13 --- /dev/null +++ b/Code/Mantid/docs/source/algorithms/LoadSavuTomoConfig-v1.rst @@ -0,0 +1,74 @@ +.. algorithm:: + +.. summary:: + +.. alias:: + +.. properties:: + +Description +----------- + +This algorithm reads a tomographic reconstruction parameterization +(configuration) file and stores the configuration in a `TableWorkspace +`_. The file is expected +to follow the format used in the savu tomography reconstruction +pipeline ``__. These files +specify a sequence of plugins to be used for tomographic +reconstruction. For each plugin four fields are given in this order: +id, parameters, name, and cite. All fields are character strings. The +parameters field is formatted as a JSON string of name,value +pairs. The workspace produced has one row for every plugin found in +the input file, and four columns of string type. + +This algorithm is used by the IMAT tomography reconstruction interface +(GUI) to load and display configurations that can then be edited and +saved. + +Usage +----- + +**Example** + +.. testcode:: LoadSavuTomoConfig + + tws = LoadSavuTomoConfig("savu_test_data_process03.nxs", OutputWorkspace='savu_tomo_config') + print "Number of columns: %d" % tws.columnCount() + print "Number of rows / processing plugins: %d" % tws.rowCount() + print "Cell 0,0: %s" % tws.cell(0,0) + print "Cell 0,1: %s" % tws.cell(0,1) + print "Cell 0,2: %s" % tws.cell(0,2) + print "Cell 0,3: %s" % tws.cell(0,3) + print "Cell 1,0: %s" % tws.cell(1,0) + print "Cell 1,1: %s" % tws.cell(1,1) + print "Cell 1,2: %s" % tws.cell(1,2) + print "Cell 1,3: %s" % tws.cell(1,3) + print "Cell 2,0: %s" % tws.cell(2,0) + print "Cell 2,1: %s" % tws.cell(2,1) + print "Cell 2,2: %s" % tws.cell(2,2) + print "Cell 2,3: %s" % tws.cell(2,3) + +.. testcleanup:: LoadSavuTomoConfig + + DeleteWorkspace(tws) + +Output: + +.. testoutput:: LoadSavuTomoConfig + + Number of columns: 4 + Number of rows / processing plugins: 3 + Cell 0,0: savu.plugins.timeseries_field_corrections + Cell 0,1: {} + Cell 0,2: Timeseries Field Corrections + Cell 0,3: Not available + Cell 1,0: savu.plugins.median_filter + Cell 1,1: {"kernel_size": [1, 3, 3]} + Cell 1,2: Median Filter + Cell 1,3: Not available + Cell 2,0: savu.plugins.simple_recon + Cell 2,1: {"center_of_rotation": 86} + Cell 2,2: Simple Reconstruction + Cell 2,3: Not available + +.. categories:: diff --git a/Code/Mantid/docs/source/algorithms/MuonLoad-v1.rst b/Code/Mantid/docs/source/algorithms/MuonLoad-v1.rst index 678f315baf77..88f1768100e8 100644 --- a/Code/Mantid/docs/source/algorithms/MuonLoad-v1.rst +++ b/Code/Mantid/docs/source/algorithms/MuonLoad-v1.rst @@ -24,7 +24,7 @@ Specifically: Workflow ######## -.. image:: ../images/MuonWorkflow.png +.. diagram:: MuonLoad-v1_wkflw.dot Usage ----- diff --git a/Code/Mantid/docs/source/algorithms/PhaseQuad-v1.rst b/Code/Mantid/docs/source/algorithms/PhaseQuad-v1.rst index ed658232fcf8..a28f9cf81a37 100644 --- a/Code/Mantid/docs/source/algorithms/PhaseQuad-v1.rst +++ b/Code/Mantid/docs/source/algorithms/PhaseQuad-v1.rst @@ -35,32 +35,69 @@ Usage .. include:: ../usagedata-note.txt -**Example - Computing squashograms:** +**Example - Computing squashograms from PhaseList:** -.. testcode:: ExCompSquash +.. testcode:: ExPhaseQuadList - # Load the first two spectra from a MUSR run - input = LoadMuonNexus('MUSR0015189.nxs',EntryNumber=1,SpectrumMin=1,SpectrumMax=2) + # Load a set of spectra from a EMU file + ws = LoadMuonNexus('EMU00006473.nxs') # Create a PhaseList file with some arbitrary detector information - file = open('PhaseList.txt','w') - file.write("MuSR\n") - file.write("Dummy line\n") - file.write("Dummy line\n") - file.write("Dummy line\n") - file.write("Dummy line\n") - file.write("2 0 60 0.0\n") - for i in range(0,2): - file.write("1 1.0 0.0 -1 -1 -1\n") - file.close() - - output = PhaseQuad('input','',60,0,0,'PhaseList.txt') - print "Counts: ", input[0].readY(0)[24] + import os + phaselist_path = os.path.join(os.path.expanduser("~"),"PhaseList.txt") + phaselist_file = open(phaselist_path,'w') + phaselist_file.write("MuSR\n") + phaselist_file.write("Dummy line\n") + phaselist_file.write("Dummy line\n") + phaselist_file.write("Dummy line\n") + phaselist_file.write("Dummy line\n") + phaselist_file.write("32 0 60 0.0\n") + for i in range(0,16): + phaselist_file.write("1 50.0 0.00 0 0 1\n") + phaselist_file.write("1 50.0 1.57 0 0 1\n") + phaselist_file.close() + + ows = PhaseQuad(InputWorkspace='ws',PhaseList=phaselist_path) + print "Output workspace contains", ows.getNumberHistograms(), "histograms" Output: -.. testoutput:: ExCompSquash +.. testoutput:: ExPhaseQuadList - Counts: 3.0 + Output workspace contains 2 histograms -.. categories:: \ No newline at end of file +.. testcleanup:: ExPhaseQuadList + + import os + try: + os.remove(phaselist_path) + except OSError: + pass + +**Example - Computing squashograms from PhaseTable:** + +.. testcode:: ExPhaseQuadTable + + # Load a set of spectra from a EMU file + ws = LoadMuonNexus('EMU00006473.nxs') + + # Create a PhaseTable with some arbitrary detector information + tab = CreateEmptyTableWorkspace() + tab.addColumn('bool', 'Status') + tab.addColumn('double', 'Asymmetry') + tab.addColumn('double', 'Phase') + tab.addColumn('double', 'DeadTime') + for i in range(0,16): + tab.addRow([1, 50.0, 0.00, 0]) + tab.addRow([1, 50.0, 1.57, 0]) + + ows = PhaseQuad(InputWorkspace='ws',PhaseTable='tab') + print "Output workspace contains", ows.getNumberHistograms(), "histograms" + +Output: + +.. testoutput:: ExPhaseQuadTable + + Output workspace contains 2 histograms + +.. categories:: diff --git a/Code/Mantid/docs/source/algorithms/SCARFTomoReconstruction-v1.rst b/Code/Mantid/docs/source/algorithms/SCARFTomoReconstruction-v1.rst new file mode 100644 index 000000000000..fff3b4e64b3a --- /dev/null +++ b/Code/Mantid/docs/source/algorithms/SCARFTomoReconstruction-v1.rst @@ -0,0 +1,87 @@ +.. algorithm:: + +.. summary:: + +.. alias:: + +.. properties:: + +Description +----------- + +Algorithm to control jobs running on the SCARF computer cluster at +RAL, STFC (see http://www.scarf.rl.ac.uk/ for more information). This +algorithm can be used to log in and out from the cluster, and to +initiate, query the status of, or cancel a job. It has been introduced +to control tomographic reconstruction jobs but in principle it can be +used for any other task. + +In a typical use case or session you would use the algorithm a first +time to login (for which you need to select the 'LogIn' action and set +the username and password fields). After this step you can use the +algorithm again several times, to submit jobs (setting the action +'SubmitJob'), query the status of the jobs running on the computer +cluster (setting the action to 'JobStatus' or 'JobStatusByID'), cancel +jobs (setting the action 'CancelJob') and log out from the cluster +(action 'LogOut'). You can also upload and download files. After +logging out, subsequent submit or status queries will fail with an +informative message. Note that the server will log out users every +undetermined amount of time, which depends on server settings. + +In principle, in a simple use case, the same username will be used in +all the calls to this algorithm. This means that you type in the +username only the first time that you use this algorithm, as it will +be remembered and filled in automatically in the next calls. But note +that it is possible to change the username passed to the algorithm +every time you call the algorithm. This means that you can use this +algorithm to control jobs for multiple users simultaneously from the +same instance of Mantid. You can use for example use the username +associated to a particular project or instrument, and in parallel your +personal username for different jobs (which can be useful to +distinguish quick tests, calibration of parameters, etc.). For this to +work, you of course need to perform a 'LogIn' action for every +username that is used in submit or query status actions. + +The 'JobStatus' and 'JobStatusByID' actions produce an output several +output properties with status and general information about the jobs, +as retrieved from the compute resource/server. + +The algorithm relies on a web service provided by the SCARF computer +cluster in order to control jobs on the cluster. If you use this +algorithm from its dialog (for example starting it from the algorithm +explorer in Mantid) the password will not be shown on the screen. This +algorithm can be used interactively. In such case, it is absolutely +not recommended to call it from scripts or the Python script +interpreter window, as you will be passing passwords as plain text. + +The alternative ways to monitor and control your jobs are via shell +login and via the web platform at https://portal.scarf.rl.ac.uk/. + +This algorithm is used by other components of Mantid, in particular +the custom graphical interface for tomography (IMAT instrument). + +Usage +----- + +**Example** + +.. testcode:: SCARFTomoReconstruction + + try: + SCARFTomoReconstruction(UserName='foouser', Action='Login') + except ValueError: + print "ValueError, as expected, because no Password= parameter given" + + try: + SCARFTomoReconstruction(UserName='foouser', Action='Submit') + except ValueError: + print "ValueError, as expected, as it was not previously logged on" + +Output: + +.. testoutput:: SCARFTomoReconstruction + + ValueError, as expected, because no Password= parameter given + ValueError, as expected, as it was not previously logged on + +.. categories:: diff --git a/Code/Mantid/docs/source/algorithms/SaveSavuTomoConfig-v1.rst b/Code/Mantid/docs/source/algorithms/SaveSavuTomoConfig-v1.rst new file mode 100644 index 000000000000..ab6fbbf5ba4e --- /dev/null +++ b/Code/Mantid/docs/source/algorithms/SaveSavuTomoConfig-v1.rst @@ -0,0 +1,64 @@ +.. algorithm:: + +.. summary:: + +.. alias:: + +.. properties:: + +Description +----------- + +This algorithm writes a file with tomographic reconstruction +parameterization (configuration) file using the format of the savu +tomography reconstruction pipeline +(``__). The parameters are +taken from a list of `TableWorkspace +`_ workspaces. The data +in every workspace is expected to have four columns, with each row +specifying one plugin. For every plugin four character string +attributes (four columns) must be given, in this order: id, parameters +(JSON string of name-value pairs), name, and cite (citation +information about plugin documentation and authors). + +This algorithm is used by the IMAT tomography reconstruction interface +(GUI) to save configuration files that can then be used to run +tomography reconstruction jobs using the savu pipeline. + +Usage +----- + +**Example** + +.. testcode:: SaveSavuTomoConfig + + import os.path + tws_name = 'saveSavuTomoTest' + tws = CreateEmptyTableWorkspace(OutputWorkspace=tws_name) + tws.addColumn('str', 'ID') + tws.addColumn('str', 'Parameters') + tws.addColumn('str', 'Name') + tws.addColumn('str', 'Cite') + tws.addRow(['savu.id1', '{"param11": val1', 'plugin name1', 'cite info1']) + tws.addRow(['savu.id2', '{"param21": val2', 'plugin name2', 'cite info2']) + print "Columns: %d" % tws.columnCount() + print "Rows: %d" % tws.rowCount() + out_fname = 'saveSavuTomoTest.nxs' + SaveSavuTomoConfig(Filename=out_fname, InputWorkspaces='saveSavuTomoTest') + res = os.path.isfile(out_fname) + print "Save result: ", res + +.. testcleanup:: SaveSavuTomoConfig + + DeleteWorkspace(tws) + os.remove(out_fname) + +Output: + +.. testoutput:: SaveSavuTomoConfig + + Columns: 4 + Rows: 2 + Save result: True + +.. categories:: diff --git a/Code/Mantid/docs/source/algorithms/Segfault-v1.rst b/Code/Mantid/docs/source/algorithms/Segfault-v1.rst new file mode 100644 index 000000000000..46d811401c31 --- /dev/null +++ b/Code/Mantid/docs/source/algorithms/Segfault-v1.rst @@ -0,0 +1,15 @@ + +.. algorithm:: + +.. summary:: + +.. alias:: + +.. properties:: + +Description +----------- + +The purpose of this algorithm is to crash mantid. Do **not** run it +unless you want that to happen. This runs a variation the example code +on `wikipedia `_. diff --git a/Code/Mantid/docs/source/concepts/Point_groups.rst b/Code/Mantid/docs/source/concepts/Point_groups.rst index c00da6633605..9d46db529ffe 100644 --- a/Code/Mantid/docs/source/concepts/Point_groups.rst +++ b/Code/Mantid/docs/source/concepts/Point_groups.rst @@ -70,9 +70,9 @@ Using these identifiers, ``SymmetryOperation``-objects can be created through a .. testcode :: ExSymmetryOperation - from mantid.geometry import SymmetryOperation, SymmetryOperationFactoryImpl + from mantid.geometry import SymmetryOperation, SymmetryOperationFactory - symOp = SymmetryOperationFactoryImpl.Instance().createSymOp("x,y,-z") + symOp = SymmetryOperationFactory.createSymOp("x,y,-z") hkl = [1, -1, 3] hklPrime = symOp.apply(hkl) @@ -85,6 +85,28 @@ The above code will print the mirrored index: Mirrored hkl: [1,-1,-3] +Sometimes it is easier to think about symmetry in terms of the elements that cause certain symmetry. These are commonly described with Herrman-Mauguin symbols. A symmetry element can be derived from the matrix/vector pair that described the symmetry operation, according to the International Tables for Crystallography A, section 11.2. Expanding a bit on the above example, it's possible to get information about the symmetry element associated to the operation ``x,y,-z``: + +.. testcode :: ExSymmetryElement + + from mantid.geometry import SymmetryOperation, SymmetryOperationFactory + from mantid.geometry import SymmetryElement, SymmetryElementFactory + + symOp = SymmetryOperationFactory.createSymOp("x,y,-z") + element = SymmetryElementFactory.createSymElement(symOp) + + print "The element corresponding to 'x,y,-z' has the following symbol:", element.hmSymbol() + print "The mirror plane is perpendicular to:", element.getAxis() + +Executing this code yields the following output: + +.. testoutput :: ExSymmetryElement + + The element corresponding to 'x,y,-z' has the following symbol: m + The mirror plane is perpendicular to: [0,0,1] + +Some symmetry elements (identity, inversion center, translation) do not have an axis. In these cases, ``[0,0,0]`` is returned from that method. + 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 @@ -94,9 +116,9 @@ Point groups are represented in Mantid by the ``PointGroup``-interface, which is .. testcode :: ExInformation - from mantid.geometry import PointGroup, PointGroupFactoryImpl + from mantid.geometry import PointGroup, PointGroupFactory - pg = PointGroupFactoryImpl.Instance().createPointGroup("-1") + pg = PointGroupFactory.createPointGroup("-1") print "Name:", pg.getName() print "Hermann-Mauguin symbol:", pg.getSymbol() @@ -114,11 +136,11 @@ It's possible to query the factory about available point groups. One option retu .. testcode :: ExQueryPointGroups - from mantid.geometry import PointGroup, PointGroupFactoryImpl + from mantid.geometry import PointGroup, PointGroupFactory - 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) + print "All point groups:", PointGroupFactory.getAllPointGroupSymbols() + print "Cubic point groups:", PointGroupFactory.getPointGroupSymbols(PointGroup.CrystalSystem.Cubic) + print "Tetragonal point groups:", PointGroupFactory.getPointGroupSymbols(PointGroup.CrystalSystem.Tetragonal) Which results in the following output: @@ -132,9 +154,9 @@ After having obtained a ``PointGroup``-object, it can be used for working with r .. testcode :: ExIsEquivalent - from mantid.geometry import PointGroup, PointGroupFactoryImpl + from mantid.geometry import PointGroup, PointGroupFactory - pg = PointGroupFactoryImpl.Instance().createPointGroup("m-3m") + pg = PointGroupFactory.createPointGroup("m-3m") hkl1 = [2, 0, 0] hkl2 = [0, 0, -2] @@ -152,9 +174,9 @@ Another common task is to find all symmetry equivalents of a reflection, for exa .. testcode :: ExGetEquivalents - from mantid.geometry import PointGroup, PointGroupFactoryImpl + from mantid.geometry import PointGroup, PointGroupFactory - pg = PointGroupFactoryImpl.Instance().createPointGroup("m-3m") + pg = PointGroupFactory.createPointGroup("m-3m") hkl1 = [2, 0, 0] equivalents1 = pg.getEquivalents(hkl1) @@ -183,9 +205,9 @@ Sometimes, a list of reflections needs to be reduced to a set of symmetry indepe .. testcode :: ExIndependentReflections - from mantid.geometry import PointGroup, PointGroupFactoryImpl + from mantid.geometry import PointGroup, PointGroupFactory - pg = PointGroupFactoryImpl.Instance().createPointGroup("m-3m") + pg = PointGroupFactory.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] diff --git a/Code/Mantid/docs/source/diagrams/AlignAndFocusPowder-v1_wkflw.dot b/Code/Mantid/docs/source/diagrams/AlignAndFocusPowder-v1_wkflw.dot new file mode 100644 index 000000000000..ecf7ba1b8fe8 --- /dev/null +++ b/Code/Mantid/docs/source/diagrams/AlignAndFocusPowder-v1_wkflw.dot @@ -0,0 +1,99 @@ +digraph AlignAndFocusPowder { + label="AlignAndFocusPowder Flowchart" + $global_style + + subgraph params { + $param_style + InputWorkspace + OutputWorkspace + RemovePromptPulseWidth + CompressTolerance + CropWaveLengthMin + MaskWorkspace + CalFileName + OffsetsWorkspace + GroupingWorkspace + UnwrapRef + LowResRef + params1 [label="Params"] + params2 [label="Params"] + } + + subgraph algoritms { + $algorithm_style + removePromptPulse [label="RemovePromptPulse v1"] + compressEvents [label="CompressEvents v1"] + cropWorkspace [label="CropWorkspace v1"] + maskDetectors [label="MaskDetectors v1"] + rebin1 [label="Rebin v1"] + rebin2 [label="Rebin v1"] + resampleX [label="ResampleX v1"] + alignDetectors [label="AlignDetectors v1"] + convertUnits1 [label="ConvertUnits v1\nTime-of-Flight"] + convertUnits2 [label="ConvertUnits v1\nd-spacing"] + convertUnits3 [label="ConvertUnits v1\nTime-of-Flight"] + unwrapSNS [label="UnwrapSNS v1"] + removeLowResTOF [label="RemoveLowResTOF v1"] + diffFocus [label="DiffractionFocussing v2"] + sortEvents [label="SortEvents v1"] + editGeom [label="EditInstrumentGeometry v1"] + loadCalFile [label="LoadCalFile v1"] + } + + subgraph decisions { + $decision_style + isEventWorkspace1 [label="Is event workspace?"] + isEventWorkspace2 [label="Is event workspace?"] + isDspace1 [label="Is d-space binning?"] + isDspace2 [label="Is d-space binning?"] + ifParams [label="LRef, minwl, or\nDIFCref specified?"] + } + + + InputWorkspace -> isEventWorkspace1 + + isEventWorkspace1 -> removePromptPulse [label="Yes"] + RemovePromptPulseWidth -> removePromptPulse + removePromptPulse -> compressEvents + CompressTolerance -> compressEvents + compressEvents -> cropWorkspace + + isEventWorkspace1 -> cropWorkspace [label="No"] + CropWaveLengthMin -> cropWorkspace + + cropWorkspace -> maskDetectors + MaskWorkspace -> maskDetectors + maskDetectors -> isDspace1 + isDspace1 -> resampleX [label="Yes"] + resampleX -> alignDetectors + isDspace1 -> rebin1 [label="No"] + params1 -> rebin1 + rebin1 -> alignDetectors + OffsetsWorkspace -> alignDetectors + alignDetectors -> ifParams + + ifParams -> isDspace2 [label="No"] + ifParams -> convertUnits1 [label="Yes"] + convertUnits1 -> unwrapSNS + UnwrapRef -> unwrapSNS + unwrapSNS -> removeLowResTOF + LowResRef -> removeLowResTOF + removeLowResTOF -> convertUnits2 + convertUnits2 -> isDspace2 + + isDspace2 -> diffFocus [label="No"] + isDspace2 -> rebin2 [label="Yes"] + params2 -> rebin2 + rebin2 -> diffFocus + GroupingWorkspace -> diffFocus + diffFocus -> isEventWorkspace2 + isEventWorkspace2 -> sortEvents [label="Yes"] + isEventWorkspace2 -> editGeom [label="No"] + sortEvents -> editGeom + editGeom -> convertUnits3 + convertUnits3 -> OutputWorkspace + + CalFileName -> loadCalFile + loadCalFile -> OffsetsWorkspace + loadCalFile -> GroupingWorkspace +} diff --git a/Code/Mantid/docs/source/diagrams/AlignAndFocusPowderFlowchart.dot b/Code/Mantid/docs/source/diagrams/AlignAndFocusPowderFlowchart.dot deleted file mode 100644 index aeb7dc9d1f2b..000000000000 --- a/Code/Mantid/docs/source/diagrams/AlignAndFocusPowderFlowchart.dot +++ /dev/null @@ -1,46 +0,0 @@ -digraph { - label="AlignAndFocusPowder Flowchart" - LoadCalFile[shape="box", stype="rounded"] - RemovePromptPulse[shape="box", stype="rounded"] - CompressEvents_or_SortEvents[shape="box", stype="rounded"] - CropWorkspaces[shape="box", stype="rounded"] - MaskBinsFromTable[shape="box", stype="rounded"] - MaskDetectors[shape="box", stype="rounded"] - Rebin_or_ResampleX_ifTOF[shape="box", stype="rounded"] - AlignDetectors[shape="box", stype="rounded"] - ConvertUnits_to_TOF[shape="box", stype="rounded"] - UnwrapSNS[shape="box", stype="rounded"] - RemoveLowResTOF[shape="box", stype="rounded"] - ConvertUnits_to_dSpacing[shape="box", stype="rounded"] - SortEvents[shape="box", stype="rounded"] - DiffractionFocussing[shape="box", stype="rounded"] - SortEvents[shape="box", stype="rounded"] - Rebin_or_ResampleX_ifdSpacing[shape="box", stype="rounded"] - Rebin_or_ResampleX__ifdSpacing[shape="box", stype="rounded"] - EditInstrumentGeometry[shape="box", stype="rounded"] - ConjoinWorkspaces[shape="box", stype="rounded"] - ConvertUnits__to_TOF[shape="box", stype="rounded"] - CompressEvents[shape="box", stype="rounded"] - Rebin_or_ResampleX[shape="box", stype="rounded"] - - InputWorkspace -> RemovePromptPulse -> CompressEvents_or_SortEvents -> CropWorkspaces -> MaskBinsFromTable -> MaskDetectors -> Rebin_or_ResampleX_ifTOF -> AlignDetectors -> ConvertUnits_to_TOF -> UnwrapSNS -> RemoveLowResTOF -> ConvertUnits_to_dSpacing -> Rebin_or_ResampleX_ifdSpacing -> SortEvents -> DiffractionFocussing -> SortEvents -> Rebin_or_ResampleX__ifdSpacing -> EditInstrumentGeometry -> ConjoinWorkspaces -> ConvertUnits__to_TOF -> CompressEvents -> Rebin_or_ResampleX -> OutputWorkspace; - CalFileName -> LoadCalFile -> GroupingWorkspace -> DiffractionFocussing - LoadCalFile -> OffsetsWorkspace -> AlignDetectors - MaskWorkspace -> MaskDetectors - MaskBinTable -> MaskBinsFromTable - Params -> Rebin_or_ResampleX_ifTOF - Params -> Rebin_or_ResampleX_ifdSpacing - Params -> Rebin_or_ResampleX__ifdSpacing - Params -> Rebin_or_ResampleX - RemovePromptPulseWidth ->RemovePromptPulse - CompressTolerance -> CompressEvents_or_SortEvents - CompressTolerance -> CompressEvents - UnwrapRef -> UnwrapSNS - LowResRef -> RemoveLowResTOF - CropWaveLengthMin -> CropWorkspaces - PrimaryFlightPath -> EditInstrumentGeometry - SpectrumIDs -> EditInstrumentGeometry - L2 -> EditInstrumentGeometry - Polar -> EditInstrumentGeometry - Azimuthal -> EditInstrumentGeometry -} diff --git a/Code/Mantid/docs/source/diagrams/DgsAbsoluteUnitsReduction-v1_wkflw.dot b/Code/Mantid/docs/source/diagrams/DgsAbsoluteUnitsReduction-v1_wkflw.dot new file mode 100644 index 000000000000..6787c18f4788 --- /dev/null +++ b/Code/Mantid/docs/source/diagrams/DgsAbsoluteUnitsReduction-v1_wkflw.dot @@ -0,0 +1,76 @@ +digraph DgsReduction { + label = "DgsAbsoluteUnitsReduction Flowchart" + $global_style + + subgraph params { + $param_style + absUDWS [label="Absolute Units\nDetector Vanadium\nWorkspace"] + absUSWS [label="Absolute Units\nSample Workspace"] + absUMWS [label="Absolute Units\nMask Workspace"] + detDiagParam [label="Detector\nDiagnostic\nParameters"] + AbsUnitsIncidentEnergy + VanadiumMass + VanadiumRmm + AbsUnitsMinimumEnergy + AbsUnitsMaximumEnergy + MaskWorkspace + GroupingWorkspace + OutputWorkspace + } + + subgraph decisions { + $decision_style + isIAUDV [label="Is Integrated\nAbsolute Units\nDetector Vanadium?"] + } + + subgraph values { + $value_style + procSample [label="Processed\nSample\nWorkspace"] + pauw [label="Processed Absolute\nUnits Workspace"] + sampleCoeff [label="SampleMass\ndivided by\nSampleRmm\ndivided by\nScattering XSec"] + IAUDV [label="Integrated\nAbsolute Units\nDetector Vanadium"] + } + + subgraph algorithms { + $algorithm_style + DgsProcessDetectorVanadium + DgsConvertToEnergyTransfer + Divide + Rebin [label="Rebin (as integration)"] + ConvertToMatrixWorkspace + DetectorDiagnostic + MaskDetectors + ConvertFromDistribution + WeightedMeanOfWorkspace + Multiply + } + + absUDWS -> DgsProcessDetectorVanadium + MaskWorkspace -> DgsConvertToEnergyTransfer + MaskWorkspace -> DgsProcessDetectorVanadium + DgsProcessDetectorVanadium -> IAUDV + GroupingWorkspace -> DgsConvertToEnergyTransfer + absUSWS -> DgsConvertToEnergyTransfer + AbsUnitsIncidentEnergy -> DgsConvertToEnergyTransfer + IAUDV -> DgsConvertToEnergyTransfer + DgsConvertToEnergyTransfer -> Divide + VanadiumMass -> Divide + VanadiumRmm -> Divide + Divide -> Rebin + AbsUnitsMinimumEnergy -> Rebin + AbsUnitsMaximumEnergy -> Rebin + Rebin -> ConvertToMatrixWorkspace + ConvertToMatrixWorkspace -> DetectorDiagnostic + detDiagParam -> DetectorDiagnostic + DetectorDiagnostic -> procSample + procSample -> absUMWS + procSample -> MaskDetectors + MaskDetectors -> ConvertFromDistribution + ConvertFromDistribution -> WeightedMeanOfWorkspace + WeightedMeanOfWorkspace -> isIAUDV + sampleCoeff -> Multiply + isIAUDV -> Multiply [label="Yes"] + isIAUDV -> pauw [label="No"] + Multiply -> pauw + pauw -> OutputWorkspace +} diff --git a/Code/Mantid/docs/source/diagrams/DgsAbsoluteUnitsReductionWorkflow.xml b/Code/Mantid/docs/source/diagrams/DgsAbsoluteUnitsReductionWorkflow.xml deleted file mode 100644 index 3af1358267da..000000000000 --- a/Code/Mantid/docs/source/diagrams/DgsAbsoluteUnitsReductionWorkflow.xml +++ /dev/null @@ -1 +0,0 @@ -7Vxbk6I4FP41Vs0+7JSI2vrYrd2z/dC7U3O7PG2lJWpqkFiA3fb++jmBHAgk7YBy01kfLEhCSL5zcq4JPXu22b/zyXb9wB3q9gZ9Z9+z573BYNLvw78oeMkVrHzmxEWWLNgxhwaZopBzN2TbbOGCex5dhJmyJXeznW3JimoFHxfE1Uu/Midcy8ENxmn5X5St1vgaazyNa4LwBftw6JLs3PDPqAjqRPWGYF/RNO1bgMbnHLoRV5v9jLoCHpx6jMXdK7XJIH3qyYEcfkAO4om4OznGnpiRvSc9++b6MeDuLqTQ4LPHwkCp+kg2W5jVoP+V+z+CLVnAdW6ywZpsxeVmvxJ0frt0+fNiTfzwrUNC8kgCqLxZMtedcZf70TP2HfxmMygPQp//oEpNP/olNUgCOX51whKDJ+qHVPJUVCQBeEf5hob+CzSRtcOppKFkONuOb59TMlsSxv5aIfGVLCOS21ZJzyngcCExN+MvX1Ua/zkNgaMBnEH/C/GIw3YbuFQaXAJdJL5IFnnbBFmGh8jyQIIfl8H51jQL8bggxEiZUyAeHYL4nc93W+atLgNmeyiXeQswS9GmwDxfBe99vqBBgEIklSCFEd7GPegAz2YC4oYBnmTZ2BrJHlSAkdVVgEcVAHxl4OMcjNRzrn2fP8PdwiVBwBaAAt2z8BuU9N+O5N13uLPk9XvqMxgKFdgJzAAb/0VpLm5F+6ROe8AB60UOgbqP/Pk2LbiJCqBCIMzAxIk6ce6AknIIDgnWVEzQYFDIooDvfFiUqhYLib+ispXkOzGMgxT0qUtC9pQ1sk6hx+R/eqD66gQ9pBWcFUAz7om5fuK3HvVXL5984gVLwOpcBZBtZSXQYCLVWxMSCN+tQHzvhRQQC4Fnjjcnk9o399ef51/+KKmAO6J8J1njHkilU+ZKCg2VMqikT6IMjrZrwkgRLkXkiYRQlSfIdM0LFMvks3ZMwnM/XPMV94hrEvNr7rP/uBfWIuilvK2OLtGjgCYRT2GDLWeekCBJz+9FQbrqEsGGJlk+DpFrb6N3d2T7gRXbIK+1H/alQDa3h4t4hikHJlAVY0qTI98FpvyVZXHQLinAjfWznk5LKyvSLQwQYhfxCpFPlWAKG51S7CienNZR2cUwzFkHaAlUxnymcMWZ27xFpJ+cZa0sWFgrmeIZr9PA414EQkKAKfBiSoKUIA0ToQjsyM3d0zqaVhjHb6hsoenRFDCqI2P63ltAMsILY4emhKkcAIzhv2LNdcFaHuUighbqcdVcxrLKzeULjKUUWlAG+7o9QaYHUNAlhMB3tPha4GzoAwxmJEINfqGNQSyV0VGxVs3oyWh1jD9syoRh64NYtChg/h2P90Ri2wjeuss4Z08gr8834GTnTNeRXLYqnJg/qDrgZMxanmFYQ8pYVeziTJqXu8acYxlQEcai9mMG0hTho5TfqxGNQupPsm5H6FDOkL8gOphc+hbpoNvaH+gj86DoDfQLDWWMm3GvTGi623J8aNp8Upsc1+1tdGcemMc2u02r3kz1Nt8olyi2pxKBJrwbQ2YyQZvsfwO0hyOpcBtBW8871mOjZIKp5SyWQkLZEOSqPplbLD46tOWLfxEfPSKygoGb48lVTusm1PqV1i0eLDfo4EIEliKoXgIX3o94csbybOlgskLbo4PusSZ7Jh5I6LP9MfviOmb7DAZAcFXAjPoGfTyWbaq2ftDSOncv1pSdR/ZpWkOMMIJTg4bQ/WPctTJnZOXxAMKvl7QWJk2uhVOd3vLWUqF9hQbjB/mgBZmse6TFdlddzobxUS6TPTZFzWs7K1EuPZRPsZ6UXk3slPwDkQumr4uo+BWLJaCrjcgUnpqHRX6sd3Uct+MhpxfGMjxdVSLW1n1pschQIZTJUnVdD1yhg9CIHtC9ZnlWQOwkVc8X4QGwAgeOzsGIwnWTWUuSyZrXNBjw+90S4UaJ1h4VdF9Y+mB3Pt/MGax+9rgT8ecLEjeTviEvW5e4Gepe7tfoFdR5oMT7Z3kBTq4lFlcGYVPmeyIFb+UIX4iTi1JAlQy4PluQDF3dcFkSVUQwg2prGb/hwSOhqh2i+FpKC+l2XcaJ0azMsPpXBiuwttPPuqN7v1SAjo4D9ey7MvjSBQuEptTwXUa/pvFFjSbxnRq2OWL2SkUXy05C9zQ3tg7JUUhWGGIxyCgtyArdAfybn6cMNti8uPpbwFV3AB/giyVs65bJS3fLBLNywQg4L2I4nVnXJgvsQ0H0O3y0ps6k2jHuXJGgVEXM3drWZvwswO/mViPi3RAxI93pi4NJLW4vP13IDDQ3D10WRchcTbFR5jMfuV0VR4Fq8vN0Aw0mAy+9IS5bgSk2X8B8BRfeIHNdy4oNc5yI+yoRv9mcwQS9DgWY2j4yo7sUMa+1t82+AkARrXY4zZQFA07rw7fSQuCm+Ks93z5SPRnbBvcNCnBfwqGVs1/TB5pO3k1z+OB6qfQUrr2O6H7dYUg/epF+B0PZSZBGHohPIvQq0U6t+LsWrvxkc4HsVVkFU0MIsoqdmLjrs3Mb6ktaUchBrWxGgNv0o5BxwjT9eKZ9+xM= \ No newline at end of file diff --git a/Code/Mantid/docs/source/diagrams/DgsReduction-v1_wkflw.dot b/Code/Mantid/docs/source/diagrams/DgsReduction-v1_wkflw.dot new file mode 100644 index 000000000000..b223146f629d --- /dev/null +++ b/Code/Mantid/docs/source/diagrams/DgsReduction-v1_wkflw.dot @@ -0,0 +1,67 @@ +digraph DgsReduction { + label = "DgsReduction Flowchart" + $global_style + + subgraph params { + $param_style + Sample + HardMask + DetectorVanadium + ComparsionDetectorVanadium + Grouping + AbsoluteUnitsSample + AbsoluteUnitsDetectorVanadium + OutputWorkspace + } + + subgraph decisions { + $decision_style + isAbsUnits [label="Absolute\nUnits?"] + } + + subgraph algorithms { + $algorithm_style + DgsDiagnose + DgsProcessDetectorVanadium + DgsConvertToEnergyTransfer + DgsAbsoluteUnitsReduction + Divide + } + + subgraph values { + $value_style + detVanMask [label="DetVan\nDiag Mask"] + intDetVan [label="Integrated\nDetVan"] + procSamp [label="Processed\nSample"] + background [label="Time-independent\nbackground"] + procUnits [label="Processed\nAbsolute\nUnits"] + absUnits [label="Absolute\nUnits\nDiag Mask"] + SPhiE [label="S(φ, E)"] + } + + Sample -> DgsConvertToEnergyTransfer + Sample -> DgsDiagnose + HardMask -> DgsConvertToEnergyTransfer + HardMask -> DgsDiagnose + DetectorVanadium -> DgsDiagnose + DetectorVanadium -> DgsProcessDetectorVanadium + ComparsionDetectorVanadium -> DgsDiagnose + Grouping -> DgsConvertToEnergyTransfer + DgsDiagnose -> detVanMask + detVanMask -> DgsConvertToEnergyTransfer + detVanMask -> DgsProcessDetectorVanadium + DgsProcessDetectorVanadium -> intDetVan + intDetVan -> DgsConvertToEnergyTransfer + AbsoluteUnitsSample -> DgsAbsoluteUnitsReduction + AbsoluteUnitsDetectorVanadium -> DgsAbsoluteUnitsReduction + DgsAbsoluteUnitsReduction -> procUnits + DgsAbsoluteUnitsReduction -> absUnits + DgsConvertToEnergyTransfer -> background + DgsConvertToEnergyTransfer -> procSamp + procSamp -> isAbsUnits + isAbsUnits -> Divide [label="Yes"] + isAbsUnits -> SPhiE [label="No"] + procUnits -> Divide + Divide -> SPhiE + SPhiE -> OutputWorkspace +} diff --git a/Code/Mantid/docs/source/diagrams/DgsReductionWorkflow.xml b/Code/Mantid/docs/source/diagrams/DgsReductionWorkflow.xml deleted file mode 100644 index 75f4e54c4631..000000000000 --- a/Code/Mantid/docs/source/diagrams/DgsReductionWorkflow.xml +++ /dev/null @@ -1 +0,0 @@ -7VxLc+K4Fv41qZpZhPIbvOyQR/eib6UmuTPTqyk1FsYVY1G2Sci/7yM4AskyDibEbROzoLAsydJ3Pp2XZC7s8Xx1l5LF7DsLaHxhGcHqwr6+sKyRYcA3L3gtFIRpFGyKTCxYRgHNlKKcsTiPFmrhhCUJneRK2ZTFamcLElKt4GFCYr30nyjIZzg4y9uVf6VROBOPMT1/cyfLX0UfAZ2SZZxfrovgHr89J6Kv9TTtG4AmZQy64b/mqzGNOTxi6hssbvfc3Q4ypQkOpLoBDuKZxEsc43WYXUckTFhGtfFnM7LgP+erkItuMI3Zy2RG0nywSNmEZgD71TSK4zGLWbpuYo/Ht/CB8ixP2ROV7hjrz/aOABVHJE8BZ/VM05wiS9ZFOKU7yuY0T1+hCt51fGOw6X7zwQ6QUOYICfWyk6NpY9lMkqGLZQTpFG4ftEMUfiCo5QDbOsA0BzICCpw69ooAAn+ThATRcl4D8CyH7/9MHXAO93jcMOCu4Q4cf/cZKYB7+AgJbx8Xhwy3dwK4HQ3uMZvD1KKMJRLg5ygDb4j4CdTNgSQR30cmNiAEVxOCBipNgi9pyl7gahKTLIsmgAldRfm/UGIMXLz6AVccX/77nqYRDIVyJDmCgFT6KlXnl7z+9l6xwVpc4qkJS2Aom7JbkN62YYBXJaoUizK2TCc4DwQVegkp1sLJ0kCxJ7rYUhqTPHpWzct7YEdpSrB/JWkgUfw7yZ46S2/ou4reoxEa4gb4bepKXSc4iP8BL2n8k73c7Ao4yxpnv8xs+yog2Yzy6az75+OD31wYEXg8BzEfNe0xzJftrpCqLKNt4cFLBJ9xzyIY8c7Qi35Ek834sZbsFYmGgonFhptZag3XRNlO7DDu6Bbq83EH12XPnZrc0Q3rA5kvgBZdVeqmpfqNQmNvHceBZQ5tH7xzx3aGo2FzKh492OOX6ceuyPevQUGmT70IQZMSPiFRbcErZCUDEk5Iwcc2kWs7Vm16PHaFY7ReiMfvN8G1CFqOiFRaFp57vhqaoE1EUG0Xe5RptqfJqcP1kgDyLmXLRZSEnVWyoCSr4IZUlXq7OS0rkmcq3ccs4ZN7ZDcJTcPXx5Qk2RQ0X1fpXkhGGRg9IPzOyFFv63FMY+RHyR9q9DCG/lBTd7QpQxh7h7JK4Gfv5ZRFGp+OGXW9HKvo5fgn9nL0TNWZ0a40O9JrpAO2S4R1VfZLwOOVk/ewPQVVamYzA5Lzxm1wyBzfqXTIxPKTiSAiA5kIzin2p/QdwE7YfBylvMAEd/oFViXvmrnrtshbCFfRqNi0F3jVjqiuUSsFztJ8xkKWkLgxi3vsRtunE39dR84TUaEYIFqMfeMo1rfxVMS++q6LkVd5/Xc7ik5N4/QWdw1fZu+Oy6f0GI9WZn1Y8gabzaHKNkisnJZteu7vW5JTcCRzkK1yeGTtkJ6F66nmomxMCDTheTqHHBNpv2ES8MhrWTCpd0yq5K8nf89CuQvh97F/XULo6edHEMTltySgC0n/XpHJUwibMgko5S7qYLOwHzNSNwTcwoZAyWbYh6lkPR+Me4/cAMIDtjKofe6gVTawKvsC8DcIeM1MaFttIKo3xQYil9qj8lwU7NEqTzCk0M/pNKAIv86RDqjcezrUoENJMjzMvvzMWLzM6f+TKM/+osFykkf8cHtHd8dd0wXiKae+HP2oelNb4K6eHhV4S9ZvDf25v04AR/P2v0PjioRcE68T6HH5ATLp+MlIR7yk9DsAb39kXjsqEySSbZLQr7/fJm1NiypzFHltC1Xo51IY3w8wUScO4ltBlZK9hp4q76eKHt5fR8/wBm9nXRfLrQzkh5BrfSOQb8qrqYzrtyZzv1XtZJhfOMU0tIYK2A2G+cIotzzVeZByRCopyrF1sV0Ls5ueHsw9/LGYRRcWNDVu/qy5yH4SeD+/JefLLX8whD9CMEae73quZagJNX9UUHL6ujMN5T2fIToVJ1+GNc++tDS9IpabvAQFu/r0So0VWfNVzLbSoeQwgdDSvUaukr8e5u71gOzbOvqZTqKM5+Q0/Txdf5rO5FTud3ie6hbpJwBEJkLmhSh7lzpuf+x40H5viUckqNWr4xrLUY8Pf8C/Ox3PCMGBxn1kIf12+8gdYIQetv6PfbCKOFa+vQN2hHz13e9DNlu6/vqHZzjqnx5UpikaPJEnEiZn6BALqvUO8U7+cLn7o8FN9d0fMto3vwA= \ No newline at end of file diff --git a/Code/Mantid/docs/source/diagrams/DgsRemap-v1_wkflw.dot b/Code/Mantid/docs/source/diagrams/DgsRemap-v1_wkflw.dot new file mode 100644 index 000000000000..ffd9d684206d --- /dev/null +++ b/Code/Mantid/docs/source/diagrams/DgsRemap-v1_wkflw.dot @@ -0,0 +1,37 @@ +digraph DgsRemap { + label="DgsRemap Flowchart" + $global_style + + subgraph params { + $param_style + InputWorkspace + MaskWorkspace + GroupingWorkspace + OutputWorkspace + } + + subgraph algorithms { + $algorithm_style + maskDet1 [label="MaskDetectors"] + maskDet2 [label="MaskDetectors"] + groupDet1 [label="GroupDetectors"] + groupDet2 [label="GroupDetectors"] + } + + subgraph decisions { + $decision_style + ExecuteOppositeOrder + } + + InputWorkspace -> ExecuteOppositeOrder + ExecuteOppositeOrder -> maskDet1 [label="True"] + ExecuteOppositeOrder -> groupDet2 [label="False"] + maskDet1 -> groupDet1 + groupDet2 -> maskDet2 + groupDet1 -> OutputWorkspace + maskDet2 -> OutputWorkspace + GroupingWorkspace -> groupDet1 + GroupingWorkspace -> groupDet2 + MaskWorkspace -> maskDet1 + MaskWorkspace -> maskDet2 +} diff --git a/Code/Mantid/docs/source/diagrams/DgsRemapWorkflow.xml b/Code/Mantid/docs/source/diagrams/DgsRemapWorkflow.xml deleted file mode 100644 index 52448c7d20cf..000000000000 --- a/Code/Mantid/docs/source/diagrams/DgsRemapWorkflow.xml +++ /dev/null @@ -1 +0,0 @@ -3ZrPcuI4EIefhqqdw6RsDGzmOCGQnUNmUzWHbE5Tii2MKsZySSIh8/RpiZYtsMjGAcy/A9gt2bS+bn6tBjrRcLa4EaSY3vKEZp1ukCw60XWn270MAnjWhtc1QypYsjSFaJizhMoVk+I8U6xYNcY8z2msVmwTnq3erCAprRl+xSSrW+9ZoqboXHdQ2f+hLJ3atwkH35YjUr3aeyR0QuaZ+mpMMKaHZ8TeyywzGgEawTncRh/NFkOaaTx26UsW4w2jpZOC5ujI+xegE88km6OPHb2iaEE60dWPvJgrGHVM91w8yYLEtLY2OSWFPpwtUh3Wi0nGX+IpEeoiIYo8EgmDVxOWZUOecWGuicbwGA7BLpXgT9QZCcyjHLHE0V13fbjkZyoUxRQyJlzvDeUzqsQrTMHRbh/zCfMrRETBSxXWMETb1AmpvY5gdqXlrSvAcICM/byjGu/RgsZzRf8tCi4ZvIqEigZwpYLn3+GRsO311tiG/TpbO8dlO9gB216N7S2RT07yjpmQ8H7jJrlLYyYZz+t8J+bRMt/IckK+XauNDt9LD15r2wYvRnJFKtY40jz5LgR/gbM4I1KyGCjQBVP/gUXnqD5+gOPgoo9nd1QwcAVyHqzaloNbejpO0afmCntSuyABmUYXJE1nMGlUma5o9mj80YwZqLm5TTKGWBqXNoVE8rkAkXM1Ej5oKcVZmGr6vd8Nm6AZUex5tYRsEwSsNp8OgiG2hyA4SP8nJB8hjip5FMT/9qrKNSw+VlzIBlpSCB5TCa6sS8lwqMW6ZSkJ18pg5CuDPqneRRm8PFOo/QDTBaH2LKw2oOJ+04F6I/i8OL9UbZWq3QmeH9b1ZG1VAULrboX1AXq5Eytmnv3FR+obFjO3vmEo2q9vYb0F/MlPYmfXcBvngW4/2wegXm8EnUblbqkTNDmvzjvqYQ+BgjOw/NvovMN6e9hQbcrM1llrc36nWW7EZMfdC+4KVtIek+8Aab9tE3miQcD97pEEYesmck9BaAgVS6YLFZP9AEzrbeJ+mDZDZMXUZYS5eABG9a7PqW/L7+rO7Lvm9Yrn3WLvreJtaAg3Ui5tfwGabmAmszyFQ0g6+uV8wuBtIPcVBhvytr6zM9pRim2lvVtriaeIHaxrKXOgrW+jPwG12jlMuWB/eK4+2B76SB9Mtb0/ER4t6UZtuBXI42gJPb8NnqZOeKi2tS+D0+q3czPm/McgGr0B \ No newline at end of file diff --git a/Code/Mantid/docs/source/diagrams/MuonLoad-v1_wkflw.dot b/Code/Mantid/docs/source/diagrams/MuonLoad-v1_wkflw.dot new file mode 100644 index 000000000000..2dc82fa8f9cb --- /dev/null +++ b/Code/Mantid/docs/source/diagrams/MuonLoad-v1_wkflw.dot @@ -0,0 +1,52 @@ +digraph MuonLoad { + label="MuonLoad Flowchart" + $global_style + + subgraph params { + $param_style + Filename + CustomDeadTimeTable + DetectorGroupingTable + TimeZero + Xmin + Xmax + RebinParams + OutputType + Alpha + FirstPairIndex + SecondPairIndex + GroupIndex + OutputWorkspace + } + + subgraph algorithms { + $algorithm_style + LoadMuonNexus + ApplyDeadTimeCorr + MuonGroupDetectors + ChangeBinOffset + CropWorkspace + Rebin + MuonCalculateAsymmetry + } + + Filename -> LoadMuonNexus + LoadMuonNexus -> ApplyDeadTimeCorr + LoadMuonNexus -> CustomDeadTimeTable + LoadMuonNexus -> DetectorGroupingTable + ApplyDeadTimeCorr -> MuonGroupDetectors + MuonGroupDetectors -> ChangeBinOffset + TimeZero -> ChangeBinOffset + ChangeBinOffset -> CropWorkspace + Xmin -> CropWorkspace + Xmax -> CropWorkspace + CropWorkspace -> Rebin + RebinParams -> Rebin + Rebin -> MuonCalculateAsymmetry + OutputType -> MuonCalculateAsymmetry + FirstPairIndex -> MuonCalculateAsymmetry + SecondPairIndex -> MuonCalculateAsymmetry + GroupIndex -> MuonCalculateAsymmetry + Alpha -> MuonCalculateAsymmetry + MuonCalculateAsymmetry -> OutputWorkspace +} diff --git a/Code/Mantid/docs/source/diagrams/MuonWorkflow.xml b/Code/Mantid/docs/source/diagrams/MuonWorkflow.xml deleted file mode 100644 index 245f45dc5a2f..000000000000 --- a/Code/Mantid/docs/source/diagrams/MuonWorkflow.xml +++ /dev/null @@ -1 +0,0 @@ -1Ztfk6I4EMA/jY9nAeHv4yyzM3dVt7dTN1O1c/dylZGo1AKhQpjRb79BOihRPEFARktLgob0L013pzvOkB9vHhlO199oQKKZocWYr2fofmYYmniJhhSvyO8kXK152azrtrc/8yMM5Pddw963Py9wROAH+9Zaw5JGQa1hQZOELORlyjZOacTDNKs1rvIwIEoTC+udBVsYlQZyBBulIeNbOcSALHEe8d92TeKcMUNfBRpGqRhN8Sne+CQq8MirQB8z46HhC5XUjCQgUuNv3nGUw0gewogkOCZHQ8zWOC0+xptVMV3zZUQ/FmvM+Dzj4v0/fYa+LMMo8mlE2e4n6EE8fF+0Z5zRn+TgjLZ7VGfkJO4k34tgHYsAUr0Txgnw3DWBPI+ExoSzrfjKx14xPNAXmBELOMDvkavP4UoY5nRVdVO0rg+Uz1YZig+AsRHpnxQH33Ka/EU2edaCa8rogmRiSCpX3y/Iduda3SZXctVNoAFgdZWs5Q1L9ggmSYI7xuiHOFpEOMvCxRELVGfhNrIggWIvMpqzBTSBWELzV0QKcJrXackZiTAP3+sXaCP6XZpG23uCg5cwFhrA2BQUC8Hx9ZplVJoDumV4I+tWccc+Mpqn94QLp0DZJG5d0+yNMGg+8DV1R/KUhG1j7gyKuFDdfwmjU/A1ZhVT9OtsTAkGOrBs6HUYpP4aJyvyJUy+L5eZsEwTUFnrRCTSUWVtxShYpqqy6HKj4AzmcISYbPsqmgo93R38Iw40MTQ4fCJMqD4nBUcYRUWr2YSedUhSfw89Ukn+CpcEP32ioRhKRd02nbmYDOR6yNUsBIOBKbBdRb/LQUIXx7yrYV2s4YymPyj7maVYyD4F/e4tnNLr4ZStujxHb2GQu6j3axwmkwj8m6Oy6yJ/t24vdOHiBvVwrzHeTALoQN7NdiuAsgtLGzhq+Ju8tdLS4ZZRfcVibv2+d42jUMy1B4ZaRLs+jha58AHkLtvGB33flrLT25pCeibA7CmRGULWXK7rLoBcKX4bzA8hy/gTDtkfSSBGPgHL4PTlvRTL4MncgOxA09vQ7aDCz0Tk74JpwXWGgStgKnR1SGsMg/YuStd4EkAH8mOuq5pcy4NLD0P0e87TnL9sBcAJYJUOqHeslorV0LSBzYCfZ5zGMjP2gt8E1ykg7m2VIGM5mRhTTYExSgD2hBmO26TEhiM7kE1wTDW2tWQC4HbZ7Jrkcn3YNlcgidWy17tgdrT09YWJlE3IqzyK+HyQRhFHZ7IoXnPO6SwZGQ0dkikD0EmRqcvaMWMkg5NeZT2dMfIcbe5qnlA8USLwkLJilHXJoTJG7Yk2L+zOEz1xX01ee5qLrOdtCEzaDWUtY6guucAAc/yGM3Gyb2fk9ZcMrKrSVdBvqQ4J2V6LaEq6i5ErrF7zIuj83QQXP9SwEu9oGiZLf7s6YJisJhNN6lpvdUBZOGgIJwdeBzXfve0VTUfQ0FbTTjj9spI9mqL1i6Gj+5LV+0MOZb35k3Jo4dpGKJuZjroYNtFxQac5+Dnq0JKmv+oOHXmDUq7+Yql+J6jZWZ7ffHNq0sb1DP1y6OghZeXxhuu4fjl03IwlCzGfKe7WUXPa4vykA6QbKn97YWUxoLWwp3Y1jCvsLvabTEVBN/vaTaPWa5TNBvZ+/TGRbJdudkx0VMw+lX0wOzpHmWi+YTR7X+5mb+MSDm4EVyueCo2u26JOwCgBTRNGtXOsMAT/v3PsYnr9LYxg5Tm1RPEVO+50q+N6qVqEj7RgEof7P4SU4fv+jzPo6y8= \ No newline at end of file diff --git a/Code/Mantid/docs/source/diagrams/ReflectometryReductionOneAuto-v1-Groups_wkflw.dot b/Code/Mantid/docs/source/diagrams/ReflectometryReductionOneAuto-v1-Groups_wkflw.dot index 800adcf09151..91c67807bd67 100644 --- a/Code/Mantid/docs/source/diagrams/ReflectometryReductionOneAuto-v1-Groups_wkflw.dot +++ b/Code/Mantid/docs/source/diagrams/ReflectometryReductionOneAuto-v1-Groups_wkflw.dot @@ -22,11 +22,11 @@ digraph ReflectometryReductionOne { inputWorkspace -> reflRedOne reflRedOne -> reflRedOne_0 [label="InputWorkspace[0]"] reflRedOne -> reflRedOne_1 [label="InputWorkspace[1]"] + reflRedOne_0 -> thetaOut [label="θ"] reflRedOne_0 -> groupIvQ [label="IvQ"] reflRedOne_1 -> groupIvQ [label="IvQ"] reflRedOne_0 -> groupIvLam [label="Ivλ"] reflRedOne_1 -> groupIvLam [label="Ivλ"] - reflRedOne_0 -> thetaOut [label="θ"] groupIvQ -> outputWorkspaceMT [label="IvQ"] groupIvLam -> outputWorkspaceWL [label="Ivλ"] } diff --git a/Code/Mantid/docs/source/images/AlignAndFocusPowderFlowchart.png b/Code/Mantid/docs/source/images/AlignAndFocusPowderFlowchart.png deleted file mode 100644 index 04c544852200..000000000000 Binary files a/Code/Mantid/docs/source/images/AlignAndFocusPowderFlowchart.png and /dev/null differ diff --git a/Code/Mantid/docs/source/images/DgsReductionWorkflow.png b/Code/Mantid/docs/source/images/DgsReductionWorkflow.png deleted file mode 100644 index 6bed2ae0165b..000000000000 Binary files a/Code/Mantid/docs/source/images/DgsReductionWorkflow.png and /dev/null differ diff --git a/Code/Mantid/docs/source/images/DgsRemapWorkflow.png b/Code/Mantid/docs/source/images/DgsRemapWorkflow.png deleted file mode 100644 index 3da968ea3c14..000000000000 Binary files a/Code/Mantid/docs/source/images/DgsRemapWorkflow.png and /dev/null differ diff --git a/Code/Mantid/docs/source/images/MuonWorkflow.png b/Code/Mantid/docs/source/images/MuonWorkflow.png deleted file mode 100644 index a994cd3a3d29..000000000000 Binary files a/Code/Mantid/docs/source/images/MuonWorkflow.png and /dev/null differ diff --git a/Code/Mantid/docs/source/interfaces/Indirect_DataReduction.rst b/Code/Mantid/docs/source/interfaces/Indirect_DataReduction.rst index 6f0d3fa22673..09fd592eca7c 100644 --- a/Code/Mantid/docs/source/interfaces/Indirect_DataReduction.rst +++ b/Code/Mantid/docs/source/interfaces/Indirect_DataReduction.rst @@ -11,12 +11,14 @@ The Indirect Data Reduction interface provides the initial reduction that is used to convert raw instrument data to S(Q, w) for analysis in the Indirect Data Analysis and Indirect Bayes interfaces. +The tabs shown on this interface will vary depending on the current default +facility such that only tabs that will work with data from the facility are +shown, this page describes all the tabs which can possibly be shown. + .. interface:: Data Reduction :align: right :width: 350 -.. warning:: Currently this interface only supports ISIS instruments. - Instrument Options ~~~~~~~~~~~~~~~~~~ @@ -49,11 +51,11 @@ Manage Directories Opens the Manage Directories dialog allowing you to change your search directories and default save directory and enable/disable data archive search. -Energy Transfer ---------------- +ISIS Energy Transfer +-------------------- .. interface:: Data Reduction - :widget: tabEnergyTransfer + :widget: tabISISEnergyTransfer This tab provides you with the functionality to convert the raw data from the experiment run into units of :math:`\Delta E`. @@ -166,11 +168,44 @@ Multiple In this mode multiple binning ranges can be defined using he rebin string syntax used by the :ref:`Rebin ` algorithm. -Calibration & Resolution ------------------------- +ILL Energy Transfer +------------------- + +.. interface:: Data Reduction + :widget: tabILLEnergyTransfer + +This tab handles the reduction of data from the IN16B instrument at the ILL. + +This will output the raw (*_raw*) data read from the file and reduced (*_red*) +workspace by default, with mirror mode enabled you will also get the left +(*_left*) and right (*_right*) hand components of the data as separate +workspaces. + +Options +~~~~~~~ + +Input + Used to select the raw data in *.nxs* format + +Grouping + Used to switch between grouping as per the IDF (*Default*) or grouping using a + mapping file (*Map FIle*). + +Mirror Mode + Enable to reduce data that has been captured with mirror mode enabled. + +Plot + If enabled will plot the result as a spectra plot. + +Save + If enabled the result will be saved as a NeXus file in the default save + directory. + +ISIS Calibration & Resolution +----------------------------- .. interface:: Data Reduction - :widget: tabCalibration + :widget: tabISISCalibration This tab gives you the ability to create Calibration and Resolution files. @@ -233,11 +268,11 @@ Background Start & Background End Low, Width & High Binning parameters used to rebin the resolution curve. -Diagnostics ------------ +ISIS Diagnostics +---------------- .. interface:: Data Reduction - :widget: tabDiagnostics + :widget: tabISISDiagnostics This tab allows you to perform an integration on a raw file over a specified time of flight range, and is equivalent to the Slice functionality found in @@ -318,7 +353,7 @@ Symmetrise ---------- .. interface:: Data Reduction - :widget: tabSymmertrise + :widget: tabSymmetrise This tab allows you to take an asymmetric reduced file and symmetrise it about the Y axis. @@ -379,7 +414,7 @@ S(Q, w) ------- .. interface:: Data Reduction - :widget: tabSofQW + :widget: tabSQw Provides an interface for running the SofQW algorithms. diff --git a/Code/Mantid/docs/sphinxext/mantiddoc/directives/diagram.py b/Code/Mantid/docs/sphinxext/mantiddoc/directives/diagram.py index 7e63ead920c7..e9fd957acb91 100644 --- a/Code/Mantid/docs/sphinxext/mantiddoc/directives/diagram.py +++ b/Code/Mantid/docs/sphinxext/mantiddoc/directives/diagram.py @@ -11,6 +11,7 @@ STYLE["global_style"] = """ fontname = Helvetica labelloc = t +ordering = out node[fontname="Helvetica", style = filled] edge[fontname="Helvetica"] """ diff --git a/Code/Mantid/docs/sphinxext/mantiddoc/directives/properties.py b/Code/Mantid/docs/sphinxext/mantiddoc/directives/properties.py index 2f9ae52a5f2b..f7dedfee1e58 100644 --- a/Code/Mantid/docs/sphinxext/mantiddoc/directives/properties.py +++ b/Code/Mantid/docs/sphinxext/mantiddoc/directives/properties.py @@ -141,7 +141,7 @@ def _get_default_prop(self, prop): elif (prop.isValid == ""): default_prop = self._create_property_default_string(prop) else: - default_prop = "Mandatory" + default_prop = "*Mandatory*" return default_prop def _create_property_default_string(self, prop): @@ -162,14 +162,14 @@ def _create_property_default_string(self, prop): try: val = int(default) if (val >= 2147483647): - defaultstr = "Optional" + defaultstr = "*Optional*" else: defaultstr = str(val) except: try: val = float(default) if (val >= 1e+307): - defaultstr = "Optional" + defaultstr = "*Optional*" else: defaultstr = str(val) except: @@ -190,7 +190,7 @@ def _create_property_default_string(self, prop): if (defaultstr == "8.9884656743115785e+307") or \ (defaultstr == "1.7976931348623157e+308") or \ (defaultstr == "2147483647"): - defaultstr = "Optional" + defaultstr = "*Optional*" if str(prop.type) == "boolean": if defaultstr == "1": diff --git a/Code/Mantid/instrument/Facilities.xml b/Code/Mantid/instrument/Facilities.xml index 108d06ac3954..5b7c6c8b41a2 100644 --- a/Code/Mantid/instrument/Facilities.xml +++ b/Code/Mantid/instrument/Facilities.xml @@ -6,6 +6,10 @@ + + https://portal.scarf.rl.ac.uk + + @@ -389,7 +393,7 @@ Neutron Diffraction Diffuse Scattering - + @@ -417,7 +421,7 @@ Neutron Spectroscopy TOF Indirect Geometry Spectroscopy Neutron Diffraction - + diff --git a/Code/Mantid/instrument/LET_Parameters.xml b/Code/Mantid/instrument/LET_Parameters.xml index 7984db910a2e..5a6df4785f29 100644 --- a/Code/Mantid/instrument/LET_Parameters.xml +++ b/Code/Mantid/instrument/LET_Parameters.xml @@ -392,6 +392,17 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Absolute normalization factor is NaN <----------------------------------------------\n' - else: - log_value = '\n--------> Warning, Monovanadium has zero spectra <--------------------------------------------\n' - log1_value = \ + if norm_factor['LibISIS'] != norm_factor['LibISIS']: + log_value = '\n--------> Absolute normalization factor is NaN <----------------------------------------------\n' + else: + log_value = '\n--------> Warning, Monovanadium has zero spectra <--------------------------------------------\n' + log1_value = \ "--------> Processing workspace: {0}\n"\ "--------> Monovan Integration range : min={1}, max={2} (meV)\n"\ "--------> Summed: {3} spectra with total signal: {4} and error: {5}\n"\ @@ -1150,24 +1169,22 @@ def get_abs_normalization_factor(self,deltaE_wkspaceName,ei_monovan): "--------> Abs norm factors: Sigma^2: {9}\n"\ "--------> Abs norm factors: Poisson: {10}\n"\ "--------> Abs norm factors: TGP : {11}\n"\ - .format(deltaE_wkspaceName,minmax[0],minmax[1],nhist,sum(signal),sum(error),izerc,scale_factor,\ + .format(ws_name,minmax[0],minmax[1],nhist,sum(signal),sum(error),izerc,scale_factor, norm_factor['LibISIS'],norm_factor['SigSq'],norm_factor['Poisson'],norm_factor['TGP']) - log_value = log_value + log1_value - propman.log(log_value,'error') + log_value = log_value + log1_value + propman.log(log_value,'error') else: if not self._debug_mode: - DeleteWorkspace(Workspace=deltaE_wkspaceName) + monovan_run.clear_resulting_ws() DeleteWorkspace(Workspace=data_ws) return (norm_factor['LibISIS'],norm_factor['SigSq'],norm_factor['Poisson'],norm_factor['TGP']) #--------------------------------------------------------------------------- # Behind the scenes stuff #--------------------------------------------------------------------------- - def __init__(self, instr_name=None,reload_instrument=False): - """ - Constructor - """ + """Constructor """ + object.__setattr__(self,'_descriptors',[]) object.__setattr__(self,'_propMan',None) # Debug parameter. Usually True unless investigating a problem @@ -1196,27 +1213,27 @@ def __init__(self, instr_name=None,reload_instrument=False): #end def __getattr__(self,attr_name): - """ overloaded to return values of properties non-existing in the class dictionary + """ overloaded to return values of properties non-existing in the class dictionary from the property manager class except this property already have descriptor in self class """ - if attr_name in self._descriptors: - return object.__getattr__(self,attr_name) - else: - return getattr(self._propMan,attr_name) + if attr_name in self._descriptors: + return object.__getattr__(self,attr_name) + else: + return getattr(self._propMan,attr_name) def __setattr__(self,attr_name,attr_value): - """ overloaded to prohibit adding non-starting with _properties to the class instance + """ overloaded to prohibit adding non-starting with _properties to the class instance and add all other properties to property manager except this property already - have a descriptor - """ - if attr_name[0] == '_': + have a descriptor + """ + if attr_name[0] == '_': object.__setattr__(self,attr_name,attr_value) - else: - if attr_name in self._descriptors: - object.__setattr__(self,attr_name,attr_value) - else: - setattr(self._propMan,attr_name,attr_value) + else: + if attr_name in self._descriptors: + object.__setattr__(self,attr_name,attr_value) + else: + setattr(self._propMan,attr_name,attr_value) def initialise(self, instr,reload_instrument=False): """ @@ -1260,20 +1277,20 @@ def setup_instrument_properties(self, workspace=None,reload_instrument=False): instrument = workspace.getInstrument() name = instrument.getName() if name != self.prop_man.instr_name: - self.prop_man = PropertyManager(name,workspace) + self.prop_man = PropertyManager(name,workspace) def get_run_descriptor(self,run): - """ Spawn temporary run descriptor for input data given in format, + """ Spawn temporary run descriptor for input data given in format, different from run descriptor. Return existing run descriptor, if it is what provided. """ - if not isinstance(run,RunDescriptor): - tRun = copy.copy(PropertyManager._tmp_run) - tRun.__set__(None,run) - return tRun - else: - return run + if not isinstance(run,RunDescriptor): + tRun = copy.copy(PropertyManager._tmp_run) + tRun.__set__(None,run) + return tRun + else: + return run # # ------------------------------------------------------------------------------------------- # This actually does the conversion for the mono-sample and @@ -1334,10 +1351,10 @@ def _do_mono_ISIS(self, data_run, ei_guess,\ energy_bins = PropertyManager.energy_bins.get_abs_range(self.prop_man) if energy_bins: - Rebin(InputWorkspace=result_name,OutputWorkspace=result_name,Params= energy_bins,PreserveEvents=False) - if bkgr_ws: # remove background after converting units and rebinning - RemoveBackground(InputWorkspace=result_name,OutputWorkspace=result_name,BkgWorkspace=bkgr_ws,EMode='Direct') - DeleteWorkspace(bkgr_ws) + Rebin(InputWorkspace=result_name,OutputWorkspace=result_name,Params= energy_bins,PreserveEvents=False) + if bkgr_ws: # remove background after converting units and rebinning + RemoveBackground(InputWorkspace=result_name,OutputWorkspace=result_name,BkgWorkspace=bkgr_ws,EMode='Direct') + DeleteWorkspace(bkgr_ws) else: pass # TODO: investigate way of removing background from event workspace if we want # result to be an event workspace @@ -1346,8 +1363,8 @@ def _do_mono_ISIS(self, data_run, ei_guess,\ if self.apply_detector_eff and energy_bins: #should detector efficiency work on event workspace too? At the moment it is #not (01/02/2015) - DetectorEfficiencyCor(InputWorkspace=result_name,OutputWorkspace=result_name) - self.prop_man.log("_do_mono: finished DetectorEfficiencyCor for : " + result_name,'information') + DetectorEfficiencyCor(InputWorkspace=result_name,OutputWorkspace=result_name) + self.prop_man.log("_do_mono: finished DetectorEfficiencyCor for : " + result_name,'information') ############# data_run.synchronize_ws(mtd[result_name]) @@ -1362,19 +1379,21 @@ def _find_or_build_bkgr_ws(self,result_ws,bkg_range_min=None,bkg_range_max=None, bkg_range_min += time_shift bkg_range_max += time_shift - # has to have specific name for this all working. This ws is build at the beginning of + # has to have specific name for this all working. This ws is build at + # the beginning of # multirep run if 'bkgr_ws_source' in mtd: bkgr_ws = CloneWorkspace(InputWorkspace='bkgr_ws_source',OutputWorkspace='bkgr_ws') if time_shift != 0: # Workspace has probably been shifted, so to have correct units conversion - # one needs to do appropriate shift here as well - CopyInstrumentParameters(result_ws,bkgr_ws) + # one needs to do appropriate shift here as + # well + CopyInstrumentParameters(result_ws,bkgr_ws) # Adjust the TOF such that the first monitor peak is at t=0 - ScaleX(InputWorkspace=bkgr_ws,OutputWorkspace='bkgr_ws',Operation="Add",Factor=time_shift,\ + ScaleX(InputWorkspace=bkgr_ws,OutputWorkspace='bkgr_ws',Operation="Add",Factor=time_shift,\ InstrumentParameter="DelayTime",Combine=True) else: - bkgr_ws = Rebin(result_ws,Params=[bkg_range_min,(bkg_range_max - bkg_range_min) * 1.001,bkg_range_max],PreserveEvents=False) - bkgr_ws = self.normalise(bkgr_ws, self.normalise_method, time_shift) + bkgr_ws = Rebin(result_ws,Params=[bkg_range_min,(bkg_range_max - bkg_range_min) * 1.001,bkg_range_max],PreserveEvents=False) + bkgr_ws = self.normalise(bkgr_ws, self.normalise_method, time_shift) return bkgr_ws @@ -1390,13 +1409,14 @@ def _do_mono(self, run, ei_guess, self._do_mono_ISIS(run,ei_guess,\ white_run, map_file, spectra_masks, Tzero) else: - result_name = run.set_action_suffix('_spe') - self._do_mono_SNS(run,result_name,ei_guess,\ + result_name = run.set_action_suffix('_spe') + self._do_mono_SNS(run,result_name,ei_guess,\ white_run, map_file, spectra_masks, Tzero) - run.synchronize_ws() + run.synchronize_ws() prop_man = self.prop_man - result_name = run.get_ws_name() + ws = run.get_workspace() + result_name = ws.name() ####################### # Ki/Kf Scaling... if prop_man.apply_kikf_correction: @@ -1406,8 +1426,8 @@ def _do_mono(self, run, ei_guess, # Make sure that our binning is consistent if prop_man.energy_bins: - bins = PropertyManager.energy_bins.get_abs_range(prop_man) - Rebin(InputWorkspace=result_name,OutputWorkspace= result_name,Params=bins) + bins = PropertyManager.energy_bins.get_abs_range(prop_man) + Rebin(InputWorkspace=result_name,OutputWorkspace= result_name,Params=bins) # Masking and grouping result_ws = mtd[result_name] @@ -1426,7 +1446,9 @@ def _do_mono(self, run, ei_guess, return result_ws #------------------------------------------------------------------------------- def _get_wb_inegrals(self,run): - """ """ + """Obtain white bean vanadium integrals either by integrating + workspace in question or cashed value + """ run = self.get_run_descriptor(run) white_ws = run.get_workspace() # This both integrates the workspace into one bin spectra and sets up @@ -1443,12 +1465,12 @@ def _get_wb_inegrals(self,run): old_log_val = targ_ws.getRun().getLogData(done_Log).value done_log_VAL = self._build_white_tag() if old_log_val == done_log_VAL: - run.synchronize_ws(targ_ws) - if self._keep_wb_workspace: + run.synchronize_ws(targ_ws) + if self._keep_wb_workspace: result = run.get_ws_clone() - else: + else: result = run.get_workspace() - return result + return result else: DeleteWorkspace(Workspace=new_ws_name) else: @@ -1484,35 +1506,29 @@ def _get_wb_inegrals(self,run): return result #------------------------------------------------------------------------------- def _build_white_tag(self): - """ build tag indicating wb-integration ranges """ + """build tag indicating wb-integration ranges """ low,upp = self.wb_integr_range white_tag = 'NormBy:{0}_IntergatedIn:{1:0>10.2f}:{2:0>10.2f}'.format(self.normalise_method,low,upp) return white_tag -#------------------------------------------------------------------------------- -#------------------------------------------------------------------------------- -#------------------------------------------------------------------------------- def get_failed_spectra_list_from_masks(masked_wksp): """Compile a list of spectra numbers that are marked as masked in the masking workspace - Input: - masking_workspace - A special masking workspace containing masking data + Input: + masking_workspace - A special masking workspace containing masking data """ #TODO: get rid of this and use data, obtained form diagnostics - failed_spectra = [] if masked_wksp is None: - return (failed_spectra,0) + return (failed_spectra,0) masking_wksp,sp_list = ExtractMask(masked_wksp) DeleteWorkspace(masking_wksp) n_spectra = len(sp_list) - return (sp_list.tolist(),n_spectra) - - + return n_spectra #----------------------------------------------------------------- if __name__ == "__main__": pass - #unittest.main() + #unittest.main() \ No newline at end of file diff --git a/Code/Mantid/scripts/Inelastic/Direct/NonIDF_Properties.py b/Code/Mantid/scripts/Inelastic/Direct/NonIDF_Properties.py index 102426faa1ce..4d7411e103b7 100644 --- a/Code/Mantid/scripts/Inelastic/Direct/NonIDF_Properties.py +++ b/Code/Mantid/scripts/Inelastic/Direct/NonIDF_Properties.py @@ -34,14 +34,8 @@ def __init__(self,Instrument,run_workspace=None): # Helper properties, defining logging options object.__setattr__(self,'_log_level','notice') object.__setattr__(self,'_log_to_mantid',False) - object.__setattr__(self,'_current_log_level',3) - - - object.__setattr__(self,'_psi',float('NaN')) - # SNS motor stuff which is difficult to test as I've never seen it - object.__setattr__(self,'_motor_name',None) - object.__setattr__(self,'_motor_offset',0) + object.__setattr__(self,'_current_log_level',3) object.__setattr__(self,'_save_file_name',None) self._set_instrument_and_facility(Instrument,run_workspace) @@ -58,7 +52,7 @@ def __init__(self,Instrument,run_workspace=None): super(NonIDF_Properties,self).__setattr__('wb_for_monovan_run',None) super(NonIDF_Properties,self).__setattr__('second_white',None) super(NonIDF_Properties,self).__setattr__('_tmp_run',None) - + super(NonIDF_Properties,self).__setattr__('_cashe_sum_ws',False) #end def log(self, msg,level="notice"): @@ -97,8 +91,6 @@ def log(self, msg,level="notice"): second_white = RunDescriptor("Second white beam currently unused in the workflow despite being referred to in Diagnostics. Should it be used for Monovan Diagnostics?") # _tmp_run = RunDescriptor("_TMP","Property used for storing intermediate run data during reduction") - # property responsible for summing runs - sum_runs = SumRuns(sample_run) #----------------------------------------------------------------------------------- def getDefaultParameterValue(self,par_name): """ method to get default parameter value, specified in IDF """ @@ -122,6 +114,17 @@ def print_diag_results(self,value): #----------------------------------------------------------------------------------- # ----------------------------------------------------------------------------- @property + def cashe_sum_ws(self): + """ Used together with sum_runs property. If True, a workspace + with partial sum is stored in ADS + and used later to add more runs to it + """ + return self._cashe_sum_ws + @cashe_sum_ws.setter + def cashe_sum_ws(self,val): + self._cashe_sum_ws = bool(val) + # ----------------------------------------------------------------------------- + @property def log_to_mantid(self): """ Property specify if high level log should be printed to stdout or added to common Mantid log""" return self._log_to_mantid @@ -129,31 +132,7 @@ def log_to_mantid(self): @log_to_mantid.setter def log_to_mantid(self,val): object.__setattr__(self,'_log_to_mantid',bool(val)) - # ----------------------------------------------------------------------------- - #----------------------------------------------------------------------------------- - @property - def psi(self): - """ rotation angle (not available from IDF)""" - return self._psi - @psi.setter - def psi(self,value): - """set rotation angle (not available from IDF). This value will be saved into NXSpe file""" - object.__setattr__(self,'_psi',value) - # ----------------------------------------------------------------------------- - @property - def motor_name(self): - return self._motor_name - @motor_name.setter - def motor_name(self,val): - object.__setattr__(self,'_motor_name',val) - # - @property - def motor_offset(self): - return self._motor_offset - @motor_offset.setter - def motor_offset(self,val): - object.__setattr__(self,'_motor_offset',val) - + # ----------------------------------------------------------------------------- # Service properties (used by class itself) # @@ -197,10 +176,6 @@ def _set_instrument_and_facility(self,Instrument,run_workspace=None): object.__setattr__(self,'_short_instr_name',new_name) - - - - if __name__ == "__main__": pass diff --git a/Code/Mantid/scripts/Inelastic/Direct/PropertiesDescriptors.py b/Code/Mantid/scripts/Inelastic/Direct/PropertiesDescriptors.py index 0459aa0c1819..32182084b3cc 100644 --- a/Code/Mantid/scripts/Inelastic/Direct/PropertiesDescriptors.py +++ b/Code/Mantid/scripts/Inelastic/Direct/PropertiesDescriptors.py @@ -7,6 +7,7 @@ from mantid.simpleapi import * from mantid.kernel import funcreturns from mantid import api,geometry,config +import numpy as np import Direct.ReductionHelpers as prop_helpers import Direct.CommonFunctions as common @@ -16,12 +17,20 @@ # class #----------------------------------------------------------------------------------------- class PropDescriptor(object): - """ Class provides common custom interface for property descriptors """ + """Class provides common custom interface for property descriptors """ def dependencies(self): - """ Returns the list of other properties names, this property depends on""" + """Returns the list of other properties names, this property depends on""" return [] + def validate(self,instance, owner): + """Interface to validate property descriptor, + provided to check properties interaction before long run + Return validation result, errors severity (0 -- fine, 1 -- warning, 2-- error) + and error message if any + """ + return (True,0,'') # end PropDescriptor + #----------------------------------------------------------------------------------------- #----------------------------------------------------------------------------------------- #----------------------------------------------------------------------------------------- @@ -30,172 +39,34 @@ class SumRuns(PropDescriptor): """ Boolean property specifies if list of files provided as input for sample_run property should be summed. - It also specifies various auxiliary operations, defined for summing runs, so property - is deeply entangled with the sample_run property """ def __init__(self,sample_run_prop): # internal reference to sample run property self._sample_run = sample_run_prop # class containing this property - self._holder = None # - self._last_ind2sum = -1 self._sum_runs = False - self._run_numbers = [] - self._file_guess = [] - self._fext = [] - - # def __get__(self,instance,holder_class): - if not self._holder: - self._holder = holder_class - if instance is None: - return self - return self._sum_runs + if instance is None: + return self + return self._sum_runs # def __set__(self,instance,value): - if not self._holder: - from Direct.PropertyManager import PropertyManager - self._holder = PropertyManager - old_value = self._sum_runs if isinstance(value,bool): self._sum_runs = value - self._last_ind2sum = -1 elif isinstance(value,int): if value > 0: - self._last_ind2sum = int(value) - 1 - self._sum_runs = True + self._sum_runs = True else: - self._last_ind2sum = -1 - self._sum_runs = False + self._sum_runs = False else: self._sum_runs = bool(value) - self._last_ind2sum = -1 # if old_value != self._sum_runs: - if len(self._run_numbers) > 0 and self._sum_runs: - # clear previous state of sample_run - ind = self.get_last_ind2sum() - self._sample_run.__set__(None,self._run_numbers[ind]) - # - def set_list2add(self,runs_to_add,fnames=None,fext=None): - """Set run numbers to add together with possible file guess-es """ - if not isinstance(runs_to_add,list): - raise KeyError('Can only set list of run numbers to add') - runs = [] - for item in runs_to_add: - runs.append(int(item)) - self._run_numbers = runs - if fnames: - self._file_guess = fnames - if len(self._file_guess) != len(self._run_numbers): - self._file_guess = [''] * len(self._run_numbers) - - if fext: - self._fext = fext - if len(self._fext) != len(self._run_numbers): - self._fext = [''] * len(self._run_numbers) - # - def clear_sum(self): - """Clear all defined summation""" - # if last_to_sum is -1, sum all run list provided - self._last_ind2sum = -1 - self._sum_runs = False - self._run_numbers = [] - self._file_guess = [] - self._fext = [] - # - def get_last_ind2sum(self): - """Get last run number contributing to sum""" - if self._last_ind2sum > 0: - return self._last_ind2sum - else: - return len(self._run_numbers) - 1 - # - def set_last_ind2sum(self,run_number): - """Check and set last number, contributing to summation - if this number is out of summation range, clear the summation - """ - run_number = int(run_number) - if run_number in self._run_numbers: - self._last_ind2sum = self._run_numbers.index(run_number) + 1 - return self._last_ind2sum - else: - self.clear_sum() - return 0 - # - def get_run_list2sum(self): - """Get run numbers of the files to be summed together """ - num_to_load = len(self._run_numbers) - if self._last_ind2sum > 0 and self._last_ind2sum < num_to_load: - num_to_load = self._last_ind2sum - return self._run_numbers[:num_to_load] + self._sample_run.notify_sum_runs_changed(old_value,self._sum_runs) - # - def load_and_sum_runs(self,inst_name,monitors_with_ws): - """ Load multiple runs and sum them together """ - - logger = lambda mess : (getattr(getattr(self,'_holder'),'log')\ - (self._sample_run._holder,mess)) - logger("*** Summing multiple runs ****") - - runs_to_load = self.get_run_list2sum() - num_to_load = len(runs_to_load) - logger("*** Loading #{0}/{1}, run N: {2} ".\ - format(1,num_to_load,self._run_numbers[0])) - - - file_h = os.path.join(self._file_guess[0],'{0}{1}{2}'.\ - format(inst_name,runs_to_load[0],self._fext[0])) - ws = self._sample_run.load_file(inst_name,'Summ',False,monitors_with_ws, - False,file_hint=file_h) - - sum_ws_name = ws.name() - sum_mon_name = sum_ws_name + '_monitors' - AddedRunNumbers = str(self._sample_run.run_number()) - - for ind,run_num in enumerate(runs_to_load[1:num_to_load]): - - file_h = os.path.join(self._file_guess[ind + 1],'{0}{1}{2}'.\ - format(inst_name,run_num,self._fext[ind + 1])) - logger("*** Adding #{0}/{1}, run N: {2} ".\ - format(ind + 2,num_to_load,run_num)) - term_name = '{0}_ADDITIVE_#{1}/{2}'.format(inst_name,ind + 2,num_to_load)# - - wsp = self._sample_run.load_file(inst_name,term_name,False,\ - monitors_with_ws,False,file_hint=file_h) - - wsp_name = wsp.name() - wsp_mon_name = wsp_name + '_monitors' - Plus(LHSWorkspace=sum_ws_name,RHSWorkspace=wsp_name,\ - OutputWorkspace=sum_ws_name,ClearRHSWorkspace=True) - AddedRunNumbers+=',{0}'.format(run_num) - if not monitors_with_ws: - Plus(LHSWorkspace=sum_mon_name,RHSWorkspace=wsp_mon_name,\ - OutputWorkspace=sum_mon_name,ClearRHSWorkspace=True) - if wsp_name in mtd: - DeleteWorkspace(wsp_name) - if wsp_mon_name in mtd: - DeleteWorkspace(wsp_mon_name) - logger("*** Summing multiple runs completed ****") - - AddSampleLog(Workspace=sum_ws_name,LogName = 'SumOfRuns:', - LogText=AddedRunNumbers,LogType='String') - ws = mtd[sum_ws_name] - return ws - # - def sum_ext(self): - if self._sum_runs: - last = self.get_last_ind2sum() - sum_ext = "SumOf{0}".format(len(self._run_numbers[:last + 1])) - else: - sum_ext = '' - return sum_ext - # - def get_runs(self): - return self._run_numbers #-------------------------------------------------------------------------------------------------------------------- class IncidentEnergy(PropDescriptor): """ Property for incident energy or range of incident energies to be processed @@ -213,58 +84,55 @@ def __init__(self): def __get__(self,instance,owner=None): """ return incident energy or list of incident energies """ if instance is None: - return self - + return self return self._incident_energy + def __set__(self,instance,value): - """ Set up incident energy or range of energies in various formats """ - if value != None: - if isinstance(value,str): - if value.find('[') > -1: - energy_list = True - value = value.translate(None, '[]').strip() - else: - energy_list = False - en_list = str.split(value,',') - if len(en_list) > 1: - rez = [] - for en_str in en_list: - val = float(en_str) - rez.append(val) - self._incident_energy = rez - else: - if energy_list: - self._incident_energy = [float(value)] + """ Set up incident energy or range of energies in various formats """ + if value != None: + if isinstance(value,str): + if value.find('[') > -1: + energy_list = True + value = value.translate(None, '[]').strip() + else: + energy_list = False + en_list = str.split(value,',') + if len(en_list) > 1: + rez = [] + for en_str in en_list: + val = float(en_str) + rez.append(val) + self._incident_energy = rez + else: + if energy_list: + self._incident_energy = [float(value)] + else: + self._incident_energy = float(value) + else: + if isinstance(value,list): + rez = [] + for val in value: + en_val = float(val) + if en_val <= 0: + raise KeyError("Incident energy has to be positive, but is: {0} ".format(en_val)) else: - self._incident_energy = float(value) + rez.append(en_val) + self._incident_energy = rez else: - if isinstance(value,list): - rez = [] - for val in value: - en_val = float(val) - if en_val <= 0: - raise KeyError("Incident energy has to be positive, but is: {0} ".format(en_val)) - else: - rez.append(en_val) - self._incident_energy = rez - else: - self._incident_energy = float(value) - else: - raise KeyError("Incident energy have to be positive number of list of positive numbers. Got None") - - # - inc_en = self._incident_energy - if isinstance(inc_en,list): - self._num_energies = len(inc_en) - for en in inc_en: - if en <= 0: - raise KeyError("Incident energy have to be positive number of list of positive numbers." + " For input argument {0} got negative value {1}".format(value,en)) - else: - self._num_energies = 1 - if inc_en <= 0: - raise KeyError("Incident energy have to be positive number of list of positive numbers." + " For value {0} got negative {1}".format(value,inc_en)) - self._cur_iter_en = 0 - + self._incident_energy = float(value) + else: + raise KeyError("Incident energy have to be positive number of list of positive numbers. Got None") + + if isinstance(self._incident_energy,list): + self._num_energies = len(self._incident_energy) + else: + self._num_energies = 1 + self._cur_iter_en = 0 + + ok,sev,message = self.validate(instance) + if not ok: + raise KeyError(message) + def multirep_mode(self): """ return true if energy is defined as list of energies and false otherwise """ if isinstance(self._incident_energy,list): @@ -280,13 +148,19 @@ def get_current(self): else: return self._incident_energy # - def set_current(self,value): - """ set current energy value (used in multirep mode) to - + def set_current(self,value,ind=None): + """ set current energy value (used in multirep mode) as + energy estimate for the reduction + + ind -- if provided, the number of the value in the list of + values (can be used together with enumerate) """ if isinstance(self._incident_energy,list): - ind = self._cur_iter_en - self._incident_energy[ind]=value + if ind is None: + ind = self._cur_iter_en + else: + self._cur_iter_en = ind + self._incident_energy[ind] = value else: self._incident_energy = value @@ -300,14 +174,25 @@ def next(self): # Python 3: def __next__(self) """ part of iterator """ self._cur_iter_en += 1 ind = self._cur_iter_en - if ind < self._num_energies: - if isinstance(self._incident_energy,list): - return self._incident_energy[ind] - else: - return self._incident_energy + if ind < self._num_energies: + if isinstance(self._incident_energy,list): + return self._incident_energy[ind] + else: + return self._incident_energy else: - raise StopIteration + raise StopIteration + def validate(self,instance,owner=None): + # + inc_en = self._incident_energy + if isinstance(inc_en,list): + for ind,en in enumerate(inc_en): + if en <= 0: + return (False,2,"Incident energy have to be positive number or list of positive numbers.\n" + "For input argument {0} got negative energy {1}".format(ind,en)) + else: + if inc_en <= 0: + return (False,2,"Incident energy have to be positive number or list of positive numbers.\n" + "Got single negative incident energy {0} ".format(inc_en)) + return (True,0,'') # end IncidentEnergy #----------------------------------------------------------------------------------------- class EnergyBins(PropDescriptor): @@ -331,22 +216,22 @@ def __init__(self,IncidentEnergyProp): def __get__(self,instance,owner=None): """ binning range for the result of convertToenergy procedure or list of such ranges """ if instance is None: - return self + return self return self._energy_bins def __set__(self,instance,values): - if values != None: - if isinstance(values,str): - values = values.translate(None, '[]').strip() - lst = values.split(',') - self.__set__(instance,lst) - return - else: - value = values - if len(value) != 3: + if values != None: + if isinstance(values,str): + values = values.translate(None, '[]').strip() + lst = values.split(',') + self.__set__(instance,lst) + return + else: + value = values + if len(value) != 3: raise KeyError("Energy_bin value has to be a tuple of 3 elements or string of 3 comma-separated numbers") - value = (float(value[0]),float(value[1]),float(value[2])) + value = (float(value[0]),float(value[1]),float(value[2])) # Let's not support list of multiple absolute energy bins for the # time being # nBlocks = len(value) @@ -354,10 +239,10 @@ def __set__(self,instance,values): # raise KeyError("Energy_bin value has to be either list of # n-blocks of 3 number each or string representation of this list # with numbers separated by commas") - else: + else: value = None #TODO: implement single value settings according to rebin? - self._energy_bins = value + self._energy_bins = value def get_abs_range(self,instance=None): """ return energies related to incident energies either as @@ -367,28 +252,28 @@ def get_abs_range(self,instance=None): ei = self._incident_energy.get_current() if self._energy_bins: if self.is_range_valid(): - rez = self._calc_relative_range(ei) + rez = self._calc_relative_range(ei) else: - if instance: - instance.log("*** WARNING! Got energy_bins specified as absolute values in multirep mode.\n"\ + if instance: + instance.log("*** WARNING! Got energy_bins specified as absolute values in multirep mode.\n"\ " Will normalize these values by max value and treat as relative values ",\ "warning") - mult = self._range / self._energy_bins[2] - rez = self._calc_relative_range(ei,mult) + mult = self._range / self._energy_bins[2] + rez = self._calc_relative_range(ei,mult) return rez else: - return None + return None else: # Absolute energy ranges - if self.is_range_valid(): - return self._energy_bins - else: - if instance: - instance.log("*** WARNING! Requested maximum binning range exceeds incident energy!\n"\ + if self.is_range_valid(): + return self._energy_bins + else: + if instance: + instance.log("*** WARNING! Requested maximum binning range exceeds incident energy!\n"\ " Will normalize binning range by max value and treat as relative range",\ "warning") - mult = self._range / self._energy_bins[2] - ei = self._incident_energy.get_current() - return self._calc_relative_range(ei,mult) + mult = self._range / self._energy_bins[2] + ei = self._incident_energy.get_current() + return self._calc_relative_range(ei,mult) def is_range_valid(self): """Method verifies if binning range is consistent with incident energy """ @@ -402,6 +287,19 @@ def _calc_relative_range(self,ei,range_mult=1): mult = range_mult * ei return (self._energy_bins[0] * mult ,self._energy_bins[1] * mult,self._energy_bins[2] * mult) + def validate(self,instance,owner): + """ function verifies if the energy binning is consistent with incident energies """ + ei = instance.incident_energy + ebin = instance.energy_bins + if isinstance(ei,list): # ebin expected to be relative + if ebin[2] > 1: + return(False,1,"Binning for multiple energy range should be relative to incident energy. Got ebin_max={0} > 1\n" + \ + "Energy range will be normalized and treated as relative range") + else: + if ebin[2] > ei: + return (False,2,'Max rebin range {0:f} exceeds incident energy {1:f}'.format(ebin[2],en)) + return(True,0,'') +#----------------------------------------------------------------------------------------- #end EnergyBins #----------------------------------------------------------------------------------------- @@ -411,11 +309,15 @@ class SaveFileName(PropDescriptor): See similar property get_sample_ws_name TODO: (leave only one) """ def __init__(self,Name=None): - self._file_name = Name + self._file_name = Name + self._custom_print = None def __get__(self,instance,owner=None): if instance is None: - return self + return self + if not (self._custom_print is None): + return self._custom_print(instance,owner) + if self._file_name: return self._file_name else: @@ -441,6 +343,8 @@ def __get__(self,instance,owner=None): def __set__(self,instance,value): self._file_name = value + def set_custom_print(self,routine): + self._custom_print = routine #end SaveFileName #----------------------------------------------------------------------------------------- class InstrumentDependentProp(PropDescriptor): @@ -451,30 +355,17 @@ def __init__(self,prop_name): self._prop_name = prop_name def __get__(self,instance,owner=None): - if instance is None: - return self + if instance is None: + return self - if instance._pInstrument is None: + if instance._pInstrument is None: raise KeyError("Attempt to use uninitialized property manager") - else: + else: return getattr(instance,self._prop_name) def __set__(self,instance,values): raise AttributeError("Property {0} can not be assigned".format(self._prop_name)) #end InstrumentDependentProp #----------------------------------------------------------------------------------------- -def check_ei_bin_consistent(ei,binning_range): - """ function verifies if the energy binning is consistent with incident energies """ - if isinstance(ei,list): - for en in ei: - range = binning_range[en] - if range[2] > en: - return (False,'Max rebin range {0:f} exceeds incident energy {1:f}'.format(range[2],en)) - else: - if binning_range[2] > ei: - return (False,'Max rebin range {0:f} exceeds incident energy {1:f}'.format(binning_range[2],ei)) - - return (True,'') -#----------------------------------------------------------------------------------------- class VanadiumRMM(PropDescriptor): """ define constant static rmm for vanadium """ def __get__(self,instance,owner=None): @@ -508,56 +399,79 @@ def __init__(self): def __get__(self,instance,owner): - """ Return actual energy range from internal relative range and incident energy """ - if instance is None: - return self - return [self._relative_range[0] * instance.incident_energy,self._relative_range[1] * instance.incident_energy] + """ Return actual energy range from internal relative range and incident energy """ + if instance is None: + return self + ei = owner.incident_energy.get_current() + return [self._relative_range[0] * ei, self._relative_range[1] * ei] def __set__(self,instance,val): - """ set detector calibration file using various formats """ - if isinstance(val,list): - self._relative_range = self._check_range(val,instance) - elif isinstance(val,str): - val = self._parce_string2list(val) - self.__set__(instance,val) - else: + """ set detector calibration file using various formats """ + if isinstance(val,list): + self._relative_range = self._check_range(val,instance) + elif isinstance(val,str): + val = self._parce_string2list(val) + self.__set__(instance,val) + else: raise KeyError('mon2_norm_energy_range needs to be initialized by two values.\n'\ 'Trying to assign value {0} of unknown type {1}'.format(val,type(val))) # def _check_range(self,val,instance): """ method to check if list of values acceptable as ranges """ + if len(val) != 2: - raise KeyError('mon2_normalization_energy_range can be initialized by list of two values only. Got {0} values'.format(len(val))) - val1 = float(val[0]) + raise KeyError("mon2_norm_energy_range needs to be initialized by lost of two values. Got {0}".format(len(val))) + self._relative_range = (float(val[0]),float(val[1])) + ok,sev,message = self.validate(instance) + if not ok: + if sev == 1: + instance.log(message,'warning') + else: + raise KeyError(message) + + return self._relative_range + # + def _parce_string2list(self,val): + """ method splits input string containing comma into list of strings""" + value = val.strip('[]()') + val = value.split(',') + return val + + def validate(self,instance,owner=None): + """ function verifies if the energy range is consistent with incident energies """ + range = self._relative_range + if len(range) != 2: + return(False,2,'mon2_normalization_energy_range can be initialized by list of two values only. Got {0} values'.format(len(range))) + + result = (True,0,'') + + val1 = float(range[0]) if val1 < 0.1 or val1 > 0.9: message = "Lower mon2_norm_energy_range describes lower limit of energy to integrate neutron signal after the chopper.\n"\ "The limit is defined as (this value)*incident_energy. Are you sure you want to set this_value to {0}?\n".format(val1) if val1 > 1: - raise KeyError(message) + return(False,2,message) else: - instance.log(message,'warning') - val2 = float(val[1]) + result = (False,1,message) + + + val2 = float(range[1]) if val2 < 1.1 or val2 > 1.9: - message = "Upper mon2_norm_energy_range describes upper limit of energy to integrate neutron signal after the chopper.\n"\ + message = "Upper mon2_norm_energy_range describes upper limit of energy to integrate neutron signal after the chopper.\n"\ "The limit is defined as (this value)*incident_energy. Are you sure you want to set this_value to {0}?\n".format(val2) - if val2 < 1: - raise KeyError(message) - else: - instance.log(message,'warning') + if val2 > 1: + if result[0]: + result = (False,1,message) + else: + result = (False,1,result[2] + message) + else: + return (False,2,message) - return [val1,val2] - # - def _parce_string2list(self,val): - """ method splits input string containing comma into list of strings""" - value = val.strip('[]()') - val = value.split(',') - return val + return result #----------------------------------------------------------------------------------------- class PropertyFromRange(PropDescriptor): """ Descriptor for property, which can have one value from a list of values """ - _current_value = None - def __init__(self,availible_values,default_value): self._availible_values = availible_values self.__set__(None,default_value) @@ -565,49 +479,48 @@ def __init__(self,availible_values,default_value): def __get__(self,instance,owner): """ Return current value for the property with range of values. """ if instance is None: - return self + return self return self._current_value def __set__(self,instance,val): - """ set detector calibration file using various formats """ - if val in self._availible_values: - self._current_value = val - else: - raise KeyError(' Property can not have value {0}'.format(val)) + if val in self._availible_values: + self._current_value = val + else: + raise KeyError(' Property can not have value {0}'.format(val)) #----------------------------------------------------------------------------------------- class DetCalFile(PropDescriptor): """ property describes various sources for the detector calibration file """ def __init__(self): self._det_cal_file = None + self._calibrated_by_run = False def __get__(self,instance,owner): if instance is None: - return self + return self return self._det_cal_file def __set__(self,instance,val): - """ set detector calibration file using various formats """ + """ set detector calibration file using various formats """ - if val is None or isinstance(val,api.Workspace) or isinstance(val,str): + if val is None or isinstance(val,api.Workspace) or isinstance(val,str): # nothing provided or workspace provided or filename probably provided - if str(val) in mtd: - # workspace name provided - val = mtd[str(val)] - self._det_cal_file = val - return + if str(val) in mtd: + # workspace name provided + val = mtd[str(val)] + self._det_cal_file = val + self._calibrated_by_run = False + return - if isinstance(val,int): + if isinstance(val,int): #if val in instance.all_run_numbers: TODO: retrieve workspace from #run numbers - file_hint = str(val) - file_name = FileFinder.findRuns(file_hint)[0] - self._det_cal_file = file_name - return - - raise NameError('Detector calibration file name can be a workspace name present in Mantid or string describing an file name') + self._det_cal_file = val + self._calibrated_by_run = True + return + raise NameError('Detector calibration file name can be a workspace name present in Mantid or string describing an file name') #if Reducer.det_cal_file != None : # if isinstance(Reducer.det_cal_file,str) and not Reducer.det_cal_file # in mtd : # it is a file @@ -619,30 +532,80 @@ def __set__(self,instance,val): #else: # Reducer.log('Setting detector calibration to detector block info from # '+str(sample_run)) + + def calibrated_by_run(self): + """ reports if the detector calibration is in a run-file or separate file(workspace)""" + return self._calibrated_by_run + + def find_file(self,**kwargs): + """ Method to find file, correspondent to + current _det_cal_file file hint + """ + if self._det_cal_file is None: + # nothing to look for + return (True,"No Detector calibration file defined") + if isinstance(self._det_cal_file,int): # this can be only a run number + file_hint = str(self._det_cal_file) + try: + file_name = FileFinder.findRuns(file_hint)[0] + except: + return (False,"Can not find run file corresponding to run N: {0}".format(file_hint)) + self._det_cal_file = file_name + return (True,file_name) + if isinstance(self._det_cal_file,api.Workspace): + # nothing to do. Workspace used for calibration + return (True,'Workspace {0} used for detectors calibration'.format(self._det_cal_file.name())) + # string can be a run number or a file name: + file_name = prop_helpers.findFile(self._det_cal_file) + if len(file_name) == 0: # it still can be a run number as string + try: + file_name = FileFinder.findRuns(self._det_cal_file)[0] + except: + return (False,"Can not find file or run file corresponding to name : {0}".format(self._det_cal_file)) + else: + pass + self._det_cal_file = file_name + return (True,file_name) #end DetCalFile #----------------------------------------------------------------------------------------- class MapMaskFile(PropDescriptor): """ common method to wrap around an auxiliary file name """ - def __init__(self,file_ext,doc_string=None): + def __init__(self,prop_name,file_ext,doc_string=None): self._file_name = None self._file_ext = file_ext - if not doc_string is None: + self._prop_name = prop_name + + if not(doc_string is None): self.__doc__ = doc_string def __get__(self,instance,type=None): if instance is None: - return self + return self return self._file_name def __set__(self,instance,value): - if value != None: - fileName, fileExtension = os.path.splitext(value) - if not fileExtension: - value = value + self._file_ext + if not(value is None): + fileName, fileExtension = os.path.splitext(value) + if not fileExtension: + value = value + self._file_ext self._file_name = value + def find_file(self,**kwargs): + """ Method to find file, correspondent to + current MapMaskFile file hint + """ + if self._file_name is None: + return (True,'No file for {0} is defined'.format(self._prop_name)) + + file_name = prop_helpers.findFile(self._file_name) + if len(file_name) == 0: # it still can be a run number as string + return (False,'No file for {0} corresponding to guess: {1} found'.format(self._prop_name,self._file_name)) + else: + self._file_name = file_name + return (True,file_name) #end MapMaskFile + #----------------------------------------------------------------------------------------- class HardMaskPlus(prop_helpers.ComplexProperty): """ Legacy HardMaskPlus class which sets up hard_mask_file to file and use_hard_mask_only to True""" @@ -650,23 +613,23 @@ def __init__(self): prop_helpers.ComplexProperty.__init__(self,['use_hard_mask_only','run_diagnostics']) def __get__(self,instance,type=None): if instance is None: - return self + return self return instance.hard_mask_file def __set__(self,instance,value): if value != None: - fileName, fileExtension = os.path.splitext(value) - if not fileExtension: - value = value + '.msk' - instance.hard_mask_file = value - prop_helpers.ComplexProperty.__set__(self,instance.__dict__,[False,True]) + fileName, fileExtension = os.path.splitext(value) + if not fileExtension: + value = value + '.msk' + instance.hard_mask_file = value + prop_helpers.ComplexProperty.__set__(self,instance.__dict__,[False,True]) else: - prop_helpers.ComplexProperty.__set__(self,instance.__dict__,[True,False]) + prop_helpers.ComplexProperty.__set__(self,instance.__dict__,[True,False]) try: - del instance.__changed_properties['hardmaskOnly'] + del instance.__changed_properties['hardmaskOnly'] except: - pass + pass #----------------------------------------------------------------------------------------- class HardMaskOnly(prop_helpers.ComplexProperty): @@ -680,7 +643,7 @@ def __init__(self): def __get__(self,instance,type=None): if instance is None: - return self + return self return prop_helpers.gen_getter(instance.__dict__,'use_hard_mask_only') def __set__(self,instance,value): @@ -710,7 +673,7 @@ def __set__(self,instance,value): run_diagnostics = True prop_helpers.ComplexProperty.__set__(self,instance.__dict__,[use_hard_mask_only,run_diagnostics]) try: - del instance.__changed_properties['hardmaskPlus'] + del instance.__changed_properties['hardmaskPlus'] except: pass #end HardMaskOnly @@ -734,14 +697,14 @@ def __init__(self,DepType=None): def __get__(self,instance,owner): if instance is None: - return self + return self if isinstance(instance,dict): - ei = 1 - tDict = instance + ei = 1 + tDict = instance else: - ei = owner.incident_energy.get_current() - tDict = instance.__dict__ + ei = owner.incident_energy.get_current() + tDict = instance.__dict__ if self._rel_range: # relative range if ei is None: @@ -754,17 +717,17 @@ def __get__(self,instance,owner): def __set__(self,instance,value): if isinstance(instance,dict): - dDict = instance + dDict = instance else: - tDict = instance.__dict__ + tDict = instance.__dict__ if value is None: if not self._rel_range: self._rel_range = True self._other_prop = ['monovan_lo_frac','monovan_hi_frac'] else: if self._rel_range: - self._rel_range = False - self._other_prop = ['monovan_lo_value','monovan_hi_value'] + self._rel_range = False + self._other_prop = ['monovan_lo_value','monovan_hi_value'] if isinstance(value,str): values = value.split(',') @@ -776,11 +739,26 @@ def __set__(self,instance,value): raise KeyError("monovan_integr_range has to be list of two values, "\ "defining min/max values of integration range or None to use relative to incident energy limits") prop_helpers.ComplexProperty.__set__(self,tDict,value) + + def validate(self,instance, owner): + """ check if monovan integration range has reasonable value """ + + if instance.monovan_run is None: + return (True,0,'') + + range = sepf.__get__(instance,owner) + ei = instance.incident_energy + if range[0] >= range[1]: + return (False,2,'monovan integration range limits = [{0}:{1}] are wrong'.format(range[0],range[1])) + if range[0] < -100 * ei or range[0] > 100 * ei: + return (False,1,'monovan integration is suspiciously wide: [{0}:{1}]. This may be incorrect'.format(range[0],range[1])) + return (True,0,'') + #end MonovanIntegrationRange #----------------------------------------------------------------------------------------- class SpectraToMonitorsList(PropDescriptor): - """ property describes list of spectra, used as monitors to estimate incident energy + """ property describes list of spectra, used as monitors to estimate incident energy in a direct scattering experiment. Necessary when a detector working in event mode is used as monitor. Specifying this number would copy @@ -788,25 +766,25 @@ class SpectraToMonitorsList(PropDescriptor): Written to work with old IDF too, where this property is absent. """ - def __init__(self): - self._spectra_to_monitors_list = None + def __init__(self): + self._spectra_to_monitors_list = None - def __get__(self,instance,type=None): - if instance is None: - return self - return self._spectra_to_monitors_list + def __get__(self,instance,type=None): + if instance is None: + return self + return self._spectra_to_monitors_list - def __set__(self,instance,spectra_list): + def __set__(self,instance,spectra_list): """ Sets copy spectra to monitors variable as a list of monitors using different forms of input """ self._spectra_to_monitors_list = self._convert_to_list(spectra_list) - def _convert_to_list(self,spectra_list): - """ convert any spectra_list representation into a list """ - if spectra_list is None: + def _convert_to_list(self,spectra_list): + """ convert any spectra_list representation into a list """ + if spectra_list is None: return None - if isinstance(spectra_list,str): + if isinstance(spectra_list,str): if spectra_list.lower() is 'none': result = None else: @@ -815,7 +793,7 @@ def _convert_to_list(self,spectra_list): for spectum in spectra : result.append(int(spectum)) - else: + else: if isinstance(spectra_list,list): if len(spectra_list) == 0: result = None @@ -825,23 +803,23 @@ def _convert_to_list(self,spectra_list): result.append(int(spectra_list[i])) else: result = [int(spectra_list)] - return result + return result #end SpectraToMonitorsList #----------------------------------------------------------------------------------------- class SaveFormat(PropDescriptor): # formats available for saving the data - save_formats = ['spe','nxspe','nxs'] - def __init__(self): - self._save_format = set() + save_formats = ['spe','nxspe','nxs'] + def __init__(self): + self._save_format = set() - def __get__(self,instance,type=None): + def __get__(self,instance,type=None): if instance is None: - return self + return self return self._save_format - def __set__(self,instance,value): + def __set__(self,instance,value): """ user can clear save formats by setting save_format=None or save_format = [] or save_format='' if empty string or empty list is provided as part of the list, all save_format-s set up earlier are cleared""" @@ -865,24 +843,33 @@ def __set__(self,instance,value): return else: try: - # set single default save format recursively - for val in value: - self.__set__(instance,val) - return + # set single default save format recursively + for val in value: + self.__set__(instance,val) + return except: - raise KeyError(' Attempting to set unknown saving format {0} of type {1}. Allowed values can be spe, nxspe or nxs'\ + raise KeyError(' Attempting to set unknown saving format {0} of type {1}. Allowed values can be spe, nxspe or nxs'\ .format(value,type(value))) #end if different types self._save_format.add(value) + + def validate(self,instance, owner): + + n_formats = len(self._save_format) + if n_formats == 0: + return (False,1,'No internal save format is defined. Results may be lost') + else: + return (True,0,'') #end SaveFormat #----------------------------------------------------------------------------------------- class DiagSpectra(PropDescriptor): - """ class describes spectra list which should be used in diagnostics + """ class describes spectra groups list, for groups to be + used in diagnostics consist of tuples list where each tuple are the numbers indicating first-last spectra in the group. - if None, all spectra are used in diagnostics + if None, all spectra used in diagnostics """ def __init__(self): @@ -890,7 +877,7 @@ def __init__(self): def __get__(self,instance,type=None): if instance is None: - return self + return self return self._diag_spectra @@ -930,23 +917,36 @@ def __init__(self): self._background_test_range = None def __get__(self,instance,type=None): - if instance is None: - return self + if instance is None: + return self - if self._background_test_range: - return self._background_test_range - else: - return instance.bkgd_range + if self._background_test_range: + return self._background_test_range + else: + return instance.bkgd_range def __set__(self,instance,value): if value is None: - self._background_test_range = None - return + self._background_test_range = None + return if isinstance(value,str): value = str.split(value,',') if len(value) != 2: - raise ValueError("background test range can be set to a 2 element list of floats") - self._background_test_range = [float(value[0]),float(value[1])] + raise ValueError("background test range can be only a 2 element list of floats") + self._background_test_range = (float(value[0]),float(value[1])) + + def validate(self,instance, owner=None): + """ validate background test range """ + range = self.__get__(instance,owner) + if range is None: + return (True,0,'') + if range[0] >= range[1]: + return (False,2,' Background test range: [{0}:{1}] is incorrect '.format(range[0],range[1])) + if range[0] < 0: + return (False,2,' Background test range is TOF range, so it can not be negative={0}'.format(range[0])) + if range[1] > 20000: + return (False,1,' Background test range is TOF range, its max value looks suspiciously big={0}'.format(range[1])) + return (True,0,'') #end BackbgroundTestRange #----------------------------------------------------------------------------------------- @@ -954,63 +954,66 @@ class MultirepTOFSpectraList(PropDescriptor): """ property describes list of spectra numbers, used to identify TOF range corresponding to the particular energy range - Usually it is list of two numbers, specifying monitors which are + Usually it is list of two numbers, specifying spectra with detectors located closest and furthest from the sample """ def __init__(self): self._spectra_list = None def __get__(self,instance,type=None): - if instance is None: - return self + if instance is None: + return self - return self._spectra_list + return self._spectra_list def __set__(self,instance,value): if value is None: - self._spectra_list = None - return + self._spectra_list = None + return if isinstance(value,str): value = str.split(value,',') self.__set__(instance,value) return if isinstance(value, list): - rez =[] - for val in value: - rez.append(int(val)) + rez = [] + for val in value: + rez.append(int(val)) else: rez = [int(value)] - self._spectra_list=rez + self._spectra_list = rez #end MultirepTOFSpectraList - class MonoCorrectionFactor(PropDescriptor): """ property contains correction factor, used to convert experimental scattering cross-section into absolute units ( mb/str/mev/fu) - There are independent two sources for this factor: - 1) if user explicitly specifies correction value. - This value then will be applied to all subsequent runs + Two independent sources for this factor can be defined: + 1) if user explicitly specifies correction value. + This value then will be applied to all subsequent runs without any checks if the correction is appropriate 2) set/get cashed value correspondent to current monovan run number, incident energy and integration range. This value is cashed at first run and reapplied if no changes to the values it depends on were identified """ - def __init__(self,ei_prop): + def __init__(self,ei_prop,monovan_run_prop): self._cor_factor = None - self._mono_run_number=None + self._mono_run_number = None self._ei_prop = ei_prop - self.cashed_values={} + self.cashed_values = {} + self._mono_run_prop = monovan_run_prop - def __get__(self,instance,type=None): - if instance is None: - return self + def __get__(self,instance,type): + if instance is None: + return self - return self._cor_factor + return self._cor_factor def __set__(self,instance,value): - self._cor_factor = value + self._cor_factor = value + # + if value is None: + self._mono_run_prop._in_cash = False # enable monovan run validation if any # def set_val_to_cash(self,instance,value): """ """ @@ -1026,28 +1029,161 @@ def get_val_from_cash(self,instance): mono_int_range = instance.monovan_integr_range cash_id = self._build_cash_val_id(mono_int_range) if cash_id in self.cashed_values: - return self.cashed_values[cash_id] + return self.cashed_values[cash_id] else: - return None + return None def set_cash_mono_run_number(self,new_value): if new_value is None: - self.cashed_values={} - self._mono_run_number = None - return + self.cashed_values = {} + self._mono_run_number = None + return if self._mono_run_number != int(new_value): - self.cashed_values={} - self._mono_run_number = int(new_value) + self.cashed_values = {} + self._mono_run_number = int(new_value) def _build_cash_val_id(self,mono_int_range): - ei = self._ei_prop.get_current() - cash_id = "Ei={0:0>9.4e}:Int({1:0>9.4e}:{2:0>9.5e}):Run{3}".\ + ei = self._ei_prop.get_current() + cash_id = "Ei={0:0>9.4e}:Int({1:0>9.4e}:{2:0>9.5e}):Run{3}".\ format(ei,mono_int_range[0],mono_int_range[1],self._mono_run_number) - return cash_id + return cash_id + + def validate(self,instance, owner=None): + + if self._cor_factor is None: + return (True,0,'') + if self._cor_factor <= 0: + return (False,2,'Mono-correction factor has to be positive if specified: {0}'.format(self._cor_factor)) + return (True,0,'') +#end MonoCorrectionFactor + +class MotorLogName(PropDescriptor): + """ The list of possible log names, for logs containing information + on crystal rotation. First log found with current workspace + will be used together with motor_offset to identify crystal + rotation (psi in Horace) + """ + def __init__(self): + self._log_names = [] + + def __get__(self,instance,type): + if instance is None: + return self + return self._log_names + + def __set__(self,instance,value): + if isinstance(value,str): + val_list = value.split(';') + elif isinstance(value,list): + val_list = [] + for val in value: + val_list.append(str(val)) + else: + val_list = [str(value)] + self._log_names = val_list +#end MotorLogName + +class MotorOffset(PropDescriptor): + """ Initial value used to identify crystal rotation angle + psi=motor_offset+wccr.timeAverageValue() + """ + def __init__(self): + self._offset = None + def __get__(self,instance,type): + if instance is None: + return self + return self._offset + def __set__(self,instance,value): + # we do not need to analyze for None or empty list + # as all this is implemented within generic setter + if value is None: + self._offset = None + else: + self._offset = float(value) +#end MotorOffset + +class RotationAngle(PropDescriptor): + """Class used to identify rotation angle: + psi=motor_offset+wccr.timeAverageValue() + """ + def __init__(self,MotorLogNamesClass,MotorOffset): + self._mot_offset = MotorOffset + self._motor_log = MotorLogNamesClass + # user may override value derived + # from log, by providing its own value + # this value would be used instead of + # calculations + self._own_psi_value = None + # user should define workspace, which contain rotation logs + # Motor log will be read from this workspace + self._log_ws_name = None + + # + def __get__(self,instance,type): + if instance is None: + return self + + if self._own_psi_value: + return self._own_psi_value + return self.read_psi_from_workspace(self._log_ws_name) + + def __set__(self,instance,value): + if isinstance(value,str): + if value in mtd: ## its workspace + self._log_ws_name = value + self._own_psi_value = None + else: # it is string representation of psi. Should be + # convertible to number. + self._own_psi_value = float(value) + elif isinstance(value,api.Workspace): + self._log_ws_name = value.name() + self._own_psi_value = None + elif value is None: # clear all + self._own_psi_value = None + else: #own psi value + self._own_psi_value = float(value) + + def _read_ws_logs(self,external_ws=None): + """read specified workspace logs from workspace + provided either internally or externally + """ + working_ws = external_ws + if working_ws is None: + working_ws = mtd[self._log_ws_name] + if working_ws is None: + raise RuntimeError("No workspace provided. Can not read logs to identify psi") + else: + if isinstance(external_ws,str): + working_ws = mtd[external_ws] + + value = None + log_names = self._motor_log._log_names + for name in log_names: + try: + value = working_ws.getRun().getLogData(name).timeAverageValue() + break + except: + pass + return value + + def read_psi_from_workspace(self,workspace): + """Independent method to read rotation angle from workspace and + previously set log and offset parameters + """ + offset = self._mot_offset._offset + if offset is None: + return np.NaN + log_val = self._read_ws_logs(workspace) + if log_val is None: + return np.NaN + else: + return offset + log_val + + def dependencies(self): + return ['motor_log_names','motor_offset'] +#end RotationAngle #----------------------------------------------------------------------------------------- # END Descriptors for PropertyManager itself #----------------------------------------------------------------------------------------- - - diff --git a/Code/Mantid/scripts/Inelastic/Direct/PropertyManager.py b/Code/Mantid/scripts/Inelastic/Direct/PropertyManager.py index 33c518c10e4c..4c0aa5fc0e88 100644 --- a/Code/Mantid/scripts/Inelastic/Direct/PropertyManager.py +++ b/Code/Mantid/scripts/Inelastic/Direct/PropertyManager.py @@ -99,7 +99,9 @@ def __init__(self,Instrument,instr_run=None): object.__setattr__(self,class_dec+'file_properties',['det_cal_file','map_file','hard_mask_file']) object.__setattr__(self,class_dec+'abs_norm_file_properties',['monovan_mapfile']) - # properties with allowed values + # Clear caches on construction to make class more like usual class then singleton (and cashes are dangerous) + PropertyManager.mono_correction_factor.set_cash_mono_run_number(None) + def _convert_params_to_properties(self,param_list,detine_subst_dict=True,descr_list=[]): """ method processes parameters obtained from IDF and modifies the IDF properties @@ -156,16 +158,16 @@ def __setattr__(self,name0,val): # replace common substitutions for string value if type(val) is str : - val1 = val.lower() - if val1 == 'none' or len(val1) == 0: - val = None - if val1 == 'default': - val = self.getDefaultParameterValue(name0) + val1 = val.lower() + if val1 == 'none' or len(val1) == 0: + val = None + if val1 == 'default': + val = self.getDefaultParameterValue(name0) # boolean property? - if val1 in ['true','yes']: - val = True - if val1 in ['false','no']: - val = False + if val1 in ['true','yes']: + val = True + if val1 in ['false','no']: + val = False if type(val) is list and len(val) == 0: @@ -173,30 +175,31 @@ def __setattr__(self,name0,val): # set property value: if name in self.__descriptors: - super(PropertyManager,self).__setattr__(name,val) + super(PropertyManager,self).__setattr__(name,val) else: - other_prop=prop_helpers.gen_setter(self.__dict__,name,val) + other_prop=prop_helpers.gen_setter(self.__dict__,name,val) # record the fact that the property have changed self.__changed_properties.add(name) # ---------------------------- def __getattr__(self,name): - """ Overloaded get method, disallowing non-existing properties being get but allowing - a property been called with different names specified in substitution dictionary. """ + """ Overloaded get method, disallowing non-existing properties being get but allowing + a property been called with different names specified in substitution dictionary. + """ - if name in self.__subst_dict: - name = self.__subst_dict[name] - return getattr(self,name) + if name in self.__subst_dict: + name = self.__subst_dict[name] + return getattr(self,name) #end - if name in self.__descriptors: + if name in self.__descriptors: # This can only happen only if descriptor is called through synonims dictionary # This to work, all descriptors should define getter to return self on Null instance. - descr=getattr(PropertyManager,name) - return descr.__get__(self,name) - else: - return prop_helpers.gen_getter(self.__dict__,name) + descr=getattr(PropertyManager,name) + return descr.__get__(self,name) + else: + return prop_helpers.gen_getter(self.__dict__,name) ##end #---------------------------------------------------------------------------------- # Overloaded setters/getters @@ -204,11 +207,11 @@ def __getattr__(self,name): # det_cal_file = DetCalFile() # - map_file = MapMaskFile('.map',"Spectra to detector mapping file for the sample run") + map_file = MapMaskFile('map_file','.map',"Spectra to detector mapping file for the sample run") # - monovan_mapfile = MapMaskFile('.map',"Spectra to detector mapping file for the monovanadium integrals calculation") + monovan_mapfile = MapMaskFile('monovan_map_file','.map',"Spectra to detector mapping file for the monovanadium integrals calculation") # - hard_mask_file = MapMaskFile('.msk',"Hard mask file") + hard_mask_file = MapMaskFile('hard_mask_file','.msk',"Hard mask file") # monovan_integr_range = MonovanIntegrationRange() # @@ -230,13 +233,20 @@ def __getattr__(self,name): # multirep_tof_specta_list=MultirepTOFSpectraList() # - mono_correction_factor = MonoCorrectionFactor(NonIDF_Properties.incident_energy) - + mono_correction_factor = MonoCorrectionFactor(NonIDF_Properties.incident_energy, + NonIDF_Properties.monovan_run) + # property responsible for summing runs + sum_runs = SumRuns(NonIDF_Properties.sample_run) + # properties responsible for rotation angle + motor_log_names= MotorLogName() + motor_offset = MotorOffset() + psi = RotationAngle(motor_log_names,motor_offset) #---------------------------------------------------------------------------------------------------------------- def getChangedProperties(self): """ method returns set of the properties changed from defaults """ decor_prop = '_'+type(self).__name__+'__changed_properties' return self.__dict__[decor_prop] + # def setChangedProperties(self,value=set([])): """ Method to clear changed properties list""" if isinstance(value,set): @@ -244,14 +254,14 @@ def setChangedProperties(self,value=set([])): self.__dict__[decor_prop] =value else: raise KeyError("Changed properties can be initialized by appropriate properties set only") - + # @property def relocate_dets(self) : if self.det_cal_file != None: return True else: return False - + # def set_input_parameters_ignore_nan(self,**kwargs): """ Like similar method set_input_parameters this one is used to set changed parameters from dictionary of parameters. @@ -260,41 +270,21 @@ def set_input_parameters_ignore_nan(self,**kwargs): with value equal to None. As such, this method is used as interface to set data from a function with a list of given parameters (*args vrt **kwargs), with some parameters missing. - """ - # if sum is in parameters one needs to set it first - if 'sum_runs' in kwargs and not kwargs['sum_runs'] is None: - self.sum_runs = kwargs['sum_runs'] - del kwargs['sum_runs'] - if 'sum' in kwargs and not kwargs['sum'] is None: - self.sum_runs = kwargs['sum'] - del kwargs['sum'] - - + """ + for par_name,value in kwargs.items() : if not value is None: setattr(self,par_name,value) - - - + # def set_input_parameters(self,**kwargs): """ Set input properties from a dictionary of parameters """ - # if sum is in parameters one needs to set it first to interpret - # - if 'sum_runs' in kwargs : - self.sum_runs = kwargs['sum_runs'] - del kwargs['sum_runs'] - if 'sum' in kwargs : - self.sum_runs = kwargs['sum'] - del kwargs['sum'] - - for par_name,value in kwargs.items() : setattr(self,par_name,value) return self.getChangedProperties() - + # def get_used_monitors_list(self): """ Method returns list of monitors ID used during reduction """ @@ -307,14 +297,13 @@ def get_used_monitors_list(self): used_mon.add(self.mon2_norm_spec) break if case(): # default, could also just omit condition or 'if True' - pass + pass used_mon.add(self.ei_mon1_spec) used_mon.add(self.ei_mon2_spec) return used_mon - - + # def get_diagnostics_parameters(self): """ Return the dictionary of the properties used in diagnostics with their values defined in IDF @@ -335,7 +324,7 @@ def get_diagnostics_parameters(self): self.log('--- Diagnostics property {0} is not found in instrument properties. Default value: {1} is used instead \n'.format(key,value),'warning') return result - + # def update_defaults_from_instrument(self,pInstrument,ignore_changes=False): """ Method used to update default parameters from the same instrument (with different parameters). @@ -368,17 +357,17 @@ def update_defaults_from_instrument(self,pInstrument,ignore_changes=False): # remove old changes which are not related to IDF (not to reapply it again) for prop_name in old_changes: if not prop_name in param_list: - try: - dependencies = getattr(PropertyManager,prop_name).dependencies() - except: - dependencies = [] - modified = False - for name in dependencies: - if name in param_list: - modified = True - break - if not modified: - del old_changes[prop_name] + try: + dependencies = getattr(PropertyManager,prop_name).dependencies() + except: + dependencies = [] + modified = False + for name in dependencies: + if name in param_list: + modified = True + break + if not modified: + del old_changes[prop_name] #end param_list,descr_dict = self._convert_params_to_properties(param_list,False,self.__descriptors) @@ -395,16 +384,16 @@ def update_defaults_from_instrument(self,pInstrument,ignore_changes=False): if not key in old_changes_list: try: # this is reliability check, and except ideally should never be hit. May occur if old IDF contains # properties, not present in recent IDF. - cur_val = getattr(self,key) - setattr(self,key,val) - new_val = getattr(self,key) + cur_val = getattr(self,key) + setattr(self,key,val) + new_val = getattr(self,key) except: - self.log("property {0} have not been found in existing IDF. Ignoring this property"\ + self.log("property {0} have not been found in existing IDF. Ignoring this property"\ .format(key),'warning') - continue + continue if isinstance(new_val,api.Workspace) and isinstance(cur_val,api.Workspace): # do simplified workspace comparison which is appropriate here - if new_val.name() == cur_val.name() and \ + if new_val.name() == cur_val.name() and \ new_val.getNumberHistograms() == cur_val.getNumberHistograms() and \ new_val.getNEvents() == cur_val.getNEvents() and \ new_val.getAxis(0).getUnit().unitID() == cur_val.getAxis(0).getUnit().unitID(): @@ -412,16 +401,16 @@ def update_defaults_from_instrument(self,pInstrument,ignore_changes=False): # #end if new_val != cur_val: - changed_descriptors.add(key) + changed_descriptors.add(key) # dependencies removed either properties are equal or not try: - dependencies = getattr(PropertyManager,key).dependencies() + dependencies = getattr(PropertyManager,key).dependencies() except: - dependencies = [] + dependencies = [] for dep_name in dependencies: if dep_name in sorted_param: - del sorted_param[dep_name] + del sorted_param[dep_name] else: # remove property from old changes list not to reapply it again? pass #end loop @@ -442,19 +431,19 @@ def update_defaults_from_instrument(self,pInstrument,ignore_changes=False): try: # this is reliability check, and except ideally should never be hit. May occur if old IDF contains # properties, not present in recent IDF. - cur_val = getattr(self,public_name) + cur_val = getattr(self,public_name) except: self.log("property {0} have not been found in existing IDF. Ignoring this property"\ .format(public_name),'warning') continue if prop_new_val !=cur_val : - setattr(self,public_name,prop_new_val) + setattr(self,public_name,prop_new_val) # Dependencies removed either properties are equal or not try: - dependencies = val.dependencies() + dependencies = val.dependencies() except: - dependencies =[] + dependencies =[] for dep_name in dependencies: # delete dependent properties not to deal with them again del sorted_param[dep_name] @@ -483,41 +472,153 @@ def update_defaults_from_instrument(self,pInstrument,ignore_changes=False): else: return None #end + def _get_properties_with_files(self): + """ Method returns list of properties, which may have + files as their values + + it does not include sample run, as this one will be + treated separately. + """ + + run_files_prop=['wb_run','monovan_run','mask_run','wb_for_monovan_run','second_white'] + map_mask_prop =['det_cal_file','map_file','hard_mask_file'] + + abs_units = not(self.monovan_run is None) + files_to_check =[] + # run files to check + for prop_name in run_files_prop: + theProp = getattr(PropertyManager,prop_name) + if theProp.has_own_value(): + if theProp.is_existing_ws(): # it is loaded workspace + continue # we do not care if it has file or not + val = theProp.__get__(self,PropertyManager) + if not(val is None) : + files_to_check.append(prop_name) + + # other files to check: + for prop_name in map_mask_prop: + val = getattr(self,prop_name) + if not(val is None or isinstance(val,api.Workspace)): + files_to_check.append(prop_name) + # Absolute units files (only one?) + if abs_units: + val = self.monovan_mapfile + if not(val is None) : + files_to_check.append('monovan_mapfile') + # + return files_to_check + # + def find_files_to_sum(self,num_files=None): + """ method searches for run files in run list to sum and returns + list of runs with run-files missing or ok and empty list if all files + are there + + if num_files is not None, find specified number of files out of total + file list to sum + """ + # this returns only runs, left to sum with current sample_run sum settings + runs,sum_ws,added = PropertyManager.sample_run.get_runs_to_sum(None,num_files) + if len(runs) == 0: + return (True,[],[]) + + ok,not_found_list,found_list = PropertyManager.sample_run.find_run_files(runs) + return (ok,not_found_list,found_list) + # + def _check_file_properties(self): + """ Method verifies if all files necessary for a reduction are available. - def _check_file_exist(self,file_name): - file_path = FileFinder.getFullPath(file) - if len(file_path) == 0: - try: - file_path = common.find_file(file) - except: - file_path ='' - - - def _check_necessary_files(self,monovan_run): - """ Method verifies if all files necessary for a run are available. - - useful for long runs to check if all files necessary for it are present/accessible + useful for long runs to check if all files necessary for it are + present/accessible before starting the run """ - - def check_files_list(files_list): - file_missing = False - for prop in files_list : - file = getattr(self,prop) - if not (file is None) and isinstance(file,str): - file_path = self._check_file_exist(file) - if len(file_path)==0: - self.log(" Can not find file ""{0}"" for property: {1} ".format(file,prop),'error') - file_missing=True - - return file_missing - - base_file_missing = check_files_list(self.__file_properties) - abs_file_missing=False - if not monovan_run is None: - abs_file_missing = check_files_list(self.__abs_norm_file_properties) - - if base_file_missing or abs_file_missing: - raise RuntimeError(" Files needed for the run are missing ") + file_prop_names = self._get_properties_with_files() + file_errors={} + for prop_name in file_prop_names: + theProp = getattr(PropertyManager,prop_name) + ok,file = theProp.find_file(be_quet=True) + if not ok: + file_errors[prop_name]=file + + if self.sum_runs : + ok,missing,found=self.find_files_to_sum() + if not ok and not self.cashe_sum_ws: + file_errors['missing_runs_toSum']=str(missing) + + result = (len(file_errors)==0) + return (result,file_errors) + # + def _check_ouptut_dir(self): + """ check if default save directory is accessible for writing """ + targ_dir = config['defaultsave.directory'] + test_file = os.path.join(targ_dir,'test_file.txt') + try: + fp = open(test_file,'w') + fp.close() + os.remove(test_file) + return (True,'') + except: + return (False,'Can not write to default save directory {0}.\n Reduction results can be lost'.format(targ_dir)) + # + def validate_properties(self,fail_on_errors=True): + """ Method validates if some properties values for + properties set up in the property manager are correct + """ + + if self.mono_correction_factor: # disable check for monovan_run, as it is not used if mono_correction provided + PropertyManager.monovan_run._in_cash = True # as soon as monovan_run is set up (mono correction disabled) + # this will be dropped + error_list={} + error_level=0 + + ok,fail_prop = self._check_file_properties() + if not ok : + for prop in fail_prop: + mess = "*** ERROR : properties : {0} -->{1}".format(prop,fail_prop[prop]) + if fail_on_errors: + self.log(mess,'warning') + else: + error_list[prop]=mess + error_level=2 + + ok,mess= self._check_ouptut_dir() + if not ok: + mess = '*** WARNING: saving results: --> {1}'.format(mess) + + if fail_on_errors: + self.log(mess,'warning') + else: + error_list['file_output']=mess + error_level=max(1,error_level) + + # verify interconnected properties + changed_prop = self.getChangedProperties() + for prop in changed_prop: + try: + theProp =getattr(PropertyManager,prop) + except: # not all changed properties are property manager properties + continue # we are not validating them + try: + ok,sev,message = theProp.validate(self,PropertyManager) + if not (ok): + error_level=max(sev,error_level) + if sev == 1: + base = '*** WARNING: properties : {0} --> {1}' + else: + base = '*** ERROR : properties : {0} --> {1}' + mess = base.format(prop,message) + if fail_on_errors: + self.log(mess,'warning') + else: + error_list[prop]=mess + except: # its simple dictionary value, which do not have validator or + pass # other property without validator + #end + if error_level>1 and fail_on_errors: + raise RuntimeError('*** Invalid properties found. Can not run convert_to energy') + if error_level>0: + OK = False + else: + OK = True + return (OK,error_level,error_list) # def _check_monovan_par_changed(self): """ method verifies, if properties necessary for monovanadium reduction have indeed been changed from defaults """ @@ -533,62 +634,62 @@ def _check_monovan_par_changed(self): # def log_changed_values(self,log_level='notice',display_header=True,already_changed=set()): - """ inform user about changed parameters and about the parameters that should be changed but have not + """ inform user about changed parameters and about the parameters that should be changed but have not This method is abstract method of NonIDF_Properties but is fully defined in PropertyManager display_header==True prints nice additional information about run. If False, only list of changed properties displayed. """ - if display_header: + if display_header: # we may want to run absolute units normalization and this function has been called with monovan run or helper procedure - if self.monovan_run != None : + if self.monovan_run != None : # check if mono-vanadium is provided as multiple files list or just put in brackets occasionally - self.log("****************************************************************",'notice') - self.log('*** Output will be in absolute units of mb/str/mev/fu','notice') - non_changed = self._check_monovan_par_changed() - if len(non_changed) > 0: - for prop in non_changed: - value = getattr(self,prop) - message = "\n***WARNING!: Abs units norm. parameter : {0} not changed from default val: {1}"\ + self.log("****************************************************************",'notice') + self.log('*** Output will be in absolute units of mb/str/mev/fu','notice') + non_changed = self._check_monovan_par_changed() + if len(non_changed) > 0: + for prop in non_changed: + value = getattr(self,prop) + message = "\n***WARNING!: Abs units norm. parameter : {0} not changed from default val: {1}"\ "\n This may need to change for correct absolute units reduction\n" - self.log(message.format(prop,value),'warning') + self.log(message.format(prop,value),'warning') # now let's report on normal run. - if PropertyManager.incident_energy.multirep_mode(): - ei = self.incident_energy - mess = "*** Provisional Incident energies: {0:>8.3f}".format(ei[0]) - for en in ei[1:]: - mess += "; {0:>8.3f}".format(en) - mess+=" mEv" - self.log(mess,log_level) - else: - self.log("*** Provisional Incident energy: {0:>12.3f} mEv".format(self.incident_energy),log_level) + if PropertyManager.incident_energy.multirep_mode(): + ei = self.incident_energy + mess = "*** Provisional Incident energies: {0:>8.3f}".format(ei[0]) + for en in ei[1:]: + mess += "; {0:>8.3f}".format(en) + mess+=" mEv" + self.log(mess,log_level) + else: + self.log("*** Provisional Incident energy: {0:>12.3f} mEv".format(self.incident_energy),log_level) #end display_header - self.log("****************************************************************",log_level) - changed_Keys= self.getChangedProperties() - for key in changed_Keys: - if key in already_changed: - continue - val = getattr(self,key) - self.log(" Value of : {0:<25} is set to : {1:<20} ".format(key,val),log_level) - - if not display_header: - return - - save_dir = config.getString('defaultsave.directory') - self.log("****************************************************************",log_level) - if self.monovan_run != None and not 'van_mass' in changed_Keys: # This output is - self.log("*** Monochromatic vanadium mass used : {0} ".format(self.van_mass),log_level) # Adroja request from may 2014 + self.log("****************************************************************",log_level) + changed_Keys= self.getChangedProperties() + for key in changed_Keys: + if key in already_changed: + continue + val = getattr(self,key) + self.log(" Value of : {0:<25} is set to : {1:<20} ".format(key,val),log_level) + + if not display_header: + return + + save_dir = config.getString('defaultsave.directory') + self.log("****************************************************************",log_level) + if self.monovan_run != None and not 'van_mass' in changed_Keys: # This output is Adroja request from may 2014 + self.log("*** Monochromatic vanadium mass used : {0} ".format(self.van_mass),log_level) # - self.log("*** By default results are saved into: {0}".format(save_dir),log_level) - self.log("*** Output will be normalized to {0}".format(self.normalise_method),log_level) - if self.map_file == None: + self.log("*** By default results are saved into: {0}".format(save_dir),log_level) + self.log("*** Output will be normalized to {0}".format(self.normalise_method),log_level) + if self.map_file == None: self.log('*** one2one map selected',log_level) - self.log("****************************************************************",log_level) + self.log("****************************************************************",log_level) #def help(self,keyword=None) : diff --git a/Code/Mantid/scripts/Inelastic/Direct/ReductionHelpers.py b/Code/Mantid/scripts/Inelastic/Direct/ReductionHelpers.py index d1943b913b8c..468f6aca787f 100644 --- a/Code/Mantid/scripts/Inelastic/Direct/ReductionHelpers.py +++ b/Code/Mantid/scripts/Inelastic/Direct/ReductionHelpers.py @@ -50,6 +50,20 @@ def len(self): return len(self._other_prop) #end ComplexProperty +def findFile(fileName): + """ Simple search within Mantid data search directories for + a file which is not a run file + """ + + if os.path.exists(fileName): + return os.path.abspath(fileName) + fbase = os.path.basename(fileName) + search_path = config.getDataSearchDirs() + for path in search_path: + fname = os.path.join(path,fbase) + if os.path.exists(fname): + return fname + return '' def get_default_parameter(instrument, name): @@ -362,6 +376,3 @@ def parse_run_file_name(run_string): fext = fext[0] # extensions should be either all the same or all defined return (filepath,filenum,fext) - - - diff --git a/Code/Mantid/scripts/Inelastic/Direct/ReductionWrapper.py b/Code/Mantid/scripts/Inelastic/Direct/ReductionWrapper.py index e18d3e1aa7de..332ff0751f6c 100644 --- a/Code/Mantid/scripts/Inelastic/Direct/ReductionWrapper.py +++ b/Code/Mantid/scripts/Inelastic/Direct/ReductionWrapper.py @@ -6,7 +6,6 @@ from Direct.PropertyManager import PropertyManager # this import is used by children from Direct.DirectEnergyConversion import DirectEnergyConversion -#import inspect import os from abc import abstractmethod @@ -24,36 +23,29 @@ def __init__(self): self.advanced_vars = None def __init__(self,instrumentName,web_var=None): - """ sets properties defaults for the instrument with Name + """ sets properties defaults for the instrument with Name and define if wrapper runs from web services or not """ # internal variable, indicating if we should try to wait for input files to appear - self._wait_for_file=False + self._wait_for_file=False + # internal variable, used in system tests to validate workflow, + # with waiting for files. It is the holder to the function + # used during debugging "wait for files" workflow + # instead of Pause algorithm + self._debug_wait_for_files_operation=None # The variables which are set up from web interface or to be exported to # web interface - if web_var: - self._run_from_web = True - self._wvs = web_var - else: - self._run_from_web = False - self._wvs = ReductionWrapper.var_holder() + if web_var: + self._run_from_web = True + self._wvs = web_var + else: + self._run_from_web = False + self._wvs = ReductionWrapper.var_holder() # Initialize reduced for given instrument - self.reducer = DirectEnergyConversion(instrumentName) + self.reducer = DirectEnergyConversion(instrumentName) - self._validation_fname=None -# - def get_validation_file_name(self,ReferenceFile=None): - """ function provides name of the file with mantid - workspace reduced earlier and which should be validated - against results of current reduction - Should be overloaded to return real file name for particular - reduction - """ - if ReferenceFile: - self._validation_fname = ReferenceFile - return self._validation_fname @property def wait_for_file(self): @@ -79,7 +71,7 @@ def save_web_variables(self,FileName=None): interface If no file is provided, reduce_var.py file will be written - to + to the folder, containing current script """ if not FileName: @@ -89,51 +81,84 @@ def save_web_variables(self,FileName=None): f.write("standard_vars = {\n") str_wrapper = ' ' for key,val in self._wvs.standard_vars.iteritems(): - if isinstance(val,str): - row = "{0}\'{1}\':\'{2}\'".format(str_wrapper,key,val) - else: - row = "{0}\'{1}\':{2}".format(str_wrapper,key,val) - f.write(row) - str_wrapper=',\n ' + if isinstance(val,str): + row = "{0}\'{1}\':\'{2}\'".format(str_wrapper,key,val) + else: + row = "{0}\'{1}\':{2}".format(str_wrapper,key,val) + f.write(row) + str_wrapper=',\n ' f.write("\n}\nadvanced_vars={\n") str_wrapper=' ' for key,val in self._wvs.advanced_vars.iteritems(): - if isinstance(val,str): - row = "{0}\'{1}\':\'{2}\'".format(str_wrapper,key,val) - else: - row = "{0}\'{1}\':{2}".format(str_wrapper,key,val) - f.write(row) - str_wrapper=',\n ' + if isinstance(val,str): + row = "{0}\'{1}\':\'{2}\'".format(str_wrapper,key,val) + else: + row = "{0}\'{1}\':{2}".format(str_wrapper,key,val) + f.write(row) + str_wrapper=',\n ' f.write("\n}\n") f.close() + def validate_settings(self): + """ method validates initial parameters, provided for reduction """ + + self.def_advanced_properties() + self.def_main_properties() + if self._run_from_web: + web_vars = dict(self._wvs.standard_vars.items()+self._wvs.advanced_vars.items()) + self.reducer.prop_man.set_input_parameters(**web_vars) + else: + pass # we should set already set up variables using + + # validate properties and report result + return self.reducer.prop_man.validate_properties(False) # -# +# def validate_result(self,build_validation=False,Error=1.e-3,ToleranceRelErr=True): - """ Overload this using build_or_validate_result to have possibility to run or validate result """ + """ Overload this using build_or_validate_result to have possibility to run or validate result """ return True - def build_or_validate_result(self,sample_run,validationFile,build_validation=False,Error=1.e-3,ToleranceRelErr=True): - """ Method validates results of the reduction against reference file provided - by get_validation_file_name() method - - At the moment, get_validation_file_name method should return the name of a file, - where workspace sample reduced workspace with default properties - is stored. - CheckWorkspaceMatch method is applied to verify if current reduced workspace is - equivalent to the workspace, stored in the reference file. + def set_custom_output_filename(self): + """ define custom name of output files if standard one is not satisfactory + User expected to overload this method within class instantiation """ + return None + + + def build_or_validate_result(self,sample_run,validation_file,build_validation=False,Error=1.e-3,ToleranceRelErr=True): + """ Method validates results of the reduction against reference file or workspace. + + Inputs: + sample_run -- the run number to reduce or validate against existing result + validation_file -- The name of nxs file, containing workspace, produced by reducing SampleRun, + or the pointer to the workspace, which is the reference workspace + for SampleRun reduction. + + Returns: + True if reduction for sample_run produces result within Error from the reference file + as reported by CheckWorkspaceMatch. + False if CheckWorkspaceMatch comparison between sample and reduction is unsuccessful + + True if was not able to load reference file. In this case, algorithm builds validation + file and returns True if the reduction and saving of this file is successful + """ if not build_validation: - if validationFile: - if isinstance(validationFile,api.Workspace): - sample = validationFile - validationFile = sample.name() - else: - sample = Load(validationFile) - else: - build_validation=True + if validation_file: + if isinstance(validation_file,api.Workspace): + sample = validation_file + validation_file = sample.name() + else: + try: + sample = Load(validation_file) + except: + self.reducer.prop_man.log\ + ("*** WARNING:can not load (find?) validation file {0}\n"\ + " Building validation".format(validation_file),'warning') + build_validation=True + else: + build_validation=True # just in case, to be sure @@ -152,10 +177,10 @@ def build_or_validate_result(self,sample_run,validationFile,build_validation=Fal reduced = self.reduce() if build_validation: - if validationFile: - result_name = os.path.splitext(validationFile)[0] + if validation_file: + result_name = os.path.splitext(validation_file)[0] else: - result_name = self.reducer.prop_man.save_file_name + result_name = self.reducer.prop_man.save_file_name self.reducer.prop_man.log("*** Saving validation file with name: {0}.nxs".format(result_name),'notice') SaveNexus(reduced,Filename=result_name+'.nxs') return True,'Created validation file {0}.nxs'.format(result_name) @@ -194,8 +219,17 @@ def def_advanced_properties(self): """ raise NotImplementedError('def_advanced_properties has to be implemented') - - + # + def _run_pause(self,timeToWait=0): + """ a wrapper around pause algorithm allowing to run something + instead of pause in debug mode + """ + + if not self._debug_wait_for_files_operation is None: + self._debug_wait_for_files_operation() + else: + Pause(timeToWait) + # def reduce(self,input_file=None,output_directory=None): """ The method performs all main reduction operations over single run file @@ -204,25 +238,118 @@ def reduce(self,input_file=None,output_directory=None): reduction properties between script and web variables """ if input_file: - self.reducer.sample_run = input_file + self.reducer.sample_run = str(input_file) + if output_directory: + config['defaultsave.directory'] = str(output_directory) timeToWait = self._wait_for_file - if timeToWait: - file = PropertyManager.sample_run.find_file(be_quet=True) - while file.find('ERROR:')>=0: + if timeToWait>0: + Found,input_file = PropertyManager.sample_run.find_file(be_quet=True) + while not Found: file_hint,fext = PropertyManager.sample_run.file_hint() self.reducer.prop_man.log("*** Waiting {0} sec for file {1} to appear on the data search path"\ .format(timeToWait,file_hint),'notice') - Pause(timeToWait) - file = PropertyManager.sample_run.find_file(be_quet=True) + + self._run_pause(timeToWait) + Found,input_file = PropertyManager.sample_run.find_file(file_hint=file_hint,be_quet=True) ws = self.reducer.convert_to_energy(None,input_file) else: ws = self.reducer.convert_to_energy(None,input_file) return ws - - + # + def sum_and_reduce(self): + """ procedure used to sum and reduce runs in case when not all files + are available and user have to wait for these files to appear + """ + if not PropertyManager.sample_run._run_list: + raise RuntimeError("sum_and_reduce expects run file list to be defined") + + self.reducer.prop_man.sum_runs = True + + timeToWait = self._wait_for_file + if timeToWait>0: + run_files = PropertyManager.sample_run.get_run_list() + num_files_to_sum = len(PropertyManager.sample_run) + + ok,missing,found = self.reducer.prop_man.find_files_to_sum() + n_found = len(found) + if not ok: + # necessary to cache intermediate sums in memory + self.reducer.prop_man.cashe_sum_ws = True + while not(ok): + while n_found>0: + last_found = found[-1] + self.reducer.prop_man.sample_run = last_found # request to reduce all up to last found + ws = self.reducer.convert_to_energy() + # reset search to whole file list again + self.reducer.prop_man.sample_run = run_files[num_files_to_sum-1] + ok,missing,found = self.reducer.prop_man.find_files_to_sum() + n_found = len(found) + if ok: # no need to cache sum any more. All necessary files found + self.reducer.prop_man.cashe_sum_ws = False + + self.reducer.prop_man.log("*** Waiting {0} sec for runs {1} to appear on the data search path"\ + .format(timeToWait,str(missing)),'notice') + self._run_pause(timeToWait) + ok,missing,found = self.reducer.prop_man.find_files_to_sum() + n_found = len(found) + #end not(ok) + if n_found>0: + # cash sum can be dropped now if it has not been done before + self.reducer.prop_man.cashe_sum_ws = False + ws = self.reducer.convert_to_energy() + else: + ws = self.reducer.convert_to_energy() + + return ws + # + def run_reduction(self): + """" Reduces runs one by one or sum all them together and reduce after this + + if wait_for_file time is > 0, it will until missing files appear on the + data search path + """ + try: + n,r = funcreturns.lhs_info('both') + out_ws_name = r[0] + except: + out_ws_name = None + + if self.reducer.sum_runs: +# --------### sum runs provided ------------------------------------### + if out_ws_name is None: + self.sum_and_reduce() + return None + else: + red_ws=self.sum_and_reduce() + RenameWorkspace(InputWorkspace=red_ws,OutputWorkspace=out_ws_name) + return mtd[out_ws_name] + else: +# --------### reduce list of runs one by one ----------------------------### + runfiles = PropertyManager.sample_run.get_run_file_list() + if out_ws_name is None: + for file in runfiles: + self.reduce(file) + #end + return None + else: + results=[] + nruns = len(runfiles) + for num,file in enumerate(runfiles): + red_ws=self.reduce(file) + if nruns >1: + out_name = out_ws_name+'#{0}of{1}'.format(num+1,nruns) + RenameWorkspace(InputWorkspace=red_ws,OutputWorkspace=out_name) + red_ws = mtd[out_name] + results.append(red_ws) + #end + if len(results) == 1: + return results[0] + else: + return results + #end def MainProperties(main_prop_definition): @@ -282,15 +409,15 @@ def iliad_wrapper(*args): output_directory=None # add input file folder to data search directory if file has it if input_file and isinstance(input_file,str): - data_path = os.path.dirname(input_file) - if len(data_path)>0: - try: - config.appendDataSearchDir(str(data_path)) - args[1] = os.path.basename(input_file) - except: # if mantid is not available, this should ignore config - pass + data_path = os.path.dirname(input_file) + if len(data_path)>0: + try: + config.appendDataSearchDir(str(data_path)) + args[1] = os.path.basename(input_file) + except: # if mantid is not available, this should ignore config + pass if output_directory: - config['defaultsave.directory'] = output_directory + config['defaultsave.directory'] = str(output_directory) if host._run_from_web: web_vars = dict(host._wvs.standard_vars.items()+host._wvs.advanced_vars.items()) @@ -298,23 +425,25 @@ def iliad_wrapper(*args): else: pass # we should set already set up variables using - + custom_print_function = host.set_custom_output_filename() + if not custom_print_function is None: + PropertyManager.save_file_name.set_custom_print(custom_print_function) + # rez = reduce(*args) # prohibit returning workspace to web services. if host._run_from_web and not isinstance(rez,str): rez="" else: - if isinstance(rez,list): + if isinstance(rez,list): # multirep run, just return as it is - return rez - if out_ws_name and rez.name() != out_ws_name : - rez=RenameWorkspace(InputWorkspace=rez,OutputWorkspace=out_ws_name) + return rez + if out_ws_name and rez.name() != out_ws_name : + rez=RenameWorkspace(InputWorkspace=rez,OutputWorkspace=out_ws_name) return rez return iliad_wrapper - if __name__=="__main__": pass diff --git a/Code/Mantid/scripts/Inelastic/Direct/RunDescriptor.py b/Code/Mantid/scripts/Inelastic/Direct/RunDescriptor.py index edddf86fb180..a7c388cd50b7 100644 --- a/Code/Mantid/scripts/Inelastic/Direct/RunDescriptor.py +++ b/Code/Mantid/scripts/Inelastic/Direct/RunDescriptor.py @@ -1,154 +1,483 @@ #pylint: disable=invalid-name """ File contains Descriptors used describe run for direct inelastic reduction """ - from mantid.simpleapi import * from Direct.PropertiesDescriptors import * import re +class RunList(object): + """Helper class to maintain list of runs used in RunDescriptor for summing + or subsequent processing range of files. + + Supports basic operations with this list + """ + def __init__(self,run_list,file_names=None,fext=None): + """ """ + self._last_ind2sum = -1 + self._file_path = None + self._fext = None + self.set_list2add(run_list,file_names,fext) + self._partial_sum_ws_name = None + # + def set_list2add(self,runs_to_add,fnames=None,fext=None): + """Set run numbers to add together with possible file guess-es """ + if not isinstance(runs_to_add,list): + raise KeyError('Can only set list of run numbers to add') + runs = [] + for item in runs_to_add: + runs.append(int(item)) + self._run_numbers = runs + self._set_fnames(fnames,fext) +#-------------------------------------------------------------------------------------------------- + def set_cashed_sum_ws(self,ws,new_ws_name=None): + """Store the name of a workspace in the class + as reference + """ + if new_ws_name: + old_name = ws.name() + if old_name != new_ws_name: + old_mon_name = old_name + '_monitors' + RenameWorkspace(ws,OutputWorkspace=new_ws_name) + if old_mon_name in mtd: + RenameWorkspace(old_mon_name,OutputWorkspace=new_ws_name + '_monitors') + else: + new_ws_name = ws.name() + self._partial_sum_ws_name = new_ws_name + # + def get_cashed_sum_ws(self): + """Return python pointer to cached sum workspace + """ + if not self._partial_sum_ws_name: + return None + if self._partial_sum_ws_name in mtd: + return mtd[self._partial_sum_ws_name] + else: + return None + # + def get_cashed_sum_clone(self): + """ """ + origin = self.get_cashed_sum_ws() + if not origin: + return None + origin_name = origin.name() + mon_name = origin_name + '_monitors' + if mon_name in mtd: + CloneWorkspace(InputWorkspace=mon_name,OutputWorkspace=origin_name + '_clone_monitors') + ws = CloneWorkspace(InputWorkspace=origin_name,OutputWorkspace=origin_name + '_clone') + return ws + # + def del_cashed_sum(self): + """ """ + if not self._partial_sum_ws_name: + return + if self._partial_sum_ws_name in mtd: + DeleteWorkspace(self._partial_sum_ws_name) + mon_ws = self._partial_sum_ws_name + '_monitors' + if mon_ws in mtd: + DeleteWorkspace(mon_ws) +#-------------------------------------------------------------------------------------------------- + # + def _set_fnames(self,fnames,fext): + """Sets filenames lists and file extension lists + of length correspondent to run number length + + if length of the list provided differs from the length + of the run list, expands fnames list and fext list + to the whole runnumber list using last for fext and + first for fnames members of the + """ + if fnames: + if isinstance(fnames,list): + self._file_path = fnames + else: + self._file_path = [fnames] + + if not(self._file_path): + self._file_path = [''] * len(self._run_numbers) + else: + if len(self._file_path) != len(self._run_numbers): + self._file_path = [self._file_path[0]] * len(self._run_numbers) + + if fext: + if isinstance(fext,list): + self._fext = fext + else: + self._fext = [fext] + + if not (self._fext): + self._fext = [''] * len(self._run_numbers) + else: + if len(self._fext) != len(self._run_numbers): + base_fext = self._fext[-1] + self._fext = [base_fext] * len(self._run_numbers) + # + def get_file_guess(self,inst_name,run_num,default_fext=None,index=None): + """Return the name of run file for run number provided + + Note: internal file extension overwrites + default_fext if internal is not empty + """ + if index is None: + index = self._run_numbers.index(run_num) + path_guess = self._file_path[index] + fext = self._fext[index] + if default_fext and len(fext) == 0: + fext = def_fext + guess = build_run_file_name(run_num,inst_name,path_guess,fext) + return (guess,index) + # + def get_run_file_list(self,inst_name,default_fext): + """Return list of files, used corresponding to runs""" + run_files = [] + for ind,run in enumerate(self._run_numbers): + fname,index = self.get_file_guess(inst_name,run,default_fext,ind) + run_files.append(fname) + return run_files + # + def get_all_run_list(self): + return self._run_numbers + # + def add_or_replace_run(self,run_number,fpath='',fext=None,default_fext=False): + """Add run number to list of existing runs + + Let's prohibit adding the same run numbers using this method. + Equivalent run numbers can still be added using list assignment + + file path and file extension are added/modified if present + regardless of run being added or replaced + """ + if not(run_number in self._run_numbers): + self._run_numbers.append(run_number) + if not fpath: + fpath = self._file_path[-1] + self._file_path.append(fpath) + if not fext: + fext = self._fext[-1] + self._fext.append(fext) + + self._last_ind2sum = len(self._run_numbers) - 1 + return self._last_ind2sum + else: + ext_ind = self._run_numbers.index(run_number) + if len(fpath) > 0: + self._file_path[ext_ind] = fpath + if fext: + if not(default_fext and len(self._fext[ext_ind]) > 0): #not keep existing + self._fext[ext_ind] = fext + self._last_ind2sum = ext_ind + return ext_ind + # + def check_runs_equal(self,run_list,fpath=None,fext=None): + """Returns true if all run numbers in existing list are + in the comparison list and vice versa. + if lists numbers coincide, + sets new file_path and fext list if such are provided + """ + if len(run_list) != len(self._run_numbers): + return False + + for run in run_list: + if not(run in self._run_numbers): + return False + self._set_fnames(fpath,fext) + return True + # + def get_current_run_info(self,sum_runs,ind=None): + """Return last run info for file to sum""" + if ind: + if not(ind > -1 and ind < len(self._run_numbers)): + raise RuntimeError("Index {0} is outside of the run list of {1} runs".format(ind,len(self._run_numbers))) + else: + ind = self.get_last_ind2sum(sum_runs) + return self._run_numbers[ind],self._file_path[ind],self._fext[ind],ind + # + def set_last_ind2sum(self,run_number): + """Check and set last number, contributing to summation + if this number is out of summation range, clear the summation + """ + run_number = int(run_number) + if run_number in self._run_numbers: + self._last_ind2sum = self._run_numbers.index(run_number) + else: + self._last_ind2sum = -1 + # + def get_run_list2sum(self,num_to_sum=None): + """Get run numbers of the files to be summed together + from the list of defined run numbers + """ + n_runs = len(self._run_numbers) + if num_to_sum: + if num_to_sum <= 0: + num_to_sum = 1 + if num_to_sum > n_runs: + num_to_sum = n_runs + else: + num_to_sum = n_runs + + if self._last_ind2sum >= 0 and self._last_ind2sum < num_to_sum: + num_to_sum = self._last_ind2sum + 1 + + return self._run_numbers[:num_to_sum] + # + def get_last_ind2sum(self,sum_runs): + """Get last run number contributing to sum""" + + if self._last_ind2sum >= 0 and self._last_ind2sum < len(self._run_numbers): + ind = self._last_ind2sum + else: + if sum_runs: + ind = len(self._run_numbers) - 1 + else: + ind = 0 + return ind + # + def sum_ext(self,sum_runs): + if sum_runs: + last = self.get_last_ind2sum(sum_runs) + sum_ext = "SumOf{0}".format(len(self._run_numbers[:last + 1])) + else: + sum_ext = '' + return sum_ext + # + def find_run_files(self,inst_name,run_list=None,default_fext=None): + """Find run files correspondent to the run list provided + and set path to these files as new internal parameters + for the files in list + + Return the list of the runs, which files were + not found and found + + Run list have to coincide or be part of self._run_numbers + No special check for correctness is performed, so may fail + miserably + """ + + if not run_list: + run_list = self._run_numbers + not_found = [] + found = [] + for run in run_list: + file_hint,index = self.get_file_guess(inst_name,run,default_fext) + try: + file = FileFinder.findRuns(file_hint)[0] + fpath,fname = os.path.split(file) + fname,fex = os.path.splitext(fname) + self._fext[index] = fex + self._file_path[index] = fpath + #self._last_ind2sum = index + found.append(run) + except RuntimeError: + not_found.append(run) + return not_found,found +#-------------------------------------------------------------------------------------------------- +#-------------------------------------------------------------------------------------------------- +#-------------------------------------------------------------------------------------------------- class RunDescriptor(PropDescriptor): - """ descriptor supporting a run and a workspace """ + """ descriptor to work with a run or list of runs specified + either as run number (run file) or as + this run loaded in memory as a workspace + Used to help + """ # the host class referencing contained all instantiated descriptors. # Descriptors methods rely on it to work (e.g. to extract file loader # preferences) # so it has to be set up manually by PropertyManager __init__ method _holder = None _logger = None - # class level reference to the property manager - _PropMan = None + _sum_log_name = 'SumRuns' #-------------------------------------------------------------------------------------------------------------------- def __init__(self,prop_name,DocString=None): """ """ + self._prop_name = prop_name + if not DocString is None: + self.__doc__ = DocString + + self._ws_name = None + # pointer to workspace used to mask this workspace obtained at diag for + # this ws + self._mask_ws_name = None + + self._clear_all() + + def __len__(self): + """ overloaded len function, which + return length of the run-files list + to work with + """ + if not(self._run_number): + return 0 + if self._run_list: + return len(self._run_list._run_numbers) + else: + return 1 +#-------------------------------------------------------------------------------------------------------------------- + def _clear_all(self): + """ clear all internal properties, workspaces and caches, + associated with this run + """ # Run number self._run_number = None # Extension of the file to load data from # - self._prop_name = prop_name self._run_file_path = '' - self._run_ext = None - # Workspace name which corresponds to the run + self._fext = None + + if self._ws_name: + mon_ws = self._ws_name + '_monitors' + # Workspace name which corresponds to the run + if self._ws_name in mtd: + DeleteWorkspace(self._ws_name) + if mon_ws in mtd: + DeleteWorkspace(mon_ws) + self._ws_name = None # none if not loaded - # String used to identify the workspace related to this property w.r.t. - # other workspaces + # String used to identify the workspace related to this property + # w.r.t. other workspaces self._ws_cname = '' self._ws_suffix = '' - self._bind_to_sum = False - + # property contains run lists + self._run_list = None # - if not DocString is None: - self.__doc__ = DocString + self._in_cash = False + # clear masking workspace if any available + if self._mask_ws_name: + if self._mask_ws_name in mtd: + DeleteWorkspace(self._mask_ws_name) + self._mask_ws_name = None + #-------------------------------------------------------------------------------------------------------------------- def __get__(self,instance,owner): - """ return current run number or workspace if it is loaded""" - if not RunDescriptor._PropMan: - RunDescriptor._PropMan = owner - if instance is None: - return self + """Return current run number or workspace if it is loaded""" + if instance is None: + return self - if self._ws_name and self._ws_name in mtd: - return mtd[self._ws_name] - else: + if self._ws_name and self._ws_name in mtd: + return mtd[self._ws_name] + else: return self._run_number #-------------------------------------------------------------------------------------------------------------------- def __set__(self,instance,value): - """ Set up Run number and define workspace name from any source """ + """Set up Run number and define workspace name from any source """ # - if not RunDescriptor._PropMan: - from PropertyManager import PropertyManager - RunDescriptor._PropMan = PropertyManager - - old_ws_name = self._ws_name - clear_fext = True - #end - if value == None: # clear current run number - self._run_number = None - self._ws_name = None - self._ws_cname = '' - self._ws_suffix = '' - # only one RunDescriptor can be summed under current approach. - # To disentangle one run descriptor from another -- set up binding - self._bind_to_sum = False - self._clear_old_ws(old_ws_name,self._ws_name,clear_fext) - RunDescriptor._PropMan.sum_runs.clear_sum() - return - if isinstance(value, api.Workspace): - #if 'SumOfRuns:' in value.getRun(): - # TODO: not implemented - - #else: - if self._ws_name != value.name(): - self._set_ws_as_source(value) - self._clear_old_ws(old_ws_name,self._ws_name,clear_fext) - self._bind_to_sum = False - RunDescriptor._PropMan.sum_runs.clear_sum() - return - else: # it is just reassigning the same workspace to itself - return - - if isinstance(value,str): # it may be run number as string or it may be a workspace name - if value in mtd: # workspace name - ws = mtd[value] - self.__set__(instance,ws) - return - else: - file_path,run_num,fext = prop_helpers.parse_run_file_name(value) - - if isinstance(run_num,list): - RunDescriptor._PropMan.sum_runs.set_list2add(run_num,file_path,fext) - self._bind_to_sum = True - if instance.sum_runs: - last_run_ind = RunDescriptor._PropMan.sum_runs.get_last_ind2sum() - main_fext = fext[last_run_ind].lower() - self._run_file_path = file_path[last_run_ind].lower() - else: - self.__set__(instance,run_num) - self._run_file_path = file_path - main_fext = fext.lower() - - # - if len(main_fext) > 0: - self._run_ext = main_fext - else: # will be default file extension - self._run_ext = None - clear_fext = False - elif isinstance(value,list): - if len(value) == 1: - self.__set__(instance,value[0]) - return - self._bind_to_sum = True - RunDescriptor._PropMan.sum_runs.set_list2add(value) - if instance.sum_runs: - last_run_ind = RunDescriptor._PropMan.sum_runs.get_last_ind2sum() - self._run_number = value[last_run_ind] - else: - self._run_number = value[0] - clear_fext = True + if value == None: # clear current run number + self._clear_all() + return + if isinstance(value, api.Workspace): + if self._ws_name: + if self._ws_name != value.name(): + self._clear_all() + self._set_ws_as_source(value) + else: + return # do nothing + # it is just reassigning the same workspace to itself + else: # first assignment of workspace to property + self._set_ws_as_source(value) + return + + if isinstance(value,str): # it may be run number as string or it may be a workspace name + if value in mtd: # workspace name + ws = mtd[value] + self.__set__(instance,ws) + return + else: # split string into run indexes and auxiliary file parameters + file_path,run_num,fext = prop_helpers.parse_run_file_name(value) + + if isinstance(run_num,list): + self._set_run_list(instance,run_num,file_path,fext) + else: + self._set_single_run(instance,run_num,file_path,fext,False) + elif isinstance(value,list): + self._set_run_list(instance,value,"",instance.data_file_ext) + else: + self._set_single_run(instance,value,"",instance.data_file_ext,True) + +#-------------------------------------------------------------------------------------------------------------------- + def _set_single_run(self,instance,run_number,file_path='',fext=None,default_fext=False): + """ """ + self._run_number = int(run_number) + # build workspace name for current run number + new_ws_name = self._build_ws_name() + + if self._run_list and instance.sum_runs: + ind = self._run_list.add_or_replace_run(self._run_number,file_path,fext,default_fext) + self._run_file_path = self._run_list._file_path[ind] + self._fext = self._run_list._fext[ind] + self._ws_name = new_ws_name else: - clear_fext = True - self._run_number = int(value) - if self._bind_to_sum and instance and instance.sum_runs: - num2_sum = RunDescriptor._PropMan.sum_runs.set_last_ind2sum(self._run_number) - if num2_sum == 0: - self._bind_to_sum = False - instance.sum_runs = False + if self._ws_name != new_ws_name: + self._clear_all() + # clear all would invalidate run number and workspace number + self._run_number = int(run_number) + self._run_file_path = file_path + self._fext = fext + self._ws_name = self._build_ws_name() + else: # nothing to do, there is workspace, which corresponds to this run number + # and it may be already loaded (may be not). Just nullify run list + # in case of previous workspace name came from a list. + self._run_list = None - self._ws_cname = '' - self._ws_name = None - self._clear_old_ws(old_ws_name,None,clear_fext) #-------------------------------------------------------------------------------------------------------------------- + def _set_run_list(self,instance,run_list,file_path=None,fext=None): + + if self._run_list and self._run_list.check_runs_equal(run_list,file_path,fext): + return + else: + self._clear_all() + self._run_list = RunList(run_list,file_path,fext) + run_num,file_path,main_fext,ind = self._run_list.get_current_run_info(instance.sum_runs) + self._run_list.set_last_ind2sum(ind) + self._run_number = run_num + self._run_file_path = file_path + self._fext = main_fext + self._ws_name = self._build_ws_name() + def run_number(self): - """ Return run number regardless of workspace is loaded or not""" + """Return run number regardless of workspace is loaded or not""" if self._ws_name and self._ws_name in mtd: ws = mtd[self._ws_name] return ws.getRunNumber() else: return self._run_number +#-------------------------------------------------------------------------------------------------------------------- +# Masking +#-------------------------------------------------------------------------------------------------------------------- + def get_masking(self): + """Return masking workspace specific to this particular workspace + together with number of masked spectra + """ + if self._mask_ws_name: + mask_ws = mtd[self._mask_ws_name] + num_masked = mask_ws.getRun().getLogData('NUM_SPECTRA_Masked').value + return (mask_ws,num_masked) + else: + return (None,0) +#-------------------------------------------------------------------------------------------------------------------- + def add_masked_ws(self,masked_ws): + """Extract masking from the workspace provided and store masks + to use with this run workspace + """ + if self._mask_ws_name: + mask_ws = mtd[self._mask_ws_name] + num_masked = mask_ws.getRun().getLogData('NUM_SPECTRA_Masked').value + add_mask_name = self._prop_name + '_tmp_masking' + else: + num_masked = 0 + add_mask_name = self._prop_name + 'CurrentMasking' + masks,spectra = ExtractMask(InputWorkspace=masked_ws,OutputWorkspace=add_mask_name) + + num_masked+=len(spectra) + if self._mask_ws_name: + mask_ws +=masks + else: + self._mask_ws_name = add_mask_name + AddSampleLog(Workspace=self._mask_ws_name,LogName = 'NUM_SPECTRA_Masked',\ + LogText=str(num_masked),LogType='Number') #-------------------------------------------------------------------------------------------------------------------- def is_monws_separate(self): - """ """ + """Is monitor workspace is separated from data workspace or not""" mon_ws = self.get_monitors_ws() if mon_ws: name = mon_ws.name() @@ -161,29 +490,115 @@ def is_monws_separate(self): return False #-------------------------------------------------------------------------------------------------------------------- def get_run_list(self): - """ Returns list of the files, assigned to current property """ + """Returns list of the files, assigned to current property """ current_run = self.run_number() - if self._bind_to_sum: - runs = RunDescriptor._PropMan.sum_runs.get_runs() + if self._run_list: + runs = self._run_list.get_all_run_list() if current_run in runs: return runs else: return [current_run] else: - return [current_run] + return [current_run] +#-------------------------------------------------------------------------------------------------------------------- + def get_run_file_list(self): + """Returns list of the files, assigned to current property """ + + inst = RunDescriptor._holder.short_inst_name + fext = self.get_file_ext() + run_num = self.run_number() + current_run = build_run_file_name(run_num,inst,self._run_file_path,fext) + if self._run_list: + runs = self._run_list.get_all_run_list() + if run_num in runs: + runf = self._run_list.get_run_file_list(inst,fext) + return runf + else: + return [current_run] + else: + return [current_run] + +#-------------------------------------------------------------------------------------------------------------------- + @staticmethod + def get_sum_run_list(ws): + """Retrieve list of contributed run numbers from the sum workspace log""" + + summed_runs = [] + if RunDescriptor._sum_log_name in ws.getRun(): + summed_str = ws.getRun().getLogData(RunDescriptor._sum_log_name).value + run_nums = summed_str.split(',') + for run_str in run_nums: + summed_runs.append(int(run_str)) + else: + raise RuntimeError("Presumably sum workspace {0} does not have sum log attached to it".format(ws.name())) + return summed_runs +#-------------------------------------------------------------------------------------------------------------------- + def get_runs_to_sum(self,existing_sum_ws=None,num_files=None): + """ return list of runs, expected to be summed together + excluding the runs, already summed and added to cached sum workspace + """ + + if not RunDescriptor._holder.sum_runs: + return ([],None,0) + if not self._run_list: + return ([],None,0) + # + summed_runs = [] + if not existing_sum_ws: + existing_sum_ws = self._run_list.get_cashed_sum_ws() + if existing_sum_ws: + summed_runs = RunDescriptor.get_sum_run_list(existing_sum_ws) + n_existing_sums = len(summed_runs) + + runs2_sum = self._run_list.get_run_list2sum(num_files) + for run in summed_runs: + if run in runs2_sum: + del runs2_sum[runs2_sum.index(run)] + return (runs2_sum,existing_sum_ws,n_existing_sums) +#-------------------------------------------------------------------------------------------------------------------- + def find_run_files(self,run_list=None): + """Find run files correspondent to the run list provided + and set path to these files as new internal parameters + for the files in the list + + Returns True and empty list or False and + the list of the runs, which files were not found + or not belong to the existing run list. + """ + + if not self._run_list: + if not run_list: + return (True,[],[]) + else: + return (False,run_list,[]) + + if run_list: + existing = self._run_list.get_all_run_list() + non_existing = [] + for run in run_list: + if not(run in existing): + raise RuntimeError('run {0} is not in the existing run list'.format(run)) + + inst = RunDescriptor._holder.short_instr_name + default_fext = RunDescriptor._holder.data_file_ext + not_found,found = self._run_list.find_run_files(inst,run_list,default_fext) + if len(not_found) == 0: + return (True,[],found) + else: + return (False,not_found,found) #-------------------------------------------------------------------------------------------------------------------- def set_action_suffix(self,suffix=None): - """ method to set part of the workspace name, which indicate some action performed over this workspace + """Method to set part of the workspace name, which indicate some action performed over this workspace + e.g.: default suffix of a loaded workspace is 'RAW' but we can set it to SPE to show that conversion to + energy will be performed for this workspace. - e.g.: default suffix of a loaded workspace is 'RAW' but we can set it to SPE to show that conversion to - energy will be performed for this workspace. + method returns the name of the workspace is will have with this suffix. + Algorithms would later work on the initial workspace and modify it in-place or to produce workspace + with new name (depending if one wants to keep initial workspace) - method returns the name of the workspace is will have with this suffix. Algorithms would later - work on the initial workspace and modify it in-place or to produce workspace with new name (depending if one - wants to keep initial workspace) - synchronize_ws(ws_pointer) then should synchronize workspace and its name. + synchronize_ws(ws_pointer) then should synchronize workspace and its name. - TODO: This method should be automatically invoked by an algorithm decorator + TODO: This method should be automatically invoked by an algorithm decorator Until implemented, one have to ensure that it is correctly used together with synchronize_ws to ensue one can always get workspace from its name """ @@ -194,13 +609,13 @@ def set_action_suffix(self,suffix=None): return self._build_ws_name() #-------------------------------------------------------------------------------------------------------------------- def synchronize_ws(self,workspace=None): - """ Synchronize workspace name (after workspace may have changed due to algorithm) - with internal run holder name. Accounts for the situation when + """Synchronize workspace name (after workspace may have changed due to algorithm) + with internal run holder name. Accounts for the situation when - TODO: This method should be automatically invoked by an algorithm decorator - Until implemented, one have to ensure that it is correctly used together with - set_action_suffix to ensue one can always get expected workspace from its name - outside of a method visibility + TODO: This method should be automatically invoked by an algorithm decorator + Until implemented, one have to ensure that it is correctly used together with + set_action_suffix to ensue one can always get expected workspace from its name + outside of a method visibility """ if not workspace: workspace = mtd[self._ws_name] @@ -208,53 +623,33 @@ def synchronize_ws(self,workspace=None): new_name = self._build_ws_name() old_name = workspace.name() if new_name != old_name: - RenameWorkspace(InputWorkspace=old_name,OutputWorkspace=new_name) + RenameWorkspace(InputWorkspace=old_name,OutputWorkspace=new_name) - old_mon_name = old_name + '_monitors' - new_mon_name = new_name + '_monitors' - if old_mon_name in mtd: - RenameWorkspace(InputWorkspace=old_mon_name,OutputWorkspace=new_mon_name) + old_mon_name = old_name + '_monitors' + new_mon_name = new_name + '_monitors' + if old_mon_name in mtd: + RenameWorkspace(InputWorkspace=old_mon_name,OutputWorkspace=new_mon_name) self._ws_name = new_name -#-------------------------------------------------------------------------------------------------------------------- - def get_file_ext(self): - """ Method returns current file extension for file to load workspace from - e.g. .raw or .nxs extension - """ - if self._run_ext: - return self._run_ext - else: # return IDF default - return RunDescriptor._holder.data_file_ext -#-------------------------------------------------------------------------------------------------------------------- - def set_file_ext(self,val): - """ set non-default file extension """ - if isinstance(val,str): - if val[0] != '.': - value = '.' + val - else: - value = val - self._run_ext = value - else: - raise AttributeError('Source file extension can be only a string') #-------------------------------------------------------------------------------------------------------------------- @staticmethod - def _check_claibration_source(): - """ if user have not specified calibration as input to the script, - try to retrieve calibration stored in file with run properties""" - changed_prop = RunDescriptor._holder.getChangedProperties() - if 'det_cal_file' in changed_prop: - use_workspace_calibration = False - else: - use_workspace_calibration = True - return use_workspace_calibration + def _check_calibration_source(): + """If user have not specified calibration as input to the script, + try to retrieve calibration stored in file with run properties""" + changed_prop = RunDescriptor._holder.getChangedProperties() + if 'det_cal_file' in changed_prop: + use_workspace_calibration = False + else: + use_workspace_calibration = True + return use_workspace_calibration #-------------------------------------------------------------------------------------------------------------------- def get_workspace(self): - """ Method returns workspace correspondent to current run number(s) - and loads this workspace if it has not been loaded + """Method returns workspace correspondent to current run number(s) + and loads this workspace if it has not been loaded - Returns Mantid pointer to the workspace, corresponding to this run number + Returns Mantid pointer to the workspace, corresponding to this run number """ if not self._ws_name: - self._ws_name = self._build_ws_name() + self._ws_name = self._build_ws_name() if self._ws_name in mtd: @@ -262,32 +657,32 @@ def get_workspace(self): if ws.run().hasProperty("calibrated"): return ws # already calibrated else: - prefer_ws_calibration = self._check_claibration_source() - self.apply_calibration(ws,RunDescriptor._holder.det_cal_file,prefer_ws_calibration) - return ws + prefer_ws_calibration = self._check_calibration_source() + self.apply_calibration(ws,RunDescriptor._holder.det_cal_file,prefer_ws_calibration) + return ws else: - if self._run_number: - prefer_ws_calibration = self._check_claibration_source() - inst_name = RunDescriptor._holder.short_inst_name - calibration = RunDescriptor._holder.det_cal_file - if self._bind_to_sum and RunDescriptor._holder.sum_runs : # Sum runs - ws = RunDescriptor._PropMan.sum_runs.load_and_sum_runs(inst_name,RunDescriptor._holder.load_monitors_with_workspace) - else: # load current workspace - ws = self.load_run(inst_name, calibration,False, RunDescriptor._holder.load_monitors_with_workspace,prefer_ws_calibration) - - - self.synchronize_ws(ws) - self.apply_calibration(ws,calibration,prefer_ws_calibration) - - return ws - else: - return None + if self._run_number: + prefer_ws_calibration = self._check_calibration_source() + inst_name = RunDescriptor._holder.short_inst_name + calibration = RunDescriptor._holder.det_cal_file + if self._run_list and RunDescriptor._holder.sum_runs : # Sum runs + ws = self._load_and_sum_runs(inst_name,RunDescriptor._holder.load_monitors_with_workspace) + else: # load current workspace + ws = self.load_run(inst_name, calibration,False, RunDescriptor._holder.load_monitors_with_workspace,prefer_ws_calibration) + + + self.synchronize_ws(ws) + self.apply_calibration(ws,calibration,prefer_ws_calibration) + + return ws + else: + return None #-------------------------------------------------------------------------------------------------------------------- def get_ws_clone(self,clone_name='ws_clone'): - """ Get unbounded clone of eisting Run workspace """ + """Get unbounded clone of existing Run workspace""" ws = self.get_workspace() CloneWorkspace(InputWorkspace=ws,OutputWorkspace=clone_name) - mon_ws_name = self.get_ws_name() + '_monitors' + mon_ws_name = ws.name() + '_monitors' if mon_ws_name in mtd: cl_mon_name = clone_name + '_monitors' CloneWorkspace(InputWorkspace=mon_ws_name,OutputWorkspace=cl_mon_name) @@ -295,42 +690,43 @@ def get_ws_clone(self,clone_name='ws_clone'): return mtd[clone_name] #-------------------------------------------------------------------------------------------------------------------- def _set_ws_as_source(self,value): - """ assign all parts of the run if input value is workspace """ + """Assign all parts of the run if input value is workspace""" self._run_number = value.getRunNumber() ws_name = value.name() - self._ws_suffix='' + self._ws_suffix = '' self._split_ws_name(ws_name) self.synchronize_ws(value) #-------------------------------------------------------------------------------------------------------------------- def chop_ws_part(self,origin,tof_range,rebin,chunk_num,n_chunks): - """ chop part of the original workspace and sets it up as new original. - Return the old one """ + """Chop part of the original workspace and sets it up to this run as new original + Return the pointer to workspace being chopped + """ if not origin: - origin = self.get_workspace() + origin = self.get_workspace() origin_name = origin.name() try: - mon_ws = mtd[origin_name+'_monitors'] + mon_ws = mtd[origin_name + '_monitors'] except: - mon_ws = None + mon_ws = None - target_name = '#{0}/{1}#'.format(chunk_num,n_chunks)+origin_name + target_name = '#{0}/{1}#'.format(chunk_num,n_chunks) + origin_name if chunk_num == n_chunks: - RenameWorkspace(InputWorkspace=origin_name,OutputWorkspace=target_name) - if mon_ws: - RenameWorkspace(InputWorkspace=mon_ws,OutputWorkspace=target_name+'_monitors') - origin_name = target_name - origin_invalidated=True + RenameWorkspace(InputWorkspace=origin_name,OutputWorkspace=target_name) + if mon_ws: + RenameWorkspace(InputWorkspace=mon_ws,OutputWorkspace=target_name + '_monitors') + origin_name = target_name + origin_invalidated = True else: - if mon_ws: - CloneWorkspace(InputWorkspace=mon_ws,OutputWorkspace=target_name+'_monitors') - origin_invalidated=False + if mon_ws: + CloneWorkspace(InputWorkspace=mon_ws,OutputWorkspace=target_name + '_monitors') + origin_invalidated = False if rebin: # debug and compatibility mode with old reduction - Rebin(origin_name,OutputWorkspace=target_name,Params=[tof_range[0],tof_range[1],tof_range[2]],PreserveEvents=False) + Rebin(origin_name,OutputWorkspace=target_name,Params=[tof_range[0],tof_range[1],tof_range[2]],PreserveEvents=False) else: - CropWorkspace(origin_name,OutputWorkspace=target_name,XMin=tof_range[0],XMax=tof_range[2]) + CropWorkspace(origin_name,OutputWorkspace=target_name,XMin=tof_range[0],XMax=tof_range[2]) self._set_ws_as_source(mtd[target_name]) if origin_invalidated: @@ -340,14 +736,16 @@ def chop_ws_part(self,origin,tof_range,rebin,chunk_num,n_chunks): #-------------------------------------------------------------------------------------------------------------------- def get_monitors_ws(self,monitor_ID=None): - """ get pointer to a workspace containing monitors. + """Get pointer to a workspace containing monitors. Explores different ways of finding monitor workspace in Mantid and returns the python pointer to the workspace which contains monitors. """ data_ws = self.get_workspace() + if not data_ws: + return None - monWS_name = self.get_ws_name() + '_monitors' + monWS_name = data_ws.name() + '_monitors' if monWS_name in mtd: mon_ws = mtd[monWS_name] monitors_separate = True @@ -361,62 +759,77 @@ def get_monitors_ws(self,monitor_ID=None): mon_ws = self.copy_spectrum2monitors(data_ws,mon_ws,specID) if monitor_ID: - try: + try: ws_index = mon_ws.getIndexFromSpectrumNumber(monitor_ID) - except: # - mon_ws = None + except: # + mon_ws = None else: mon_list = self._holder.get_used_monitors_list() for monID in mon_list: try: ws_ind = mon_ws.getIndexFromSpectrumNumber(int(monID)) except: - mon_ws = None - break + mon_ws = None + break return mon_ws #-------------------------------------------------------------------------------------------------------------------- - def get_ws_name(self): - """ return workspace name. If ws name is not defined, build it first and set up as the target ws name - """ + def is_existing_ws(self): + """Method verifies if property value relates to workspace, present in ADS""" if self._ws_name: if self._ws_name in mtd: - return self._ws_name + return True else: - raise RuntimeError('Getting workspace name {0} for undefined workspace. Run get_workspace first'.format(self._ws_name)) - - self._ws_name = self._build_ws_name() - return self._ws_name + return False + else: + return False +#-------------------------------------------------------------------------------------------------------------------- #-------------------------------------------------------------------------------------------------------------------- + def get_file_ext(self): + """Method returns current file extension for file to load workspace from + e.g. .raw or .nxs extension + """ + if self._fext and len(self._fext) > 0: + return self._fext + else: # return IDF default + return RunDescriptor._holder.data_file_ext +#-------------------------------------------------------------------------------------------------------------------- + def set_file_ext(self,val): + """Set non-default file extension """ + if isinstance(val,str): + if val[0] != '.': + value = '.' + val + else: + value = val + self._fext = value + else: + raise AttributeError('Source file extension can be only a string') + def file_hint(self,run_num_str=None,filePath=None,fileExt=None,**kwargs): - """ procedure to provide run file guess name from run properties + """Procedure to provide run file guess name from run properties - main purpose -- to support customized order of file extensions + main purpose -- to support customized order of file extensions """ if not run_num_str: - run_num_str = str(self.run_number()) - - + run_num_str = str(self.run_number()) inst_name = RunDescriptor._holder.short_inst_name + if 'file_hint' in kwargs: hint = kwargs['file_hint'] fname,old_ext = os.path.splitext(hint) if len(old_ext) == 0: old_ext = self.get_file_ext() else: - if fileExt: - old_ext = fileExt - else: - old_ext = self.get_file_ext() - - hint = inst_name + run_num_str + old_ext - if not filePath: + old_ext = self._fext + if fileExt is None: + fileExt = self.get_file_ext() + if filePath is None: filePath = self._run_file_path - if os.path.exists(filePath): - hint = os.path.join(filePath,hint) - if os.path.exists(hint): - return hint,old_ext + fname = build_run_file_name(run_num_str,inst_name,filePath,fileExt) + + if os.path.exists(fname): + return fname,old_ext else: - fp,hint = os.path.split(hint) + fp,hint = os.path.split(fname) return hint,old_ext #-------------------------------------------------------------------------------------------------------------------- @@ -436,40 +849,40 @@ def find_file(self,inst_name=None,run_num=None,filePath=None,fileExt=None,**kwar try: file = FileFinder.findRuns(file_hint)[0] fname,fex = os.path.splitext(file) - self._run_ext = fex + self._fext = fex if old_ext != fex: - message = ' Cannot find run-file with extension {0}.\n'\ - ' Found file {1} instead'.format(old_ext,file) + message = '*** Cannot find run-file with extension {0}.\n'\ + ' Found file {1} instead'.format(old_ext,file) RunDescriptor._logger(message,'notice') self._run_file_path = os.path.dirname(fname) - return file + return (True,file) except RuntimeError: - message = 'Cannot find file matching hint {0} on current search paths ' \ - 'for instrument {1}'.format(file_hint,inst_name) + message = '*** Cannot find file matching hint {0} on Mantid search paths '.\ + format(file_hint) if not 'be_quet' in kwargs: RunDescriptor._logger(message,'warning') - return 'ERROR:find_file: ' + message + return (False,message) #-------------------------------------------------------------------------------------------------------------------- def load_file(self,inst_name,ws_name,run_number=None,load_mon_with_workspace=False,filePath=None,fileExt=None,**kwargs): - """ load run for the instrument name provided. If run_numner is None, look for the current run""" + """Load run for the instrument name provided. If run_numner is None, look for the current run""" - data_file = self.find_file(None,filePath,fileExt,**kwargs) - if data_file.find('ERROR') > -1: - self._ws_name = None - raise IOError(data_file) + ok,data_file = self.find_file(None,filePath,fileExt,**kwargs) + if not ok: + self._ws_name = None + raise IOError(data_file) if load_mon_with_workspace: - mon_load_option = 'Include' + mon_load_option = 'Include' else: - mon_load_option = 'Separate' + mon_load_option = 'Separate' # try: # Hack: LoadEventNexus does not understand Separate at the moment and throws. # And event loader always loads monitors separately - Load(Filename=data_file, OutputWorkspace=ws_name,LoadMonitors = mon_load_option) + Load(Filename=data_file, OutputWorkspace=ws_name,LoadMonitors = mon_load_option) except ValueError: #mon_load_option =str(int(load_mon_with_workspace)) - Load(Filename=data_file, OutputWorkspace=ws_name,LoadMonitors = '1',MonitorsAsEvents='0') + Load(Filename=data_file, OutputWorkspace=ws_name,LoadMonitors = '1',MonitorsAsEvents='0') RunDescriptor._logger("Loaded {0}".format(data_file),'information') @@ -490,11 +903,7 @@ def load_run(self,inst_name, calibration=None, force=False, mon_load_option=Fals ws_name = kwargs['ws_name'] del kwargs['ws_name'] else: - try: - ws_name = self.get_ws_name() - except RuntimeError: - self._ws_name = None - ws_name = self.get_ws_name() + ws_name = self._build_ws_name() #----------------------------------- if ws_name in mtd and not force: RunDescriptor._logger("{0} already loaded as workspace.".format(ws_name),'information') @@ -507,16 +916,16 @@ def load_run(self,inst_name, calibration=None, force=False, mon_load_option=Fals return loaded_ws #-------------------------------------------------------------------------------------------------------------------- def apply_calibration(self,loaded_ws,calibration=None,use_ws_calibration=True): - """ If calibration is present, apply it to the workspace + """If calibration is present, apply it to the workspace - use_ws_calibration -- if true, retrieve workspace property, which defines - calibration option (e.g. det_cal_file used a while ago) and try to use it + use_ws_calibration -- if true, retrieve workspace property, which defines + calibration option (e.g. det_cal_file used a while ago) and try to use it """ - if not (calibration or use_ws_calibration): + if not calibration or use_ws_calibration: return if not isinstance(loaded_ws, api.Workspace): - raise RuntimeError(' Calibration can be applied to a workspace only and got object of type {0}'.format(type(loaded_ws))) + raise RuntimeError(' Calibration can be applied to a workspace only and got object of type {0}'.format(type(loaded_ws))) if loaded_ws.run().hasProperty("calibrated"): return # already calibrated @@ -533,7 +942,7 @@ def apply_calibration(self,loaded_ws,calibration=None,use_ws_calibration=True): test_name = ws_calibration ws_calibration = FileFinder.getFullPath(ws_calibration) if len(ws_calibration) == 0: - raise RuntimeError('Can not find defined in run {0} calibration file {1}\n'\ + raise RuntimeError('Can not find defined in run {0} calibration file {1}\n'\ 'Define det_cal_file reduction parameter properly'.format(loaded_ws.name(),test_name)) RunDescriptor._logger('*** load_data: Calibrating data using workspace defined calibration file: {0}'.format(ws_calibration),'notice') except KeyError: # no det_cal_file defined in workspace @@ -561,24 +970,24 @@ def copy_spectrum2monitors(data_ws,mon_ws,spectraID): @param mon_ws -- the histogram workspace with monitors where one needs to place the detector's spectra @param spectraID-- the ID of the spectra to copy. - """ + """ - # ---------------------------- + # ---------------------------- try: ws_index = mon_ws.getIndexFromSpectrumNumber(spectraID) - # Spectra is already in the monitor workspace + # Spectra is already in the monitor workspace return mon_ws except: ws_index = data_ws.getIndexFromSpectrumNumber(spectraID) - # + # x_param = mon_ws.readX(0) bins = [x_param[0],x_param[1] - x_param[0],x_param[-1]] ExtractSingleSpectrum(InputWorkspace=data_ws,OutputWorkspace='tmp_mon',WorkspaceIndex=ws_index) Rebin(InputWorkspace='tmp_mon',OutputWorkspace='tmp_mon',Params=bins,PreserveEvents='0') - # should be vice versa but Conjoin invalidate ws pointers and hopefully - # nothing could happen with workspace during conjoining - #AddSampleLog(Workspace=monWS,LogName=done_log_name,LogText=str(ws_index),LogType='Number') + # should be vice versa but Conjoin invalidate ws pointers and hopefully + # nothing could happen with workspace during conjoining + #AddSampleLog(Workspace=monWS,LogName=done_log_name,LogText=str(ws_index),LogType='Number') mon_ws_name = mon_ws.getName() ConjoinWorkspaces(InputWorkspace1=mon_ws,InputWorkspace2='tmp_mon') mon_ws = mtd[mon_ws_name] @@ -589,22 +998,49 @@ def copy_spectrum2monitors(data_ws,mon_ws,spectraID): #-------------------------------------------------------------------------------------------------------------------- def clear_monitors(self): """ method removes monitor workspace form analysis data service if it is there - (assuming it is not needed any more) """ monWS_name = self._ws_name + '_monitors' if monWS_name in mtd: DeleteWorkspace(monWS_name) - #-------------------------------------------------------------------------------------------------------------------- + def clear_resulting_ws(self): + """Remove workspace from memory as if it has not been processed + and clear all operations indicators except cashes and run lists. - def _build_ws_name(self): + Attempt to get workspace for a file based run should in this case + load workspace again + """ + ws_name = self._ws_name + mon_name = ws_name + '_monitors' + self._ws_name = '' + self._ws_cname = '' + self._ws_suffix = '' + if ws_name in mtd: + ws = mtd[ws_name] + self._run_number = ws.getRunNumber() + DeleteWorkspace(ws_name) + if mon_name in mtd: + DeleteWorkspace(mon_name) + if self._run_list: + ind = self._run_list.add_or_replace_run(self._run_number) + self._run_file_path = self._run_list._file_path[ind] + self._fext = self._run_list._fext[ind] +#-------------------------------------------------------------------------------------------------------------------- + + def _build_ws_name(self,sum_runs=None): instr_name = self._instr_name() + if self._run_list: + if not sum_runs: + sum_runs = RunDescriptor._holder.sum_runs + sum_ext = self._run_list.sum_ext(sum_runs) + else: + sum_ext = '' - sum_ext = RunDescriptor._PropMan.sum_runs.sum_ext() if self._run_number: - ws_name = '{0}{1}{2}{3:0>#6d}{4}{5}'.format(self._prop_name,instr_name,self._ws_cname,self._run_number,sum_ext,self._ws_suffix) + ws_name = '{0}{1}{2}{3:0>#6d}{4}{5}'.format(self._prop_name,instr_name,self._ws_cname,self._run_number,\ + sum_ext,self._ws_suffix) else: ws_name = '{0}{1}{2}{3}'.format(self._prop_name,self._ws_cname,sum_ext,self._ws_suffix) @@ -617,30 +1053,33 @@ def rremove(thestr, trailing): return thestr[:-thelen] return thestr def _split_ws_name(self,ws_name): - """ Method to split existing workspace name - into parts, in such a way that _build_name would restore the same name + """Method to split existing workspace name + into parts, in such a way that _build_name would restore the same name """ # Remove suffix name = self.rremove(ws_name,self._ws_suffix) - sumExt = RunDescriptor._PropMan.sum_runs.sum_ext() + if self._run_list: + summed = RunDescriptor._holder.sum_runs + sumExt = self._run_list.sum_ext(summed) + else: + sumExt = '' if len(sumExt) > 0: name = self.rremove(ws_name,sumExt) # remove _prop_name: name = name.replace(self._prop_name,'',1) try: - part_ind = re.search('#(.+?)#', name).group(0) - name =name.replace(part_ind,'',1) + part_ind = re.search('#(.+?)#', name).group(0) + name = name.replace(part_ind,'',1) except AttributeError: - part_ind='' + part_ind = '' if self._run_number: instr_name = self._instr_name() name = name.replace(instr_name,'',1) - self._ws_cname = part_ind+filter(lambda c: not c.isdigit(), name) - + self._ws_cname = part_ind + filter(lambda c: not c.isdigit(), name) else: - self._ws_cname = part_ind+name + self._ws_cname = part_ind + name # def _instr_name(self): if RunDescriptor._holder: @@ -649,56 +1088,285 @@ def _instr_name(self): instr_name = '_test_instrument' return instr_name - def _clear_old_ws(self,old_ws_name,new_name,clear_fext=False): - """ helper method used in __set__. When new data (run or wod) """ - if old_ws_name: - if new_name != old_ws_name: - if old_ws_name in mtd: - DeleteWorkspace(old_ws_name) - old_mon_ws = old_ws_name + '_monitors' - if old_mon_ws in mtd: - DeleteWorkspace(old_mon_ws) - if clear_fext: - self._run_ext = None - self._run_file_path = '' + def has_own_value(self): + """Interface property used to verify if + the class got its own values or been shadowed by + property, this one depends on + """ + return not(self._in_cash) + + def notify_sum_runs_changed(self,old_value,new_value): + """ Take actions on changes to sum_runs option + """ + if self._run_list: + if old_value != new_value: + rl = self._run_list + self._clear_all() + rl.set_last_ind2sum(-1) # this will reset index to default + self._run_list = rl + run_num,file_path,main_fext,ind = self._run_list.get_current_run_info(new_value) + self._run_list.set_last_ind2sum(ind) + self._run_number = run_num + self._run_file_path = file_path + self._fext = main_fext + self._ws_name = self._build_ws_name(new_value) + if new_value is False: + self._run_list.del_cashed_sum() + + def _load_and_sum_runs(self,inst_name,monitors_with_ws): + """Load multiple runs and sum them together + + monitors_with_ws -- if true, load monitors with workspace + """ + + RunDescriptor._logger("*** Summing multiple runs ****") + + runs_to_sum,sum_ws,n_already_summed = self.get_runs_to_sum() + num_to_sum = len(runs_to_sum) + + if sum_ws: + RunDescriptor._logger("*** Use cached sum of {0} workspaces and adding {1} remaining".\ + format(n_already_summed,num_to_sum)) + sum_ws_name = sum_ws.name() + sum_mon_name = sum_ws_name + '_monitors' + AddedRunNumbers = sum_ws.getRun().getLogData(RunDescriptor._sum_log_name).value + load_start = 0 + else: + RunDescriptor._logger("*** Loading #{0}/{1}, run N: {2} ".\ + format(1,num_to_sum,runs_to_sum[0])) + + f_guess,index = self._run_list.get_file_guess(inst_name,runs_to_sum[0]) + ws = self.load_file(inst_name,'Sum_ws',False,monitors_with_ws, + False,file_hint=f_guess) + + sum_ws_name = ws.name() + sum_mon_name = sum_ws_name + '_monitors' + #AddedRunNumbers = [ws.getRunNumber()] + AddedRunNumbers = str(ws.getRunNumber()) + load_start = 1 + #end + + for ind,run_num in enumerate(runs_to_sum[load_start:num_to_sum]): + + RunDescriptor._logger("*** Adding #{0}/{1}, run N: {2} ".\ + format(ind + 1 + load_start,num_to_sum,run_num)) + + term_name = '{0}_ADDITIVE_#{1}/{2}'.format(inst_name,ind + 1 + load_start,num_to_sum)# + f_guess,index = self._run_list.get_file_guess(inst_name,run_num) + + wsp = self.load_file(inst_name,term_name,False, + monitors_with_ws,False,file_hint=f_guess) + + wsp_name = wsp.name() + wsp_mon_name = wsp_name + '_monitors' + Plus(LHSWorkspace=sum_ws_name,RHSWorkspace=wsp_name, + OutputWorkspace=sum_ws_name,ClearRHSWorkspace=True) + # AddedRunNumbers.append(run_num) + AddedRunNumbers+=',' + str(run_num) + if not monitors_with_ws: + Plus(LHSWorkspace=sum_mon_name,RHSWorkspace=wsp_mon_name, + OutputWorkspace=sum_mon_name,ClearRHSWorkspace=True) + if wsp_name in mtd: + DeleteWorkspace(wsp_name) + if wsp_mon_name in mtd: + DeleteWorkspace(wsp_mon_name) + #end for + RunDescriptor._logger("*** Summing multiple runs completed ****") + + #AddSampleLog(Workspace=sum_ws_name,LogName = + #RunDescriptor._sum_log_name, + # LogText=AddedRunNumbers,LogType='Number Series') + AddSampleLog(Workspace=sum_ws_name,LogName = RunDescriptor._sum_log_name, + LogText=AddedRunNumbers,LogType='String') + + if RunDescriptor._holder.cashe_sum_ws: + # store workspace in cash for further usage + self._run_list.set_cashed_sum_ws(mtd[sum_ws_name],self._prop_name + 'Sum_ws') + ws = self._run_list.get_cashed_sum_clone() + else: + ws = mtd[sum_ws_name] + return ws #------------------------------------------------------------------------------------------------------------------------------- #------------------------------------------------------------------------------------------------------------------------------- #------------------------------------------------------------------------------------------------------------------------------- class RunDescriptorDependent(RunDescriptor): - """ Simple RunDescriptor class dependent on another RunDescriptor, - providing the host descriptor if current descriptor value is not defined - or usual descriptor functionality if somebody sets current descriptor up + """Simple RunDescriptor class dependent on another RunDescriptor, + providing the host descriptor if current descriptor value is not defined + or usual descriptor functionality if somebody sets current descriptor up """ def __init__(self,host_run,ws_preffix,DocString=None): RunDescriptor.__init__(self,ws_preffix,DocString) self._host = host_run - self._this_run_defined = False + self._has_own_value = False def __get__(self,instance,owner=None): - """ return dependent run number which is host run number if this one has not been set or this run number if it was""" - if self._this_run_defined: - if instance is None: - return self - else: - return super(RunDescriptorDependent,self).__get__(instance,owner) + """Return dependent run number which is host run number if this one has not been set + or this run number if it was + """ + if instance is None: # this class functions and the host functions + return self + + if self._has_own_value: # this allows to switch between + return super(RunDescriptorDependent,self).__get__(instance,owner) else: return self._host.__get__(instance,owner) + def __set__(self,instance,value): if value is None: - self._this_run_defined = False + self._has_own_value = False return - self._this_run_defined = True + self._has_own_value = True super(RunDescriptorDependent,self).__set__(instance,value) - #def __del__(self): - # # destructor removes bounded workspace - # # Probably better not to at current approach - # if self._ws_name in mtd: - # DeleteWorkspace(self._ws_name) - # object.__del__(self) + def has_own_value(self): + """Interface property used to verify if + the class got its own values or been shadowed by + property, this one depends on + """ + return self._has_own_value + #-------------------------------------------------------------- + # TODO -- how to automate all these functions below? + def run_number(self): + if self._has_own_value: + return super(RunDescriptorDependent,self).run_number() + else: + return self._host.run_number() + # + def is_monws_separate(self): + if self._has_own_value: + return super(RunDescriptorDependent,self).is_monws_separate() + else: + return self._host.is_monws_separate() + + def get_run_files_list(self): + if self._has_own_value: + return super(RunDescriptorDependent,self).get_run_files_list() + else: + return self._host.get_run_files_list() + + def get_run_list(self): + if self._has_own_value: + return super(RunDescriptorDependent,self).get_run_list() + else: + return self._host.get_run_list() + + + def set_action_suffix(self,suffix=None): + if self._has_own_value: + return super(RunDescriptorDependent,self).set_action_suffix(suffix) + else: + return self._host.set_action_suffix(suffix) + + def synchronize_ws(self,workspace=None): + if self._has_own_value: + return super(RunDescriptorDependent,self).synchronize_ws(workspace) + else: + return self._host.synchronize_ws(workspace) + + def get_file_ext(self): + if self._has_own_value: + return super(RunDescriptorDependent,self).get_file_ext() + else: + return self._host.get_file_ext() + + def set_file_ext(self,val): + if self._has_own_value: + return super(RunDescriptorDependent,self).set_file_ex(val) + else: + return self._host.set_file_ex(val) + + def get_workspace(self): + if self._has_own_value: + return super(RunDescriptorDependent,self).get_workspace() + else: + return self._host.get_workspace() + + def get_ws_clone(self,clone_name='ws_clone'): + if self._has_own_value: + return super(RunDescriptorDependent,self).get_ws_clone() + else: + return self._host.get_ws_clone() + + def chop_ws_part(self,origin,tof_range,rebin,chunk_num,n_chunks): + if self._has_own_value: + return super(RunDescriptorDependent,self).chop_ws_part(origin,tof_range,rebin,chunk_num,n_chunks) + else: + return self._host.chop_ws_part(origin,tof_range,rebin,chunk_num,n_chunks) + + def get_monitors_ws(self,monitor_ID=None): + if self._has_own_value: + return super(RunDescriptorDependent,self).get_monitors_ws(monitor_ID) + else: + return self._host.get_monitors_ws(monitor_ID) + + def is_existing_ws(self): + if self._has_own_value: + return super(RunDescriptorDependent,self).is_existing_ws() + else: + return self._host.is_existing_ws() + + def file_hint(self,run_num_str=None,filePath=None,fileExt=None,**kwargs): + if self._has_own_value: + return super(RunDescriptorDependent,self).file_hint(run_num_str,filePath,fileExt,**kwargs) + else: + return self._host.file_hint(run_num_str,filePath,fileExt,**kwargs) + + def find_file(self,inst_name=None,run_num=None,filePath=None,fileExt=None,**kwargs): + if self._has_own_value: + return super(RunDescriptorDependent,self).find_file(inst_name,run_num,filePath,fileExt,**kwargs) + else: + return self._host.find_file(inst_name,run_num,filePath,fileExt,**kwargs) + + def load_file(self,inst_name,ws_name,run_number=None,load_mon_with_workspace=False,filePath=None,fileExt=None,**kwargs): + if self._has_own_value: + return super(RunDescriptorDependent,self).load_file(inst_name,ws_name,run_number,load_mon_with_workspace,filePath,fileExt,**kwargs) + else: + return self._host.load_file(inst_name,ws_name,run_number,load_mon_with_workspace,filePath,fileExt,**kwargs) + + def load_run(self,inst_name, calibration=None, force=False, mon_load_option=False,use_ws_calibration=True,\ + filePath=None,fileExt=None,**kwargs): + if self._has_own_value: + return super(RunDescriptorDependent,self).load_run(inst_name,calibration, force, mon_load_option,use_ws_calibration,\ + filePath,fileExt,**kwargs) + else: + return self._host.load_run(inst_name,calibration, force, mon_load_option,use_ws_calibration,\ + filePath,fileExt,**kwargs) + + def apply_calibration(self,loaded_ws,calibration=None,use_ws_calibration=True): + if self._has_own_value: + return super(RunDescriptorDependent,self).apply_calibration(loaded_ws,calibration,use_ws_calibration) + else: + return self._host.apply_calibration(loaded_ws,calibration,use_ws_calibration) + + def clear_monitors(self): + if self._has_own_value: + return super(RunDescriptorDependent,self).clear_monitors() + else: + return self._host.clear_monitors() + def get_masking(self): + if self._has_own_value: + return super(RunDescriptorDependent,self).get_masking() + else: + return self._host.get_masking() + def add_masked_ws(self,masked_ws): + if self._has_own_value: + return super(RunDescriptorDependent,self).add_masked_ws(masked_ws) + else: + return self._host.add_masked_ws(masked_ws) +#-------------------------------------------------------------------------------------------------------------------- +#-------------------------------------------------------------------------------------------------------------------- +def build_run_file_name(run_num,inst,file_path='',fext=''): + """Build the full name of a runfile from all possible components""" + if fext is None: + fext = '' + fname = '{0}{1}{2}'.format(inst,run_num,fext) + if not file_path is None: + if os.path.exists(file_path): + fname = os.path.join(file_path,fname) + return fname + - diff --git a/Code/Mantid/scripts/Inelastic/Direct/dgreduce.py b/Code/Mantid/scripts/Inelastic/Direct/dgreduce.py index 9b4c61b5bcc3..fd1318c9e670 100644 --- a/Code/Mantid/scripts/Inelastic/Direct/dgreduce.py +++ b/Code/Mantid/scripts/Inelastic/Direct/dgreduce.py @@ -240,10 +240,10 @@ def abs_units(wb_for_run,sample_run,monovan_run,wb_for_monovanadium,samp_rmm,sam if sample_run: Reducer.sample_run = sample_run + try: n,r=funcreturns.lhs_info('both') results_name=r[0] - except: results_name = Reducer.prop_man.get_sample_ws_name() if wb_for_run == wb_for_monovanadium: # wb_for_monovanadium property does not accept duplicated workspace diff --git a/Code/Mantid/scripts/Inelastic/Direct/diagnostics.py b/Code/Mantid/scripts/Inelastic/Direct/diagnostics.py index 76ba5a12bb48..1891c01c73c8 100644 --- a/Code/Mantid/scripts/Inelastic/Direct/diagnostics.py +++ b/Code/Mantid/scripts/Inelastic/Direct/diagnostics.py @@ -68,40 +68,63 @@ def diagnose(white_int,**kwargs): # Hard mask hardmask_file = kwargs.get('hard_mask_file', None) - if hardmask_file is not None: + + # process subsequent calls to this routine, when white mask is already defined + white= kwargs.get('white_mask',None) # and white beam is not changed + # white mask assumed to be global so no sectors in there + if not(white is None) and isinstance(white,RunDescriptor.RunDescriptor): + hardmask_file = None + white_mask,num_failed = white.get_masking() + add_masking(white_int, white_mask) + van_mask = None + else: # prepare workspace to keep white mask + white_mask = None + van_mask = CloneWorkspace(white_int) + + if not (hardmask_file is None): LoadMask(Instrument=kwargs.get('instr_name',''),InputFile=parser.hard_mask_file, OutputWorkspace='hard_mask_ws') MaskDetectors(Workspace=white_int, MaskedWorkspace='hard_mask_ws') + MaskDetectors(Workspace=van_mask, MaskedWorkspace='hard_mask_ws') # Find out how many detectors we hard masked _dummy_ws,masked_list = ExtractMask(InputWorkspace='hard_mask_ws') DeleteWorkspace('_dummy_ws') test_results[0][0] = os.path.basename(parser.hard_mask_file) test_results[0][1] = len(masked_list) + DeleteWorkspace('hard_mask_ws') if not parser.use_hard_mask_only : - # White beam Test - __white_masks, num_failed = do_white_test(white_int, parser.tiny, parser.huge, - parser.van_out_lo, parser.van_out_hi, - parser.van_lo, parser.van_hi, - parser.van_sig, start_index, end_index) - test_results[1] = [str(__white_masks), num_failed] - add_masking(white_int, __white_masks, start_index, end_index) - DeleteWorkspace(__white_masks) - - # Second white beam test - if 'second_white' in kwargs: - __second_white_masks, num_failed = do_second_white_test(white_int, parser.second_white, parser.tiny, parser.huge,\ + # White beam Test + if white_mask: + test_results[1] = ['white_mask cache global', num_failed] + else: + __white_masks, num_failed = do_white_test(white_int, parser.tiny, parser.huge, + parser.van_out_lo, parser.van_out_hi, + parser.van_lo, parser.van_hi, + parser.van_sig, start_index, end_index) + test_results[1] = [str(__white_masks), num_failed] + add_masking(white_int, __white_masks, start_index, end_index) + if van_mask: + add_masking(van_mask, __white_masks, start_index, end_index) + DeleteWorkspace(__white_masks) + + # Second white beam test + if 'second_white' in kwargs: #NOT IMPLEMENTED + raise NotImplementedError("Second white is not yet implemented") + __second_white_masks, num_failed = do_second_white_test(white_int, parser.second_white, parser.tiny, parser.huge,\ parser.van_out_lo, parser.van_out_hi,\ parser.van_lo, parser.van_hi, parser.variation,\ parser.van_sig, start_index, end_index) - test_results[2] = [str(__second_white_masks), num_failed] - add_masking(white_int, __second_white_masks, start_index, end_index) + test_results[2] = [str(__second_white_masks), num_failed] + add_masking(white_int, __second_white_masks, start_index, end_index) + #TODO + #add_masking(van_mask, __second_white_masks, start_index, end_index) # # Zero total count check for sample counts # - zero_count_failures = 0 - if kwargs.get('sample_counts',None) is not None and kwargs.get('samp_zero',False): + zero_count_failures = 0 + if kwargs.get('sample_counts',None) is not None and kwargs.get('samp_zero',False): add_masking(parser.sample_counts, white_int) maskZero, zero_count_failures = FindDetectorsOutsideLimits(InputWorkspace=parser.sample_counts,\ StartWorkspaceIndex=start_index, EndWorkspaceIndex=end_index,\ @@ -112,10 +135,10 @@ def diagnose(white_int,**kwargs): # # Background check # - if hasattr(parser, 'background_int'): + if hasattr(parser, 'background_int'): add_masking(parser.background_int, white_int) __bkgd_mask, failures = do_background_test(parser.background_int, parser.samp_lo,\ - parser.samp_hi, parser.samp_sig, parser.samp_zero, start_index, end_index) + parser.samp_hi, parser.samp_sig, parser.samp_zero, start_index, end_index) test_results[3] = [str(__bkgd_mask), zero_count_failures + failures] add_masking(white_int, __bkgd_mask, start_index, end_index) DeleteWorkspace(__bkgd_mask) @@ -123,7 +146,7 @@ def diagnose(white_int,**kwargs): # # Bleed test # - if hasattr(parser, 'bleed_test') and parser.bleed_test: + if hasattr(parser, 'bleed_test') and parser.bleed_test: if not hasattr(parser, 'sample_run'): raise RuntimeError("Bleed test requested but the sample_run keyword has not been provided") __bleed_masks, failures = do_bleed_test(parser.sample_run, parser.bleed_maxrate, parser.bleed_pixels) @@ -135,21 +158,22 @@ def diagnose(white_int,**kwargs): end_index_name=" to: end" default = True if hasattr(parser, 'print_diag_results') and parser.print_diag_results: - default=True + default=True if 'start_index' in kwargs: - default = False - start_index_name = "from: "+str(kwargs['start_index']) + default = False + start_index_name = "from: "+str(kwargs['start_index']) if 'end_index' in kwargs : - default = False - end_index_name = " to: "+str(kwargs['end_index']) + default = False + end_index_name = " to: "+str(kwargs['end_index']) testName=start_index_name+end_index_name if not default : - testName = " For bank: "+start_index_name+end_index_name + testName = " For bank: "+start_index_name+end_index_name if hasattr(parser, 'print_diag_results') and parser.print_diag_results: print_test_summary(test_results,testName) + return van_mask #------------------------------------------------------------------------------- @@ -325,11 +349,11 @@ def do_bleed_test(sample_run, max_framerate, ignored_pixels): if __Reducer__: # Try to use generic loader which would work with files or workspaces alike sample_run = __Reducer__.get_run_descriptor(sample_run) data_ws = sample_run.get_workspace() # this will load data if necessary - ws_name = sample_run.get_ws_name()+'_bleed' + ws_name = data_ws.name()+'_bleed' else: # may be sample run is already a run descriptor despite __Reducer__ have not been exposed data_ws = sample_run.get_workspace() # this will load data if necessary - ws_name = sample_run.get_ws_name()+'_bleed' + ws_name = data_ws.name()+'_bleed' if max_framerate is None: max_framerate = float(data_ws.getInstrument().getNumberParameter('max-tube-framerate')[0]) diff --git a/Code/Mantid/scripts/Interface/reduction_gui/reduction/diffraction/diffraction_adv_setup_script.py b/Code/Mantid/scripts/Interface/reduction_gui/reduction/diffraction/diffraction_adv_setup_script.py index 0c202970df84..d30aadcc5f79 100644 --- a/Code/Mantid/scripts/Interface/reduction_gui/reduction/diffraction/diffraction_adv_setup_script.py +++ b/Code/Mantid/scripts/Interface/reduction_gui/reduction/diffraction/diffraction_adv_setup_script.py @@ -58,6 +58,8 @@ class AdvancedSetupScript(BaseScriptElement): outputfileprefix = "" scaledata = "" + parnamelist = None + def __init__(self, inst_name): """ Initialization """ diff --git a/Code/Mantid/scripts/Interface/reduction_gui/reduction/diffraction/diffraction_filter_setup_script.py b/Code/Mantid/scripts/Interface/reduction_gui/reduction/diffraction/diffraction_filter_setup_script.py index d31ee3d5a9bd..211eb62b693b 100644 --- a/Code/Mantid/scripts/Interface/reduction_gui/reduction/diffraction/diffraction_filter_setup_script.py +++ b/Code/Mantid/scripts/Interface/reduction_gui/reduction/diffraction/diffraction_filter_setup_script.py @@ -37,6 +37,8 @@ class FilterSetupScript(BaseScriptElement): logvaluetimesections = 1 titleofsplitters = "" + parnamelist = None + def __init__(self, inst_name): """ Initialization """ diff --git a/Code/Mantid/scripts/Interface/reduction_gui/reduction/diffraction/diffraction_run_setup_script.py b/Code/Mantid/scripts/Interface/reduction_gui/reduction/diffraction/diffraction_run_setup_script.py index 91c46724fb6c..d05f5e60e765 100644 --- a/Code/Mantid/scripts/Interface/reduction_gui/reduction/diffraction/diffraction_run_setup_script.py +++ b/Code/Mantid/scripts/Interface/reduction_gui/reduction/diffraction/diffraction_run_setup_script.py @@ -38,6 +38,8 @@ class RunSetupScript(BaseScriptElement): disablevanbkgdcorrection = False doresamplex = False + parnamelist = None + def __init__(self, inst_name): """ Initialization diff --git a/Code/Mantid/scripts/Interface/reduction_gui/reduction/inelastic/dgs_absolute_units_script.py b/Code/Mantid/scripts/Interface/reduction_gui/reduction/inelastic/dgs_absolute_units_script.py index 9e89b2a27269..c69c5cfc9a03 100644 --- a/Code/Mantid/scripts/Interface/reduction_gui/reduction/inelastic/dgs_absolute_units_script.py +++ b/Code/Mantid/scripts/Interface/reduction_gui/reduction/inelastic/dgs_absolute_units_script.py @@ -27,6 +27,7 @@ class AbsoluteUnitsScript(BaseScriptElement): absunits_median_test_out_high = 100 absunits_median_test_out_low = 0.01 absunits_errorbar_criterion = 0.0 + find_bad_detectors = None def __init__(self, inst_name): super(AbsoluteUnitsScript, self).__init__() diff --git a/Code/Mantid/scripts/Interface/reduction_gui/widgets/cluster_status.py b/Code/Mantid/scripts/Interface/reduction_gui/widgets/cluster_status.py index 099d45abb1a8..261aba78e9b8 100644 --- a/Code/Mantid/scripts/Interface/reduction_gui/widgets/cluster_status.py +++ b/Code/Mantid/scripts/Interface/reduction_gui/widgets/cluster_status.py @@ -25,6 +25,8 @@ class RemoteJobsWidget(BaseWidget): ## Widget name name = "Remote Jobs" + copyAction = None + def __init__(self, parent=None, state=None, settings=None): super(RemoteJobsWidget, self).__init__(parent, state, settings) diff --git a/Code/Mantid/scripts/Interface/reduction_gui/widgets/diffraction/diffraction_filter_setup.py b/Code/Mantid/scripts/Interface/reduction_gui/widgets/diffraction/diffraction_filter_setup.py index 6d4731dea439..02a98e6c7096 100644 --- a/Code/Mantid/scripts/Interface/reduction_gui/widgets/diffraction/diffraction_filter_setup.py +++ b/Code/Mantid/scripts/Interface/reduction_gui/widgets/diffraction/diffraction_filter_setup.py @@ -26,6 +26,8 @@ class FilterSetupWidget(BaseWidget): # Widge name name = "Event Filters Setup" + _metaws = None + def __init__(self, parent=None, state=None, settings=None, data_type=None): """ Initialization """ diff --git a/Code/Mantid/scripts/Interface/reduction_gui/widgets/inelastic/dgs_absolute_units.py b/Code/Mantid/scripts/Interface/reduction_gui/widgets/inelastic/dgs_absolute_units.py index 6a87cf213116..2ce7819e1eb7 100644 --- a/Code/Mantid/scripts/Interface/reduction_gui/widgets/inelastic/dgs_absolute_units.py +++ b/Code/Mantid/scripts/Interface/reduction_gui/widgets/inelastic/dgs_absolute_units.py @@ -12,6 +12,9 @@ class AbsoluteUnitsWidget(BaseWidget): ## Widget name name = "Absolute Units" + _old_absunits = None + copyAction = None + def __init__(self, parent=None, state=None, settings=None, data_type=None): super(AbsoluteUnitsWidget, self).__init__(parent, state, settings, data_type=data_type) diff --git a/Code/Mantid/scripts/Interface/reduction_gui/widgets/inelastic/dgs_data_corrections.py b/Code/Mantid/scripts/Interface/reduction_gui/widgets/inelastic/dgs_data_corrections.py index 97fd1f0bf314..811de8769e55 100644 --- a/Code/Mantid/scripts/Interface/reduction_gui/widgets/inelastic/dgs_data_corrections.py +++ b/Code/Mantid/scripts/Interface/reduction_gui/widgets/inelastic/dgs_data_corrections.py @@ -13,6 +13,10 @@ class DataCorrectionsWidget(BaseWidget): ## Widget name name = "Data Corrections" + _old_backgnd_sub = None + _old_norm_button = None + incident_beam_norm_grp = None + def __init__(self, parent=None, state=None, settings=None, data_type=None): super(DataCorrectionsWidget, self).__init__(parent, state, settings, data_type=data_type) 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 d1a8c68ff43d..ea324c63828a 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 @@ -41,6 +41,9 @@ class BaseRefWidget(BaseWidget): bDEBUG = False + _run_number_first_edit = None + ref_det_view = None + def __init__(self, parent=None, state=None, settings=None, name="", data_proxy=None): super(BaseRefWidget, self).__init__(parent, state, settings, data_proxy=data_proxy) @@ -214,6 +217,8 @@ def getMetadata(self,file): _full_file_name = file tmpWks = LoadEventNexus(Filename=_full_file_name,MetaDataOnly='1') + isSi = False + #mt1 = mtd['tmpWks'] #mt_run = mt1.getRun() mt_run = tmpWks.getRun() @@ -229,14 +234,20 @@ def getMetadata(self,file): #s1h, s2h, s1w and s2w s1h = mt_run.getProperty('S1VHeight').value[0] - s2h = mt_run.getProperty('S2VHeight').value[0] + s1w = mt_run.getProperty('S1HWidth').value[0] + try: - s1w = mt_run.getProperty('S1HWidth').value[0] + s2h = mt_run.getProperty('SiVHeight').value[0] + isSi = True except: - s1w = 'N/A' - s2w = mt_run.getProperty('S2HWidth').value[0] + s2h = mt_run.getProperty('S2VHeight').value[0] - return [tthd,ths, lambda_requested, s1h, s2h, s1w, s2w] + try: + s2w = mt_run.getProperty('SiHWidth').value[0] + except: + s2w = mt_run.getProperty('S2HWidth').value[0] + + return [tthd,ths, lambda_requested, s1h, s2h, s1w, s2w, isSi] def data_run_number_validated(self): """ @@ -288,6 +299,14 @@ def data_run_number_validated(self): s2w_value_string = '{0:.2f}'.format(s2w_value) self._summary.s2w.setText(s2w_value_string) + isSi = metadata[7] + print isSi + if isSi: + self._summary.label_25.setText("Si height:") + self._summary.label_27.setText("Si width:") + else: + self._summary.label25.setText("S2 height:") + self._summary.label27.setText("S2 width:") # self._summary.data_run_number_processing.hide() except: pass diff --git a/Code/Mantid/scripts/Interface/reduction_gui/widgets/reflectometer/launch_peak_back_selection_1d.py b/Code/Mantid/scripts/Interface/reduction_gui/widgets/reflectometer/launch_peak_back_selection_1d.py index db89665db9b7..4e1a0455aae2 100644 --- a/Code/Mantid/scripts/Interface/reduction_gui/widgets/reflectometer/launch_peak_back_selection_1d.py +++ b/Code/Mantid/scripts/Interface/reduction_gui/widgets/reflectometer/launch_peak_back_selection_1d.py @@ -49,6 +49,27 @@ class DesignerMainWindow(QtGui.QMainWindow): x2=None y1=None y2=None + topHorizontalLayout = None + topHorizontalLayoutPeak = None + peakTo = None + peakFrom = None + topHorizontalLayoutBack = None + label = None + backTo = None + backFrom = None + topHorizontalLayoutLowres = None + lowresTo = None + lowresFrom = None + topHorizontalLayoutRight = None + log = None + linear = None + main_frame = None + mpl_toolbar = None + dpi = None + fig = None + canvas = None + bottomHorizontalLayout = None + _file_menu = None def __init__(self, wk1=None, wk2=None, parent=None, type='data'): diff --git a/Code/Mantid/scripts/Interface/reduction_gui/widgets/reflectometer/refl_data_simple.py b/Code/Mantid/scripts/Interface/reduction_gui/widgets/reflectometer/refl_data_simple.py index b20f3a35624f..bfb043368ad5 100644 --- a/Code/Mantid/scripts/Interface/reduction_gui/widgets/reflectometer/refl_data_simple.py +++ b/Code/Mantid/scripts/Interface/reduction_gui/widgets/reflectometer/refl_data_simple.py @@ -33,6 +33,7 @@ class DataReflWidget(BaseWidget): short_name = 'REFL' peak_pixel_range = [] background_pixel_range = [] + _run_number_first_edit = None def __init__(self, parent=None, state=None, settings=None, name="REFL", data_proxy=None): super(DataReflWidget, self).__init__(parent, state, settings, data_proxy=data_proxy) 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 a6b69395b762..9d6d57194cf4 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 @@ -32,6 +32,8 @@ class DataReflWidget(BaseWidget): short_name = 'REFM' peak_pixel_range = [] background_pixel_range = [] + _run_number_first_edit = None + ref_det_view = None def __init__(self, parent=None, state=None, settings=None, name="REFM", data_proxy=None): super(DataReflWidget, self).__init__(parent, state, settings, data_proxy=data_proxy) diff --git a/Code/Mantid/scripts/Interface/reduction_gui/widgets/reflectometer/stitcher.py b/Code/Mantid/scripts/Interface/reduction_gui/widgets/reflectometer/stitcher.py index 5486443fe023..fc7febe2cc7a 100644 --- a/Code/Mantid/scripts/Interface/reduction_gui/widgets/reflectometer/stitcher.py +++ b/Code/Mantid/scripts/Interface/reduction_gui/widgets/reflectometer/stitcher.py @@ -212,6 +212,8 @@ class StitcherWidget(BaseWidget): ## Widget name name = "Data Stitching" + radio_group = None + def __init__(self, parent=None, state=None, settings=None): super(StitcherWidget, self).__init__(parent, state, settings) diff --git a/Code/Mantid/scripts/Interface/ui/reflectometer/refl_gui.py b/Code/Mantid/scripts/Interface/ui/reflectometer/refl_gui.py index 0789e8d3c743..e33fd3b6747b 100644 --- a/Code/Mantid/scripts/Interface/ui/reflectometer/refl_gui.py +++ b/Code/Mantid/scripts/Interface/ui/reflectometer/refl_gui.py @@ -34,6 +34,12 @@ class ReflGui(QtGui.QMainWindow, refl_window.Ui_windowRefl): + current_instrument = None + current_table = None + current_polarisation_method = None + labelStatus = None + accMethod = None + def __init__(self): """ Initialise the interface diff --git a/Code/Mantid/scripts/LargeScaleStructures/data_stitching.py b/Code/Mantid/scripts/LargeScaleStructures/data_stitching.py index 976d7f45a2ca..03534cce3e7e 100644 --- a/Code/Mantid/scripts/LargeScaleStructures/data_stitching.py +++ b/Code/Mantid/scripts/LargeScaleStructures/data_stitching.py @@ -15,12 +15,13 @@ class RangeSelector(object): Brings up range selector window and connects the user selection to a call-back function. """ - __instance=None + __instance = None class _Selector(object): def __init__(self): self._call_back = None + self._ws_output_base = None self._graph = "Range Selector" def disconnect(self): diff --git a/Code/Mantid/scripts/SANS/isis_instrument.py b/Code/Mantid/scripts/SANS/isis_instrument.py index 1377abde7fae..743145fa0b79 100644 --- a/Code/Mantid/scripts/SANS/isis_instrument.py +++ b/Code/Mantid/scripts/SANS/isis_instrument.py @@ -160,6 +160,9 @@ def __init__(self, scale=1.0, shift=0.0, fitScale=False, fitShift=False, qMin=No else: self.qRangeUserSelected = True + _first_spec_num = None + last_spec_num = None + def __init__(self, instr, det_type): #detectors are known by many names, the 'uni' name is an instrument independent alias the 'long' name is the instrument view name and 'short' name often used for convenience @@ -409,6 +412,8 @@ def crop_to_detector(self, input_name, output_name=None): + str(sys.exc_info())) class ISISInstrument(BaseInstrument): + lowAngDetSet = None + def __init__(self, filename=None): """ Reads the instrument definition xml file diff --git a/Code/Mantid/scripts/reduction/instruments/reflectometer/wks_utility.py b/Code/Mantid/scripts/reduction/instruments/reflectometer/wks_utility.py index 4269d3fb1607..befc884bb307 100644 --- a/Code/Mantid/scripts/reduction/instruments/reflectometer/wks_utility.py +++ b/Code/Mantid/scripts/reduction/instruments/reflectometer/wks_utility.py @@ -73,12 +73,15 @@ def getSheight(mt, index): """ mt_run = mt.getRun() if index == 2: + isSi = False try: tag = 'SiVHeight' value = mt_run.getProperty(tag).value + isSi = True except: tag = 'S2VHeight' value = mt_run.getProperty(tag).value + return [isSi, value[0]] else: tag = 'S1VHeight' value = mt_run.getProperty(tag).value @@ -91,7 +94,7 @@ def getS1h(mt=None): """ if mt != None: # _h, units = getSh(mt, 's1t', 's1b') - _h = getSheight(mt, '1') + _h = getSheight(mt, 1) return _h return None @@ -100,13 +103,9 @@ def getS2h(mt=None): returns the height and units of the slit #2 """ if mt != None: -# _h, units = getSh(mt, 's2t', 's2b') - _h = getSheight(mt, '2') - return _h - return None - - - + [isSi, _h] = getSheight(mt, 2) + return [isSi,_h] + return [False, None] def getSwidth(mt, index): """ @@ -115,12 +114,15 @@ def getSwidth(mt, index): """ mt_run = mt.getRun() if index==2: + isSi = False try: tag = 'SiHWidth' value = mt_run.getProperty(tag).value + isSi = True except: tag = 'S2HWidth' value = mt_run.getProperty(tag).value + return [isSi, value[0]] else: tag = 'S1HWidth' value = mt_run.getProperty(tag).value @@ -143,7 +145,7 @@ def getS1w(mt=None): """ if mt != None: # _w, units = getSw(mt, 's1l', 's1r') - _w = getSwidth(mt, '1') + _w = getSwidth(mt, 1) return _w return None @@ -152,10 +154,9 @@ def getS2w(mt=None): returns the width and units of the slit #2 """ if mt != None: -# _w, units = getSh(mt, 's2l', 's2r') - _w = getSwidth(mt, '2') - return _w - return None + [isSi, _w] = getSwidth(mt, 2) + return [isSi,_w] + return [False,None] def getLambdaValue(mt_name): @@ -789,121 +790,121 @@ def isWithinPrecisionRange(value_file, value_run, precision): else: return False -def applySF(InputWorkspace, - incidentMedium, - sfFile, - valuePrecision, - slitsWidthFlag): - """ - Function that apply scaling factor to data using sfCalculator.txt - file created by the sfCalculator procedure - """ - - #check if config file is there - if os.path.isfile(sfFile): - - #parse file and put info into array - f = open(sfFile, 'r') - sfFactorTable = [] - for line in f.read().split('\n'): - if len(line) > 0 and line[0] != '#': - sfFactorTable.append(line.split(' ')) - f.close() - - sz_table = shape(sfFactorTable) - nbr_row = sz_table[0] - - _incidentMedium = incidentMedium.strip() - - _lr = getLambdaValue(mtd[InputWorkspace]) - _lr_value = _lr[0] - _lr_value = float("{0:.2f}".format(_lr_value)) - - #retrieve s1h and s2h values - s1h = getS1h(mtd[InputWorkspace]) - s2h = getS2h(mtd[InputWorkspace]) - - s1h_value = abs(s1h) - s2h_value = abs(s2h) - - #retrieve s1w and s2w values - s1w = getS1w(mtd[InputWorkspace]) - s2w = getS2w(mtd[InputWorkspace]) - - s1w_value = abs(s1w) - s2w_value = abs(s2w) - -# print sfFactorTable - - print '--> Data Lambda Requested: {0:2f}'.format(_lr_value) - print '--> Data S1H: {0:2f}'.format(s1h_value) - print '--> Data S2H: {0:2f}'.format(s2h_value) - print '--> Data S1W: {0:2f}'.format(s1w_value) - print '--> Data S2W: {0:2f}'.format(s2w_value) - - print 'mERDDEEEEDEDEED' - for i in range(nbr_row): - - _file_incidentMedium = getFieldValue(sfFactorTable,i,0) - if _file_incidentMedium.strip() == _incidentMedium.strip(): - print '--- incident medium match ---' - _file_lambdaRequested = getFieldValue(sfFactorTable,i,1) - if (isWithinPrecisionRange(_file_lambdaRequested, - _lr_value, - valuePrecision)): - print '--- lambda requested match ---' - _file_s1h = getFieldValue(sfFactorTable,i,2) - if(isWithinPrecisionRange(_file_s1h, - s1h_value, - valuePrecision)): - print '--- S1H match ---' - _file_s2h = getFieldValue(sfFactorTable,i,3) - if(isWithinPrecisionRange(_file_s2h, - s2h_value, - valuePrecision)): - print '--- S2H match ---' - if slitsWidthFlag: - print '--- (with Width flag) ----' - _file_s1w = getFieldValue(sfFactorTable,i,4) - if(isWithinPrecisionRange(_file_s1w, - s1w_value, - valuePrecision)): - print '--- S1W match ---' - _file_s2w = getFieldValue(sfFactorTable,i,5) - if(isWithinPrecisionRange(_file_s2w, - s2w_value, - valuePrecision)): - print '--- S2W match ---' - - print '--> Found a perfect match' - a = float(getFieldValue(sfFactorTable,i,6)) - b = float(getFieldValue(sfFactorTable,i,7)) - a_error = float(getFieldValue(sfFactorTable,i,8)) - b_error = float(getFieldValue(sfFactorTable,i,9)) - - OutputWorkspace = _applySFtoArray(InputWorkspace, - a, b, a_error, b_error) - - return OutputWorkspace - - else: - - print '--> Found a perfect match' - a = float(getFieldValue(sfFactorTable,i,6)) - b = float(getFieldValue(sfFactorTable,i,7)) - a_error = float(getFieldValue(sfFactorTable,i,8)) - b_error = float(getFieldValue(sfFactorTable,i,9)) - - OutputWorkspace = _applySFtoArray(InputWorkspace, - a, b, a_error, b_error) - - return OutputWorkspace - - else: - - print '-> scaling factor file for requested lambda NOT FOUND!' - - return InputWorkspace +#def applySF(InputWorkspace, + #incidentMedium, + #sfFile, + #valuePrecision, + #slitsWidthFlag): + #""" + #Function that apply scaling factor to data using sfCalculator.txt + #file created by the sfCalculator procedure + #""" + + ##check if config file is there + #if os.path.isfile(sfFile): + + ##parse file and put info into array + #f = open(sfFile, 'r') + #sfFactorTable = [] + #for line in f.read().split('\n'): + #if len(line) > 0 and line[0] != '#': + #sfFactorTable.append(line.split(' ')) + #f.close() + + #sz_table = shape(sfFactorTable) + #nbr_row = sz_table[0] + + #_incidentMedium = incidentMedium.strip() + + #_lr = getLambdaValue(mtd[InputWorkspace]) + #_lr_value = _lr[0] + #_lr_value = float("{0:.2f}".format(_lr_value)) + + ##retrieve s1h and s2h values + #s1h = getS1h(mtd[InputWorkspace]) + #s2h = getS2h(mtd[InputWorkspace]) + + #s1h_value = abs(s1h) + #s2h_value = abs(s2h) + + ##retrieve s1w and s2w values + #s1w = getS1w(mtd[InputWorkspace]) + #s2w = getS2w(mtd[InputWorkspace]) + + #s1w_value = abs(s1w) + #s2w_value = abs(s2w) + +## print sfFactorTable + + #print '--> Data Lambda Requested: {0:2f}'.format(_lr_value) + #print '--> Data S1H: {0:2f}'.format(s1h_value) + #print '--> Data S2H: {0:2f}'.format(s2h_value) + #print '--> Data S1W: {0:2f}'.format(s1w_value) + #print '--> Data S2W: {0:2f}'.format(s2w_value) + + #print 'mERDDEEEEDEDEED' + #for i in range(nbr_row): + + #_file_incidentMedium = getFieldValue(sfFactorTable,i,0) + #if _file_incidentMedium.strip() == _incidentMedium.strip(): + #print '--- incident medium match ---' + #_file_lambdaRequested = getFieldValue(sfFactorTable,i,1) + #if (isWithinPrecisionRange(_file_lambdaRequested, + #_lr_value, + #valuePrecision)): + #print '--- lambda requested match ---' + #_file_s1h = getFieldValue(sfFactorTable,i,2) + #if(isWithinPrecisionRange(_file_s1h, + #s1h_value, + #valuePrecision)): + #print '--- S1H match ---' + #_file_s2h = getFieldValue(sfFactorTable,i,3) + #if(isWithinPrecisionRange(_file_s2h, + #s2h_value, + #valuePrecision)): + #print '--- S2H match ---' + #if slitsWidthFlag: + #print '--- (with Width flag) ----' + #_file_s1w = getFieldValue(sfFactorTable,i,4) + #if(isWithinPrecisionRange(_file_s1w, + #s1w_value, + #valuePrecision)): + #print '--- S1W match ---' + #_file_s2w = getFieldValue(sfFactorTable,i,5) + #if(isWithinPrecisionRange(_file_s2w, + #s2w_value, + #valuePrecision)): + #print '--- S2W match ---' + + #print '--> Found a perfect match' + #a = float(getFieldValue(sfFactorTable,i,6)) + #b = float(getFieldValue(sfFactorTable,i,7)) + #a_error = float(getFieldValue(sfFactorTable,i,8)) + #b_error = float(getFieldValue(sfFactorTable,i,9)) + + #OutputWorkspace = _applySFtoArray(InputWorkspace, + #a, b, a_error, b_error) + + #return OutputWorkspace + + #else: + + #print '--> Found a perfect match' + #a = float(getFieldValue(sfFactorTable,i,6)) + #b = float(getFieldValue(sfFactorTable,i,7)) + #a_error = float(getFieldValue(sfFactorTable,i,8)) + #b_error = float(getFieldValue(sfFactorTable,i,9)) + + #OutputWorkspace = _applySFtoArray(InputWorkspace, + #a, b, a_error, b_error) + + #return OutputWorkspace + + #else: + + #print '-> scaling factor file for requested lambda NOT FOUND!' + + #return InputWorkspace def _applySFtoArray(workspace, a, b, a_error, b_error): """ @@ -1442,24 +1443,30 @@ def applyScalingFactor(tof_axis, #retrieve s1h and s2h or sih values s1h = getS1h(mtd['ws_event_data']) - s2h = getS2h(mtd['ws_event_data']) + [isSih, s2h] = getS2h(mtd['ws_event_data']) s1h_value = abs(s1h) s2h_value = abs(s2h) #retrieve s1w and s2w values s1w = getS1w(mtd['ws_event_data']) - s2w = getS2w(mtd['ws_event_data']) + [isSiw, s2w] = getS2w(mtd['ws_event_data']) s1w_value = abs(s1w) s2w_value = abs(s2w) print '--> Data Lambda Requested: {0:2f}'.format(_lr_value) print '--> Data S1H: {0:2f}'.format(s1h_value) - print '--> Data S2H: {0:2f}'.format(s2h_value) + if isSih: + print '--> Data SiH: {0:2f}'.format(s2h_value) + else: + print '--> Data S2H: {0:2f}'.format(s2h_value) print '--> Data S1W: {0:2f}'.format(s1w_value) - print '--> Data S2W: {0:2f}'.format(s2w_value) - + if isSiw: + print '--> Data SiW: {0:2f}'.format(s2w_value) + else: + print '--> Data S2W: {0:2f}'.format(s2w_value) + for i in range(nbr_row): _file_incidentMedium = getFieldValue(sfFactorTable,i,0) diff --git a/Code/Mantid/scripts/test/DirectEnergyConversionTest.py b/Code/Mantid/scripts/test/DirectEnergyConversionTest.py index 897c2e03e105..9c8e3439a26d 100644 --- a/Code/Mantid/scripts/test/DirectEnergyConversionTest.py +++ b/Code/Mantid/scripts/test/DirectEnergyConversionTest.py @@ -1,5 +1,5 @@ import os, sys -#os.environ["PATH"] = r"c:/Mantid/Code/builds/br_master/bin/Release;"+os.environ["PATH"] +#os.environ["PATH"] = r"c:\Mantid\Code\builds\br_master\bin\Release;"+os.environ["PATH"] from mantid.simpleapi import * from mantid import api import unittest @@ -8,7 +8,6 @@ from Direct.PropertyManager import PropertyManager import Direct.dgreduce as dgreduce - #----------------------------------------------------------------------------------------------------------------------------------------- #----------------------------------------------------------------------------------------------------------------------------------------- #----------------------------------------------------------------------------------------------------------------------------------------- @@ -25,9 +24,6 @@ def tearDown(self): api.AnalysisDataService.clear() pass - #def test_build_coupled_keys_dict_simple(self): - # params = ["] - def test_init_reducer(self): tReducer = self.reducer self.assertFalse(tReducer.prop_man is None) @@ -62,7 +58,8 @@ def verify_present_and_delete(file_list): clean_up(files) tReducer.prop_man.save_format='' - tws =CreateSampleWorkspace(Function='Flat background', NumBanks=1, BankPixelWidth=1, NumEvents=10, XUnit='DeltaE', XMin=-10, XMax=10, BinWidth=0.1) + tws =CreateSampleWorkspace(Function='Flat background', NumBanks=1, BankPixelWidth=1,\ + NumEvents=10, XUnit='DeltaE', XMin=-10, XMax=10, BinWidth=0.1) self.assertTrue(len(tReducer.prop_man.save_format) ==0) @@ -73,10 +70,8 @@ def verify_present_and_delete(file_list): - # redefine test save methors to produce test ouptut - + # redefine test save methods to produce test output tReducer.prop_man.save_format=['spe','nxspe','nxs'] - tReducer.save_results(tws,'save_formats_test_file.tt') files = ['save_formats_test_file.spe','save_formats_test_file.nxspe','save_formats_test_file.nxs'] @@ -162,8 +157,9 @@ def test_get_abs_normalization_factor(self) : tReducer = DirectEnergyConversion(mono_ws.getInstrument()) tReducer.prop_man.incident_energy = 5. tReducer.prop_man.monovan_integr_range=[-10,10] + tReducer.wb_run = mono_ws - (nf1,nf2,nf3,nf4) = tReducer.get_abs_normalization_factor(mono_ws.getName(),5.) + (nf1,nf2,nf3,nf4) = tReducer.get_abs_normalization_factor(PropertyManager.wb_run,5.) self.assertAlmostEqual(nf1,0.58561121802167193,7) self.assertAlmostEqual(nf1,nf2) self.assertAlmostEqual(nf2,nf3) @@ -175,7 +171,8 @@ def test_get_abs_normalization_factor(self) : sig = mono_ws.dataY(0) sig[:]=0 - (nf1,nf2,nf3,nf4) = tReducer.get_abs_normalization_factor(mono_ws.getName(),5.) + tReducer.wb_run = mono_ws + (nf1,nf2,nf3,nf4) = tReducer.get_abs_normalization_factor(PropertyManager.wb_run,5.) self.assertAlmostEqual(nf1,0.585611218022,7) self.assertAlmostEqual(nf1,nf2) self.assertAlmostEqual(nf2,nf3) @@ -190,9 +187,6 @@ def test_dgreduce_works(self): wb_ws = CloneWorkspace(run_ws) #wb_ws=CreateSampleWorkspace( Function='Multiple Peaks', NumBanks=1, BankPixelWidth=4, NumEvents=10000) - - - dgreduce.setup('MAR') par = {} par['ei_mon_spectra']=[4,5] @@ -205,12 +199,6 @@ def test_dgreduce_works(self): ws = dgreduce.abs_units(wb_ws,run_ws,None,wb_ws,10,100,8.8,[-10,0.1,7],None,None,**par) self.assertTrue(isinstance(ws,api.MatrixWorkspace)) - - ##def test_diag_call(self): - ## tReducer = self.reducer - ## # should do nothing as already initialized above, but if not will initiate the instrument - ## tReducer.initialise("MAP") - ## tReducet.di def test_energy_to_TOF_range(self): @@ -292,8 +280,8 @@ def test_late_rebinning(self): def test_tof_range(self): - run=CreateSampleWorkspace(Function='Multiple Peaks', NumBanks=6, BankPixelWidth=1, NumEvents=10, XUnit='DeltaE', - XMin=-20, XMax=65, BinWidth=0.2) + run=CreateSampleWorkspace(Function='Multiple Peaks', NumBanks=6, BankPixelWidth=1, NumEvents=10,\ + XUnit='DeltaE', XMin=-20, XMax=65, BinWidth=0.2) LoadInstrument(run,InstrumentName='MARI') red = DirectEnergyConversion(run.getInstrument()) @@ -327,16 +315,16 @@ def test_tof_range(self): def test_multirep_mode(self): # create test workspace - run_monitors=CreateSampleWorkspace(Function='Multiple Peaks', NumBanks=4, BankPixelWidth=1, NumEvents=100000, XUnit='Energy', - XMin=3, XMax=200, BinWidth=0.1) + run_monitors=CreateSampleWorkspace(Function='Multiple Peaks', NumBanks=4, BankPixelWidth=1,\ + NumEvents=100000,XUnit='Energy', XMin=3, XMax=200, BinWidth=0.1) LoadInstrument(run_monitors,InstrumentName='MARI') ConvertUnits(InputWorkspace='run_monitors', OutputWorkspace='run_monitors', Target='TOF') run_monitors = mtd['run_monitors'] tof = run_monitors.dataX(3) tMin = tof[0] tMax = tof[-1] - run = CreateSampleWorkspace( Function='Multiple Peaks',WorkspaceType='Event',NumBanks=8, BankPixelWidth=1, NumEvents=100000, - XUnit='TOF',xMin=tMin,xMax=tMax) + run = CreateSampleWorkspace( Function='Multiple Peaks',WorkspaceType='Event',NumBanks=8, BankPixelWidth=1,\ + NumEvents=100000, XUnit='TOF',xMin=tMin,xMax=tMax) LoadInstrument(run,InstrumentName='MARI') # do second @@ -347,7 +335,7 @@ def test_multirep_mode(self): # Run multirep tReducer = DirectEnergyConversion(run.getInstrument()) - tReducer.prop_man.run_diagnostics=False + tReducer.prop_man.run_diagnostics=True tReducer.hard_mask_file=None tReducer.map_file=None tReducer.save_format=None @@ -383,16 +371,16 @@ def test_multirep_mode(self): def test_multirep_abs_units_mode(self): # create test workspace - run_monitors=CreateSampleWorkspace(Function='Multiple Peaks', NumBanks=4, BankPixelWidth=1, NumEvents=100000, XUnit='Energy', - XMin=3, XMax=200, BinWidth=0.1) + run_monitors=CreateSampleWorkspace(Function='Multiple Peaks', NumBanks=4, BankPixelWidth=1,\ + NumEvents=100000, XUnit='Energy', XMin=3, XMax=200, BinWidth=0.1) LoadInstrument(run_monitors,InstrumentName='MARI') ConvertUnits(InputWorkspace='run_monitors', OutputWorkspace='run_monitors', Target='TOF') run_monitors = mtd['run_monitors'] tof = run_monitors.dataX(3) tMin = tof[0] tMax = tof[-1] - run = CreateSampleWorkspace( Function='Multiple Peaks',WorkspaceType='Event',NumBanks=8, BankPixelWidth=1, NumEvents=100000, - XUnit='TOF',xMin=tMin,xMax=tMax) + run = CreateSampleWorkspace( Function='Multiple Peaks',WorkspaceType='Event',NumBanks=8, BankPixelWidth=1,\ + NumEvents=100000, XUnit='TOF',xMin=tMin,xMax=tMax) LoadInstrument(run,InstrumentName='MARI') # build "monovanadium" @@ -408,7 +396,7 @@ def test_multirep_abs_units_mode(self): # Run multirep tReducer = DirectEnergyConversion(run.getInstrument()) - tReducer.prop_man.run_diagnostics=False # temporary + tReducer.prop_man.run_diagnostics=True tReducer.hard_mask_file=None tReducer.map_file=None tReducer.prop_man.background_range=[0.99*tMax,tMax] @@ -416,7 +404,6 @@ def test_multirep_abs_units_mode(self): tReducer.save_format=None tReducer.prop_man.normalise_method='monitor-1' tReducer.norm_mon_integration_range=[tMin,tMax] - #tReducer.prop_man. result = tReducer.convert_to_energy(wb_ws,run,[67.,122.],[-2,0.02,0.8],None,mono) @@ -448,5 +435,4 @@ def test_multirep_abs_units_mode(self): if __name__=="__main__": - unittest.main() - + unittest.main() diff --git a/Code/Mantid/scripts/test/DirectPropertyManagerTest.py b/Code/Mantid/scripts/test/DirectPropertyManagerTest.py index 2ef643c166d4..d96737c8ad3d 100644 --- a/Code/Mantid/scripts/test/DirectPropertyManagerTest.py +++ b/Code/Mantid/scripts/test/DirectPropertyManagerTest.py @@ -1,11 +1,12 @@ import os -os.environ["PATH"] = r"c:/Mantid/Code/builds/br_master/bin/Release;"+os.environ["PATH"] +#os.environ["PATH"] = r"c:/Mantid/Code/builds/br_master/bin/Release;" + os.environ["PATH"] from mantid.simpleapi import * from mantid import api import unittest import inspect import numpy as np -import sys,copy +import sys +import copy from Direct.PropertyManager import PropertyManager @@ -21,7 +22,7 @@ def __init__(self, methodName): def setUp(self): if self.prop_man == None or type(self.prop_man) != type(PropertyManager): - self.prop_man = PropertyManager("MAR") + self.prop_man = PropertyManager("MAR") def tearDown(self): pass @@ -29,16 +30,16 @@ def tearDown(self): def getInstrument(InstrumentName='MAR'): """ test method used to obtain default instrument for testing """ idf_dir = config.getString('instrumentDefinition.directory') - idf_file=api.ExperimentInfo.getInstrumentFilename(InstrumentName) + idf_file = api.ExperimentInfo.getInstrumentFilename(InstrumentName) tmp_ws_name = '__empty_' + InstrumentName if not mtd.doesExist(tmp_ws_name): - LoadEmptyInstrument(Filename=idf_file,OutputWorkspace=tmp_ws_name) + LoadEmptyInstrument(Filename=idf_file,OutputWorkspace=tmp_ws_name) return mtd[tmp_ws_name].getInstrument() def test_init_reducer(self): - propman=self.prop_man + propman = self.prop_man self.assertEqual(propman.deltaE_mode,'direct') @@ -69,7 +70,7 @@ def test_set_non_default_simple_value(self): self.assertEqual(len(prop_changed),2) self.assertTrue('van_mass' in prop_changed) - self.assertTrue('van_sig' in prop_changed) + self.assertTrue('van_sig' in prop_changed) def test_overloaded_setters_getters(self): propman = self.prop_man @@ -95,7 +96,7 @@ def test_overloaded_setters_getters(self): self.assertEqual(propman.monovan_mapfile,'the_monovan_map_file.rst') - prop_changed =propman.getChangedProperties() + prop_changed = propman.getChangedProperties() self.assertEqual(len(prop_changed),3) self.assertTrue('det_cal_file' in prop_changed) self.assertTrue('map_file' in prop_changed) @@ -108,7 +109,7 @@ def test_hartmask_plus_or_only(self): propman.hard_mask_file = 'a_mask_file' self.assertEqual(propman.hard_mask_file,'a_mask_file.msk') - prop_changed =propman.getChangedProperties() + prop_changed = propman.getChangedProperties() self.assertTrue('hard_mask_file' in prop_changed) @@ -156,7 +157,7 @@ def test_set_non_default_complex_value(self): propman.norm_mon_integration_range = [50,1050] - range=propman.norm_mon_integration_range + range = propman.norm_mon_integration_range self.assertAlmostEqual(range[0],50.,7) self.assertAlmostEqual(range[1],1050.,7) propman.ei_mon1_spec = 10 @@ -191,13 +192,13 @@ def test_set_non_default_complex_value_synonims(self): self.assertTrue("ei_mon_spectra" in prop_changed,"changing test_mon_spectra_composite should change ei_mon_spectra") - ## HOW TO MAKE IT WORK? it fails silently - propman.ei_mon_spectra[1]=100 + ## HOW TO MAKE IT WORK? it fails silently + propman.ei_mon_spectra[1] = 100 self.assertEqual(10000,propman.ei_mon_spectra[0]) self.assertEqual(2000,propman.ei_mon_spectra[1]) - propman.ei_mon_spectra=[100,200] + propman.ei_mon_spectra = [100,200] self.assertEqual(100,propman.ei_mon_spectra[0]) self.assertEqual(200,propman.ei_mon_spectra[1]) @@ -211,7 +212,7 @@ def test_set_get_mono_range(self): hi_frac = propman.monovan_hi_frac lo_frac = propman.monovan_lo_frac #propman.monovan_integr_range = None - self.assertEqual(propman.monovan_integr_range,[lo_frac*energy_incident,hi_frac*energy_incident]) + self.assertEqual(propman.monovan_integr_range,[lo_frac * energy_incident,hi_frac * energy_incident]) def test_load_monitors_with_workspace(self): @@ -219,11 +220,11 @@ def test_load_monitors_with_workspace(self): self.assertTrue(propman.load_monitors_with_workspace,'MARI loads monitors with workspace by default') - propman.load_monitors_with_workspace=True + propman.load_monitors_with_workspace = True self.assertTrue(propman.load_monitors_with_workspace) - propman.load_monitors_with_workspace=0 + propman.load_monitors_with_workspace = 0 self.assertFalse(propman.load_monitors_with_workspace) - propman.load_monitors_with_workspace=10 + propman.load_monitors_with_workspace = 10 self.assertTrue(propman.load_monitors_with_workspace) @@ -243,10 +244,10 @@ def test_save_format(self): propman = self.prop_man formats = propman.save_format - self.assertTrue(len(formats)==0) + self.assertTrue(len(formats) == 0) - propman.save_format='unknown' - self.assertTrue(len(propman.save_format)==0) + propman.save_format = 'unknown' + self.assertTrue(len(propman.save_format) == 0) propman.save_format = '.spe' formats = propman.save_format @@ -260,7 +261,7 @@ def test_save_format(self): propman.save_format = '' - self.assertTrue(len(propman.save_format)==0) + self.assertTrue(len(propman.save_format) == 0) propman.save_format = ['nxspe','.nxs'] formats = propman.save_format @@ -268,7 +269,7 @@ def test_save_format(self): self.assertTrue('nxspe' in formats) propman.save_format = None - self.assertTrue(len(propman.save_format)==0) + self.assertTrue(len(propman.save_format) == 0) propman.save_format = 'spe,.nxs' formats = propman.save_format self.assertEqual(len(propman.save_format),2) @@ -280,7 +281,7 @@ def test_save_format(self): self.assertEqual(len(propman.save_format),3) propman.save_format = 'None' - self.assertTrue(len(propman.save_format)==0) + self.assertTrue(len(propman.save_format) == 0) propman.save_format = ('spe','nxspe') self.assertEqual(len(propman.save_format),2) @@ -292,11 +293,11 @@ def test_allowed_values(self): propman = self.prop_man nm = propman.normalise_method self.assertEqual(nm, 'monitor-1') - propman.normalise_method=None + propman.normalise_method = None self.assertEqual(propman.normalise_method, None) - propman.normalise_method='monitor-2' + propman.normalise_method = 'monitor-2' self.assertEqual(propman.normalise_method, 'monitor-2') - propman.normalise_method='current' + propman.normalise_method = 'current' self.assertEqual(propman.normalise_method, 'current') self.assertRaises(KeyError,setattr,propman,'normalise_method','unsupported') @@ -328,17 +329,64 @@ def test_instr_name_and_psi(self): propman.psi = 10 self.assertEqual(propman.psi,10) + logs = propman.motor_log_names + self.assertTrue(isinstance(logs,list)) + self.assertEqual(len(logs),2) + self.assertEqual(logs[0],'wccr') + self.assertEqual(logs[1],'Rot') + + self.assertTrue(propman.motor_offset is None) + + sample_ws = CreateSampleWorkspace(Function='Multiple Peaks', NumBanks=4, BankPixelWidth=1,\ + NumEvents=10,XUnit='Energy', XMin=3, XMax=200, BinWidth=0.1) + + propman.motor_offset = 10 + psi = PropertyManager.psi.read_psi_from_workspace(sample_ws) + self.assertTrue(np.isnan(psi)) + + + AddSampleLog(Workspace=sample_ws,LogName='Rot',LogText='20.', LogType='Number Series') + propman.motor_offset = None + psi = PropertyManager.psi.read_psi_from_workspace(sample_ws) + self.assertTrue(np.isnan(psi)) + + + propman.psi = sample_ws + self.assertTrue(np.isnan(propman.psi)) + + propman.motor_offset = 10 + self.assertEqual(propman.motor_offset,10) + self.assertAlmostEqual(propman.psi,30.) + psi = PropertyManager.psi.read_psi_from_workspace(sample_ws) + self.assertAlmostEqual(psi,30.) + + AddSampleLog(Workspace=sample_ws,LogName='CCR_ROT',LogText='50.', LogType='Number Series') + propman.motor_log_names = 'Some_log' + logs = propman.motor_log_names + self.assertTrue(isinstance(logs,list)) + self.assertEqual(len(logs),1) + self.assertEqual(logs[0],'Some_log') + + self.assertTrue(np.isnan(propman.psi)) + propman.motor_log_names = 'CCR_ROT' + self.assertAlmostEqual(propman.psi,60.) + + psi = PropertyManager.psi.read_psi_from_workspace(sample_ws) + self.assertAlmostEqual(psi,60.) + + api.AnalysisDataService.clear() + def test_diag_spectra(self): propman = self.prop_man self.assertTrue(propman.diag_spectra is None) - propman.diag_spectra ='(19,299);(399,500)' + propman.diag_spectra = '(19,299);(399,500)' spectra = propman.diag_spectra self.assertEqual(spectra[0],(19,299)) self.assertEqual(spectra[1],(399,500)) - propman = PropertyManager("MAP") + propman = PropertyManager("MAP") spectra = propman.diag_spectra # (1,17280);(17281,18432);(18433,32256);(32257,41472) self.assertEqual(len(spectra),4) @@ -352,14 +400,14 @@ def test_get_diagnostics_parameters(self): self.assertEqual(len(params),20) bkg_test_range0 = propman.background_test_range - bkg_test_range = params['background_test_range'] + bkg_test_range = params['background_test_range'] bkg_range = propman.background_range self.assertEqual(bkg_range,bkg_test_range) self.assertEqual(bkg_range,bkg_test_range0) propman.background_test_range = [1000,2000] bkg_test_range = propman.background_test_range - self.assertEqual(bkg_test_range,[1000,2000]) + self.assertEqual(bkg_test_range,(1000.,2000.)) def test_check_monovan_changed(self): propman = self.prop_man @@ -394,7 +442,7 @@ def test_set_defailts_from_instrument(self) : self.assertEquals(propman.TestParam2,"initial1") self.assertEquals(propman.TestParam3,"initial2") - propman.TestParam2="gui_changed1" + propman.TestParam2 = "gui_changed1" self.assertEquals(propman.TestParam2,"gui_changed1") SetInstrumentParameter(ws,ParameterName="TestParam2",Value="instr_changed1",ParameterType="String") @@ -451,7 +499,8 @@ def test_set_complex_defailts_from_instrument(self) : changed_prop = propman.update_defaults_from_instrument(ws.getInstrument()) self.assertEqual(len(changed_prop),4) - #property have been changed from GUI and changes from instrument are ignored + #property have been changed from GUI and changes from instrument are + #ignored SampleResult = ['OtherVal1','OtherVal2'] cVal = propman.Param1 for test,sample in zip(cVal,SampleResult): @@ -465,15 +514,16 @@ def test_set_complex_defailts_from_instrument(self) : def test_set_all_defaults_from_instrument(self) : ws = CreateSampleWorkspace(NumBanks=1, BankPixelWidth=4, NumEvents=10) #idf_dir = config.getString('instrumentDefinition.directory') - idf_file=api.ExperimentInfo.getInstrumentFilename('LET','2014-05-03 23:59:59') + idf_file = api.ExperimentInfo.getInstrumentFilename('LET','2014-05-03 23:59:59') ws = LoadEmptyInstrument(Filename=idf_file,OutputWorkspace=ws) - # Propman was defined for MARI but reduction parameters are all the same, so testing on LET + # Propman was defined for MARI but reduction parameters are all the + # same, so testing on LET propman = self.prop_man self.assertEqual(propman.ei_mon1_spec,2) ws = mtd['ws'] - changed_prop=propman.update_defaults_from_instrument( ws.getInstrument(),False) + changed_prop = propman.update_defaults_from_instrument(ws.getInstrument(),False) self.assertFalse('ei-mon1-spec' in changed_prop) self.assertEqual(propman.ei_mon1_spec,65542) @@ -486,9 +536,9 @@ def test_set_energy_bins_and_ei(self): propman = self.prop_man - propman.incident_energy =20 + propman.incident_energy = 20 self.assertFalse(PropertyManager.incident_energy.multirep_mode()) - propman.energy_bins='-30,3,10' + propman.energy_bins = '-30,3,10' bins = propman.energy_bins self.assertAlmostEqual(bins[0],-30) @@ -501,8 +551,8 @@ def test_set_energy_bins_and_ei(self): self.assertAlmostEqual(bins[2],10) - propman.incident_energy =100.01 - propman.energy_bins=[-20,4,100] + propman.incident_energy = 100.01 + propman.energy_bins = [-20,4,100] bins = propman.energy_bins self.assertAlmostEqual(bins[0],-20) self.assertAlmostEqual(bins[1],4) @@ -514,39 +564,39 @@ def test_set_energy_bins_and_ei(self): - propman.incident_energy=10 + propman.incident_energy = 10 self.assertAlmostEqual(propman.incident_energy,10) bins = PropertyManager.energy_bins.get_abs_range(propman) - self.assertAlmostEqual(bins[0],-20*9.9999/100) - self.assertAlmostEqual(bins[1],4*9.9999/100) + self.assertAlmostEqual(bins[0],-20 * 9.9999 / 100) + self.assertAlmostEqual(bins[1],4 * 9.9999 / 100) self.assertAlmostEqual(bins[2],9.9999) ei = [20,30] - propman.incident_energy=ei + propman.incident_energy = ei got_ei = propman.incident_energy for ind,en in enumerate(got_ei): self.assertAlmostEqual(en,ei[ind]) self.assertTrue(PropertyManager.incident_energy.multirep_mode()) bins = PropertyManager.energy_bins.get_abs_range(propman) - self.assertAlmostEqual(bins[0],-20*20*0.99999/100) - self.assertAlmostEqual(bins[1],4*20*0.99999/100) - self.assertAlmostEqual(bins[2],20*0.99999) + self.assertAlmostEqual(bins[0],-20 * 20 * 0.99999 / 100) + self.assertAlmostEqual(bins[1],4 * 20 * 0.99999 / 100) + self.assertAlmostEqual(bins[2],20 * 0.99999) - propman.energy_bins=[-2,0.1,0.8] + propman.energy_bins = [-2,0.1,0.8] bins = propman.energy_bins self.assertAlmostEqual(bins[0],-2) self.assertAlmostEqual(bins[1],0.1) self.assertAlmostEqual(bins[2],0.8) bins = PropertyManager.energy_bins.get_abs_range(propman) - self.assertAlmostEqual(bins[0],-20*2) - self.assertAlmostEqual(bins[1],20*0.1) - self.assertAlmostEqual(bins[2],20*0.8) + self.assertAlmostEqual(bins[0],-20 * 2) + self.assertAlmostEqual(bins[1],20 * 0.1) + self.assertAlmostEqual(bins[2],20 * 0.8) - propman.incident_energy='20,30' + propman.incident_energy = '20,30' self.assertTrue(PropertyManager.incident_energy.multirep_mode()) got_ei = propman.incident_energy @@ -560,11 +610,11 @@ def test_set_energy_bins_and_ei(self): def test_multirep_ei_iterate_over(self): propman = self.prop_man - propman.incident_energy=20 - propman.energy_bins=[-2,0.1,0.8] + propman.incident_energy = 20 + propman.energy_bins = [-2,0.1,0.8] self.assertFalse(PropertyManager.incident_energy.multirep_mode()) - ic=0 + ic = 0 for en in PropertyManager.incident_energy: ic+=1 self.assertAlmostEqual(en,20) @@ -581,11 +631,11 @@ def test_multirep_ei_iterate_over(self): self.assertEqual(ic,1) - propman.incident_energy=[20] - propman.energy_bins=[-2,0.1,0.8] + propman.incident_energy = [20] + propman.energy_bins = [-2,0.1,0.8] self.assertTrue(PropertyManager.incident_energy.multirep_mode()) - ic=0 + ic = 0 for en in PropertyManager.incident_energy: ic+=1 self.assertAlmostEqual(en,20) @@ -597,27 +647,27 @@ def test_multirep_ei_iterate_over(self): bins = PropertyManager.energy_bins.get_abs_range(propman) - self.assertAlmostEqual(bins[0],-2*20) - self.assertAlmostEqual(bins[1],0.1*20) - self.assertAlmostEqual(bins[2],0.8*20) + self.assertAlmostEqual(bins[0],-2 * 20) + self.assertAlmostEqual(bins[1],0.1 * 20) + self.assertAlmostEqual(bins[2],0.8 * 20) self.assertEqual(ic,1) - eng=[20,40,60] - propman.incident_energy=eng - propman.energy_bins=[-2,0.1,0.8] + eng = [20,40,60] + propman.incident_energy = eng + propman.energy_bins = [-2,0.1,0.8] self.assertTrue(PropertyManager.incident_energy.multirep_mode()) - ic=0 + ic = 0 for en in PropertyManager.incident_energy: self.assertAlmostEqual(en,eng[ic]) bins = PropertyManager.energy_bins.get_abs_range(propman) - self.assertAlmostEqual(bins[0],-2*en) - self.assertAlmostEqual(bins[1],0.1*en) - self.assertAlmostEqual(bins[2],0.8*en) + self.assertAlmostEqual(bins[0],-2 * en) + self.assertAlmostEqual(bins[1],0.1 * en) + self.assertAlmostEqual(bins[2],0.8 * en) ic+=1 self.assertEqual(ic,3) # - ic=0 + ic = 0 for en in PropertyManager.incident_energy: self.assertAlmostEqual(en,eng[ic]) ei_stored = PropertyManager.incident_energy.get_current() @@ -626,27 +676,29 @@ def test_multirep_ei_iterate_over(self): PropertyManager.incident_energy.set_current(en) bins = PropertyManager.energy_bins.get_abs_range(propman) - self.assertAlmostEqual(bins[0],-2*eng[ic]) - self.assertAlmostEqual(bins[1],0.1*eng[ic]) - self.assertAlmostEqual(bins[2],0.8*eng[ic]) + self.assertAlmostEqual(bins[0],-2 * eng[ic]) + self.assertAlmostEqual(bins[1],0.1 * eng[ic]) + self.assertAlmostEqual(bins[2],0.8 * eng[ic]) ic+=1 self.assertEqual(ic,3) - #def test_incident_energy_custom_enum(self): - ###### Custom enum does not work - # propman = self.prop_man - # en_source = [20,40,80] - # propman.incident_energy=en_source - # propman.energy_bins=[-2,0.1,0.8] - # self.assertTrue(PropertyManager.incident_energy.multirep_mode()) - - # ic=0 - # for ind,en in enumerate(PropertyManager.incident_energy): - # ic+=1 - # self.assertAlmostEqual(en,en_source[ind]) - # en_internal = PropertyManager.incident_energy.get_current() - # self.assertAlmostEqual(en_internal,en_source[ind]) - # self.assertEqual(ind,ic-1) + def test_incident_energy_custom_enum(self): + ##### Custom enum works in a peculiar way + propman = self.prop_man + en_source = [20,40,80] + propman.incident_energy = en_source + propman.energy_bins = [-2,0.1,0.8] + self.assertTrue(PropertyManager.incident_energy.multirep_mode()) + + ic = 0 + for ind,en in enumerate(PropertyManager.incident_energy): + ic+=1 + # propagate current energy value to incident energy class + PropertyManager.incident_energy.set_current(en,ind) + self.assertAlmostEqual(en,en_source[ind]) + en_internal = PropertyManager.incident_energy.get_current() + self.assertAlmostEqual(en_internal,en_source[ind]) + self.assertEqual(ind,ic - 1) def test_ignore_complex_defailts_changes_fom_instrument(self) : ws = CreateSampleWorkspace(NumBanks=1, BankPixelWidth=4, NumEvents=10) @@ -657,12 +709,12 @@ def test_ignore_complex_defailts_changes_fom_instrument(self) : propman = self.prop_man - propman.background_range=[20,40] + propman.background_range = [20,40] bkgd_range = propman.bkgd_range self.assertAlmostEqual(bkgd_range[0],20) self.assertAlmostEqual(bkgd_range[1],40) - changed_prop=propman.update_defaults_from_instrument( ws.getInstrument()) + changed_prop = propman.update_defaults_from_instrument(ws.getInstrument()) self.assertEqual(len(changed_prop),1) bkgd_range = propman.bkgd_range @@ -684,7 +736,7 @@ def test_ignore_complex_defailts_single_fom_instrument(self) : self.assertAlmostEqual(bkgd_range[0],mari_bkgd_range[0]) self.assertAlmostEqual(bkgd_range[1],40) - changed_prop=propman.update_defaults_from_instrument( ws.getInstrument()) + changed_prop = propman.update_defaults_from_instrument(ws.getInstrument()) self.assertEqual(len(changed_prop),2) bkgd_range = propman.bkgd_range @@ -693,55 +745,55 @@ def test_ignore_complex_defailts_single_fom_instrument(self) : def test_monovan_integration_range(self): - propman = self.prop_man + propman = self.prop_man - propman.incident_energy = 10 - propman.monovan_lo_frac = -0.6 - propman.monovan_hi_frac = 0.7 + propman.incident_energy = 10 + propman.monovan_lo_frac = -0.6 + propman.monovan_hi_frac = 0.7 - range = propman.abs_units_van_range - self.assertAlmostEqual(range[0],-6.) - self.assertAlmostEqual(range[1], 7.) + range = propman.abs_units_van_range + self.assertAlmostEqual(range[0],-6.) + self.assertAlmostEqual(range[1], 7.) - range = propman.monovan_integr_range - self.assertAlmostEqual(range[0],-6.) - self.assertAlmostEqual(range[1], 7.) + range = propman.monovan_integr_range + self.assertAlmostEqual(range[0],-6.) + self.assertAlmostEqual(range[1], 7.) - propman.monovan_lo_value = -10 - propman.monovan_hi_value = 10 + propman.monovan_lo_value = -10 + propman.monovan_hi_value = 10 - range = propman.abs_units_van_range - self.assertAlmostEqual(range[0],-6.) - self.assertAlmostEqual(range[1], 7.) + range = propman.abs_units_van_range + self.assertAlmostEqual(range[0],-6.) + self.assertAlmostEqual(range[1], 7.) - propman.abs_units_van_range=[-40,40] - self.assertAlmostEqual(propman.monovan_lo_value,-40) - self.assertAlmostEqual(propman.monovan_hi_value,40) + propman.abs_units_van_range = [-40,40] + self.assertAlmostEqual(propman.monovan_lo_value,-40) + self.assertAlmostEqual(propman.monovan_hi_value,40) - range = propman.monovan_integr_range - self.assertAlmostEqual(range[0],-40) - self.assertAlmostEqual(range[1], 40) + range = propman.monovan_integr_range + self.assertAlmostEqual(range[0],-40) + self.assertAlmostEqual(range[1], 40) - propman.abs_units_van_range=None + propman.abs_units_van_range = None - range = propman.monovan_integr_range - self.assertAlmostEqual(range[0],-6.) - self.assertAlmostEqual(range[1], 7.) - # - propman.monovan_lo_frac = -0.7 - range = propman.monovan_integr_range - self.assertAlmostEqual(range[0],-7.) + range = propman.monovan_integr_range + self.assertAlmostEqual(range[0],-6.) + self.assertAlmostEqual(range[1], 7.) + # + propman.monovan_lo_frac = -0.7 + range = propman.monovan_integr_range + self.assertAlmostEqual(range[0],-7.) def test_save_filename(self): - propman = self.prop_man + propman = self.prop_man - propman.incident_energy = 10 - propman.sample_run = 0 - propman.monovan_run = None + propman.incident_energy = 10 + propman.sample_run = 0 + propman.monovan_run = None - name = propman.save_file_name - self.assertEqual(name,'MAR00000Ei10d00meV') + name = propman.save_file_name + self.assertEqual(name,'MAR00000Ei10d00meV') def test_log_to_Mantid(self): propman = self.prop_man @@ -787,7 +839,7 @@ def test_hadmask_options_locked(self): self.assertFalse(propman1.use_hard_mask_only) self.assertEqual(propman1.hard_mask_file,'a_hard_mask_file.msk') self.assertTrue(propman1.run_diagnostics) - changed_prop=propman1.getChangedProperties() + changed_prop = propman1.getChangedProperties() self.assertEqual(len(changed_prop),2) @@ -798,7 +850,7 @@ def test_hadmask_options_locked(self): SetInstrumentParameter(ws,ParameterName="use_hard_mask_only",Value="True",ParameterType="String") # verify if changed properties list does not change anything - changed_prop=propman1.update_defaults_from_instrument( ws.getInstrument()) + changed_prop = propman1.update_defaults_from_instrument(ws.getInstrument()) self.assertEqual(len(changed_prop),4) self.assertFalse(propman1.use_hard_mask_only) self.assertEqual(propman1.hard_mask_file,'a_hard_mask_file.msk') @@ -808,13 +860,24 @@ def test_hadmask_options_locked(self): propman1.hardmaskOnly = 'more_hard_mask_file' # verify if changed properties list does not change anything - changed_prop=propman1.update_defaults_from_instrument( ws.getInstrument()) + changed_prop = propman1.update_defaults_from_instrument(ws.getInstrument()) self.assertTrue(propman1.use_hard_mask_only) self.assertEqual(propman1.hard_mask_file,'more_hard_mask_file.msk') self.assertTrue(propman1.run_diagnostics) - + def test_sum_runs(self): + propman = self.prop_man + propman.sum_runs = True + self.assertTrue(propman.sum_runs) + propman.sum_runs = False + self.assertFalse(propman.sum_runs) + + propman.sum_runs = 10 #TODO should we define number of runs to sum? + self.assertTrue(propman.sum_runs) + propman.sum_runs = 0 + self.assertFalse(propman.sum_runs) + #def test_do_white(self) : # tReducer = self.reducer # monovan = 1000 @@ -824,7 +887,6 @@ def test_hadmask_options_locked(self): - def test_monitors_list(self): propman = self.prop_man mons = propman.get_used_monitors_list() @@ -847,17 +909,17 @@ def test_mon2_integration_range(self): self.assertAlmostEqual(range[0],8.) self.assertAlmostEqual(range[1],12.) - propman.mon2_norm_energy_range=[0.7,1.3] + propman.mon2_norm_energy_range = [0.7,1.3] range = propman.mon2_norm_energy_range self.assertAlmostEqual(range[0],7.) self.assertAlmostEqual(range[1],13.) - propman.mon2_norm_energy_range='[0.5,1.5]' + propman.mon2_norm_energy_range = '[0.5,1.5]' range = propman.mon2_norm_energy_range self.assertAlmostEqual(range[0],5.) self.assertAlmostEqual(range[1],15.) - propman.mon2_norm_energy_range='0.6,1.4' + propman.mon2_norm_energy_range = '0.6,1.4' range = propman.mon2_norm_energy_range self.assertAlmostEqual(range[0],6.) self.assertAlmostEqual(range[1],14.) @@ -867,31 +929,49 @@ def test_mon2_integration_range(self): self.assertRaises(KeyError,setattr,propman,'mon2_norm_energy_range','[0.95,1.05,4]') self.assertRaises(KeyError,setattr,propman,'mon2_norm_energy_range','[0.05,0.9]') - propman.mon2_norm_energy_range='0.95,1.05' + propman.mon2_norm_energy_range = '0.95,1.05' + range = propman.mon2_norm_energy_range + self.assertAlmostEqual(range[0],9.5) + self.assertAlmostEqual(range[1],10.5) + +# Test multirep mode + propman.incident_energy = [10,20,30] range = propman.mon2_norm_energy_range self.assertAlmostEqual(range[0],9.5) self.assertAlmostEqual(range[1],10.5) + PropertyManager.incident_energy.next() + range = propman.mon2_norm_energy_range + self.assertAlmostEqual(range[0],2 * 9.5) + self.assertAlmostEqual(range[1],2 * 10.5) + + PropertyManager.incident_energy.next() + range = propman.mon2_norm_energy_range + self.assertAlmostEqual(range[0],3 * 9.5) + self.assertAlmostEqual(range[1],3 * 10.5) + + + def test_multirep_tof_specta_list(self): propman = self.prop_man sp = propman.multirep_tof_specta_list - self.assertTrue(len(sp)==2) + self.assertTrue(len(sp) == 2) self.assertEqual(sp[0],5) - propman.multirep_tof_specta_list='10' + propman.multirep_tof_specta_list = '10' sp = propman.multirep_tof_specta_list - self.assertTrue(len(sp)==1) + self.assertTrue(len(sp) == 1) self.assertEqual(sp[0],10) - propman.multirep_tof_specta_list='10,11,13,15' + propman.multirep_tof_specta_list = '10,11,13,15' sp = propman.multirep_tof_specta_list - self.assertTrue(len(sp)==4) + self.assertTrue(len(sp) == 4) self.assertEqual(sp[3],15) def test_mono_correction_factor(self): propman = self.prop_man - propman.incident_energy=[10,20] + propman.incident_energy = [10,20] #propman.m PropertyManager.mono_correction_factor.set_cash_mono_run_number(11015) @@ -913,7 +993,94 @@ def test_mono_correction_factor(self): PropertyManager.mono_correction_factor.set_cash_mono_run_number(11060) self.assertTrue(PropertyManager.mono_correction_factor.get_val_from_cash(propman) is None) -if __name__=="__main__": + def test_mono_file_properties(self): + propman = self.prop_man + propman.wb_run = 11001 + sw = CreateSampleWorkspace(NumBanks=1, BankPixelWidth=4, NumEvents=10) + propman.monovan_run = sw + propman.mask_run = CloneWorkspace(sw,OutputWorkspace='mask_clone') + propman.map_file = None + propman.hard_mask_file = 'testmasking.xml' + propman.det_cal_file = 11001 + propman.monovan_mapfile = None + + + file_prop = propman._get_properties_with_files() + + self.assertEqual(len(file_prop),3) + self.assertTrue('wb_run' in file_prop) + self.assertFalse('monovan_run' in file_prop) + self.assertFalse('mask_run' in file_prop) + self.assertFalse('wb_for_monovan_run' in file_prop) + + self.assertTrue('hard_mask_file' in file_prop) + self.assertTrue('det_cal_file' in file_prop) + + ok,fail_list = propman._check_file_properties() + self.assertTrue(ok) + + api.AnalysisDataService.clear() + + propman.monovan_run = 11002 + propman.mask_run = None + propman.wb_for_monovan_run = 11001 + propman.map_file = 'some_missing_map' + + ok,fail_list = propman._check_file_properties() + self.assertFalse(ok) + self.assertEqual(len(fail_list),2) + self.assertTrue('monovan_run' in fail_list) + self.assertTrue('map_file' in fail_list) + + def test_find_files2sum(self): + propman = self.prop_man + propman.sample_run = [11001,11111] + + propman.sum_runs = False + ok,not_found,found = propman.find_files_to_sum() + self.assertTrue(ok) + self.assertEqual(len(not_found),0) + self.assertEqual(len(found),0) + + propman.sum_runs = True + ok,not_found,found = propman.find_files_to_sum() + self.assertFalse(ok) + self.assertEqual(len(not_found),1) + self.assertEqual(len(found),1) + self.assertEqual(not_found[0],11111) + self.assertEqual(found[0],11001) + + + ok,err_list = propman._check_file_properties() + self.assertFalse(ok) + self.assertEqual(len(err_list),2) + self.assertTrue('missing_runs_toSum' in err_list) + self.assertEqual(err_list['missing_runs_toSum'],'[11111]') + + def test_custom_print(self): + + propman = self.prop_man + propman.sample_run = 1000 + propman.incident_energy = 20. + + def custom_print(propman,PropertyManager): + + ei = propman.incident_energy + run_n = PropertyManager.sample_run.run_number() + name = "RUN{0}atEi{1:<4.1f}meV_One2One".format(run_n,ei) + return name + + PropertyManager.save_file_name.set_custom_print(custom_print) + + + self.assertEqual(propman.save_file_name,'RUN1000atEi20.0meV_One2One') + + propman.sample_run = 2000 + self.assertEqual(propman.save_file_name,'RUN2000atEi20.0meV_One2One') + # clean up + PropertyManager.save_file_name.set_custom_print(None) + +if __name__ == "__main__": unittest.main() #tester = DirectPropertyManagerTest('test_set_energy_bins_and_ei') #tester.run() diff --git a/Code/Mantid/scripts/test/MariReduction.py b/Code/Mantid/scripts/test/MariReduction.py index 44a63b6fa310..69b940459d6b 100644 --- a/Code/Mantid/scripts/test/MariReduction.py +++ b/Code/Mantid/scripts/test/MariReduction.py @@ -1,4 +1,7 @@ """ Sample MARI reduction scrip used in testing ReductionWrapper """ +import os +#os.environ["PATH"] =\ +#r"c:/Mantid/Code/builds/br_10881/bin/Release;"+os.environ["PATH"] from Direct.ReductionWrapper import * try: @@ -13,47 +16,62 @@ class ReduceMARI(ReductionWrapper): #-------------------------------------------------------------------------------------------------# @MainProperties def def_main_properties(self): - """ Define main properties used in reduction """ - prop = {} - prop['sample_run'] = 11001 - prop['wb_run'] = 11060 - prop['incident_energy'] = 12 - prop['energy_bins'] = [-11,0.05,11] - - # Absolute units reduction properties. - prop['monovan_run'] = 11015 - prop['sample_mass'] = 10 - prop['sample_rmm'] = 435.96 - return prop + + """ Define main properties used in reduction """ + prop = {} + prop['sample_run'] = 11001 + prop['wb_run'] = 11060 + prop['incident_energy'] = 12 + prop['energy_bins'] = [-11,0.05,11] + + # Absolute units reduction properties. + prop['monovan_run'] = 11015 + prop['sample_mass'] = 10 + prop['sample_rmm'] = 435.96 + return prop #-------------------------------------------------------------------------------------------------# @AdvancedProperties def def_advanced_properties(self): - """ separation between simple and advanced properties depends - on scientist, experiment and user. - main properties override advanced properties. - """ - prop = {} - prop['map_file'] = "mari_res.map" - prop['monovan_mapfile'] = "mari_res.map" - prop['hard_mask_file'] = "mar11015.msk" - prop['det_cal_file'] = "11060" - prop['save_format'] = '' - return prop + """ separation between simple and advanced properties depends + on scientist, experiment and user. + main properties override advanced properties. + """ + prop = {} + prop['map_file'] = "mari_res.map" + prop['monovan_mapfile'] = "mari_res.map" + prop['hard_mask_file'] = "mar11015.msk" + prop['det_cal_file'] = "11060" + prop['save_format'] = '' + return prop # #-------------------------------------------------------------------------------------------------# @iliad def reduce(self,input_file=None,output_directory=None): - """ Method executes reduction over single file + """ Method executes reduction over single file + Overload only if custom reduction is needed + """ + ws = ReductionWrapper.reduce(self,input_file,output_directory) + #SaveNexus(ws,Filename = 'MARNewReduction.nxs') + return ws +#------------------------------------------------------------------------------------------------ # + def validate_result(self,build_validation=False): + """ Change this method to verify different results """ - Overload only if custom reduction is needed - """ - ws = ReductionWrapper.reduce(input_file,output_directory) - #SaveNexus(ws,Filename = 'MARNewReduction.nxs') - return ws + # Two commented code rows below define location of the validation file in this script folder + # (which is incorrect for Mantid development, as the files are on the data search path or + # mantid distribution, as the files are not there) + #run_dir = os.path.dirname(os.path.realpath(__file__)) + #validation_file = os.path.join(run_dir,"MARIReduction.nxs") + + # build_validation -- if true, build and overwrite new workspace rather then validating the old one + # if file is missing, the validation tries to build it + rez,message = ReductionWrapper.build_or_validate_result(self,11001,"MARIReduction.nxs", + build_validation,1.e-3) + return rez,message def __init__(self,web_var=None): - """ sets properties defaults for the instrument with Name""" - ReductionWrapper.__init__(self,'MAR',web_var) + """ sets properties defaults for the instrument with Name""" + ReductionWrapper.__init__(self,'MAR',web_var) #-------------------------------------------------------------------------------------------------# #-------------------------------------------------------------------------------------------------# #-------------------------------------------------------------------------------------------------# @@ -79,28 +97,30 @@ def main(input_file=None,output_directory=None): ##### Here one sets up folders where to find input data and where to save results ##### # It can be done here or from Mantid GUI # Folder where map files are located: - map_mask_dir = 'd:/Data/MantidSystemTests/Data' + map_mask_dir = 'd:/Data/MantidSystemTests/Data' # folder where input data can be found - data_dir = 'd:/Data/Mantid_Testing/14_11_27' - # auxiliary folder with results - ref_data_dir = 'd:/Data/MantidSystemTests/SystemTests/AnalysisTests/ReferenceResults' - # Set input path to - config.setDataSearchDirs('{0};{1};{2}'.format(data_dir,map_mask_dir,ref_data_dir)) - # use appendDataSearch directory to add to existing data search path - #config.appendDataSearchDir('d:/Data/Mantid_GIT/Test/AutoTestData') - # folder to save resulting spe/nxspe files. - config['defaultsave.directory'] = data_dir + data_dir = 'd:/Data/Mantid_Testing/14_11_27' + # auxiliary folder with results + ref_data_dir = 'd:/Data/MantidSystemTests/SystemTests/AnalysisTests/ReferenceResults' + # Set input path to + config.setDataSearchDirs('{0};{1};{2}'.format(data_dir,map_mask_dir,ref_data_dir)) + # use appendDataSearch directory to add to existing data search path + #config.appendDataSearchDir('d:/Data/Mantid_GIT/Test/AutoTestData') + # folder to save resulting spe/nxspe files. + config['defaultsave.directory'] = data_dir ###### Initialize reduction class above and set up reduction properties. Note no parameters ###### - rd = ReduceMARI() - # set up advanced and main properties - rd.def_advanced_properties() - rd.def_main_properties() - - # uncomment rows below to save web variables to use in web services. - #run_dir = os.path.dirname(os.path.realpath(__file__)) - #file = os.path.join(run_dir,'reduce_vars.py') - #rd.save_web_variables(file) + rd = ReduceMARI() + # set up advanced and main properties + rd.def_advanced_properties() + rd.def_main_properties() - rd.reduce() + # uncomment rows below to save web variables to use in web services. + #run_dir = os.path.dirname(os.path.realpath(__file__)) + #file = os.path.join(run_dir,'reduce_vars.py') + #rd.save_web_variables(file) + # Web-like reduction over sequence of files + #rd.reduce() +###### Run reduction on all files provided as parameters ###### + red_ws = rd.run_reduction() diff --git a/Code/Mantid/scripts/test/ReductionWrapperTest.py b/Code/Mantid/scripts/test/ReductionWrapperTest.py index cda0accc84f1..83f558655efa 100644 --- a/Code/Mantid/scripts/test/ReductionWrapperTest.py +++ b/Code/Mantid/scripts/test/ReductionWrapperTest.py @@ -2,7 +2,7 @@ #os.environ["PATH"] = r"c:/Mantid/Code/builds/br_master/bin/Release;"+os.environ["PATH"] from mantid.simpleapi import * -from mantid import api +from mantid import api,config from Direct.ReductionWrapper import ReductionWrapper import MariReduction as mr @@ -78,6 +78,56 @@ def test_export_advanced_values(self): if os.path.isfile(fcomp): os.remove(fcomp) + def test_validate_settings(self): + dsp = config.getDataSearchDirs() + # clear all not to find any files + config.setDataSearchDirs('') + + red = mr.ReduceMARI() + ok,level,errors = red.validate_settings() + + self.assertFalse(ok) + self.assertEqual(level,2) + self.assertEqual(len(errors),7) + + + + + # this run should be in data search directory for basic Mantid + red.reducer.wb_run = 11001 + red.reducer.det_cal_file = '11001' + red.reducer.monovan_run = None + red.reducer.hard_mask_file = None + red.reducer.map_file = None + red.reducer.save_format = 'nxspe' + + path = [] + for item in dsp: + path.append(item) + config.setDataSearchDirs(path) + + + # hack -- let's pretend we are running from webservices + # but web var are empty (not to overwrite values above) + red._run_from_web = True + red._wvs.standard_vars={} + red._wvs.advanced_vars={} + ok,level,errors = red.validate_settings() + + self.assertTrue(ok) + self.assertEqual(level,0) + self.assertEqual(len(errors),0) + + # this is how we set it up from web + red._wvs.advanced_vars={'save_format':''} + ok,level,errors = red.validate_settings() + + self.assertFalse(ok) + self.assertEqual(level,1) + self.assertEqual(len(errors),1) + + + if __name__=="__main__": unittest.main() diff --git a/Code/Mantid/scripts/test/RunDescriptorTest.py b/Code/Mantid/scripts/test/RunDescriptorTest.py index 5ab61fe01be7..e4f60adca811 100644 --- a/Code/Mantid/scripts/test/RunDescriptorTest.py +++ b/Code/Mantid/scripts/test/RunDescriptorTest.py @@ -1,5 +1,5 @@ import os,sys,inspect -#os.environ["PATH"] = r"c:/Mantid/Code/builds/br_master/bin/Release"+os.environ["PATH"] +#os.environ["PATH"] = r"d:\Data\Mantid_GIT_test\Code\builds\br_master\bin\Release;"+os.environ["PATH"] from mantid.simpleapi import * from mantid import api import unittest @@ -22,7 +22,7 @@ def setUp(self): if self.prop_man == None or type(self.prop_man) != type(PropertyManager): self.prop_man = PropertyManager("MAR") def tearDown(self): - pass + api.AnalysisDataService.clear() @staticmethod def getInstrument(InstrumentName='MAR'): @@ -31,7 +31,7 @@ def getInstrument(InstrumentName='MAR'): idf_file=api.ExperimentInfo.getInstrumentFilename(InstrumentName) tmp_ws_name = '__empty_' + InstrumentName if not mtd.doesExist(tmp_ws_name): - LoadEmptyInstrument(Filename=idf_file,OutputWorkspace=tmp_ws_name) + LoadEmptyInstrument(Filename=idf_file,OutputWorkspace=tmp_ws_name) return mtd[tmp_ws_name].getInstrument() @@ -53,21 +53,41 @@ def test_descr_basic(self): self.assertEqual(rez,'Success!') + propman.sample_run='MAR11001.RAW' + self.assertFalse('run_ws' in mtd) + self.assertEqual(PropertyManager.sample_run.run_number(),11001) + self.assertEqual(PropertyManager.sample_run._fext,'.RAW') + + + def test_descr_dependend(self): propman = self.prop_man propman.wb_run = 100 + self.assertTrue(PropertyManager.wb_run.has_own_value()) self.assertEqual(propman.wb_run,100) self.assertEqual(propman.wb_for_monovan_run,100) + self.assertFalse(PropertyManager.wb_for_monovan_run.has_own_value()) + self.assertTrue(PropertyManager.wb_run.has_own_value()) propman.wb_for_monovan_run = 200 self.assertEqual(propman.wb_for_monovan_run,200) self.assertEqual(propman.wb_run,100) + self.assertTrue(PropertyManager.wb_run.has_own_value()) + self.assertTrue(PropertyManager.wb_for_monovan_run.has_own_value()) + + propman.wb_for_monovan_run = None + self.assertFalse(PropertyManager.wb_for_monovan_run.has_own_value()) + self.assertEqual(propman.wb_for_monovan_run,100) + self.assertEqual(propman.wb_run,100) + + def test_find_file(self): propman = self.prop_man propman.sample_run = 11001 - file=PropertyManager.sample_run.find_file() + ok,file=PropertyManager.sample_run.find_file() + self.assertTrue(ok) self.assertTrue(len(file)>0) ext = PropertyManager.sample_run.get_file_ext() @@ -95,10 +115,10 @@ def test_find_file(self): propman.sample_run = 101111 PropertyManager.sample_run.set_file_ext('nxs') - file=PropertyManager.sample_run.find_file() + ok,file=PropertyManager.sample_run.find_file() self.assertEqual(testFile1,os.path.normpath(file)) PropertyManager.sample_run.set_file_ext('.raw') - file=PropertyManager.sample_run.find_file() + ok,file=PropertyManager.sample_run.find_file() self.assertEqual(testFile2,os.path.normpath(file)) os.remove(testFile1) @@ -109,12 +129,12 @@ def test_load_workspace(self): # MARI run with number 11001 and extension raw must among unit test files propman.sample_run = 11001 - PropertyManager.sample_run.set_file_ext('raw') + PropertyManager.sample_run.set_file_ext('nxs') ws = PropertyManager.sample_run.get_workspace() + self.assertEqual(PropertyManager.sample_run.get_file_ext(),'.raw') self.assertTrue(isinstance(ws, api.Workspace)) - self.assertEqual(ws.name(), PropertyManager.sample_run.get_ws_name()) mon_ws = PropertyManager.sample_run.get_monitors_ws() self.assertTrue(isinstance(mon_ws, api.Workspace)) @@ -140,12 +160,12 @@ def test_ws_name(self): propman = self.prop_man propman.sample_run = run_ws - self.assertEqual(PropertyManager.sample_run.get_ws_name(),'SR_run_ws') ws = PropertyManager.sample_run.get_workspace() self.assertEqual(ws.name(),'SR_run_ws') propman.sample_run = ws - self.assertEqual(PropertyManager.sample_run.get_ws_name(),'SR_run_ws') + ws = PropertyManager.sample_run.get_workspace() + self.assertEqual(ws.name(),'SR_run_ws') self.assertTrue('SR_run_ws' in mtd) propman.sample_run = 11001 @@ -154,12 +174,11 @@ def test_ws_name(self): propman.load_monitors_with_workspace = False ws = PropertyManager.sample_run.get_workspace() ws_name = ws.name() - self.assertEqual(PropertyManager.sample_run.get_ws_name(),ws_name) + self.assertEqual('SR_MAR011001',ws_name) self.assertTrue(ws_name in mtd) self.assertTrue(ws_name+'_monitors' in mtd) propman.sample_run = ws - self.assertEqual(PropertyManager.sample_run.get_ws_name(),ws_name) self.assertTrue(ws_name in mtd) ws1 = PropertyManager.sample_run.get_workspace() @@ -174,72 +193,64 @@ def test_ws_name(self): propman.sample_run = ws1 self.assertEqual(ws1.name(),PropertyManager.sample_run._ws_name) - ws_name = PropertyManager.sample_run.get_ws_name() + ws = PropertyManager.sample_run.get_workspace() + ws_name = ws.name() # if no workspace is available, attempt to get workspace name fails DeleteWorkspace(ws_name) - self.assertRaises(RuntimeError,PropertyManager.sample_run.get_ws_name) propman.sample_run = None self.assertFalse(ws_name+'_monitors' in mtd) - # name of empty property workspace - self.assertEqual(PropertyManager.sample_run.get_ws_name(),'SR_') + def test_assign_fname(self): + propman = self.prop_man + propman.sample_run = 'MAR11001.RAW' + + self.assertEqual(PropertyManager.sample_run.run_number(),11001) + self.assertEqual(PropertyManager.sample_run._fext,'.RAW') - def test_sum_runs(self): + def test_chop_ws_part(self): propman = self.prop_man - propman.sample_run = [11001,11001] - ws = PropertyManager.sample_run.get_workspace() - test_val1 = ws.dataY(3)[0] - test_val2 = ws.dataY(6)[100] - test_val3 = ws.dataY(50)[200] - self.assertEqual(ws.name(),'SR_MAR011001') - self.assertEqual(ws.getNEvents(),2455286) + ws=CreateSampleWorkspace(Function='Multiple Peaks', NumBanks=4, BankPixelWidth=1, NumEvents=100, XUnit='TOF', + XMin=2000, XMax=20000, BinWidth=1) - #propman.sample_run = [11001,11001] - propman.sum_runs = True - ws = PropertyManager.sample_run.get_workspace() - self.assertEqual(ws.name(),'SR_MAR011001SumOf2') - ws_name = PropertyManager.sample_run.get_ws_name() - self.assertEqual(ws.name(),ws_name) + ws_monitors=CreateSampleWorkspace(Function='Multiple Peaks', NumBanks=4, BankPixelWidth=1, NumEvents=100, XUnit='TOF', + XMin=2000, XMax=20000, BinWidth=1) - self.assertEqual(2*test_val1, ws.dataY(3)[0]) - self.assertEqual(2*test_val2, ws.dataY(6)[100]) - self.assertEqual(2*test_val3, ws.dataY(50)[200]) + propman.sample_run = ws + ws1 = PropertyManager.sample_run.chop_ws_part(None,(2000,1,5000),False,1,2) - propman.sample_run = "MAR11001.raw,11001.nxs,MAR11001.raw" - self.assertFalse('SR_MAR011001SumOf2' in mtd) - ws = PropertyManager.sample_run.get_workspace() - self.assertEqual(ws.name(),'SR_MAR011001SumOf3') - ws_name = PropertyManager.sample_run.get_ws_name() - self.assertEqual(ws.name(),ws_name) + rez=CheckWorkspacesMatch('SR_ws',ws1) + self.assertEqual(rez,'Success!') - self.assertEqual(3*test_val1, ws.dataY(3)[0]) - self.assertEqual(3*test_val2, ws.dataY(6)[100]) - self.assertEqual(3*test_val3, ws.dataY(50)[200]) + wsc=PropertyManager.sample_run.get_workspace() + x =wsc.readX(0) + self.assertAlmostEqual(x[0],2000) + self.assertAlmostEqual(x[-1],5000) - propman.sum_runs = 2 - propman.sample_run = "/home/my_path/MAR11001.raw,c:/somewhere/11001.nxs,MAR11001.raw" - self.assertFalse('SR_MAR011001SumOf3' in mtd) - self.assertFalse('SR_MAR011001SumOf2' in mtd) - ws = PropertyManager.sample_run.get_workspace() - self.assertEqual(ws.name(),'SR_MAR011001SumOf2') - ws_name = PropertyManager.sample_run.get_ws_name() - self.assertEqual(ws.name(),ws_name) + self.assertEqual(wsc.name(),'SR_#1/2#ws') + self.assertTrue('SR_#1/2#ws_monitors' in mtd) - def test_assign_fname(self): - propman = self.prop_man - propman.sample_run = 'MAR11001.RAW' + ws1 = PropertyManager.sample_run.chop_ws_part(ws1,(10000,100,20000),True,2,2) + x =ws1.readX(0) + self.assertAlmostEqual(x[0],10000) + self.assertAlmostEqual(x[-1],20000) + + self.assertEqual(ws1.name(),'SR_#2/2#ws') + self.assertTrue('SR_#2/2#ws_monitors' in mtd) + - self.assertEqual(PropertyManager.sample_run.run_number(),11001) - self.assertEqual(PropertyManager.sample_run._run_ext,'.raw') def test_get_run_list(self): + """ verify the logic behind setting a run file as + a sample run when run list is defined + + """ propman = PropertyManager('MAR') propman.sample_run = [10204] @@ -247,27 +258,45 @@ def test_get_run_list(self): runs = PropertyManager.sample_run.get_run_list() self.assertEqual(len(runs),1) self.assertEqual(runs[0],10204) + sum_list,sum_ws,n_sum = PropertyManager.sample_run.get_runs_to_sum() + self.assertEqual(len(sum_list),0) + self.assertTrue(sum_ws is None) + self.assertEqual(n_sum,0) + + + # the same run list changes nothing + propman.sample_run = [10204] + self.assertEqual(propman.sample_run,10204) + runs = PropertyManager.sample_run.get_run_list() + self.assertEqual(len(runs),1) + self.assertEqual(runs[0],10204) + propman.sample_run = [11230,10382,10009] self.assertEqual(propman.sample_run,11230) + + propman.sum_runs = True + self.assertEqual(propman.sample_run,10009) propman.sample_run = [11231,10382,10010] self.assertEqual(propman.sample_run,10010) - sum_list = PropertyManager.sum_runs.get_run_list2sum() + sum_list,sum_ws,n_sum = PropertyManager.sample_run.get_runs_to_sum() self.assertEqual(len(sum_list),3) - runs = PropertyManager.sample_run.get_run_list() self.assertEqual(runs[0],sum_list[0]) + # Autoreduction workflow with summation. Runs appear + # one by one and summed together when next run appears propman.sample_run = 11231 - sum_list = PropertyManager.sum_runs.get_run_list2sum() + sum_list,sum_ws,n_sum = PropertyManager.sample_run.get_runs_to_sum() + self.assertEqual(len(sum_list),1) self.assertEqual(sum_list[0],11231) self.assertEqual(propman.sample_run,11231) propman.sample_run = 10382 - sum_list = PropertyManager.sum_runs.get_run_list2sum() + sum_list,sum_ws,n_sum = PropertyManager.sample_run.get_runs_to_sum() self.assertEqual(len(sum_list),2) self.assertEqual(sum_list[0],11231) self.assertEqual(sum_list[1],10382) @@ -276,7 +305,7 @@ def test_get_run_list(self): self.assertEqual(len(runs),3) propman.sample_run = 10010 - sum_list = PropertyManager.sum_runs.get_run_list2sum() + sum_list,sum_ws,n_sum = PropertyManager.sample_run.get_runs_to_sum() self.assertEqual(len(sum_list),3) self.assertEqual(sum_list[0],11231) self.assertEqual(sum_list[1],10382) @@ -285,50 +314,174 @@ def test_get_run_list(self): self.assertEqual(len(runs),3) self.assertTrue(propman.sum_runs) + # check asigning file with path + propman.sample_run = 'c:/data/MAR10382.nxs' + self.assertEqual(propman.sample_run,10382) + self.assertEqual(PropertyManager.sample_run._run_list._last_ind2sum,1) + self.assertEqual(PropertyManager.sample_run._run_list._file_path[1],'c:/data') + self.assertEqual(PropertyManager.sample_run._run_list._fext[1],'.nxs') - propman.sample_run = 10011 - sum_list = PropertyManager.sum_runs.get_run_list2sum() - self.assertEqual(len(sum_list),0) + + # check extend when summing + propman.sample_run = 10999 + sum_list,sum_ws,n_sum = PropertyManager.sample_run.get_runs_to_sum() + self.assertEqual(len(sum_list),4) + self.assertEqual(sum_list[0],11231) + self.assertEqual(sum_list[1],10382) + self.assertEqual(sum_list[2],10010) + self.assertEqual(sum_list[3],10999) + self.assertTrue(propman.sum_runs) runs = PropertyManager.sample_run.get_run_list() - self.assertEqual(len(runs),1) - self.assertEqual(runs[0],10011) - self.assertFalse(propman.sum_runs) + self.assertEqual(len(runs),4) + self.assertTrue(propman.sum_runs) - def test_chop_ws_part(self): + + propman.sum_runs=False + run_list = PropertyManager.sample_run.get_run_list() + self.assertEqual(len(run_list),4) + self.assertEqual(propman.sample_run,11231) + sum_list,sum_ws,n_sum = PropertyManager.sample_run.get_runs_to_sum() + self.assertEqual(len(sum_list),0) + + # check clear list when not summing + propman.sample_run = 11999 + run_list = PropertyManager.sample_run.get_run_list() + self.assertEqual(len(run_list),1) + + def test_sum_runs(self): propman = self.prop_man - ws=CreateSampleWorkspace(Function='Multiple Peaks', NumBanks=4, BankPixelWidth=1, NumEvents=100, XUnit='TOF', - XMin=2000, XMax=20000, BinWidth=1) + propman.sample_run = [11001,11001] + ws = PropertyManager.sample_run.get_workspace() + test_val1 = ws.dataY(3)[0] + test_val2 = ws.dataY(6)[100] + test_val3 = ws.dataY(50)[200] + self.assertEqual(ws.name(),'SR_MAR011001') + self.assertEqual(ws.getNEvents(),2455286) - ws_monitors=CreateSampleWorkspace(Function='Multiple Peaks', NumBanks=4, BankPixelWidth=1, NumEvents=100, XUnit='TOF', - XMin=2000, XMax=20000, BinWidth=1) + #propman.sample_run = [11001,11001] + propman.sum_runs = True + self.assertFalse('SR_MAR011001' in mtd) + ws = PropertyManager.sample_run.get_workspace() + self.assertEqual(ws.name(),'SR_MAR011001SumOf2') + + self.assertEqual(2*test_val1, ws.dataY(3)[0]) + self.assertEqual(2*test_val2, ws.dataY(6)[100]) + self.assertEqual(2*test_val3, ws.dataY(50)[200]) - propman.sample_run = ws - ws1 = PropertyManager.sample_run.chop_ws_part(None,(2000,1,5000),False,1,2) + propman.sample_run = "MAR11001.raw,11001.nxs,MAR11001.raw" + self.assertFalse('SR_MAR011001SumOf2' in mtd) + ws = PropertyManager.sample_run.get_workspace() + self.assertEqual(ws.name(),'SR_MAR011001SumOf3') + + self.assertEqual(3*test_val1, ws.dataY(3)[0]) + self.assertEqual(3*test_val2, ws.dataY(6)[100]) + self.assertEqual(3*test_val3, ws.dataY(50)[200]) - rez=CheckWorkspacesMatch('SR_ws',ws1) - self.assertEqual(rez,'Success!') + #TODO: Partial sum is not implemented. Should it? + #propman.sum_runs = 2 + #propman.sample_run = "/home/my_path/MAR11001.raw,c:/somewhere/11001.nxs,MAR11001.raw" + #self.assertFalse('SR_MAR011001SumOf3' in mtd) + #self.assertFalse('SR_MAR011001SumOf2' in mtd) + #ws = PropertyManager.sample_run.get_workspace() + #self.assertEqual(ws.name(),'SR_MAR011001SumOf2') - wsc=PropertyManager.sample_run.get_workspace() - x =wsc.readX(0) - self.assertAlmostEqual(x[0],2000) - self.assertAlmostEqual(x[-1],5000) - self.assertEqual(wsc.name(),'SR_#1/2#ws') - self.assertTrue('SR_#1/2#ws_monitors' in mtd) + propman.sample_run = 11111 + sum_list,sum_ws,n_sum = PropertyManager.sample_run.get_runs_to_sum() + self.assertEqual(len(sum_list),4) + runs = PropertyManager.sample_run.get_run_list() + self.assertEqual(len(runs),4) + self.assertEqual(runs[3],11111) + self.assertTrue(propman.sum_runs) + self.assertTrue('SR_MAR011001SumOf3' in mtd) + propman.cashe_sum_ws = True # Not used at this stage but will be used at loading + PropertyManager.sample_run._run_list.set_cashed_sum_ws(mtd['SR_MAR011001SumOf3'],'SumWS_cashe') + self.assertTrue('SumWS_cashe' in mtd) + self.assertFalse('SR_MAR011001SumOf3' in mtd) - ws1 = PropertyManager.sample_run.chop_ws_part(ws1,(10000,100,20000),True,2,2) - x =ws1.readX(0) - self.assertAlmostEqual(x[0],10000) - self.assertAlmostEqual(x[-1],20000) + sum_list,sum_ws,n_summed = PropertyManager.sample_run.get_runs_to_sum() + self.assertEqual(len(sum_list),1) + self.assertEqual(n_summed,3) + self.assertEqual(sum_ws.name(),'SumWS_cashe') + self.assertEqual(sum_list[0],11111) - self.assertEqual(ws1.name(),'SR_#2/2#ws') - self.assertTrue('SR_#2/2#ws_monitors' in mtd) + # file 1 does not exist, so can not be found. Otherwise it should load it + self.assertRaises(IOError,PropertyManager.sample_run.get_workspace) - api.AnalysisDataService.clear() + # Clear all + propman.sum_runs=False + self.assertFalse('SR_MAR011001SumOf3' in mtd) + # disabling sum_runs clears sum cash + self.assertFalse('SumWS_cashe' in mtd) + runs = PropertyManager.sample_run.get_run_list() + self.assertEqual(len(runs),4) + self.assertEqual(propman.sample_run,11001) + + propman.sample_run = 10111 + runs = PropertyManager.sample_run.get_run_list() + self.assertEqual(len(runs),1) + self.assertEqual(runs[0],10111) + self.assertEqual(propman.sample_run,10111) + sums,ws,n_sums = PropertyManager.sample_run.get_runs_to_sum() + self.assertEqual(len(sums),0) + self.assertTrue(ws is None) + self.assertEqual(n_sums,0) + + def test_find_runfiles(self): + propman = self.prop_man + propman.sample_run = [11001,11111] + files = PropertyManager.sample_run.get_run_file_list() + self.assertEqual(len(files),2) + + + nf,found=PropertyManager.sample_run._run_list.find_run_files('MAR') + self.assertEqual(len(nf),1) + self.assertEqual(len(found),1) + self.assertEqual(nf[0],11111) + + files = PropertyManager.sample_run.get_run_file_list() + self.assertEqual(len(files),2) + + def test_add_masks(self): + propman = self.prop_man + ws=CreateSampleWorkspace(Function='Multiple Peaks',WorkspaceType='Event', + NumBanks=4, BankPixelWidth=1, NumEvents=100, XUnit='TOF', + XMin=2000, XMax=20000, BinWidth=1) + + PropertyManager.sample_run.add_masked_ws(ws) + + masks,masked = PropertyManager.sample_run.get_masking() + self.assertEqual(masked,0) + self.assertTrue(isinstance(masks,api.MatrixWorkspace)) + ws_name = PropertyManager.sample_run._mask_ws_name + self.assertTrue(ws_name in mtd) + + propman.sample_run = None + self.assertFalse(ws_name in mtd) + + + def test_runDescriptorDependant(self): + propman = self.prop_man + self.assertTrue(PropertyManager.wb_run.has_own_value()) + propman.wb_for_monovan_run = None + self.assertFalse(PropertyManager.wb_for_monovan_run.has_own_value()) + propman.wb_run = 2000 + self.assertEqual(propman.wb_for_monovan_run,2000) + self.assertEqual(propman.wb_run,2000) + self.assertFalse(PropertyManager.wb_for_monovan_run.has_own_value()) + propman.wb_for_monovan_run = None + self.assertEqual(propman.wb_for_monovan_run,2000) + self.assertEqual(propman.wb_run,2000) + + + propman.wb_for_monovan_run = 3000 + self.assertTrue(PropertyManager.wb_for_monovan_run.has_own_value()) + self.assertEqual(propman.wb_run,2000) + self.assertEqual(propman.wb_for_monovan_run,3000) diff --git a/README.md b/README.md index 0057183c12e8..65158b33336e 100644 --- a/README.md +++ b/README.md @@ -11,5 +11,3 @@ Useful links * Issue tracking: http://trac.mantidproject.org/mantid/ * Build server: http://builds.mantidproject.org * Developer site: http://developer.mantidproject.org - -[![Bitdeli Badge](https://d2weczhvl823v0.cloudfront.net/mantidproject/mantid/trend.png)](https://bitdeli.com/free "Bitdeli Badge")